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