11175Sbill /*
21175Sbill  * egrep -- print lines containing (or not containing) a regular expression
31175Sbill  *
41175Sbill  *	status returns:
51175Sbill  *		0 - ok, and some matches
61175Sbill  *		1 - ok, but no matches
71175Sbill  *		2 - some error
81175Sbill  */
91175Sbill %token CHAR DOT CCL NCCL OR CAT STAR PLUS QUEST
101175Sbill %left OR
111175Sbill %left CHAR DOT CCL NCCL '('
121175Sbill %left CAT
131175Sbill %left STAR PLUS QUEST
141175Sbill 
151175Sbill %{
16*32331Sbostic static char *sccsid = "@(#)old.egrep.y	4.5 (Berkeley) 10/03/87";
171175Sbill #include <stdio.h>
1821255Smckusick #include <sys/types.h>
1921255Smckusick #include <sys/stat.h>
20*32331Sbostic #include <ctype.h>
211175Sbill 
2221255Smckusick #define BLKSIZE 8192
231175Sbill #define MAXLIN 350
241175Sbill #define MAXPOS 4000
251175Sbill #define NCHARS 128
261175Sbill #define NSTATES 128
271175Sbill #define FINAL -1
281175Sbill char gotofn[NSTATES][NCHARS];
29*32331Sbostic char cmap[256];
301175Sbill int state[NSTATES];
311175Sbill char out[NSTATES];
321175Sbill int line = 1;
331175Sbill int name[MAXLIN];
341175Sbill int left[MAXLIN];
351175Sbill int right[MAXLIN];
361175Sbill int parent[MAXLIN];
371175Sbill int foll[MAXLIN];
381175Sbill int positions[MAXPOS];
391175Sbill char chars[MAXLIN];
401175Sbill int nxtpos;
411175Sbill int nxtchar = 0;
421175Sbill int tmpstat[MAXLIN];
431175Sbill int initstat[MAXLIN];
441175Sbill int xstate;
451175Sbill int count;
461175Sbill int icount;
471175Sbill char *input;
489117Srrh FILE *exprfile;
491175Sbill 
501175Sbill long	lnum;
511175Sbill int	bflag;
521175Sbill int	cflag;
531175Sbill int	fflag;
54*32331Sbostic int	iflag;
551175Sbill int	lflag;
561175Sbill int	nflag;
571175Sbill int	hflag	= 1;
581175Sbill int	sflag;
591175Sbill int	vflag;
6011561Sedward int	retcode = 0;
611175Sbill int	nfile;
621175Sbill int	blkno;
631175Sbill long	tln;
641175Sbill int	nsucc;
651175Sbill 
661175Sbill int	f;
679117Srrh char	*fname;
681175Sbill %}
691175Sbill 
701175Sbill %%
711175Sbill s:	t
721175Sbill 		={ unary(FINAL, $1);
731175Sbill 		  line--;
741175Sbill 		}
751175Sbill 	;
761175Sbill t:	b r
771175Sbill 		={ $$ = node(CAT, $1, $2); }
781175Sbill 	| OR b r OR
791175Sbill 		={ $$ = node(CAT, $2, $3); }
801175Sbill 	| OR b r
811175Sbill 		={ $$ = node(CAT, $2, $3); }
821175Sbill 	| b r OR
831175Sbill 		={ $$ = node(CAT, $1, $2); }
841175Sbill 	;
851175Sbill b:
861175Sbill 		={ $$ = enter(DOT);
871175Sbill 		   $$ = unary(STAR, $$); }
881175Sbill 	;
891175Sbill r:	CHAR
901175Sbill 		={ $$ = enter($1); }
911175Sbill 	| DOT
921175Sbill 		={ $$ = enter(DOT); }
931175Sbill 	| CCL
941175Sbill 		={ $$ = cclenter(CCL); }
951175Sbill 	| NCCL
961175Sbill 		={ $$ = cclenter(NCCL); }
971175Sbill 	;
981175Sbill 
991175Sbill r:	r OR r
1001175Sbill 		={ $$ = node(OR, $1, $3); }
1011175Sbill 	| r r %prec CAT
1021175Sbill 		={ $$ = node(CAT, $1, $2); }
1031175Sbill 	| r STAR
1041175Sbill 		={ $$ = unary(STAR, $1); }
1051175Sbill 	| r PLUS
1061175Sbill 		={ $$ = unary(PLUS, $1); }
1071175Sbill 	| r QUEST
1081175Sbill 		={ $$ = unary(QUEST, $1); }
1091175Sbill 	| '(' r ')'
1101175Sbill 		={ $$ = $2; }
1111175Sbill 	| error
1121175Sbill 	;
1131175Sbill 
1141175Sbill %%
1151175Sbill yyerror(s) {
1161175Sbill 	fprintf(stderr, "egrep: %s\n", s);
1171175Sbill 	exit(2);
1181175Sbill }
1191175Sbill 
1201175Sbill yylex() {
1211175Sbill 	extern int yylval;
1221175Sbill 	int cclcnt, x;
1231175Sbill 	register char c, d;
1241175Sbill 	switch(c = nextch()) {
1251175Sbill 		case '$':
1261175Sbill 		case '^': c = '\n';
1271175Sbill 			goto defchar;
1281175Sbill 		case '|': return (OR);
1291175Sbill 		case '*': return (STAR);
1301175Sbill 		case '+': return (PLUS);
1311175Sbill 		case '?': return (QUEST);
1321175Sbill 		case '(': return (c);
1331175Sbill 		case ')': return (c);
1341175Sbill 		case '.': return (DOT);
1351175Sbill 		case '\0': return (0);
1361175Sbill 		case '\n': return (OR);
1371175Sbill 		case '[':
1381175Sbill 			x = CCL;
1391175Sbill 			cclcnt = 0;
1401175Sbill 			count = nxtchar++;
1411175Sbill 			if ((c = nextch()) == '^') {
1421175Sbill 				x = NCCL;
1431175Sbill 				c = nextch();
1441175Sbill 			}
1451175Sbill 			do {
1461175Sbill 				if (c == '\0') synerror();
1471175Sbill 				if (c == '-' && cclcnt > 0 && chars[nxtchar-1] != 0) {
1481175Sbill 					if ((d = nextch()) != 0) {
1491175Sbill 						c = chars[nxtchar-1];
1501175Sbill 						while (c < d) {
1511175Sbill 							if (nxtchar >= MAXLIN) overflo();
1521175Sbill 							chars[nxtchar++] = ++c;
1531175Sbill 							cclcnt++;
1541175Sbill 						}
1551175Sbill 						continue;
1561175Sbill 					}
1571175Sbill 				}
1581175Sbill 				if (nxtchar >= MAXLIN) overflo();
1591175Sbill 				chars[nxtchar++] = c;
1601175Sbill 				cclcnt++;
1611175Sbill 			} while ((c = nextch()) != ']');
1621175Sbill 			chars[count] = cclcnt;
1631175Sbill 			return (x);
1641175Sbill 		case '\\':
1651175Sbill 			if ((c = nextch()) == '\0') synerror();
1661175Sbill 		defchar:
1671175Sbill 		default: yylval = c; return (CHAR);
1681175Sbill 	}
1691175Sbill }
1701175Sbill nextch() {
171*32331Sbostic 	register int c;
1721175Sbill 	if (fflag) {
1739117Srrh 		if ((c = getc(exprfile)) == EOF) {
1749117Srrh 			fclose(exprfile);
1759117Srrh 			return(0);
1769117Srrh 		}
1771175Sbill 	}
1781175Sbill 	else c = *input++;
1791175Sbill 	return(c);
1801175Sbill }
1811175Sbill 
1821175Sbill synerror() {
1831175Sbill 	fprintf(stderr, "egrep: syntax error\n");
1841175Sbill 	exit(2);
1851175Sbill }
1861175Sbill 
1871175Sbill enter(x) int x; {
1881175Sbill 	if(line >= MAXLIN) overflo();
1891175Sbill 	name[line] = x;
1901175Sbill 	left[line] = 0;
1911175Sbill 	right[line] = 0;
1921175Sbill 	return(line++);
1931175Sbill }
1941175Sbill 
1951175Sbill cclenter(x) int x; {
1961175Sbill 	register linno;
1971175Sbill 	linno = enter(x);
1981175Sbill 	right[linno] = count;
1991175Sbill 	return (linno);
2001175Sbill }
2011175Sbill 
2021175Sbill node(x, l, r) {
2031175Sbill 	if(line >= MAXLIN) overflo();
2041175Sbill 	name[line] = x;
2051175Sbill 	left[line] = l;
2061175Sbill 	right[line] = r;
2071175Sbill 	parent[l] = line;
2081175Sbill 	parent[r] = line;
2091175Sbill 	return(line++);
2101175Sbill }
2111175Sbill 
2121175Sbill unary(x, d) {
2131175Sbill 	if(line >= MAXLIN) overflo();
2141175Sbill 	name[line] = x;
2151175Sbill 	left[line] = d;
2161175Sbill 	right[line] = 0;
2171175Sbill 	parent[d] = line;
2181175Sbill 	return(line++);
2191175Sbill }
2201175Sbill overflo() {
2211175Sbill 	fprintf(stderr, "egrep: regular expression too long\n");
2221175Sbill 	exit(2);
2231175Sbill }
2241175Sbill 
2251175Sbill cfoll(v) {
2261175Sbill 	register i;
2271175Sbill 	if (left[v] == 0) {
2281175Sbill 		count = 0;
2291175Sbill 		for (i=1; i<=line; i++) tmpstat[i] = 0;
2301175Sbill 		follow(v);
2311175Sbill 		add(foll, v);
2321175Sbill 	}
2331175Sbill 	else if (right[v] == 0) cfoll(left[v]);
2341175Sbill 	else {
2351175Sbill 		cfoll(left[v]);
2361175Sbill 		cfoll(right[v]);
2371175Sbill 	}
2381175Sbill }
2391175Sbill cgotofn() {
2401175Sbill 	register c, i, k;
2411175Sbill 	int n, s;
2421175Sbill 	char symbol[NCHARS];
2431175Sbill 	int j, nc, pc, pos;
2441175Sbill 	int curpos, num;
2451175Sbill 	int number, newpos;
2461175Sbill 	count = 0;
2471175Sbill 	for (n=3; n<=line; n++) tmpstat[n] = 0;
2481175Sbill 	if (cstate(line-1)==0) {
2491175Sbill 		tmpstat[line] = 1;
2501175Sbill 		count++;
2511175Sbill 		out[0] = 1;
2521175Sbill 	}
2531175Sbill 	for (n=3; n<=line; n++) initstat[n] = tmpstat[n];
2541175Sbill 	count--;		/*leave out position 1 */
2551175Sbill 	icount = count;
2561175Sbill 	tmpstat[1] = 0;
2571175Sbill 	add(state, 0);
2581175Sbill 	n = 0;
2591175Sbill 	for (s=0; s<=n; s++)  {
2601175Sbill 		if (out[s] == 1) continue;
2611175Sbill 		for (i=0; i<NCHARS; i++) symbol[i] = 0;
2621175Sbill 		num = positions[state[s]];
2631175Sbill 		count = icount;
2641175Sbill 		for (i=3; i<=line; i++) tmpstat[i] = initstat[i];
2651175Sbill 		pos = state[s] + 1;
2661175Sbill 		for (i=0; i<num; i++) {
2671175Sbill 			curpos = positions[pos];
2681175Sbill 			if ((c = name[curpos]) >= 0) {
2691175Sbill 				if (c < NCHARS) symbol[c] = 1;
2701175Sbill 				else if (c == DOT) {
2711175Sbill 					for (k=0; k<NCHARS; k++)
2721175Sbill 						if (k!='\n') symbol[k] = 1;
2731175Sbill 				}
2741175Sbill 				else if (c == CCL) {
2751175Sbill 					nc = chars[right[curpos]];
2761175Sbill 					pc = right[curpos] + 1;
2771175Sbill 					for (k=0; k<nc; k++) symbol[chars[pc++]] = 1;
2781175Sbill 				}
2791175Sbill 				else if (c == NCCL) {
2801175Sbill 					nc = chars[right[curpos]];
2811175Sbill 					for (j = 0; j < NCHARS; j++) {
2821175Sbill 						pc = right[curpos] + 1;
2831175Sbill 						for (k = 0; k < nc; k++)
2841175Sbill 							if (j==chars[pc++]) goto cont;
2851175Sbill 						if (j!='\n') symbol[j] = 1;
2861175Sbill 						cont:;
2871175Sbill 					}
2881175Sbill 				}
2891175Sbill 				else printf("something's funny\n");
2901175Sbill 			}
2911175Sbill 			pos++;
2921175Sbill 		}
2931175Sbill 		for (c=0; c<NCHARS; c++) {
2941175Sbill 			if (symbol[c] == 1) { /* nextstate(s,c) */
2951175Sbill 				count = icount;
2961175Sbill 				for (i=3; i <= line; i++) tmpstat[i] = initstat[i];
2971175Sbill 				pos = state[s] + 1;
2981175Sbill 				for (i=0; i<num; i++) {
2991175Sbill 					curpos = positions[pos];
3001175Sbill 					if ((k = name[curpos]) >= 0)
3011175Sbill 						if (
3021175Sbill 							(k == c)
3031175Sbill 							| (k == DOT)
3041175Sbill 							| (k == CCL && member(c, right[curpos], 1))
3051175Sbill 							| (k == NCCL && member(c, right[curpos], 0))
3061175Sbill 						) {
3071175Sbill 							number = positions[foll[curpos]];
3081175Sbill 							newpos = foll[curpos] + 1;
3091175Sbill 							for (k=0; k<number; k++) {
3101175Sbill 								if (tmpstat[positions[newpos]] != 1) {
3111175Sbill 									tmpstat[positions[newpos]] = 1;
3121175Sbill 									count++;
3131175Sbill 								}
3141175Sbill 								newpos++;
3151175Sbill 							}
3161175Sbill 						}
3171175Sbill 					pos++;
3181175Sbill 				} /* end nextstate */
3191175Sbill 				if (notin(n)) {
3201175Sbill 					if (n >= NSTATES) overflo();
3211175Sbill 					add(state, ++n);
3221175Sbill 					if (tmpstat[line] == 1) out[n] = 1;
3231175Sbill 					gotofn[s][c] = n;
3241175Sbill 				}
3251175Sbill 				else {
3261175Sbill 					gotofn[s][c] = xstate;
3271175Sbill 				}
3281175Sbill 			}
3291175Sbill 		}
3301175Sbill 	}
3311175Sbill }
3321175Sbill 
3331175Sbill cstate(v) {
3341175Sbill 	register b;
3351175Sbill 	if (left[v] == 0) {
3361175Sbill 		if (tmpstat[v] != 1) {
3371175Sbill 			tmpstat[v] = 1;
3381175Sbill 			count++;
3391175Sbill 		}
3401175Sbill 		return(1);
3411175Sbill 	}
3421175Sbill 	else if (right[v] == 0) {
3431175Sbill 		if (cstate(left[v]) == 0) return (0);
3441175Sbill 		else if (name[v] == PLUS) return (1);
3451175Sbill 		else return (0);
3461175Sbill 	}
3471175Sbill 	else if (name[v] == CAT) {
3481175Sbill 		if (cstate(left[v]) == 0 && cstate(right[v]) == 0) return (0);
3491175Sbill 		else return (1);
3501175Sbill 	}
3511175Sbill 	else { /* name[v] == OR */
3521175Sbill 		b = cstate(right[v]);
3531175Sbill 		if (cstate(left[v]) == 0 || b == 0) return (0);
3541175Sbill 		else return (1);
3551175Sbill 	}
3561175Sbill }
3571175Sbill 
3581175Sbill 
3591175Sbill member(symb, set, torf) {
3601175Sbill 	register i, num, pos;
3611175Sbill 	num = chars[set];
3621175Sbill 	pos = set + 1;
3631175Sbill 	for (i=0; i<num; i++)
3641175Sbill 		if (symb == chars[pos++]) return (torf);
3651175Sbill 	return (!torf);
3661175Sbill }
3671175Sbill 
3681175Sbill notin(n) {
3691175Sbill 	register i, j, pos;
3701175Sbill 	for (i=0; i<=n; i++) {
3711175Sbill 		if (positions[state[i]] == count) {
3721175Sbill 			pos = state[i] + 1;
3731175Sbill 			for (j=0; j < count; j++)
3741175Sbill 				if (tmpstat[positions[pos++]] != 1) goto nxt;
3751175Sbill 			xstate = i;
3761175Sbill 			return (0);
3771175Sbill 		}
3781175Sbill 		nxt: ;
3791175Sbill 	}
3801175Sbill 	return (1);
3811175Sbill }
3821175Sbill 
3831175Sbill add(array, n) int *array; {
3841175Sbill 	register i;
3851175Sbill 	if (nxtpos + count > MAXPOS) overflo();
3861175Sbill 	array[n] = nxtpos;
3871175Sbill 	positions[nxtpos++] = count;
3881175Sbill 	for (i=3; i <= line; i++) {
3891175Sbill 		if (tmpstat[i] == 1) {
3901175Sbill 			positions[nxtpos++] = i;
3911175Sbill 		}
3921175Sbill 	}
3931175Sbill }
3941175Sbill 
3951175Sbill follow(v) int v; {
3961175Sbill 	int p;
3971175Sbill 	if (v == line) return;
3981175Sbill 	p = parent[v];
3991175Sbill 	switch(name[p]) {
4001175Sbill 		case STAR:
4011175Sbill 		case PLUS:	cstate(v);
4021175Sbill 				follow(p);
4031175Sbill 				return;
4041175Sbill 
4051175Sbill 		case OR:
4061175Sbill 		case QUEST:	follow(p);
4071175Sbill 				return;
4081175Sbill 
4091175Sbill 		case CAT:	if (v == left[p]) {
4101175Sbill 					if (cstate(right[p]) == 0) {
4111175Sbill 						follow(p);
4121175Sbill 						return;
4131175Sbill 					}
4141175Sbill 				}
4151175Sbill 				else follow(p);
4161175Sbill 				return;
4171175Sbill 		case FINAL:	if (tmpstat[line] != 1) {
4181175Sbill 					tmpstat[line] = 1;
4191175Sbill 					count++;
4201175Sbill 				}
4211175Sbill 				return;
4221175Sbill 	}
4231175Sbill }
4241175Sbill 
4251175Sbill 
4261175Sbill main(argc, argv)
4271175Sbill char **argv;
4281175Sbill {
429*32331Sbostic 	register int i;
430*32331Sbostic 
4311175Sbill 	while (--argc > 0 && (++argv)[0][0]=='-')
4321175Sbill 		switch (argv[0][1]) {
4331175Sbill 
4341175Sbill 		case 's':
4351175Sbill 			sflag++;
4361175Sbill 			continue;
4371175Sbill 
4381175Sbill 		case 'h':
4391175Sbill 			hflag = 0;
4401175Sbill 			continue;
4411175Sbill 
4421175Sbill 		case 'b':
4431175Sbill 			bflag++;
4441175Sbill 			continue;
4451175Sbill 
4461175Sbill 		case 'c':
4471175Sbill 			cflag++;
4481175Sbill 			continue;
4491175Sbill 
4501175Sbill 		case 'e':
4511175Sbill 			argc--;
4521175Sbill 			argv++;
4531175Sbill 			goto out;
4541175Sbill 
4551175Sbill 		case 'f':
4561175Sbill 			fflag++;
4571175Sbill 			continue;
4581175Sbill 
459*32331Sbostic 		case 'i':
460*32331Sbostic 			iflag++;
461*32331Sbostic 			for ( i = 'A'; i <= 'Z'; i++ )
462*32331Sbostic 				cmap[i] = (char) tolower ( i );
463*32331Sbostic 			continue;
464*32331Sbostic 
4651175Sbill 		case 'l':
4661175Sbill 			lflag++;
4671175Sbill 			continue;
4681175Sbill 
4691175Sbill 		case 'n':
4701175Sbill 			nflag++;
4711175Sbill 			continue;
4721175Sbill 
4731175Sbill 		case 'v':
4741175Sbill 			vflag++;
4751175Sbill 			continue;
4761175Sbill 
4771175Sbill 		default:
4781175Sbill 			fprintf(stderr, "egrep: unknown flag\n");
4791175Sbill 			continue;
4801175Sbill 		}
4811175Sbill out:
4821175Sbill 	if (argc<=0)
4831175Sbill 		exit(2);
484*32331Sbostic 
485*32331Sbostic 	for (i = 0; i < 256; ++i)
486*32331Sbostic 		cmap[i] = (char)i;
487*32331Sbostic 
4881175Sbill 	if (fflag) {
4899117Srrh 		fname = *argv;
4909117Srrh 		exprfile = fopen(fname, "r");
4919117Srrh 		if (exprfile == (FILE *)NULL) {
4921175Sbill 			fprintf(stderr, "egrep: can't open %s\n", fname);
4931175Sbill 			exit(2);
4941175Sbill 		}
4951175Sbill 	}
4961175Sbill 	else input = *argv;
497*32331Sbostic 	if ( iflag ) {
498*32331Sbostic 		register char *s;
499*32331Sbostic 		for ( s = input; *s != '\0'; s++ )
500*32331Sbostic 			if ( isupper ( (int)(*s) ) )
501*32331Sbostic 				*s = (char) tolower ( (int)(*s) );
502*32331Sbostic 	}
5031175Sbill 	argc--;
5041175Sbill 	argv++;
5051175Sbill 
5061175Sbill 	yyparse();
5071175Sbill 
5081175Sbill 	cfoll(line-1);
5091175Sbill 	cgotofn();
5101175Sbill 	nfile = argc;
5111175Sbill 	if (argc<=0) {
5121175Sbill 		if (lflag) exit(1);
5131175Sbill 		execute(0);
5141175Sbill 	}
5151175Sbill 	else while (--argc >= 0) {
5161175Sbill 		execute(*argv);
5171175Sbill 		argv++;
5181175Sbill 	}
51911561Sedward 	exit(retcode != 0 ? retcode : nsucc == 0);
5201175Sbill }
5211175Sbill 
5221175Sbill execute(file)
5231175Sbill char *file;
5241175Sbill {
5251175Sbill 	register char *p;
5261175Sbill 	register cstat;
5271175Sbill 	register ccount;
528*32331Sbostic 	register char *cmapr = cmap;
52921255Smckusick 	static char *buf;
53021255Smckusick 	static int blksize;
53121255Smckusick 	struct stat stb;
5321175Sbill 	char *nlp;
5331175Sbill 	int istat;
5341175Sbill 	if (file) {
5351175Sbill 		if ((f = open(file, 0)) < 0) {
5361175Sbill 			fprintf(stderr, "egrep: can't open %s\n", file);
53711561Sedward 			retcode = 2;
53811561Sedward 			return;
5391175Sbill 		}
5401175Sbill 	}
5411175Sbill 	else f = 0;
54221255Smckusick 	if (buf == NULL) {
54321255Smckusick 		if (fstat(f, &stb) > 0 && stb.st_blksize > 0)
54421255Smckusick 			blksize = stb.st_blksize;
54521255Smckusick 		else
54621255Smckusick 			blksize = BLKSIZE;
54721255Smckusick 		buf = (char *)malloc(2*blksize);
54821255Smckusick 		if (buf == NULL) {
54921255Smckusick 			fprintf(stderr, "egrep: no memory for %s\n", file);
55021255Smckusick 			retcode = 2;
55121255Smckusick 			return;
55221255Smckusick 		}
55321255Smckusick 	}
5541175Sbill 	ccount = 0;
5551175Sbill 	lnum = 1;
5561175Sbill 	tln = 0;
5571175Sbill 	blkno = 0;
5581175Sbill 	p = buf;
5591175Sbill 	nlp = p;
56021255Smckusick 	if ((ccount = read(f,p,blksize))<=0) goto done;
5611175Sbill 	istat = cstat = gotofn[0]['\n'];
5621175Sbill 	if (out[cstat]) goto found;
5631175Sbill 	for (;;) {
564*32331Sbostic 		cstat = gotofn[cstat][(unsigned char)cmapr[*(unsigned char *)p]];
5651175Sbill 		if (out[cstat]) {
5661175Sbill 		found:	for(;;) {
5671175Sbill 				if (*p++ == '\n') {
5681175Sbill 					if (vflag == 0) {
5691175Sbill 				succeed:	nsucc = 1;
5701175Sbill 						if (cflag) tln++;
5711175Sbill 						else if (sflag)
5721175Sbill 							;	/* ugh */
5731175Sbill 						else if (lflag) {
5741175Sbill 							printf("%s\n", file);
5751175Sbill 							close(f);
5761175Sbill 							return;
5771175Sbill 						}
5781175Sbill 						else {
5791175Sbill 							if (nfile > 1 && hflag) printf("%s:", file);
5801175Sbill 							if (bflag) printf("%d:", blkno);
5811175Sbill 							if (nflag) printf("%ld:", lnum);
5821175Sbill 							if (p <= nlp) {
58321255Smckusick 								while (nlp < &buf[2*blksize]) putchar(*nlp++);
5841175Sbill 								nlp = buf;
5851175Sbill 							}
5861175Sbill 							while (nlp < p) putchar(*nlp++);
5871175Sbill 						}
5881175Sbill 					}
5891175Sbill 					lnum++;
5901175Sbill 					nlp = p;
5911175Sbill 					if ((out[(cstat=istat)]) == 0) goto brk2;
5921175Sbill 				}
5931175Sbill 				cfound:
5941175Sbill 				if (--ccount <= 0) {
59521255Smckusick 					if (p <= &buf[blksize]) {
59621255Smckusick 						if ((ccount = read(f, p, blksize)) <= 0) goto done;
5971175Sbill 					}
59821255Smckusick 					else if (p == &buf[2*blksize]) {
5991175Sbill 						p = buf;
60021255Smckusick 						if ((ccount = read(f, p, blksize)) <= 0) goto done;
6011175Sbill 					}
6021175Sbill 					else {
60321255Smckusick 						if ((ccount = read(f, p, &buf[2*blksize]-p)) <= 0) goto done;
6041175Sbill 					}
60521255Smckusick 					blkno += ccount / 512;
6061175Sbill 				}
6071175Sbill 			}
6081175Sbill 		}
6091175Sbill 		if (*p++ == '\n') {
6101175Sbill 			if (vflag) goto succeed;
6111175Sbill 			else {
6121175Sbill 				lnum++;
6131175Sbill 				nlp = p;
6141175Sbill 				if (out[(cstat=istat)]) goto cfound;
6151175Sbill 			}
6161175Sbill 		}
6171175Sbill 		brk2:
6181175Sbill 		if (--ccount <= 0) {
61921255Smckusick 			if (p <= &buf[blksize]) {
62021255Smckusick 				if ((ccount = read(f, p, blksize)) <= 0) break;
6211175Sbill 			}
62221255Smckusick 			else if (p == &buf[2*blksize]) {
6231175Sbill 				p = buf;
62421255Smckusick 				if ((ccount = read(f, p, blksize)) <= 0) break;
6251175Sbill 			}
6261175Sbill 			else {
62721255Smckusick 				if ((ccount = read(f, p, &buf[2*blksize] - p)) <= 0) break;
6281175Sbill 			}
62921255Smckusick 			blkno += ccount / 512;
6301175Sbill 		}
6311175Sbill 	}
6321175Sbill done:	close(f);
6331175Sbill 	if (cflag) {
6341175Sbill 		if (nfile > 1)
6351175Sbill 			printf("%s:", file);
6361175Sbill 		printf("%ld\n", tln);
6371175Sbill 	}
6381175Sbill }
639