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