summaryrefslogtreecommitdiff
path: root/usr/src/cmd/fgrep
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/fgrep
downloadillumos-gate-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/fgrep')
-rw-r--r--usr/src/cmd/fgrep/Makefile46
-rw-r--r--usr/src/cmd/fgrep/fgrep.c646
2 files changed, 692 insertions, 0 deletions
diff --git a/usr/src/cmd/fgrep/Makefile b/usr/src/cmd/fgrep/Makefile
new file mode 100644
index 0000000000..a5ac396dcd
--- /dev/null
+++ b/usr/src/cmd/fgrep/Makefile
@@ -0,0 +1,46 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# Copyright (c) 1989,1996 by Sun Microsystems, Inc.
+# All rights reserved.
+#
+
+PROG= fgrep
+
+include ../Makefile.cmd
+
+CPPFLAGS += -D_FILE_OFFSET_BITS=64
+
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all $(ROOTPROG)
+
+clean:
+
+lint: lint_PROG
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/fgrep/fgrep.c b/usr/src/cmd/fgrep/fgrep.c
new file mode 100644
index 0000000000..dd7836ee88
--- /dev/null
+++ b/usr/src/cmd/fgrep/fgrep.c
@@ -0,0 +1,646 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+/* Copyright (c) 1987, 1988 Microsoft Corporation */
+/* All Rights Reserved */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * fgrep -- print all lines containing any of a set of keywords
+ *
+ * status returns:
+ * 0 - ok, and some matches
+ * 1 - ok, but no matches
+ * 2 - some error
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <libintl.h>
+#include <euc.h>
+
+#include <getwidth.h>
+
+eucwidth_t WW;
+#define WIDTH1 WW._eucw1
+#define WIDTH2 WW._eucw2
+#define WIDTH3 WW._eucw3
+#define MULTI_BYTE WW._multibyte
+#define GETONE(lc, p) \
+ cw = ISASCII(lc = (unsigned char)*p++) ? 1 : \
+ (ISSET2(lc) ? WIDTH2 : \
+ (ISSET3(lc) ? WIDTH3 : WIDTH1)); \
+ if (--cw > --ccount) { \
+ cw -= ccount; \
+ while (ccount--) \
+ lc = (lc << 7) | ((*p++) & 0177); \
+ if (p >= &buf[fw_lBufsiz + BUFSIZ]) { \
+ if (nlp == buf) { \
+ /* Increase the buffer size */ \
+ fw_lBufsiz += BUFSIZ; \
+ if ((buf = realloc(buf, \
+ fw_lBufsiz + BUFSIZ)) == NULL) { \
+ exit(2); /* out of memory */ \
+ } \
+ nlp = buf; \
+ p = &buf[fw_lBufsiz]; \
+ } else { \
+ /* shift the buffer contents down */ \
+ (void) memmove(buf, nlp, \
+ &buf[fw_lBufsiz + BUFSIZ] - nlp);\
+ p -= nlp - buf; \
+ nlp = buf; \
+ } \
+ } \
+ if (p > &buf[fw_lBufsiz]) { \
+ if ((ccount = fread(p, sizeof (char), \
+ &buf[fw_lBufsiz + BUFSIZ] - p, fptr))\
+ <= 0) break; \
+ } else if ((ccount = fread(p, \
+ sizeof (char), BUFSIZ, fptr)) <= 0) \
+ break; \
+ blkno += (long long)ccount; \
+ } \
+ ccount -= cw; \
+ while (cw--) \
+ lc = (lc << 7) | ((*p++) & 0177)
+
+/*
+ * The same() macro and letter() function were inserted to allow for
+ * the -i option work for the multi-byte environment.
+ */
+wchar_t letter();
+#define same(a, b) \
+ (a == b || iflag && (!MULTI_BYTE || ISASCII(a)) && (a ^ b) == ' ' && \
+ letter(a) == letter(b))
+
+#define MAXSIZ 6000
+
+#define QSIZE 400
+struct words {
+ wchar_t inp;
+ char out;
+ struct words *nst;
+ struct words *link;
+ struct words *fail;
+} w[MAXSIZ], *smax, *q;
+
+FILE *fptr;
+long long lnum;
+int bflag, cflag, lflag, fflag, nflag, vflag, xflag, eflag, sflag;
+int hflag, iflag;
+int retcode = 0;
+int nfile;
+long long blkno;
+int nsucc;
+long long tln;
+FILE *wordf;
+char *argptr;
+
+void execute(char *);
+void cgotofn(void);
+void overflo(void);
+void cfail(void);
+
+static long fw_lBufsiz = 0;
+
+int
+main(int argc, char **argv)
+{
+ int c;
+ int errflg = 0;
+
+ (void) setlocale(LC_ALL, "");
+#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
+#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
+#endif
+ (void) textdomain(TEXT_DOMAIN);
+
+ while ((c = getopt(argc, argv, "hybcie:f:lnvxs")) != EOF)
+ switch (c) {
+
+ case 's':
+ sflag++;
+ continue;
+ case 'h':
+ hflag++;
+ continue;
+ case 'b':
+ bflag++;
+ continue;
+
+ case 'i':
+ case 'y':
+ iflag++;
+ continue;
+
+ case 'c':
+ cflag++;
+ continue;
+
+ case 'e':
+ eflag++;
+ argptr = optarg;
+ continue;
+
+ case 'f':
+ fflag++;
+ wordf = fopen(optarg, "r");
+ if (wordf == NULL) {
+ (void) fprintf(stderr,
+ gettext("fgrep: can't open %s\n"),
+ optarg);
+ exit(2);
+ }
+ continue;
+
+ case 'l':
+ lflag++;
+ continue;
+
+ case 'n':
+ nflag++;
+ continue;
+
+ case 'v':
+ vflag++;
+ continue;
+
+ case 'x':
+ xflag++;
+ continue;
+
+ case '?':
+ errflg++;
+ }
+
+ argc -= optind;
+ if (errflg || ((argc <= 0) && !fflag && !eflag)) {
+ (void) printf(gettext("usage: fgrep [ -bchilnsvx ] "
+ "[ -e exp ] [ -f file ] [ strings ] [ file ] ...\n"));
+ exit(2);
+ }
+ if (!eflag && !fflag) {
+ argptr = argv[optind];
+ optind++;
+ argc--;
+ }
+
+ getwidth(&WW);
+ if ((WIDTH1 == 0) && (WIDTH2 == 0) &&
+ (WIDTH3 == 0)) {
+ /*
+ * If non EUC-based locale,
+ * assume WIDTH1 is 1.
+ */
+ WIDTH1 = 1;
+ }
+ WIDTH2++;
+ WIDTH3++;
+
+ cgotofn();
+ cfail();
+ nfile = argc;
+ argv = &argv[optind];
+ if (argc <= 0) {
+ execute((char *)NULL);
+ } else
+ while (--argc >= 0) {
+ execute(*argv);
+ argv++;
+ }
+ return (retcode != 0 ? retcode : nsucc == 0);
+}
+
+void
+execute(char *file)
+{
+ char *p;
+ struct words *c;
+ int ccount;
+ static char *buf = NULL;
+ int failed;
+ char *nlp;
+ wchar_t lc;
+ int cw;
+
+ if (buf == NULL) {
+ fw_lBufsiz = BUFSIZ;
+ if ((buf = malloc(fw_lBufsiz + BUFSIZ)) == NULL) {
+ exit(2); /* out of memory */
+ }
+ }
+
+ if (file) {
+ if ((fptr = fopen(file, "r")) == NULL) {
+ (void) fprintf(stderr,
+ gettext("fgrep: can't open %s\n"), file);
+ retcode = 2;
+ return;
+ }
+ } else {
+ file = "<stdin>";
+ fptr = stdin;
+ }
+ ccount = 0;
+ failed = 0;
+ lnum = 1;
+ tln = 0;
+ blkno = 0;
+ p = buf;
+ nlp = p;
+ c = w;
+ for (;;) {
+ if (c == 0)
+ break;
+ if (ccount <= 0) {
+ if (p >= &buf[fw_lBufsiz + BUFSIZ]) {
+ if (nlp == buf) {
+ /* increase the buffer size */
+ fw_lBufsiz += BUFSIZ;
+ if ((buf = realloc(buf,
+ fw_lBufsiz + BUFSIZ)) == NULL) {
+ exit(2); /* out of memory */
+ }
+ nlp = buf;
+ p = &buf[fw_lBufsiz];
+ } else {
+ /* shift the buffer down */
+ (void) memmove(buf, nlp,
+ &buf[fw_lBufsiz + BUFSIZ]
+ - nlp);
+ p -= nlp - buf;
+ nlp = buf;
+ }
+
+ }
+ if (p > &buf[fw_lBufsiz]) {
+ if ((ccount = fread(p, sizeof (char),
+ &buf[fw_lBufsiz + BUFSIZ] - p, fptr))
+ <= 0)
+ break;
+ } else if ((ccount = fread(p, sizeof (char),
+ BUFSIZ, fptr)) <= 0)
+ break;
+ blkno += (long long)ccount;
+ }
+ GETONE(lc, p);
+nstate:
+ if (same(c->inp, lc)) {
+ c = c->nst;
+ } else if (c->link != 0) {
+ c = c->link;
+ goto nstate;
+ } else {
+ c = c->fail;
+ failed = 1;
+ if (c == 0) {
+ c = w;
+istate:
+ if (same(c->inp, lc)) {
+ c = c->nst;
+ } else if (c->link != 0) {
+ c = c->link;
+ goto istate;
+ }
+ } else
+ goto nstate;
+ }
+
+ if (c == 0)
+ break;
+
+ if (c->out) {
+ while (lc != '\n') {
+ if (ccount <= 0) {
+if (p == &buf[fw_lBufsiz + BUFSIZ]) {
+ if (nlp == buf) {
+ /* increase buffer size */
+ fw_lBufsiz += BUFSIZ;
+ if ((buf = realloc(buf, fw_lBufsiz + BUFSIZ)) == NULL) {
+ exit(2); /* out of memory */
+ }
+ nlp = buf;
+ p = &buf[fw_lBufsiz];
+ } else {
+ /* shift buffer down */
+ (void) memmove(buf, nlp, &buf[fw_lBufsiz + BUFSIZ] - nlp);
+ p -= nlp - buf;
+ nlp = buf;
+ }
+}
+if (p > &buf[fw_lBufsiz]) {
+ if ((ccount = fread(p, sizeof (char),
+ &buf[fw_lBufsiz + BUFSIZ] - p, fptr)) <= 0) break;
+ } else if ((ccount = fread(p, sizeof (char), BUFSIZ,
+ fptr)) <= 0) break;
+ blkno += (long long)ccount;
+ }
+ GETONE(lc, p);
+}
+ if ((vflag && (failed == 0 || xflag == 0)) ||
+ (vflag == 0 && xflag && failed))
+ goto nomatch;
+succeed:
+ nsucc = 1;
+ if (cflag)
+ tln++;
+ else if (lflag && !sflag) {
+ (void) printf("%s\n", file);
+ (void) fclose(fptr);
+ return;
+ } else if (!sflag) {
+ if (nfile > 1 && !hflag)
+ (void) printf("%s:", file);
+ if (bflag)
+ (void) printf("%lld:",
+ (blkno - (long long)(ccount-1))
+ / BUFSIZ);
+ if (nflag)
+ (void) printf("%lld:", lnum);
+ if (p <= nlp) {
+ while (nlp < &buf[fw_lBufsiz + BUFSIZ])
+ (void) putchar(*nlp++);
+ nlp = buf;
+ }
+ while (nlp < p)
+ (void) putchar(*nlp++);
+ }
+nomatch:
+ lnum++;
+ nlp = p;
+ c = w;
+ failed = 0;
+ continue;
+ }
+ if (lc == '\n')
+ if (vflag)
+ goto succeed;
+ else {
+ lnum++;
+ nlp = p;
+ c = w;
+ failed = 0;
+ }
+ }
+ (void) fclose(fptr);
+ if (cflag) {
+ if ((nfile > 1) && !hflag)
+ (void) printf("%s:", file);
+ (void) printf("%lld\n", tln);
+ }
+}
+
+
+wchar_t
+getargc(void)
+{
+ /* appends a newline to shell quoted argument list so */
+ /* the list looks like it came from an ed style file */
+ wchar_t c;
+ int cw;
+ int b;
+ static int endflg;
+
+
+ if (wordf) {
+ if ((b = getc(wordf)) == EOF)
+ return (EOF);
+ cw = ISASCII(c = (wchar_t)b) ? 1 :
+ (ISSET2(c) ? WIDTH2 : (ISSET3(c) ? WIDTH3 : WIDTH1));
+ while (--cw) {
+ if ((b = getc(wordf)) == EOF)
+ return (EOF);
+ c = (c << 7) | (b & 0177);
+ }
+ return (iflag ? letter(c) : c);
+ }
+
+ if (endflg)
+ return (EOF);
+
+ {
+ cw = ISASCII(c = (unsigned char)*argptr++) ? 1 :
+ (ISSET2(c) ? WIDTH2 : (ISSET3(c) ? WIDTH3 : WIDTH1));
+
+ while (--cw)
+ c = (c << 7) | ((*argptr++) & 0177);
+ if (c == '\0') {
+ endflg++;
+ return ('\n');
+ }
+ }
+ return (iflag ? letter(c) : c);
+
+
+}
+
+void
+cgotofn(void)
+{
+ int c;
+ struct words *s;
+
+ s = smax = w;
+nword:
+ for (;;) {
+ c = getargc();
+ if (c == EOF)
+ return;
+ if (c == 0)
+ goto enter;
+ if (c == '\n') {
+ if (xflag) {
+ for (;;) {
+ if (s->inp == c) {
+ s = s->nst;
+ break;
+ }
+ if (s->inp == 0)
+ goto nenter;
+ if (s->link == 0) {
+ if (smax >= &w[MAXSIZ -1])
+ overflo();
+ s->link = ++smax;
+ s = smax;
+ goto nenter;
+ }
+ s = s->link;
+ }
+ }
+ s->out = 1;
+ s = w;
+ } else {
+loop:
+ if (s->inp == c) {
+ s = s->nst;
+ continue;
+ }
+ if (s->inp == 0)
+ goto enter;
+ if (s->link == 0) {
+ if (smax >= &w[MAXSIZ - 1])
+ overflo();
+ s->link = ++smax;
+ s = smax;
+ goto enter;
+ }
+ s = s->link;
+ goto loop;
+ }
+ }
+
+enter:
+ do {
+ s->inp = c;
+ if (smax >= &w[MAXSIZ - 1])
+ overflo();
+ s->nst = ++smax;
+ s = smax;
+ } while ((c = getargc()) != '\n' && c != EOF);
+ if (xflag) {
+nenter:
+ s->inp = '\n';
+ if (smax >= &w[MAXSIZ -1])
+ overflo();
+ s->nst = ++smax;
+ }
+ smax->out = 1;
+ s = w;
+ if (c != EOF)
+ goto nword;
+}
+
+void
+overflo(void)
+{
+ (void) fprintf(stderr, gettext("wordlist too large\n"));
+ exit(2);
+}
+
+void
+cfail(void)
+{
+ int qsize = QSIZE;
+ struct words **queue = NULL;
+
+ /*
+ * front and rear are pointers used to traverse the global words
+ * structure "w" which contains the data of input pattern file
+ */
+ struct words **front, **rear;
+ struct words *state;
+ unsigned long frontoffset = 0, rearoffset = 0;
+ char c;
+ struct words *s;
+ s = w;
+ if ((queue = (struct words **)calloc(qsize, sizeof (struct words *)))
+ == NULL) {
+ perror("fgrep");
+ exit(2);
+ }
+ front = rear = queue;
+init:
+ if ((s->inp) != 0) {
+ *rear++ = s->nst;
+ /*
+ * Reallocates the queue if the number of distinct starting
+ * character of patterns exceeds the qsize value
+ */
+ if (rear >= &queue[qsize - 1]) {
+ frontoffset = front - queue;
+ rearoffset = rear - queue;
+ qsize += QSIZE;
+ if ((queue = (struct words **)realloc(queue,
+ qsize * sizeof (struct words *))) == NULL) {
+ perror("fgrep");
+ exit(2);
+ }
+ front = queue + frontoffset;
+ rear = queue + rearoffset;
+ }
+ }
+ if ((s = s->link) != 0) {
+ goto init;
+ }
+
+ while (rear != front) {
+ s = *front++;
+cloop:
+ if ((c = s->inp) != 0) {
+ *rear++ = (q = s->nst);
+ /*
+ * Reallocate the queue if the rear pointer reaches the end
+ * queue
+ */
+ if (rear >= &queue[qsize - 1]) {
+ frontoffset = front - queue;
+ rearoffset = rear - queue;
+ qsize += QSIZE;
+ if ((queue = (struct words **)realloc(queue,
+ qsize * sizeof (struct words *))) == NULL) {
+ perror("fgrep");
+ exit(2);
+ }
+ front = queue + frontoffset;
+ rear = queue + rearoffset;
+ }
+ state = s->fail;
+floop:
+ if (state == 0)
+ state = w;
+ if (state->inp == c) {
+qloop:
+ q->fail = state->nst;
+ if ((state->nst)->out == 1)
+ q->out = 1;
+ if ((q = q->link) != 0)
+ goto qloop;
+ } else if ((state = state->link) != 0)
+ goto floop;
+ }
+ if ((s = s->link) != 0)
+ goto cloop;
+ }
+}
+
+wchar_t
+letter(wchar_t c)
+{
+ if (c >= 'a' && c <= 'z')
+ return (c);
+ if (c >= 'A' && c <= 'Z')
+ return (c + 'a' - 'A');
+ return (c);
+}