1: #include <stdio.h>
   2: #include <sys/types.h>
   3: 
   4: #define ASTERISK '*'        /* The '*' metacharacter */
   5: #define QUESTION '?'        /* The '?' metacharacter */
   6: #define LEFT_BRACKET '['    /* The '[' metacharacter */
   7: #define RIGHT_BRACKET ']'   /* The ']' metacharacter */
   8: 
   9: #define IS_OCTAL(ch) (ch >= '0' && ch <= '7')
  10: 
  11: typedef int BOOLEAN;
  12: #define VOID void
  13: #define TRUE 1
  14: #define FALSE 0
  15: #define EOS '\000'
  16: 
  17: static BOOLEAN do_list ();
  18: static char nextch ();
  19: static VOID list_parse ();
  20: 
  21: 
  22: /*
  23:  *  FUNCTION
  24:  *
  25:  *	match	test string for wildcard match
  26:  *
  27:  *  SYNOPSIS
  28:  *
  29:  *	BOOLEAN match (string, pattern)
  30:  *	register char *string;
  31:  *	register char *pattern;
  32:  *
  33:  *  DESCRIPTION
  34:  *
  35:  *	Test string for match using pattern.  The pattern may
  36:  *	contain the normal shell metacharacters for pattern
  37:  *	matching.  The '*' character matches any string,
  38:  *	including the null string.  The '?' character matches
  39:  *	any single character.  A list of characters enclosed
  40:  *	in '[' and ']' matches any character in the list.
  41:  *	If the first character following the beginning '['
  42:  *	is a '!' then any character not in the list is matched.
  43:  *
  44:  */
  45: 
  46: 
  47: /*
  48:  *  PSEUDO CODE
  49:  *
  50:  *	Begin match
  51:  *	    Switch on type of pattern character
  52:  *		Case ASTERISK:
  53:  *		    Attempt to match asterisk
  54:  *		    Break
  55:  *		Case QUESTION MARK:
  56:  *		    Attempt to match question mark
  57:  *		    Break
  58:  *		Case EOS:
  59:  *		    Match is result of EOS on string test
  60:  *		    Break
  61:  *		Case default:
  62:  *		    If explicit match then
  63:  *			Match is result of submatch
  64:  *		    Else
  65:  *			Match is FALSE
  66:  *		    End if
  67:  *		    Break
  68:  *	    End switch
  69:  *	    Return result of match test
  70:  *	End match
  71:  *
  72:  */
  73: 
  74: BOOLEAN match (string, pattern)
  75: register char *string;
  76: register char *pattern;
  77: {
  78:     register BOOLEAN ismatch;
  79: 
  80:     ismatch = FALSE;
  81:     switch (*pattern) {
  82:     case ASTERISK:
  83:         pattern++;
  84:         do {
  85:         ismatch = match (string, pattern);
  86:         } while (!ismatch && *string++ != EOS);
  87:         break;
  88:     case QUESTION:
  89:         if (*string != EOS) {
  90:         ismatch = match (++string, ++pattern);
  91:         }
  92:         break;
  93:     case EOS:
  94:         if (*string == EOS) {
  95:         ismatch = TRUE;
  96:         }
  97:         break;
  98:     case LEFT_BRACKET:
  99:         if (*string != EOS) {
 100:         ismatch = do_list (string, pattern);
 101:         }
 102:         break;
 103:     default:
 104:         if (*string++ == *pattern++) {
 105:         ismatch = match (string, pattern);
 106:         } else {
 107:         ismatch = FALSE;
 108:         }
 109:         break;
 110:     }
 111:     return (ismatch);
 112: }
 113: 
 114: 
 115: /*
 116:  *  FUNCTION
 117:  *
 118:  *	do_list    process a list and following substring
 119:  *
 120:  *  SYNOPSIS
 121:  *
 122:  *	static BOOLEAN do_list (string, pattern)
 123:  *	register char *string;
 124:  *	register char *pattern;
 125:  *
 126:  *  DESCRIPTION
 127:  *
 128:  *	Called when a list is found in the pattern.  Returns
 129:  *	TRUE if the current character matches the list and
 130:  *	the remaining substring matches the remaining pattern.
 131:  *
 132:  *	Returns FALSE if either the current character fails to
 133:  *	match the list or the list matches but the remaining
 134:  *	substring and subpattern's don't.
 135:  *
 136:  *  RESTRICTIONS
 137:  *
 138:  *	The mechanism used to match characters in an inclusive
 139:  *	pair (I.E. [a-d]) may not be portable to machines
 140:  *	in which the native character set is not ASCII.
 141:  *
 142:  *	The rules implemented here are:
 143:  *
 144:  *		(1)	The backslash character may be
 145:  *			used to quote any special character.
 146:  *			I.E.  "\]" and "\-" anywhere in list,
 147:  *			or "\!" at start of list.
 148:  *
 149:  *		(2)	The sequence \nnn becomes the character
 150:  *			given by nnn (in octal).
 151:  *
 152:  *		(3)	Any non-escaped ']' marks the end of list.
 153:  *
 154:  *		(4)	A list beginning with the special character
 155:  *			'!' matches any character NOT in list.
 156:  *			The '!' character is only special if it
 157:  *			is the first character in the list.
 158:  *
 159:  */
 160: 
 161: 
 162: /*
 163:  *  PSEUDO CODE
 164:  *
 165:  *	Begin do_list
 166:  *	    Default result is no match
 167:  *	    Skip over the opening left bracket
 168:  *	    If the next pattern character is a '!' then
 169:  *		List match gives FALSE
 170:  *		Skip over the '!' character
 171:  *	    Else
 172:  *		List match gives TRUE
 173:  *	    End if
 174:  *	    While not at closing bracket or EOS
 175:  *		Get lower and upper bounds
 176:  *		If character in bounds then
 177:  *		    Result is same as sense flag.
 178:  *		    Skip over rest of list
 179:  *		End if
 180:  *	    End while
 181:  *	    If match found then
 182:  *		If not at end of pattern then
 183:  *		    Call match with rest of pattern
 184:  *		End if
 185:  *	    End if
 186:  *	    Return match result
 187:  *	End do_list
 188:  *
 189:  */
 190: 
 191: static BOOLEAN do_list (string, pattern)
 192: register char *string;
 193: char *pattern;
 194: {
 195:     register BOOLEAN ismatch;
 196:     register BOOLEAN if_found;
 197:     register BOOLEAN if_not_found;
 198:     auto char lower;
 199:     auto char upper;
 200: 
 201:     pattern++;
 202:     if (*pattern == '!') {
 203:     if_found = FALSE;
 204:     if_not_found = TRUE;
 205:     pattern++;
 206:     } else {
 207:     if_found = TRUE;
 208:     if_not_found = FALSE;
 209:     }
 210:     ismatch = if_not_found;
 211:     while (*pattern != ']' && *pattern != EOS) {
 212:     list_parse (&pattern, &lower, &upper);
 213:     if (*string >= lower && *string <= upper) {
 214:         ismatch = if_found;
 215:         while (*pattern != ']' && *pattern != EOS) {pattern++;}
 216:     }
 217:     }
 218:     if (*pattern++ != ']') {
 219:     fprintf (stderr, "warning - character class error\n");
 220:     } else {
 221:     if (ismatch) {
 222:         ismatch = match (++string, pattern);
 223:     }
 224:     }
 225:     return (ismatch);
 226: }
 227: 
 228: 
 229: /*
 230:  *  FUNCTION
 231:  *
 232:  *	list_parse    parse part of list into lower and upper bounds
 233:  *
 234:  *  SYNOPSIS
 235:  *
 236:  *	static VOID list_parse (patp, lowp, highp)
 237:  *	char **patp;
 238:  *	char *lowp;
 239:  *	char *highp;
 240:  *
 241:  *  DESCRIPTION
 242:  *
 243:  *	Given pointer to a pattern pointer (patp), pointer to
 244:  *	a place to store lower bound (lowp), and pointer to a
 245:  *	place to store upper bound (highp), parses part of
 246:  *	the list, updating the pattern pointer in the process.
 247:  *
 248:  *	For list characters which are not part of a range,
 249:  *	the lower and upper bounds are set to that character.
 250:  *
 251:  */
 252: 
 253: static VOID list_parse (patp, lowp, highp)
 254: char **patp;
 255: char *lowp;
 256: char *highp;
 257: {
 258:     *lowp = nextch (patp);
 259:     if (**patp == '-') {
 260:     (*patp)++;
 261:     *highp = nextch (patp);
 262:     } else {
 263:     *highp = *lowp;
 264:     }
 265: }
 266: 
 267: 
 268: /*
 269:  *  FUNCTION
 270:  *
 271:  *	nextch	  determine next character in a pattern
 272:  *
 273:  *  SYNOPSIS
 274:  *
 275:  *	static char nextch (patp)
 276:  *	char **patp;
 277:  *
 278:  *  DESCRIPTION
 279:  *
 280:  *	Given pointer to a pointer to a pattern, uses the pattern
 281:  *	pointer to determine the next character in the pattern,
 282:  *	subject to translation of backslash-char and backslash-octal
 283:  *	sequences.
 284:  *
 285:  *	The character pointer is updated to point at the next pattern
 286:  *	character to be processed.
 287:  *
 288:  */
 289: 
 290: static char nextch (patp)
 291: char **patp;
 292: {
 293:     register char ch;
 294:     register char chsum;
 295:     register int count;
 296: 
 297:     ch = *(*patp)++;
 298:     if (ch == '\\') {
 299:     ch = *(*patp)++;
 300:     if (IS_OCTAL (ch)) {
 301:         chsum = 0;
 302:         for (count = 0; count < 3 && IS_OCTAL (ch); count++) {
 303:         chsum *= 8;
 304:         chsum += ch - '0';
 305:         ch = *(*patp)++;
 306:         }
 307:         (*patp)--;
 308:         ch = chsum;
 309:     }
 310:     }
 311:     return (ch);
 312: }

Defined functions

do_list defined in line 191; used 2 times
list_parse defined in line 253; used 2 times
match defined in line 74; used 5 times
nextch defined in line 290; used 3 times

Defined typedef's

BOOLEAN defined in line 11; used 7 times

Defined macros

ASTERISK defined in line 4; never used
EOS defined in line 15; used 6 times
FALSE defined in line 14; used 4 times
IS_OCTAL defined in line 9; used 2 times
LEFT_BRACKET defined in line 6; never used
QUESTION defined in line 5; never used
RIGHT_BRACKET defined in line 7; never used
TRUE defined in line 13; used 3 times
VOID defined in line 12; used 2 times
Last modified: 1988-03-25
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2647
Valid CSS Valid XHTML 1.0 Strict