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"
7 e05b0ff3 2008-07-03 rsc // Convert globbish pattern to regular expression
8 e05b0ff3 2008-07-03 rsc // The wildcards are
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
18 e05b0ff3 2008-07-03 rsc glob2regexp(char *glob)
20 e05b0ff3 2008-07-03 rsc char *s, *p, *w;
22 e05b0ff3 2008-07-03 rsc int boe; // beginning of path element
24 e05b0ff3 2008-07-03 rsc s = malloc(20*(strlen(glob)+1));
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);
39 e05b0ff3 2008-07-03 rsc if(p[0] == '*'){
41 e05b0ff3 2008-07-03 rsc strcpy(w, "([^./][^/]*)?");
43 e05b0ff3 2008-07-03 rsc strcpy(w, "[^/]*");
44 e05b0ff3 2008-07-03 rsc w += strlen(w);
48 e05b0ff3 2008-07-03 rsc if(p[0] == '?'){
50 e05b0ff3 2008-07-03 rsc strcpy(w, "[^./]");
52 e05b0ff3 2008-07-03 rsc strcpy(w, "[^/]");
53 e05b0ff3 2008-07-03 rsc w += strlen(w);
57 e05b0ff3 2008-07-03 rsc if(p[0] == '['){
59 e05b0ff3 2008-07-03 rsc if(*++p == '~'){
63 e05b0ff3 2008-07-03 rsc while(*p != ']'){
64 e05b0ff3 2008-07-03 rsc if(*p == '/')
66 e05b0ff3 2008-07-03 rsc if(*p == '^' || *p == '\\')
74 e05b0ff3 2008-07-03 rsc if(strchr("()|^$[]*?+\\.", *p)){
80 e05b0ff3 2008-07-03 rsc if(*p == '/'){
93 e05b0ff3 2008-07-03 rsc re = regcomp(s);
94 e05b0ff3 2008-07-03 rsc if(re == nil){
97 e05b0ff3 2008-07-03 rsc werrstr("glob syntax error");
104 e05b0ff3 2008-07-03 rsc typedef struct Pattern Pattern;
105 e05b0ff3 2008-07-03 rsc struct Pattern
108 e05b0ff3 2008-07-03 rsc int include;
111 e05b0ff3 2008-07-03 rsc Pattern *pattern;
112 e05b0ff3 2008-07-03 rsc int npattern;
115 e05b0ff3 2008-07-03 rsc loadexcludefile(char *file)
118 e05b0ff3 2008-07-03 rsc char *p, *q;
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)))
128 e05b0ff3 2008-07-03 rsc switch(p[0]){
135 e05b0ff3 2008-07-03 rsc if(strncmp(p, "include ", 8) == 0){
137 e05b0ff3 2008-07-03 rsc }else if(strncmp(p, "exclude ", 8) == 0){
140 e05b0ff3 2008-07-03 rsc sysfatal("%s:%d: line does not begin with include or exclude", file, n);
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);
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);
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;
157 e05b0ff3 2008-07-03 rsc excludepattern(char *p)
161 e05b0ff3 2008-07-03 rsc if((re = glob2regexp(p)) == nil)
162 e05b0ff3 2008-07-03 rsc sysfatal("bad glob pattern %s", p);
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;
171 e05b0ff3 2008-07-03 rsc includefile(char *file)
173 e05b0ff3 2008-07-03 rsc Pattern *p, *ep;
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;