1 #define EXTERN 2 #include "grep.h" 3 4 char *validflags = "chiLlnsv"; 5 void 6 usage(void) 7 { 8 fprint(2, "usage: grep [-%s] [-f file] [-e expr] [file ...]\n", validflags); 9 exits("usage"); 10 } 11 12 void 13 main(int argc, char *argv[]) 14 { 15 int i, status; 16 17 ARGBEGIN { 18 default: 19 if(utfrune(validflags, ARGC()) == nil) 20 usage(); 21 22 flags[ARGC()]++; 23 break; 24 25 case 'e': 26 flags['e']++; 27 lineno = 0; 28 str2top(ARGF()); 29 break; 30 31 case 'f': 32 flags['f']++; 33 filename = ARGF(); 34 rein = Bopen(filename, OREAD); 35 if(rein == 0) { 36 fprint(2, "grep: can't open %s: %r\n", filename); 37 exits("open"); 38 } 39 lineno = 1; 40 str2top(filename); 41 break; 42 } ARGEND 43 44 if(flags['f'] == 0 && flags['e'] == 0) { 45 if(argc <= 0) 46 usage(); 47 str2top(argv[0]); 48 argc--; 49 argv++; 50 } 51 52 follow = mal(maxfollow*sizeof(*follow)); 53 state0 = initstate(topre.beg); 54 55 Binit(&bout, 1, OWRITE); 56 switch(argc) { 57 case 0: 58 status = search(0, 0); 59 break; 60 case 1: 61 status = search(argv[0], 0); 62 break; 63 default: 64 status = 0; 65 for(i=0; i<argc; i++) 66 status |= search(argv[i], Hflag); 67 break; 68 } 69 if(status) 70 exits(0); 71 exits("no matches"); 72 } 73 74 int 75 search(char *file, int flag) 76 { 77 State *s, *ns; 78 int c, fid; 79 long count, lineno, n; 80 uchar *elp, *lp, *bol; 81 82 if(file == 0) { 83 file = "stdin"; 84 fid = 0; 85 } else 86 fid = open(file, OREAD); 87 88 if(fid < 0) { 89 fprint(2, "grep: can't open %s: %r\n", file); 90 return 0; 91 } 92 93 if(flags['c']) 94 flag |= Cflag; /* count */ 95 if(flags['h']) 96 flag &= ~Hflag; /* do not print file name in output */ 97 if(flags['i']) 98 flag |= Iflag; /* fold upper-lower */ 99 if(flags['l']) 100 flag |= Llflag; /* print only name of file if any match */ 101 if(flags['L']) 102 flag |= LLflag; /* print only name of file if any non match */ 103 if(flags['n']) 104 flag |= Nflag; /* count only */ 105 if(flags['s']) 106 flag |= Sflag; /* status only */ 107 if(flags['v']) 108 flag |= Vflag; /* inverse match */ 109 110 s = state0; 111 lineno = 0; 112 count = 0; 113 lp = u.buf; 114 bol = lp; 115 116 loop0: 117 n = lp-bol; 118 if(n > sizeof(u.pre)) 119 n = sizeof(u.pre); 120 memmove(u.buf-n, bol, n); 121 bol = u.buf-n; 122 n = read(fid, u.buf, sizeof(u.buf)); 123 if(n <= 0) { 124 close(fid); 125 if(flag & Cflag) { 126 if(flag & Hflag) 127 Bprint(&bout, "%s:", file); 128 Bprint(&bout, "%ld\n", count); 129 } 130 if(((flag&Llflag) && count != 0) || ((flag&LLflag) && count == 0)) 131 Bprint(&bout, "%s\n", file); 132 Bflush(&bout); 133 return count != 0; 134 } 135 lp = u.buf; 136 elp = lp+n; 137 if(flag & Iflag) 138 goto loopi; 139 140 /* 141 * normal character loop 142 */ 143 loop: 144 c = *lp; 145 ns = s->next[c]; 146 if(ns == 0) { 147 increment(s, c); 148 goto loop; 149 } 150 // if(flags['2']) 151 // if(s->match) 152 // print("%d: %.2x**\n", s, c); 153 // else 154 // print("%d: %.2x\n", s, c); 155 lp++; 156 s = ns; 157 if(c == '\n') { 158 lineno++; 159 if(!!s->match == !(flag&Vflag)) { 160 count++; 161 if(flag & (Cflag|Sflag|Llflag|LLflag)) 162 goto cont; 163 if(flag & Hflag) 164 Bprint(&bout, "%s:", file); 165 if(flag & Nflag) 166 Bprint(&bout, "%ld: ", lineno); 167 Bwrite(&bout, bol, lp-bol); 168 Bflush(&bout); 169 } 170 cont: 171 bol = lp; 172 } 173 if(lp != elp) 174 goto loop; 175 goto loop0; 176 177 /* 178 * character loop for -i flag 179 * for speed 180 */ 181 loopi: 182 c = *lp; 183 if(c >= 'A' && c <= 'Z') 184 c += 'a'-'A'; 185 ns = s->next[c]; 186 if(ns == 0) { 187 increment(s, c); 188 goto loopi; 189 } 190 lp++; 191 s = ns; 192 if(c == '\n') { 193 lineno++; 194 if(!!s->match == !(flag&Vflag)) { 195 count++; 196 if(flag & (Cflag|Sflag|Llflag|LLflag)) 197 goto conti; 198 if(flag & Hflag) 199 Bprint(&bout, "%s:", file); 200 if(flag & Nflag) 201 Bprint(&bout, "%ld: ", lineno); 202 Bwrite(&bout, bol, lp-bol); 203 Bflush(&bout); 204 } 205 conti: 206 bol = lp; 207 } 208 if(lp != elp) 209 goto loopi; 210 goto loop0; 211 } 212 213 State* 214 initstate(Re *r) 215 { 216 State *s; 217 int i; 218 219 addcase(r); 220 if(flags['1']) 221 reprint("r", r); 222 nfollow = 0; 223 gen++; 224 fol1(r, Cbegin); 225 follow[nfollow++] = r; 226 qsort(follow, nfollow, sizeof(*follow), fcmp); 227 228 s = sal(nfollow); 229 for(i=0; i<nfollow; i++) 230 s->re[i] = follow[i]; 231 return s; 232 } 233