Blob
1 #define EXTERN2 #include "grep.h"4 char *validflags = "bchiLlnsv";5 void6 usage(void)7 {8 fprint(2, "usage: grep [-%s] [-f file] [-e expr] [file ...]\n", validflags);9 exits("usage");10 }12 void13 main(int argc, char *argv[])14 {15 int i, status;17 ARGBEGIN {18 default:19 if(utfrune(validflags, ARGC()) == nil)20 usage();21 flags[ARGC()]++;22 break;24 case 'E': /* ignore, turns gnu grep into egrep */25 break;27 case 'e':28 flags['e']++;29 lineno = 0;30 str2top(ARGF());31 break;33 case 'f':34 flags['f']++;35 filename = ARGF();36 rein = Bopen(filename, OREAD);37 if(rein == 0) {38 fprint(2, "grep: can't open %s: %r\n", filename);39 exits("open");40 }41 lineno = 1;42 str2top(filename);43 break;44 } ARGEND46 if(flags['f'] == 0 && flags['e'] == 0) {47 if(argc <= 0)48 usage();49 str2top(argv[0]);50 argc--;51 argv++;52 }54 follow = mal(maxfollow*sizeof(*follow));55 state0 = initstate(topre.beg);57 Binit(&bout, 1, OWRITE);58 switch(argc) {59 case 0:60 status = search(0, 0);61 break;62 case 1:63 status = search(argv[0], 0);64 break;65 default:66 status = 0;67 for(i=0; i<argc; i++)68 status |= search(argv[i], Hflag);69 break;70 }71 if(status)72 exits(0);73 exits("no matches");74 }76 int77 search(char *file, int flag)78 {79 State *s, *ns;80 int c, fid, eof, nl, empty;81 long count, lineno, n;82 uchar *elp, *lp, *bol;84 if(file == 0) {85 file = "stdin";86 fid = 0;87 flag |= Bflag;88 } else89 fid = open(file, OREAD);91 if(fid < 0) {92 fprint(2, "grep: can't open %s: %r\n", file);93 return 0;94 }96 if(flags['b'])97 flag ^= Bflag; /* dont buffer output */98 if(flags['c'])99 flag |= Cflag; /* count */100 if(flags['h'])101 flag &= ~Hflag; /* do not print file name in output */102 if(flags['i'])103 flag |= Iflag; /* fold upper-lower */104 if(flags['l'])105 flag |= Llflag; /* print only name of file if any match */106 if(flags['L'])107 flag |= LLflag; /* print only name of file if any non match */108 if(flags['n'])109 flag |= Nflag; /* count only */110 if(flags['s'])111 flag |= Sflag; /* status only */112 if(flags['v'])113 flag |= Vflag; /* inverse match */115 s = state0;116 lineno = 0;117 count = 0;118 eof = 0;119 empty = 1;120 nl = 0;121 lp = u.u.buf;122 bol = lp;124 loop0:125 n = lp-bol;126 if(n > sizeof(u.u.pre))127 n = sizeof(u.u.pre);128 memmove(u.u.buf-n, bol, n);129 bol = u.u.buf-n;130 n = read(fid, u.u.buf, sizeof(u.u.buf));131 /* if file has no final newline, simulate one to emit matches to last line */132 if(n > 0) {133 empty = 0;134 nl = u.u.buf[n-1]=='\n';135 } else {136 if(n < 0){137 fprint(2, "grep: read error on %s: %r\n", file);138 return count != 0;139 }140 if(!eof && !nl && !empty) {141 u.u.buf[0] = '\n';142 n = 1;143 eof = 1;144 }145 }146 if(n <= 0) {147 close(fid);148 if(flag & Cflag) {149 if(flag & Hflag)150 Bprint(&bout, "%s:", file);151 Bprint(&bout, "%ld\n", count);152 }153 if(((flag&Llflag) && count != 0) || ((flag&LLflag) && count == 0))154 Bprint(&bout, "%s\n", file);155 Bflush(&bout);156 return count != 0;157 }158 lp = u.u.buf;159 elp = lp+n;160 if(flag & Iflag)161 goto loopi;163 /*164 * normal character loop165 */166 loop:167 c = *lp;168 ns = s->next[c];169 if(ns == 0) {170 increment(s, c);171 goto loop;172 }173 // if(flags['2'])174 // if(s->match)175 // print("%d: %.2x**\n", s, c);176 // else177 // print("%d: %.2x\n", s, c);178 lp++;179 s = ns;180 if(c == '\n') {181 lineno++;182 if(!!s->match == !(flag&Vflag)) {183 count++;184 if(flag & (Cflag|Sflag|Llflag|LLflag))185 goto cont;186 if(flag & Hflag)187 Bprint(&bout, "%s:", file);188 if(flag & Nflag)189 Bprint(&bout, "%ld: ", lineno);190 /* suppress extra newline at EOF unless we are labeling matches with file name */191 Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));192 if(flag & Bflag)193 Bflush(&bout);194 }195 if((lineno & Flshcnt) == 0)196 Bflush(&bout);197 cont:198 bol = lp;199 }200 if(lp != elp)201 goto loop;202 goto loop0;204 /*205 * character loop for -i flag206 * for speed207 */208 loopi:209 c = *lp;210 if(c >= 'A' && c <= 'Z')211 c += 'a'-'A';212 ns = s->next[c];213 if(ns == 0) {214 increment(s, c);215 goto loopi;216 }217 lp++;218 s = ns;219 if(c == '\n') {220 lineno++;221 if(!!s->match == !(flag&Vflag)) {222 count++;223 if(flag & (Cflag|Sflag|Llflag|LLflag))224 goto conti;225 if(flag & Hflag)226 Bprint(&bout, "%s:", file);227 if(flag & Nflag)228 Bprint(&bout, "%ld: ", lineno);229 /* suppress extra newline at EOF unless we are labeling matches with file name */230 Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));231 if(flag & Bflag)232 Bflush(&bout);233 }234 if((lineno & Flshcnt) == 0)235 Bflush(&bout);236 conti:237 bol = lp;238 }239 if(lp != elp)240 goto loopi;241 goto loop0;242 }244 State*245 initstate(Re *r)246 {247 State *s;248 int i;250 addcase(r);251 if(flags['1'])252 reprint("r", r);253 nfollow = 0;254 gen++;255 fol1(r, Cbegin);256 follow[nfollow++] = r;257 qsort(follow, nfollow, sizeof(*follow), fcmp);259 s = sal(nfollow);260 for(i=0; i<nfollow; i++)261 s->re[i] = follow[i];262 return s;263 }