Quake-2

Quake 2 GPL Source Release
Log | Files | Refs

glob.c (3171B)


      1 
      2 #include <stdio.h>
      3 #include "../linux/glob.h"
      4 
      5 /* Like glob_match, but match PATTERN against any final segment of TEXT.  */
      6 static int glob_match_after_star(char *pattern, char *text)
      7 {
      8 	register char *p = pattern, *t = text;
      9 	register char c, c1;
     10 
     11 	while ((c = *p++) == '?' || c == '*')
     12 		if (c == '?' && *t++ == '\0')
     13 			return 0;
     14 
     15 	if (c == '\0')
     16 		return 1;
     17 
     18 	if (c == '\\')
     19 		c1 = *p;
     20 	else
     21 		c1 = c;
     22 
     23 	while (1) {
     24 		if ((c == '[' || *t == c1) && glob_match(p - 1, t))
     25 			return 1;
     26 		if (*t++ == '\0')
     27 			return 0;
     28 	}
     29 }
     30 
     31 /* Return nonzero if PATTERN has any special globbing chars in it.  */
     32 static int glob_pattern_p(char *pattern)
     33 {
     34 	register char *p = pattern;
     35 	register char c;
     36 	int open = 0;
     37 
     38 	while ((c = *p++) != '\0')
     39 		switch (c) {
     40 		case '?':
     41 		case '*':
     42 			return 1;
     43 
     44 		case '[':		/* Only accept an open brace if there is a close */
     45 			open++;		/* brace to match it.  Bracket expressions must be */
     46 			continue;	/* complete, according to Posix.2 */
     47 		case ']':
     48 			if (open)
     49 				return 1;
     50 			continue;
     51 
     52 		case '\\':
     53 			if (*p++ == '\0')
     54 				return 0;
     55 		}
     56 
     57 	return 0;
     58 }
     59 
     60 /* Match the pattern PATTERN against the string TEXT;
     61    return 1 if it matches, 0 otherwise.
     62 
     63    A match means the entire string TEXT is used up in matching.
     64 
     65    In the pattern string, `*' matches any sequence of characters,
     66    `?' matches any character, [SET] matches any character in the specified set,
     67    [!SET] matches any character not in the specified set.
     68 
     69    A set is composed of characters or ranges; a range looks like
     70    character hyphen character (as in 0-9 or A-Z).
     71    [0-9a-zA-Z_] is the set of characters allowed in C identifiers.
     72    Any other character in the pattern must be matched exactly.
     73 
     74    To suppress the special syntactic significance of any of `[]*?!-\',
     75    and match the character exactly, precede it with a `\'.
     76 */
     77 
     78 int glob_match(char *pattern, char *text)
     79 {
     80 	register char *p = pattern, *t = text;
     81 	register char c;
     82 
     83 	while ((c = *p++) != '\0')
     84 		switch (c) {
     85 		case '?':
     86 			if (*t == '\0')
     87 				return 0;
     88 			else
     89 				++t;
     90 			break;
     91 
     92 		case '\\':
     93 			if (*p++ != *t++)
     94 				return 0;
     95 			break;
     96 
     97 		case '*':
     98 			return glob_match_after_star(p, t);
     99 
    100 		case '[':
    101 			{
    102 				register char c1 = *t++;
    103 				int invert;
    104 
    105 				if (!c1)
    106 					return (0);
    107 
    108 				invert = ((*p == '!') || (*p == '^'));
    109 				if (invert)
    110 					p++;
    111 
    112 				c = *p++;
    113 				while (1) {
    114 					register char cstart = c, cend = c;
    115 
    116 					if (c == '\\') {
    117 						cstart = *p++;
    118 						cend = cstart;
    119 					}
    120 					if (c == '\0')
    121 						return 0;
    122 
    123 					c = *p++;
    124 					if (c == '-' && *p != ']') {
    125 						cend = *p++;
    126 						if (cend == '\\')
    127 							cend = *p++;
    128 						if (cend == '\0')
    129 							return 0;
    130 						c = *p++;
    131 					}
    132 					if (c1 >= cstart && c1 <= cend)
    133 						goto match;
    134 					if (c == ']')
    135 						break;
    136 				}
    137 				if (!invert)
    138 					return 0;
    139 				break;
    140 
    141 			  match:
    142 				/* Skip the rest of the [...] construct that already matched.  */
    143 				while (c != ']') {
    144 					if (c == '\0')
    145 						return 0;
    146 					c = *p++;
    147 					if (c == '\0')
    148 						return 0;
    149 					else if (c == '\\')
    150 						++p;
    151 				}
    152 				if (invert)
    153 					return 0;
    154 				break;
    155 			}
    156 
    157 		default:
    158 			if (c != *t++)
    159 				return 0;
    160 		}
    161 
    162 	return *t == '\0';
    163 }
    164