xref: /titanic_54/usr/src/cmd/fgrep/fgrep.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1987, 1988 Microsoft Corporation	*/
31*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved	*/
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate /*
36*7c478bd9Sstevel@tonic-gate  * fgrep -- print all lines containing any of a set of keywords
37*7c478bd9Sstevel@tonic-gate  *
38*7c478bd9Sstevel@tonic-gate  *	status returns:
39*7c478bd9Sstevel@tonic-gate  *		0 - ok, and some matches
40*7c478bd9Sstevel@tonic-gate  *		1 - ok, but no matches
41*7c478bd9Sstevel@tonic-gate  *		2 - some error
42*7c478bd9Sstevel@tonic-gate  */
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate #include <stdio.h>
45*7c478bd9Sstevel@tonic-gate #include <ctype.h>
46*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
47*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
48*7c478bd9Sstevel@tonic-gate #include <string.h>
49*7c478bd9Sstevel@tonic-gate #include <locale.h>
50*7c478bd9Sstevel@tonic-gate #include <libintl.h>
51*7c478bd9Sstevel@tonic-gate #include <euc.h>
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate #include <getwidth.h>
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate eucwidth_t WW;
56*7c478bd9Sstevel@tonic-gate #define	WIDTH1	WW._eucw1
57*7c478bd9Sstevel@tonic-gate #define	WIDTH2	WW._eucw2
58*7c478bd9Sstevel@tonic-gate #define	WIDTH3	WW._eucw3
59*7c478bd9Sstevel@tonic-gate #define	MULTI_BYTE	WW._multibyte
60*7c478bd9Sstevel@tonic-gate #define	GETONE(lc, p) \
61*7c478bd9Sstevel@tonic-gate 	cw = ISASCII(lc = (unsigned char)*p++) ? 1 :     \
62*7c478bd9Sstevel@tonic-gate 		(ISSET2(lc) ? WIDTH2 :                       \
63*7c478bd9Sstevel@tonic-gate 		(ISSET3(lc) ? WIDTH3 : WIDTH1));             \
64*7c478bd9Sstevel@tonic-gate 	if (--cw > --ccount) {                           \
65*7c478bd9Sstevel@tonic-gate 		cw -= ccount;                                \
66*7c478bd9Sstevel@tonic-gate 		while (ccount--)                             \
67*7c478bd9Sstevel@tonic-gate 			lc = (lc << 7) | ((*p++) & 0177);        \
68*7c478bd9Sstevel@tonic-gate 			if (p >= &buf[fw_lBufsiz + BUFSIZ]) {    \
69*7c478bd9Sstevel@tonic-gate 			if (nlp == buf) {                        \
70*7c478bd9Sstevel@tonic-gate 				/* Increase the buffer size */       \
71*7c478bd9Sstevel@tonic-gate 				fw_lBufsiz += BUFSIZ;                \
72*7c478bd9Sstevel@tonic-gate 				if ((buf = realloc(buf,              \
73*7c478bd9Sstevel@tonic-gate 					fw_lBufsiz + BUFSIZ)) == NULL) { \
74*7c478bd9Sstevel@tonic-gate 					exit(2); /* out of memory */     \
75*7c478bd9Sstevel@tonic-gate 				}                                    \
76*7c478bd9Sstevel@tonic-gate 				nlp = buf;                           \
77*7c478bd9Sstevel@tonic-gate 				p = &buf[fw_lBufsiz];                \
78*7c478bd9Sstevel@tonic-gate 			} else {                                 \
79*7c478bd9Sstevel@tonic-gate 				/* shift the buffer contents down */ \
80*7c478bd9Sstevel@tonic-gate 				(void) memmove(buf, nlp,             \
81*7c478bd9Sstevel@tonic-gate 					&buf[fw_lBufsiz + BUFSIZ] - nlp);\
82*7c478bd9Sstevel@tonic-gate 				p -= nlp - buf;                      \
83*7c478bd9Sstevel@tonic-gate 				nlp = buf;                           \
84*7c478bd9Sstevel@tonic-gate 			}                                        \
85*7c478bd9Sstevel@tonic-gate 		}                                            \
86*7c478bd9Sstevel@tonic-gate 		if (p > &buf[fw_lBufsiz]) {                  \
87*7c478bd9Sstevel@tonic-gate 			if ((ccount = fread(p, sizeof (char),    \
88*7c478bd9Sstevel@tonic-gate 			    &buf[fw_lBufsiz + BUFSIZ] - p, fptr))\
89*7c478bd9Sstevel@tonic-gate 				<= 0) break;                         \
90*7c478bd9Sstevel@tonic-gate 		} else if ((ccount = fread(p,                \
91*7c478bd9Sstevel@tonic-gate 			sizeof (char),  BUFSIZ, fptr)) <= 0)     \
92*7c478bd9Sstevel@tonic-gate 			break;                                   \
93*7c478bd9Sstevel@tonic-gate 		blkno += (long long)ccount;                  \
94*7c478bd9Sstevel@tonic-gate 	}                                                \
95*7c478bd9Sstevel@tonic-gate 	ccount -= cw;                                    \
96*7c478bd9Sstevel@tonic-gate 	while (cw--)                                     \
97*7c478bd9Sstevel@tonic-gate 		lc = (lc << 7) | ((*p++) & 0177)
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate /*
100*7c478bd9Sstevel@tonic-gate  * The same() macro and letter() function were inserted to allow for
101*7c478bd9Sstevel@tonic-gate  * the -i option work for the multi-byte environment.
102*7c478bd9Sstevel@tonic-gate  */
103*7c478bd9Sstevel@tonic-gate wchar_t letter();
104*7c478bd9Sstevel@tonic-gate #define	same(a, b) \
105*7c478bd9Sstevel@tonic-gate 	(a == b || iflag && (!MULTI_BYTE || ISASCII(a)) && (a ^ b) == ' ' && \
106*7c478bd9Sstevel@tonic-gate 	letter(a) == letter(b))
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate #define	MAXSIZ 6000
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate #define	QSIZE 400
111*7c478bd9Sstevel@tonic-gate struct words {
112*7c478bd9Sstevel@tonic-gate 	wchar_t inp;
113*7c478bd9Sstevel@tonic-gate 	char	out;
114*7c478bd9Sstevel@tonic-gate 	struct	words *nst;
115*7c478bd9Sstevel@tonic-gate 	struct	words *link;
116*7c478bd9Sstevel@tonic-gate 	struct	words *fail;
117*7c478bd9Sstevel@tonic-gate } w[MAXSIZ], *smax, *q;
118*7c478bd9Sstevel@tonic-gate 
119*7c478bd9Sstevel@tonic-gate FILE *fptr;
120*7c478bd9Sstevel@tonic-gate long long lnum;
121*7c478bd9Sstevel@tonic-gate int	bflag, cflag, lflag, fflag, nflag, vflag, xflag, eflag, sflag;
122*7c478bd9Sstevel@tonic-gate int	hflag, iflag;
123*7c478bd9Sstevel@tonic-gate int	retcode = 0;
124*7c478bd9Sstevel@tonic-gate int	nfile;
125*7c478bd9Sstevel@tonic-gate long long blkno;
126*7c478bd9Sstevel@tonic-gate int	nsucc;
127*7c478bd9Sstevel@tonic-gate long long tln;
128*7c478bd9Sstevel@tonic-gate FILE	*wordf;
129*7c478bd9Sstevel@tonic-gate char	*argptr;
130*7c478bd9Sstevel@tonic-gate 
131*7c478bd9Sstevel@tonic-gate void	execute(char *);
132*7c478bd9Sstevel@tonic-gate void	cgotofn(void);
133*7c478bd9Sstevel@tonic-gate void	overflo(void);
134*7c478bd9Sstevel@tonic-gate void	cfail(void);
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate static long fw_lBufsiz = 0;
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate int
139*7c478bd9Sstevel@tonic-gate main(int argc, char **argv)
140*7c478bd9Sstevel@tonic-gate {
141*7c478bd9Sstevel@tonic-gate 	int c;
142*7c478bd9Sstevel@tonic-gate 	int errflg = 0;
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
145*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
146*7c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it weren't */
147*7c478bd9Sstevel@tonic-gate #endif
148*7c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "hybcie:f:lnvxs")) != EOF)
151*7c478bd9Sstevel@tonic-gate 		switch (c) {
152*7c478bd9Sstevel@tonic-gate 
153*7c478bd9Sstevel@tonic-gate 		case 's':
154*7c478bd9Sstevel@tonic-gate 			sflag++;
155*7c478bd9Sstevel@tonic-gate 			continue;
156*7c478bd9Sstevel@tonic-gate 		case 'h':
157*7c478bd9Sstevel@tonic-gate 			hflag++;
158*7c478bd9Sstevel@tonic-gate 			continue;
159*7c478bd9Sstevel@tonic-gate 		case 'b':
160*7c478bd9Sstevel@tonic-gate 			bflag++;
161*7c478bd9Sstevel@tonic-gate 			continue;
162*7c478bd9Sstevel@tonic-gate 
163*7c478bd9Sstevel@tonic-gate 		case 'i':
164*7c478bd9Sstevel@tonic-gate 		case 'y':
165*7c478bd9Sstevel@tonic-gate 			iflag++;
166*7c478bd9Sstevel@tonic-gate 			continue;
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate 		case 'c':
169*7c478bd9Sstevel@tonic-gate 			cflag++;
170*7c478bd9Sstevel@tonic-gate 			continue;
171*7c478bd9Sstevel@tonic-gate 
172*7c478bd9Sstevel@tonic-gate 		case 'e':
173*7c478bd9Sstevel@tonic-gate 			eflag++;
174*7c478bd9Sstevel@tonic-gate 			argptr = optarg;
175*7c478bd9Sstevel@tonic-gate 			continue;
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate 		case 'f':
178*7c478bd9Sstevel@tonic-gate 			fflag++;
179*7c478bd9Sstevel@tonic-gate 			wordf = fopen(optarg, "r");
180*7c478bd9Sstevel@tonic-gate 			if (wordf == NULL) {
181*7c478bd9Sstevel@tonic-gate 				(void) fprintf(stderr,
182*7c478bd9Sstevel@tonic-gate 					gettext("fgrep: can't open %s\n"),
183*7c478bd9Sstevel@tonic-gate 					optarg);
184*7c478bd9Sstevel@tonic-gate 				exit(2);
185*7c478bd9Sstevel@tonic-gate 			}
186*7c478bd9Sstevel@tonic-gate 			continue;
187*7c478bd9Sstevel@tonic-gate 
188*7c478bd9Sstevel@tonic-gate 		case 'l':
189*7c478bd9Sstevel@tonic-gate 			lflag++;
190*7c478bd9Sstevel@tonic-gate 			continue;
191*7c478bd9Sstevel@tonic-gate 
192*7c478bd9Sstevel@tonic-gate 		case 'n':
193*7c478bd9Sstevel@tonic-gate 			nflag++;
194*7c478bd9Sstevel@tonic-gate 			continue;
195*7c478bd9Sstevel@tonic-gate 
196*7c478bd9Sstevel@tonic-gate 		case 'v':
197*7c478bd9Sstevel@tonic-gate 			vflag++;
198*7c478bd9Sstevel@tonic-gate 			continue;
199*7c478bd9Sstevel@tonic-gate 
200*7c478bd9Sstevel@tonic-gate 		case 'x':
201*7c478bd9Sstevel@tonic-gate 			xflag++;
202*7c478bd9Sstevel@tonic-gate 			continue;
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate 		case '?':
205*7c478bd9Sstevel@tonic-gate 			errflg++;
206*7c478bd9Sstevel@tonic-gate 	}
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate 	argc -= optind;
209*7c478bd9Sstevel@tonic-gate 	if (errflg || ((argc <= 0) && !fflag && !eflag)) {
210*7c478bd9Sstevel@tonic-gate 		(void) printf(gettext("usage: fgrep [ -bchilnsvx ] "
211*7c478bd9Sstevel@tonic-gate 			"[ -e exp ] [ -f file ] [ strings ] [ file ] ...\n"));
212*7c478bd9Sstevel@tonic-gate 		exit(2);
213*7c478bd9Sstevel@tonic-gate 	}
214*7c478bd9Sstevel@tonic-gate 	if (!eflag && !fflag) {
215*7c478bd9Sstevel@tonic-gate 		argptr = argv[optind];
216*7c478bd9Sstevel@tonic-gate 		optind++;
217*7c478bd9Sstevel@tonic-gate 		argc--;
218*7c478bd9Sstevel@tonic-gate 	}
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate 	getwidth(&WW);
221*7c478bd9Sstevel@tonic-gate 	if ((WIDTH1 == 0) && (WIDTH2 == 0) &&
222*7c478bd9Sstevel@tonic-gate 		(WIDTH3 == 0)) {
223*7c478bd9Sstevel@tonic-gate 		/*
224*7c478bd9Sstevel@tonic-gate 		 * If non EUC-based locale,
225*7c478bd9Sstevel@tonic-gate 		 * assume WIDTH1 is 1.
226*7c478bd9Sstevel@tonic-gate 		 */
227*7c478bd9Sstevel@tonic-gate 		WIDTH1 = 1;
228*7c478bd9Sstevel@tonic-gate 	}
229*7c478bd9Sstevel@tonic-gate 	WIDTH2++;
230*7c478bd9Sstevel@tonic-gate 	WIDTH3++;
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 	cgotofn();
233*7c478bd9Sstevel@tonic-gate 	cfail();
234*7c478bd9Sstevel@tonic-gate 	nfile = argc;
235*7c478bd9Sstevel@tonic-gate 	argv = &argv[optind];
236*7c478bd9Sstevel@tonic-gate 	if (argc <= 0) {
237*7c478bd9Sstevel@tonic-gate 		execute((char *)NULL);
238*7c478bd9Sstevel@tonic-gate 	} else
239*7c478bd9Sstevel@tonic-gate 		while (--argc >= 0) {
240*7c478bd9Sstevel@tonic-gate 			execute(*argv);
241*7c478bd9Sstevel@tonic-gate 			argv++;
242*7c478bd9Sstevel@tonic-gate 		}
243*7c478bd9Sstevel@tonic-gate 	return (retcode != 0 ? retcode : nsucc == 0);
244*7c478bd9Sstevel@tonic-gate }
245*7c478bd9Sstevel@tonic-gate 
246*7c478bd9Sstevel@tonic-gate void
247*7c478bd9Sstevel@tonic-gate execute(char *file)
248*7c478bd9Sstevel@tonic-gate {
249*7c478bd9Sstevel@tonic-gate 	char *p;
250*7c478bd9Sstevel@tonic-gate 	struct words *c;
251*7c478bd9Sstevel@tonic-gate 	int ccount;
252*7c478bd9Sstevel@tonic-gate 	static char *buf = NULL;
253*7c478bd9Sstevel@tonic-gate 	int failed;
254*7c478bd9Sstevel@tonic-gate 	char *nlp;
255*7c478bd9Sstevel@tonic-gate 	wchar_t lc;
256*7c478bd9Sstevel@tonic-gate 	int cw;
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate 	if (buf == NULL) {
259*7c478bd9Sstevel@tonic-gate 		fw_lBufsiz = BUFSIZ;
260*7c478bd9Sstevel@tonic-gate 		if ((buf = malloc(fw_lBufsiz + BUFSIZ)) == NULL) {
261*7c478bd9Sstevel@tonic-gate 			exit(2); /* out of memory */
262*7c478bd9Sstevel@tonic-gate 		}
263*7c478bd9Sstevel@tonic-gate 	}
264*7c478bd9Sstevel@tonic-gate 
265*7c478bd9Sstevel@tonic-gate 	if (file) {
266*7c478bd9Sstevel@tonic-gate 		if ((fptr = fopen(file, "r")) == NULL) {
267*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
268*7c478bd9Sstevel@tonic-gate 				gettext("fgrep: can't open %s\n"), file);
269*7c478bd9Sstevel@tonic-gate 			retcode = 2;
270*7c478bd9Sstevel@tonic-gate 			return;
271*7c478bd9Sstevel@tonic-gate 		}
272*7c478bd9Sstevel@tonic-gate 	} else {
273*7c478bd9Sstevel@tonic-gate 		file = "<stdin>";
274*7c478bd9Sstevel@tonic-gate 		fptr = stdin;
275*7c478bd9Sstevel@tonic-gate 	}
276*7c478bd9Sstevel@tonic-gate 	ccount = 0;
277*7c478bd9Sstevel@tonic-gate 	failed = 0;
278*7c478bd9Sstevel@tonic-gate 	lnum = 1;
279*7c478bd9Sstevel@tonic-gate 	tln = 0;
280*7c478bd9Sstevel@tonic-gate 	blkno = 0;
281*7c478bd9Sstevel@tonic-gate 	p = buf;
282*7c478bd9Sstevel@tonic-gate 	nlp = p;
283*7c478bd9Sstevel@tonic-gate 	c = w;
284*7c478bd9Sstevel@tonic-gate 	for (;;) {
285*7c478bd9Sstevel@tonic-gate 		if (c == 0)
286*7c478bd9Sstevel@tonic-gate 			break;
287*7c478bd9Sstevel@tonic-gate 		if (ccount <= 0) {
288*7c478bd9Sstevel@tonic-gate 			if (p >= &buf[fw_lBufsiz + BUFSIZ]) {
289*7c478bd9Sstevel@tonic-gate 				if (nlp == buf) {
290*7c478bd9Sstevel@tonic-gate 					/* increase the buffer size */
291*7c478bd9Sstevel@tonic-gate 					fw_lBufsiz += BUFSIZ;
292*7c478bd9Sstevel@tonic-gate 					if ((buf = realloc(buf,
293*7c478bd9Sstevel@tonic-gate 						fw_lBufsiz + BUFSIZ)) == NULL) {
294*7c478bd9Sstevel@tonic-gate 						exit(2); /* out of memory */
295*7c478bd9Sstevel@tonic-gate 					}
296*7c478bd9Sstevel@tonic-gate 					nlp = buf;
297*7c478bd9Sstevel@tonic-gate 					p = &buf[fw_lBufsiz];
298*7c478bd9Sstevel@tonic-gate 				} else {
299*7c478bd9Sstevel@tonic-gate 					/* shift the buffer down */
300*7c478bd9Sstevel@tonic-gate 					(void) memmove(buf, nlp,
301*7c478bd9Sstevel@tonic-gate 						&buf[fw_lBufsiz + BUFSIZ]
302*7c478bd9Sstevel@tonic-gate 						- nlp);
303*7c478bd9Sstevel@tonic-gate 					p -= nlp - buf;
304*7c478bd9Sstevel@tonic-gate 					nlp = buf;
305*7c478bd9Sstevel@tonic-gate 				}
306*7c478bd9Sstevel@tonic-gate 
307*7c478bd9Sstevel@tonic-gate 			}
308*7c478bd9Sstevel@tonic-gate 			if (p > &buf[fw_lBufsiz]) {
309*7c478bd9Sstevel@tonic-gate 				if ((ccount = fread(p, sizeof (char),
310*7c478bd9Sstevel@tonic-gate 					&buf[fw_lBufsiz + BUFSIZ] - p, fptr))
311*7c478bd9Sstevel@tonic-gate 					<= 0)
312*7c478bd9Sstevel@tonic-gate 					break;
313*7c478bd9Sstevel@tonic-gate 			} else if ((ccount = fread(p, sizeof (char),
314*7c478bd9Sstevel@tonic-gate 				BUFSIZ, fptr)) <= 0)
315*7c478bd9Sstevel@tonic-gate 				break;
316*7c478bd9Sstevel@tonic-gate 			blkno += (long long)ccount;
317*7c478bd9Sstevel@tonic-gate 		}
318*7c478bd9Sstevel@tonic-gate 		GETONE(lc, p);
319*7c478bd9Sstevel@tonic-gate nstate:
320*7c478bd9Sstevel@tonic-gate 		if (same(c->inp, lc)) {
321*7c478bd9Sstevel@tonic-gate 			c = c->nst;
322*7c478bd9Sstevel@tonic-gate 		} else if (c->link != 0) {
323*7c478bd9Sstevel@tonic-gate 			c = c->link;
324*7c478bd9Sstevel@tonic-gate 			goto nstate;
325*7c478bd9Sstevel@tonic-gate 		} else {
326*7c478bd9Sstevel@tonic-gate 			c = c->fail;
327*7c478bd9Sstevel@tonic-gate 			failed = 1;
328*7c478bd9Sstevel@tonic-gate 			if (c == 0) {
329*7c478bd9Sstevel@tonic-gate 				c = w;
330*7c478bd9Sstevel@tonic-gate istate:
331*7c478bd9Sstevel@tonic-gate 				if (same(c->inp, lc)) {
332*7c478bd9Sstevel@tonic-gate 					c = c->nst;
333*7c478bd9Sstevel@tonic-gate 				} else if (c->link != 0) {
334*7c478bd9Sstevel@tonic-gate 					c = c->link;
335*7c478bd9Sstevel@tonic-gate 					goto istate;
336*7c478bd9Sstevel@tonic-gate 				}
337*7c478bd9Sstevel@tonic-gate 			} else
338*7c478bd9Sstevel@tonic-gate 				goto nstate;
339*7c478bd9Sstevel@tonic-gate 		}
340*7c478bd9Sstevel@tonic-gate 
341*7c478bd9Sstevel@tonic-gate 		if (c == 0)
342*7c478bd9Sstevel@tonic-gate 			break;
343*7c478bd9Sstevel@tonic-gate 
344*7c478bd9Sstevel@tonic-gate 		if (c->out) {
345*7c478bd9Sstevel@tonic-gate 			while (lc != '\n') {
346*7c478bd9Sstevel@tonic-gate 				if (ccount <= 0) {
347*7c478bd9Sstevel@tonic-gate if (p == &buf[fw_lBufsiz + BUFSIZ]) {
348*7c478bd9Sstevel@tonic-gate 	if (nlp == buf) {
349*7c478bd9Sstevel@tonic-gate 		/* increase buffer size */
350*7c478bd9Sstevel@tonic-gate 		fw_lBufsiz += BUFSIZ;
351*7c478bd9Sstevel@tonic-gate 		if ((buf = realloc(buf, fw_lBufsiz + BUFSIZ)) == NULL) {
352*7c478bd9Sstevel@tonic-gate 			exit(2); /* out of memory */
353*7c478bd9Sstevel@tonic-gate 		}
354*7c478bd9Sstevel@tonic-gate 		nlp = buf;
355*7c478bd9Sstevel@tonic-gate 		p = &buf[fw_lBufsiz];
356*7c478bd9Sstevel@tonic-gate 	} else {
357*7c478bd9Sstevel@tonic-gate 		/* shift buffer down */
358*7c478bd9Sstevel@tonic-gate 		(void) memmove(buf, nlp, &buf[fw_lBufsiz + BUFSIZ] - nlp);
359*7c478bd9Sstevel@tonic-gate 		p -= nlp - buf;
360*7c478bd9Sstevel@tonic-gate 		nlp = buf;
361*7c478bd9Sstevel@tonic-gate 	}
362*7c478bd9Sstevel@tonic-gate }
363*7c478bd9Sstevel@tonic-gate if (p > &buf[fw_lBufsiz]) {
364*7c478bd9Sstevel@tonic-gate 	if ((ccount = fread(p, sizeof (char),
365*7c478bd9Sstevel@tonic-gate 		&buf[fw_lBufsiz + BUFSIZ] - p, fptr)) <= 0) break;
366*7c478bd9Sstevel@tonic-gate 	} else if ((ccount = fread(p, sizeof (char), BUFSIZ,
367*7c478bd9Sstevel@tonic-gate 		fptr)) <= 0) break;
368*7c478bd9Sstevel@tonic-gate 		blkno += (long long)ccount;
369*7c478bd9Sstevel@tonic-gate 	}
370*7c478bd9Sstevel@tonic-gate 	GETONE(lc, p);
371*7c478bd9Sstevel@tonic-gate }
372*7c478bd9Sstevel@tonic-gate 			if ((vflag && (failed == 0 || xflag == 0)) ||
373*7c478bd9Sstevel@tonic-gate 				(vflag == 0 && xflag && failed))
374*7c478bd9Sstevel@tonic-gate 				goto nomatch;
375*7c478bd9Sstevel@tonic-gate succeed:
376*7c478bd9Sstevel@tonic-gate 			nsucc = 1;
377*7c478bd9Sstevel@tonic-gate 			if (cflag)
378*7c478bd9Sstevel@tonic-gate 				tln++;
379*7c478bd9Sstevel@tonic-gate 			else if (lflag && !sflag) {
380*7c478bd9Sstevel@tonic-gate 				(void) printf("%s\n", file);
381*7c478bd9Sstevel@tonic-gate 				(void) fclose(fptr);
382*7c478bd9Sstevel@tonic-gate 				return;
383*7c478bd9Sstevel@tonic-gate 			} else if (!sflag) {
384*7c478bd9Sstevel@tonic-gate 				if (nfile > 1 && !hflag)
385*7c478bd9Sstevel@tonic-gate 					(void) printf("%s:", file);
386*7c478bd9Sstevel@tonic-gate 				if (bflag)
387*7c478bd9Sstevel@tonic-gate 					(void) printf("%lld:",
388*7c478bd9Sstevel@tonic-gate 						(blkno - (long long)(ccount-1))
389*7c478bd9Sstevel@tonic-gate 						/ BUFSIZ);
390*7c478bd9Sstevel@tonic-gate 				if (nflag)
391*7c478bd9Sstevel@tonic-gate 					(void) printf("%lld:", lnum);
392*7c478bd9Sstevel@tonic-gate 				if (p <= nlp) {
393*7c478bd9Sstevel@tonic-gate 					while (nlp < &buf[fw_lBufsiz + BUFSIZ])
394*7c478bd9Sstevel@tonic-gate 						(void) putchar(*nlp++);
395*7c478bd9Sstevel@tonic-gate 					nlp = buf;
396*7c478bd9Sstevel@tonic-gate 				}
397*7c478bd9Sstevel@tonic-gate 				while (nlp < p)
398*7c478bd9Sstevel@tonic-gate 					(void) putchar(*nlp++);
399*7c478bd9Sstevel@tonic-gate 			}
400*7c478bd9Sstevel@tonic-gate nomatch:
401*7c478bd9Sstevel@tonic-gate 			lnum++;
402*7c478bd9Sstevel@tonic-gate 			nlp = p;
403*7c478bd9Sstevel@tonic-gate 			c = w;
404*7c478bd9Sstevel@tonic-gate 			failed = 0;
405*7c478bd9Sstevel@tonic-gate 			continue;
406*7c478bd9Sstevel@tonic-gate 		}
407*7c478bd9Sstevel@tonic-gate 		if (lc == '\n')
408*7c478bd9Sstevel@tonic-gate 			if (vflag)
409*7c478bd9Sstevel@tonic-gate 				goto succeed;
410*7c478bd9Sstevel@tonic-gate 			else {
411*7c478bd9Sstevel@tonic-gate 				lnum++;
412*7c478bd9Sstevel@tonic-gate 				nlp = p;
413*7c478bd9Sstevel@tonic-gate 				c = w;
414*7c478bd9Sstevel@tonic-gate 				failed = 0;
415*7c478bd9Sstevel@tonic-gate 			}
416*7c478bd9Sstevel@tonic-gate 	}
417*7c478bd9Sstevel@tonic-gate 	(void) fclose(fptr);
418*7c478bd9Sstevel@tonic-gate 	if (cflag) {
419*7c478bd9Sstevel@tonic-gate 		if ((nfile > 1) && !hflag)
420*7c478bd9Sstevel@tonic-gate 			(void) printf("%s:", file);
421*7c478bd9Sstevel@tonic-gate 		(void) printf("%lld\n", tln);
422*7c478bd9Sstevel@tonic-gate 	}
423*7c478bd9Sstevel@tonic-gate }
424*7c478bd9Sstevel@tonic-gate 
425*7c478bd9Sstevel@tonic-gate 
426*7c478bd9Sstevel@tonic-gate wchar_t
427*7c478bd9Sstevel@tonic-gate getargc(void)
428*7c478bd9Sstevel@tonic-gate {
429*7c478bd9Sstevel@tonic-gate 	/* appends a newline to shell quoted argument list so */
430*7c478bd9Sstevel@tonic-gate 	/* the list looks like it came from an ed style file  */
431*7c478bd9Sstevel@tonic-gate 	wchar_t c;
432*7c478bd9Sstevel@tonic-gate 	int cw;
433*7c478bd9Sstevel@tonic-gate 	int b;
434*7c478bd9Sstevel@tonic-gate 	static int endflg;
435*7c478bd9Sstevel@tonic-gate 
436*7c478bd9Sstevel@tonic-gate 
437*7c478bd9Sstevel@tonic-gate 	if (wordf) {
438*7c478bd9Sstevel@tonic-gate 		if ((b = getc(wordf)) == EOF)
439*7c478bd9Sstevel@tonic-gate 			return (EOF);
440*7c478bd9Sstevel@tonic-gate 		cw = ISASCII(c = (wchar_t)b) ? 1 :
441*7c478bd9Sstevel@tonic-gate 			(ISSET2(c) ? WIDTH2 : (ISSET3(c) ? WIDTH3 : WIDTH1));
442*7c478bd9Sstevel@tonic-gate 		while (--cw) {
443*7c478bd9Sstevel@tonic-gate 			if ((b = getc(wordf)) == EOF)
444*7c478bd9Sstevel@tonic-gate 				return (EOF);
445*7c478bd9Sstevel@tonic-gate 			c = (c << 7) | (b & 0177);
446*7c478bd9Sstevel@tonic-gate 		}
447*7c478bd9Sstevel@tonic-gate 		return (iflag ? letter(c) : c);
448*7c478bd9Sstevel@tonic-gate 	}
449*7c478bd9Sstevel@tonic-gate 
450*7c478bd9Sstevel@tonic-gate 	if (endflg)
451*7c478bd9Sstevel@tonic-gate 		return (EOF);
452*7c478bd9Sstevel@tonic-gate 
453*7c478bd9Sstevel@tonic-gate 	{
454*7c478bd9Sstevel@tonic-gate 		cw = ISASCII(c = (unsigned char)*argptr++) ? 1 :
455*7c478bd9Sstevel@tonic-gate 			(ISSET2(c) ? WIDTH2 : (ISSET3(c) ? WIDTH3 : WIDTH1));
456*7c478bd9Sstevel@tonic-gate 
457*7c478bd9Sstevel@tonic-gate 		while (--cw)
458*7c478bd9Sstevel@tonic-gate 			c = (c << 7) | ((*argptr++) & 0177);
459*7c478bd9Sstevel@tonic-gate 		if (c == '\0') {
460*7c478bd9Sstevel@tonic-gate 			endflg++;
461*7c478bd9Sstevel@tonic-gate 			return ('\n');
462*7c478bd9Sstevel@tonic-gate 		}
463*7c478bd9Sstevel@tonic-gate 	}
464*7c478bd9Sstevel@tonic-gate 	return (iflag ? letter(c) : c);
465*7c478bd9Sstevel@tonic-gate 
466*7c478bd9Sstevel@tonic-gate 
467*7c478bd9Sstevel@tonic-gate }
468*7c478bd9Sstevel@tonic-gate 
469*7c478bd9Sstevel@tonic-gate void
470*7c478bd9Sstevel@tonic-gate cgotofn(void)
471*7c478bd9Sstevel@tonic-gate {
472*7c478bd9Sstevel@tonic-gate 	int c;
473*7c478bd9Sstevel@tonic-gate 	struct words *s;
474*7c478bd9Sstevel@tonic-gate 
475*7c478bd9Sstevel@tonic-gate 	s = smax = w;
476*7c478bd9Sstevel@tonic-gate nword:
477*7c478bd9Sstevel@tonic-gate 	for (;;) {
478*7c478bd9Sstevel@tonic-gate 		c = getargc();
479*7c478bd9Sstevel@tonic-gate 		if (c == EOF)
480*7c478bd9Sstevel@tonic-gate 			return;
481*7c478bd9Sstevel@tonic-gate 		if (c == 0)
482*7c478bd9Sstevel@tonic-gate 			goto enter;
483*7c478bd9Sstevel@tonic-gate 		if (c == '\n') {
484*7c478bd9Sstevel@tonic-gate 			if (xflag) {
485*7c478bd9Sstevel@tonic-gate 				for (;;) {
486*7c478bd9Sstevel@tonic-gate 					if (s->inp == c) {
487*7c478bd9Sstevel@tonic-gate 						s = s->nst;
488*7c478bd9Sstevel@tonic-gate 						break;
489*7c478bd9Sstevel@tonic-gate 					}
490*7c478bd9Sstevel@tonic-gate 					if (s->inp == 0)
491*7c478bd9Sstevel@tonic-gate 						goto nenter;
492*7c478bd9Sstevel@tonic-gate 					if (s->link == 0) {
493*7c478bd9Sstevel@tonic-gate 						if (smax >= &w[MAXSIZ -1])
494*7c478bd9Sstevel@tonic-gate 							overflo();
495*7c478bd9Sstevel@tonic-gate 						s->link = ++smax;
496*7c478bd9Sstevel@tonic-gate 						s = smax;
497*7c478bd9Sstevel@tonic-gate 						goto nenter;
498*7c478bd9Sstevel@tonic-gate 					}
499*7c478bd9Sstevel@tonic-gate 					s = s->link;
500*7c478bd9Sstevel@tonic-gate 				}
501*7c478bd9Sstevel@tonic-gate 			}
502*7c478bd9Sstevel@tonic-gate 			s->out = 1;
503*7c478bd9Sstevel@tonic-gate 			s = w;
504*7c478bd9Sstevel@tonic-gate 		} else {
505*7c478bd9Sstevel@tonic-gate loop:
506*7c478bd9Sstevel@tonic-gate 			if (s->inp == c) {
507*7c478bd9Sstevel@tonic-gate 				s = s->nst;
508*7c478bd9Sstevel@tonic-gate 				continue;
509*7c478bd9Sstevel@tonic-gate 			}
510*7c478bd9Sstevel@tonic-gate 			if (s->inp == 0)
511*7c478bd9Sstevel@tonic-gate 				goto enter;
512*7c478bd9Sstevel@tonic-gate 			if (s->link == 0) {
513*7c478bd9Sstevel@tonic-gate 				if (smax >= &w[MAXSIZ - 1])
514*7c478bd9Sstevel@tonic-gate 					overflo();
515*7c478bd9Sstevel@tonic-gate 				s->link = ++smax;
516*7c478bd9Sstevel@tonic-gate 				s = smax;
517*7c478bd9Sstevel@tonic-gate 				goto enter;
518*7c478bd9Sstevel@tonic-gate 			}
519*7c478bd9Sstevel@tonic-gate 			s = s->link;
520*7c478bd9Sstevel@tonic-gate 			goto loop;
521*7c478bd9Sstevel@tonic-gate 		}
522*7c478bd9Sstevel@tonic-gate 	}
523*7c478bd9Sstevel@tonic-gate 
524*7c478bd9Sstevel@tonic-gate enter:
525*7c478bd9Sstevel@tonic-gate 	do {
526*7c478bd9Sstevel@tonic-gate 		s->inp = c;
527*7c478bd9Sstevel@tonic-gate 		if (smax >= &w[MAXSIZ - 1])
528*7c478bd9Sstevel@tonic-gate 			overflo();
529*7c478bd9Sstevel@tonic-gate 		s->nst = ++smax;
530*7c478bd9Sstevel@tonic-gate 		s = smax;
531*7c478bd9Sstevel@tonic-gate 	} while ((c = getargc()) != '\n' && c != EOF);
532*7c478bd9Sstevel@tonic-gate 	if (xflag) {
533*7c478bd9Sstevel@tonic-gate nenter:
534*7c478bd9Sstevel@tonic-gate 		s->inp = '\n';
535*7c478bd9Sstevel@tonic-gate 		if (smax >= &w[MAXSIZ -1])
536*7c478bd9Sstevel@tonic-gate 			overflo();
537*7c478bd9Sstevel@tonic-gate 		s->nst = ++smax;
538*7c478bd9Sstevel@tonic-gate 	}
539*7c478bd9Sstevel@tonic-gate 	smax->out = 1;
540*7c478bd9Sstevel@tonic-gate 	s = w;
541*7c478bd9Sstevel@tonic-gate 	if (c != EOF)
542*7c478bd9Sstevel@tonic-gate 		goto nword;
543*7c478bd9Sstevel@tonic-gate }
544*7c478bd9Sstevel@tonic-gate 
545*7c478bd9Sstevel@tonic-gate void
546*7c478bd9Sstevel@tonic-gate overflo(void)
547*7c478bd9Sstevel@tonic-gate {
548*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext("wordlist too large\n"));
549*7c478bd9Sstevel@tonic-gate 	exit(2);
550*7c478bd9Sstevel@tonic-gate }
551*7c478bd9Sstevel@tonic-gate 
552*7c478bd9Sstevel@tonic-gate void
553*7c478bd9Sstevel@tonic-gate cfail(void)
554*7c478bd9Sstevel@tonic-gate {
555*7c478bd9Sstevel@tonic-gate 	int qsize = QSIZE;
556*7c478bd9Sstevel@tonic-gate 	struct words **queue = NULL;
557*7c478bd9Sstevel@tonic-gate 
558*7c478bd9Sstevel@tonic-gate 	/*
559*7c478bd9Sstevel@tonic-gate 	 * front and rear are pointers used to traverse the global words
560*7c478bd9Sstevel@tonic-gate 	 * structure "w" which contains the data of input pattern file
561*7c478bd9Sstevel@tonic-gate 	 */
562*7c478bd9Sstevel@tonic-gate 	struct words **front, **rear;
563*7c478bd9Sstevel@tonic-gate 	struct words *state;
564*7c478bd9Sstevel@tonic-gate 	unsigned long frontoffset = 0, rearoffset = 0;
565*7c478bd9Sstevel@tonic-gate 	char c;
566*7c478bd9Sstevel@tonic-gate 	struct words *s;
567*7c478bd9Sstevel@tonic-gate 	s = w;
568*7c478bd9Sstevel@tonic-gate 	if ((queue = (struct words **)calloc(qsize, sizeof (struct words *)))
569*7c478bd9Sstevel@tonic-gate 				== NULL) {
570*7c478bd9Sstevel@tonic-gate 		perror("fgrep");
571*7c478bd9Sstevel@tonic-gate 		exit(2);
572*7c478bd9Sstevel@tonic-gate 	}
573*7c478bd9Sstevel@tonic-gate 	front = rear = queue;
574*7c478bd9Sstevel@tonic-gate init:
575*7c478bd9Sstevel@tonic-gate 	if ((s->inp) != 0) {
576*7c478bd9Sstevel@tonic-gate 		*rear++ = s->nst;
577*7c478bd9Sstevel@tonic-gate 	/*
578*7c478bd9Sstevel@tonic-gate 	 * Reallocates the queue if the number of distinct starting
579*7c478bd9Sstevel@tonic-gate 	 * character of patterns exceeds the qsize value
580*7c478bd9Sstevel@tonic-gate 	 */
581*7c478bd9Sstevel@tonic-gate 		if (rear >= &queue[qsize - 1]) {
582*7c478bd9Sstevel@tonic-gate 			frontoffset = front - queue;
583*7c478bd9Sstevel@tonic-gate 			rearoffset = rear - queue;
584*7c478bd9Sstevel@tonic-gate 			qsize += QSIZE;
585*7c478bd9Sstevel@tonic-gate 			if ((queue = (struct words **)realloc(queue,
586*7c478bd9Sstevel@tonic-gate 				qsize * sizeof (struct words *))) == NULL) {
587*7c478bd9Sstevel@tonic-gate 				perror("fgrep");
588*7c478bd9Sstevel@tonic-gate 				exit(2);
589*7c478bd9Sstevel@tonic-gate 			}
590*7c478bd9Sstevel@tonic-gate 			front = queue + frontoffset;
591*7c478bd9Sstevel@tonic-gate 			rear = queue + rearoffset;
592*7c478bd9Sstevel@tonic-gate 		}
593*7c478bd9Sstevel@tonic-gate 	}
594*7c478bd9Sstevel@tonic-gate 	if ((s = s->link) != 0) {
595*7c478bd9Sstevel@tonic-gate 		goto init;
596*7c478bd9Sstevel@tonic-gate 	}
597*7c478bd9Sstevel@tonic-gate 
598*7c478bd9Sstevel@tonic-gate 	while (rear != front) {
599*7c478bd9Sstevel@tonic-gate 		s = *front++;
600*7c478bd9Sstevel@tonic-gate cloop:
601*7c478bd9Sstevel@tonic-gate 		if ((c = s->inp) != 0) {
602*7c478bd9Sstevel@tonic-gate 			*rear++ = (q = s->nst);
603*7c478bd9Sstevel@tonic-gate 		/*
604*7c478bd9Sstevel@tonic-gate 		 * Reallocate the queue if the rear pointer reaches the end
605*7c478bd9Sstevel@tonic-gate 		 * queue
606*7c478bd9Sstevel@tonic-gate 		 */
607*7c478bd9Sstevel@tonic-gate 			if (rear >= &queue[qsize - 1]) {
608*7c478bd9Sstevel@tonic-gate 				frontoffset = front - queue;
609*7c478bd9Sstevel@tonic-gate 				rearoffset = rear - queue;
610*7c478bd9Sstevel@tonic-gate 				qsize += QSIZE;
611*7c478bd9Sstevel@tonic-gate 				if ((queue = (struct words **)realloc(queue,
612*7c478bd9Sstevel@tonic-gate 				    qsize * sizeof (struct words *))) == NULL) {
613*7c478bd9Sstevel@tonic-gate 					perror("fgrep");
614*7c478bd9Sstevel@tonic-gate 					exit(2);
615*7c478bd9Sstevel@tonic-gate 				}
616*7c478bd9Sstevel@tonic-gate 				front = queue + frontoffset;
617*7c478bd9Sstevel@tonic-gate 				rear = queue + rearoffset;
618*7c478bd9Sstevel@tonic-gate 			}
619*7c478bd9Sstevel@tonic-gate 			state = s->fail;
620*7c478bd9Sstevel@tonic-gate floop:
621*7c478bd9Sstevel@tonic-gate 			if (state == 0)
622*7c478bd9Sstevel@tonic-gate 				state = w;
623*7c478bd9Sstevel@tonic-gate 			if (state->inp == c) {
624*7c478bd9Sstevel@tonic-gate qloop:
625*7c478bd9Sstevel@tonic-gate 				q->fail = state->nst;
626*7c478bd9Sstevel@tonic-gate 				if ((state->nst)->out == 1)
627*7c478bd9Sstevel@tonic-gate 					q->out = 1;
628*7c478bd9Sstevel@tonic-gate 				if ((q = q->link) != 0)
629*7c478bd9Sstevel@tonic-gate 					goto qloop;
630*7c478bd9Sstevel@tonic-gate 			} else if ((state = state->link) != 0)
631*7c478bd9Sstevel@tonic-gate 				goto floop;
632*7c478bd9Sstevel@tonic-gate 		}
633*7c478bd9Sstevel@tonic-gate 		if ((s = s->link) != 0)
634*7c478bd9Sstevel@tonic-gate 			goto cloop;
635*7c478bd9Sstevel@tonic-gate 	}
636*7c478bd9Sstevel@tonic-gate }
637*7c478bd9Sstevel@tonic-gate 
638*7c478bd9Sstevel@tonic-gate wchar_t
639*7c478bd9Sstevel@tonic-gate letter(wchar_t c)
640*7c478bd9Sstevel@tonic-gate {
641*7c478bd9Sstevel@tonic-gate 	if (c >= 'a' && c <= 'z')
642*7c478bd9Sstevel@tonic-gate 		return (c);
643*7c478bd9Sstevel@tonic-gate 	if (c >= 'A' && c <= 'Z')
644*7c478bd9Sstevel@tonic-gate 		return (c + 'a' - 'A');
645*7c478bd9Sstevel@tonic-gate 	return (c);
646*7c478bd9Sstevel@tonic-gate }
647