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':25 flags['e']++;26 lineno = 0;27 str2top(ARGF());28 break;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 } ARGEND43 if(flags['f'] == 0 && flags['e'] == 0) {44 if(argc <= 0)45 usage();46 str2top(argv[0]);47 argc--;48 argv++;49 }51 follow = mal(maxfollow*sizeof(*follow));52 state0 = initstate(topre.beg);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 }73 int74 search(char *file, int flag)75 {76 State *s, *ns;77 int c, fid, eof, nl, empty;78 long count, lineno, n;79 uchar *elp, *lp, *bol;81 if(file == 0) {82 file = "stdin";83 fid = 0;84 flag |= Bflag;85 } else86 fid = open(file, OREAD);88 if(fid < 0) {89 fprint(2, "grep: can't open %s: %r\n", file);90 return 0;91 }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 */112 s = state0;113 lineno = 0;114 count = 0;115 eof = 0;116 empty = 1;117 nl = 0;118 lp = u.u.buf;119 bol = lp;121 loop0:122 n = lp-bol;123 if(n > sizeof(u.u.pre))124 n = sizeof(u.u.pre);125 memmove(u.u.buf-n, bol, n);126 bol = u.u.buf-n;127 n = read(fid, u.u.buf, sizeof(u.u.buf));128 /* if file has no final newline, simulate one to emit matches to last line */129 if(n > 0) {130 empty = 0;131 nl = u.u.buf[n-1]=='\n';132 } else {133 if(n < 0){134 fprint(2, "grep: read error on %s: %r\n", file);135 return count != 0;136 }137 if(!eof && !nl && !empty) {138 u.u.buf[0] = '\n';139 n = 1;140 eof = 1;141 }142 }143 if(n <= 0) {144 close(fid);145 if(flag & Cflag) {146 if(flag & Hflag)147 Bprint(&bout, "%s:", file);148 Bprint(&bout, "%ld\n", count);149 }150 if(((flag&Llflag) && count != 0) || ((flag&LLflag) && count == 0))151 Bprint(&bout, "%s\n", file);152 Bflush(&bout);153 return count != 0;154 }155 lp = u.u.buf;156 elp = lp+n;157 if(flag & Iflag)158 goto loopi;160 /*161 * normal character loop162 */163 loop:164 c = *lp;165 ns = s->next[c];166 if(ns == 0) {167 increment(s, c);168 goto loop;169 }170 // if(flags['2'])171 // if(s->match)172 // print("%d: %.2x**\n", s, c);173 // else174 // print("%d: %.2x\n", s, c);175 lp++;176 s = ns;177 if(c == '\n') {178 lineno++;179 if(!!s->match == !(flag&Vflag)) {180 count++;181 if(flag & (Cflag|Sflag|Llflag|LLflag))182 goto cont;183 if(flag & Hflag)184 Bprint(&bout, "%s:", file);185 if(flag & Nflag)186 Bprint(&bout, "%ld: ", lineno);187 /* suppress extra newline at EOF unless we are labeling matches with file name */188 Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));189 if(flag & Bflag)190 Bflush(&bout);191 }192 if((lineno & Flshcnt) == 0)193 Bflush(&bout);194 cont:195 bol = lp;196 }197 if(lp != elp)198 goto loop;199 goto loop0;201 /*202 * character loop for -i flag203 * for speed204 */205 loopi:206 c = *lp;207 if(c >= 'A' && c <= 'Z')208 c += 'a'-'A';209 ns = s->next[c];210 if(ns == 0) {211 increment(s, c);212 goto loopi;213 }214 lp++;215 s = ns;216 if(c == '\n') {217 lineno++;218 if(!!s->match == !(flag&Vflag)) {219 count++;220 if(flag & (Cflag|Sflag|Llflag|LLflag))221 goto conti;222 if(flag & Hflag)223 Bprint(&bout, "%s:", file);224 if(flag & Nflag)225 Bprint(&bout, "%ld: ", lineno);226 /* suppress extra newline at EOF unless we are labeling matches with file name */227 Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));228 if(flag & Bflag)229 Bflush(&bout);230 }231 if((lineno & Flshcnt) == 0)232 Bflush(&bout);233 conti:234 bol = lp;235 }236 if(lp != elp)237 goto loopi;238 goto loop0;239 }241 State*242 initstate(Re *r)243 {244 State *s;245 int i;247 addcase(r);248 if(flags['1'])249 reprint("r", r);250 nfollow = 0;251 gen++;252 fol1(r, Cbegin);253 follow[nfollow++] = r;254 qsort(follow, nfollow, sizeof(*follow), fcmp);256 s = sal(nfollow);257 for(i=0; i<nfollow; i++)258 s->re[i] = follow[i];259 return s;260 }