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