Blame


1 e05b0ff3 2008-07-03 rsc #include "stdinc.h"
2 e05b0ff3 2008-07-03 rsc #include "vac.h"
3 e05b0ff3 2008-07-03 rsc #include "dat.h"
4 e05b0ff3 2008-07-03 rsc #include "fns.h"
5 e05b0ff3 2008-07-03 rsc #include "error.h"
6 e05b0ff3 2008-07-03 rsc
7 e05b0ff3 2008-07-03 rsc // Convert globbish pattern to regular expression
8 e05b0ff3 2008-07-03 rsc // The wildcards are
9 e05b0ff3 2008-07-03 rsc //
10 e05b0ff3 2008-07-03 rsc // * any non-slash characters
11 e05b0ff3 2008-07-03 rsc // ... any characters including /
12 e05b0ff3 2008-07-03 rsc // ? any single character except /
13 e05b0ff3 2008-07-03 rsc // [a-z] character class
14 e05b0ff3 2008-07-03 rsc // [~a-z] negated character class
15 e05b0ff3 2008-07-03 rsc //
16 e05b0ff3 2008-07-03 rsc
17 e05b0ff3 2008-07-03 rsc Reprog*
18 e05b0ff3 2008-07-03 rsc glob2regexp(char *glob)
19 e05b0ff3 2008-07-03 rsc {
20 e05b0ff3 2008-07-03 rsc char *s, *p, *w;
21 e05b0ff3 2008-07-03 rsc Reprog *re;
22 e05b0ff3 2008-07-03 rsc int boe; // beginning of path element
23 e05b0ff3 2008-07-03 rsc
24 e05b0ff3 2008-07-03 rsc s = malloc(20*(strlen(glob)+1));
25 e05b0ff3 2008-07-03 rsc if(s == nil)
26 e05b0ff3 2008-07-03 rsc return nil;
27 e05b0ff3 2008-07-03 rsc w = s;
28 e05b0ff3 2008-07-03 rsc boe = 1;
29 e05b0ff3 2008-07-03 rsc *w++ = '^';
30 e05b0ff3 2008-07-03 rsc *w++ = '(';
31 e05b0ff3 2008-07-03 rsc for(p=glob; *p; p++){
32 e05b0ff3 2008-07-03 rsc if(p[0] == '.' && p[1] == '.' && p[2] == '.'){
33 e05b0ff3 2008-07-03 rsc strcpy(w, ".*");
34 e05b0ff3 2008-07-03 rsc w += strlen(w);
35 e05b0ff3 2008-07-03 rsc p += 3-1;
36 e05b0ff3 2008-07-03 rsc boe = 0;
37 e05b0ff3 2008-07-03 rsc continue;
38 e05b0ff3 2008-07-03 rsc }
39 e05b0ff3 2008-07-03 rsc if(p[0] == '*'){
40 e05b0ff3 2008-07-03 rsc if(boe)
41 e05b0ff3 2008-07-03 rsc strcpy(w, "([^./][^/]*)?");
42 e05b0ff3 2008-07-03 rsc else
43 e05b0ff3 2008-07-03 rsc strcpy(w, "[^/]*");
44 e05b0ff3 2008-07-03 rsc w += strlen(w);
45 e05b0ff3 2008-07-03 rsc boe = 0;
46 e05b0ff3 2008-07-03 rsc continue;
47 e05b0ff3 2008-07-03 rsc }
48 e05b0ff3 2008-07-03 rsc if(p[0] == '?'){
49 e05b0ff3 2008-07-03 rsc if(boe)
50 e05b0ff3 2008-07-03 rsc strcpy(w, "[^./]");
51 e05b0ff3 2008-07-03 rsc else
52 e05b0ff3 2008-07-03 rsc strcpy(w, "[^/]");
53 e05b0ff3 2008-07-03 rsc w += strlen(w);
54 e05b0ff3 2008-07-03 rsc boe = 0;
55 e05b0ff3 2008-07-03 rsc continue;
56 e05b0ff3 2008-07-03 rsc }
57 e05b0ff3 2008-07-03 rsc if(p[0] == '['){
58 e05b0ff3 2008-07-03 rsc *w++ = '[';
59 e05b0ff3 2008-07-03 rsc if(*++p == '~'){
60 e05b0ff3 2008-07-03 rsc *w++ = '^';
61 e05b0ff3 2008-07-03 rsc p++;
62 e05b0ff3 2008-07-03 rsc }
63 e05b0ff3 2008-07-03 rsc while(*p != ']'){
64 e05b0ff3 2008-07-03 rsc if(*p == '/')
65 e05b0ff3 2008-07-03 rsc goto syntax;
66 e05b0ff3 2008-07-03 rsc if(*p == '^' || *p == '\\')
67 e05b0ff3 2008-07-03 rsc *w++ = '\\';
68 e05b0ff3 2008-07-03 rsc *w++ = *p++;
69 e05b0ff3 2008-07-03 rsc }
70 e05b0ff3 2008-07-03 rsc *w++ = ']';
71 e05b0ff3 2008-07-03 rsc boe = 0;
72 e05b0ff3 2008-07-03 rsc continue;
73 e05b0ff3 2008-07-03 rsc }
74 e05b0ff3 2008-07-03 rsc if(strchr("()|^$[]*?+\\.", *p)){
75 e05b0ff3 2008-07-03 rsc *w++ = '\\';
76 e05b0ff3 2008-07-03 rsc *w++ = *p;
77 e05b0ff3 2008-07-03 rsc boe = 0;
78 e05b0ff3 2008-07-03 rsc continue;
79 e05b0ff3 2008-07-03 rsc }
80 e05b0ff3 2008-07-03 rsc if(*p == '/'){
81 e05b0ff3 2008-07-03 rsc *w++ = '/';
82 e05b0ff3 2008-07-03 rsc boe = 1;
83 e05b0ff3 2008-07-03 rsc continue;
84 e05b0ff3 2008-07-03 rsc }
85 e05b0ff3 2008-07-03 rsc *w++ = *p;
86 e05b0ff3 2008-07-03 rsc boe = 0;
87 e05b0ff3 2008-07-03 rsc continue;
88 e05b0ff3 2008-07-03 rsc }
89 e05b0ff3 2008-07-03 rsc *w++ = ')';
90 e05b0ff3 2008-07-03 rsc *w++ = '$';
91 e05b0ff3 2008-07-03 rsc *w = 0;
92 fa325e9b 2020-01-10 cross
93 e05b0ff3 2008-07-03 rsc re = regcomp(s);
94 e05b0ff3 2008-07-03 rsc if(re == nil){
95 e05b0ff3 2008-07-03 rsc syntax:
96 e05b0ff3 2008-07-03 rsc free(s);
97 e05b0ff3 2008-07-03 rsc werrstr("glob syntax error");
98 e05b0ff3 2008-07-03 rsc return nil;
99 e05b0ff3 2008-07-03 rsc }
100 e05b0ff3 2008-07-03 rsc free(s);
101 e05b0ff3 2008-07-03 rsc return re;
102 e05b0ff3 2008-07-03 rsc }
103 e05b0ff3 2008-07-03 rsc
104 e05b0ff3 2008-07-03 rsc typedef struct Pattern Pattern;
105 e05b0ff3 2008-07-03 rsc struct Pattern
106 e05b0ff3 2008-07-03 rsc {
107 e05b0ff3 2008-07-03 rsc Reprog *re;
108 e05b0ff3 2008-07-03 rsc int include;
109 e05b0ff3 2008-07-03 rsc };
110 e05b0ff3 2008-07-03 rsc
111 e05b0ff3 2008-07-03 rsc Pattern *pattern;
112 e05b0ff3 2008-07-03 rsc int npattern;
113 e05b0ff3 2008-07-03 rsc
114 e05b0ff3 2008-07-03 rsc void
115 e05b0ff3 2008-07-03 rsc loadexcludefile(char *file)
116 e05b0ff3 2008-07-03 rsc {
117 e05b0ff3 2008-07-03 rsc Biobuf *b;
118 e05b0ff3 2008-07-03 rsc char *p, *q;
119 e05b0ff3 2008-07-03 rsc int n, inc;
120 e05b0ff3 2008-07-03 rsc Reprog *re;
121 e05b0ff3 2008-07-03 rsc
122 e05b0ff3 2008-07-03 rsc if((b = Bopen(file, OREAD)) == nil)
123 e05b0ff3 2008-07-03 rsc sysfatal("open %s: %r", file);
124 e05b0ff3 2008-07-03 rsc for(n=1; (p=Brdstr(b, '\n', 1)) != nil; free(p), n++){
125 e05b0ff3 2008-07-03 rsc q = p+strlen(p);
126 e05b0ff3 2008-07-03 rsc while(q > p && isspace((uchar)*(q-1)))
127 e05b0ff3 2008-07-03 rsc *--q = 0;
128 e05b0ff3 2008-07-03 rsc switch(p[0]){
129 e05b0ff3 2008-07-03 rsc case '\0':
130 e05b0ff3 2008-07-03 rsc case '#':
131 e05b0ff3 2008-07-03 rsc continue;
132 e05b0ff3 2008-07-03 rsc }
133 fa325e9b 2020-01-10 cross
134 e05b0ff3 2008-07-03 rsc inc = 0;
135 e05b0ff3 2008-07-03 rsc if(strncmp(p, "include ", 8) == 0){
136 e05b0ff3 2008-07-03 rsc inc = 1;
137 e05b0ff3 2008-07-03 rsc }else if(strncmp(p, "exclude ", 8) == 0){
138 e05b0ff3 2008-07-03 rsc inc = 0;
139 e05b0ff3 2008-07-03 rsc }else
140 e05b0ff3 2008-07-03 rsc sysfatal("%s:%d: line does not begin with include or exclude", file, n);
141 e05b0ff3 2008-07-03 rsc
142 e05b0ff3 2008-07-03 rsc if(strchr(p+8, ' '))
143 e05b0ff3 2008-07-03 rsc fprint(2, "%s:%d: warning: space in pattern\n", file, n);
144 e05b0ff3 2008-07-03 rsc
145 e05b0ff3 2008-07-03 rsc if((re = glob2regexp(p+8)) == nil)
146 e05b0ff3 2008-07-03 rsc sysfatal("%s:%d: bad glob pattern", file, n);
147 e05b0ff3 2008-07-03 rsc
148 e05b0ff3 2008-07-03 rsc pattern = vtrealloc(pattern, (npattern+1)*sizeof pattern[0]);
149 e05b0ff3 2008-07-03 rsc pattern[npattern].re = re;
150 e05b0ff3 2008-07-03 rsc pattern[npattern].include = inc;
151 e05b0ff3 2008-07-03 rsc npattern++;
152 e05b0ff3 2008-07-03 rsc }
153 e05b0ff3 2008-07-03 rsc Bterm(b);
154 e05b0ff3 2008-07-03 rsc }
155 e05b0ff3 2008-07-03 rsc
156 e05b0ff3 2008-07-03 rsc void
157 e05b0ff3 2008-07-03 rsc excludepattern(char *p)
158 e05b0ff3 2008-07-03 rsc {
159 e05b0ff3 2008-07-03 rsc Reprog *re;
160 fa325e9b 2020-01-10 cross
161 e05b0ff3 2008-07-03 rsc if((re = glob2regexp(p)) == nil)
162 e05b0ff3 2008-07-03 rsc sysfatal("bad glob pattern %s", p);
163 e05b0ff3 2008-07-03 rsc
164 e05b0ff3 2008-07-03 rsc pattern = vtrealloc(pattern, (npattern+1)*sizeof pattern[0]);
165 e05b0ff3 2008-07-03 rsc pattern[npattern].re = re;
166 e05b0ff3 2008-07-03 rsc pattern[npattern].include = 0;
167 e05b0ff3 2008-07-03 rsc npattern++;
168 e05b0ff3 2008-07-03 rsc }
169 e05b0ff3 2008-07-03 rsc
170 e05b0ff3 2008-07-03 rsc int
171 e05b0ff3 2008-07-03 rsc includefile(char *file)
172 e05b0ff3 2008-07-03 rsc {
173 e05b0ff3 2008-07-03 rsc Pattern *p, *ep;
174 fa325e9b 2020-01-10 cross
175 e05b0ff3 2008-07-03 rsc for(p=pattern, ep=p+npattern; p<ep; p++)
176 e05b0ff3 2008-07-03 rsc if(regexec(p->re, file, nil, 0))
177 e05b0ff3 2008-07-03 rsc return p->include;
178 e05b0ff3 2008-07-03 rsc return 1;
179 e05b0ff3 2008-07-03 rsc }