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