|
|
1.1 root 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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.