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