From 5b40436aaf8ffc319103a035a119365dffb808a5 Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Sun, 20 Jun 2010 11:48:00 +0000 Subject: [PATCH] remove minix greps. --- commands/Makefile | 6 +- commands/cgrep/Makefile | 4 - commands/cgrep/cgrep.c | 379 ---------------------------------------- commands/fgrep/Makefile | 4 - commands/fgrep/fgrep.c | 354 ------------------------------------- commands/grep/Makefile | 6 - commands/grep/grep.c | 379 ---------------------------------------- 7 files changed, 3 insertions(+), 1129 deletions(-) delete mode 100644 commands/cgrep/Makefile delete mode 100644 commands/cgrep/cgrep.c delete mode 100644 commands/fgrep/Makefile delete mode 100644 commands/fgrep/fgrep.c delete mode 100644 commands/grep/Makefile delete mode 100644 commands/grep/grep.c diff --git a/commands/Makefile b/commands/Makefile index b0307a8c1..65d4abbd5 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -5,14 +5,14 @@ SUBDIR= aal add_route adduser advent arp ash at autil awk \ backup badblocks banner basename bigmake binpackage \ binpackages binsizes bzip2 bzip2recover cal calendar \ - cat cawf cd cdiff cdprobe cgrep checkhier chmem \ + cat cawf cd cdiff cdprobe checkhier chmem \ chmod chown chroot ci cksum cleantmp clear cmp co \ comm compress cp crc cron crontab cut datasizes date \ dd de decomp16 DESCRIBE dev2name devsize df dhcpd \ dhrystone diff dirname dis88 du dumpcore easypack \ - ed eject elle elvis env expand factor fgrep file \ + ed eject elle elvis env expand factor file \ find finger fingerd fix fold format fortune fsck \ - fsck1 ftp101 ftpd200 getty gomoku grep head host \ + fsck1 ftp101 ftpd200 getty gomoku head host \ hostaddr id ifconfig ifdef indent install \ intr ipcrm ipcs irdpd isoread join kill last leave \ lex life loadkeys loadramdisk logger login look lp \ diff --git a/commands/cgrep/Makefile b/commands/cgrep/Makefile deleted file mode 100644 index 8f6940d71..000000000 --- a/commands/cgrep/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -PROG= cgrep -MAN= - -.include diff --git a/commands/cgrep/cgrep.c b/commands/cgrep/cgrep.c deleted file mode 100644 index d243dc9e3..000000000 --- a/commands/cgrep/cgrep.c +++ /dev/null @@ -1,379 +0,0 @@ -/* cgrep - grep and display context Author: Mark Mallet */ - -/* - Nov 19 1984 Mark Mallett (mem@zinn.MV.COM) - -mem 860224 Modified to do r/e (regular expression) parsing on unix -mem 860324 Added -f, -n; added code to number lines correctly on output. -mem 870325 Added support for regcmp()/regex() style regular expression - library; redid some conditionals to provide better mix'n'match. -mem 870326 Don't try to print the filename if reading from stdin. - Add -w option. Fix a small problem which occasionally allowed - the separator to come out between adjacent lines of the file. -mem 871119 Fix semantics of call to regcmp(): the NULL terminating the - argument list was missing. It worked, but probably only - due to some bizarre coincidence. -dro 890109 Minor mods to compile under Minix - -*/ - -#define OS_UNIX /* Define this for unix systems */ - /* #define REGEX *//* Define this for re_comp/re_exec library */ -#define REGCMP /* Define this to use regcmp/regex */ - /* #define OS_CPM *//* Define this for CP/M-80 */ - - -/* Don't touch these */ -#define NOREGEXP /* Set this for no regular expression */ -#ifdef REGEX -#undef NOREGEXP -#endif /* REGEX */ - -#ifdef REGCMP -#undef NOREGEXP -#endif /* REGCMP */ - - -#ifdef OS_CPM -#include "stdio.h" -#include "ctype.h" -#endif /* OS_CPM */ - -#ifdef OS_UNIX -#include -#include /* Either here or in sys directory - dro */ -#include -#include /* should have this - dro */ -#include /* should have this - dro */ -#include -#include -#endif /* OS_UNIX */ - - -/* Local definitions */ - -#ifndef NULL -#define NULL ((char *)0) -#endif /* NULL */ - -#ifndef NUL -#define NUL '\000' -#endif - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - - -/* Internal data declared global */ - - -/* Internal routines */ - -_PROTOTYPE(int main, (int argc, char **argv)); -_PROTOTYPE(void dosrch, (char *ifnm)); -_PROTOTYPE(void shwlin, (char *fnm, int linnum, char *line)); -_PROTOTYPE(int matlin, (char *line)); -_PROTOTYPE(void regerror, (const char *s)); - -/* External data */ - - -/* Local data */ - -static int Debug = {FALSE}; /* Debug enabled flag */ -static int Lcur = {0}; /* Current line (in Lines array) */ -static char **Lines = {NULL}; /* Lines pointer array */ -static int Linlen = {100}; /* Line length */ -static int Lone = {0}; /* Line one (in Lines array) */ -static int Nmr = {0}; /* Number of matched regions */ -static char *Pat = {NULL}; /* Pattern */ -static char Shwfile = {TRUE}; /* Show file name... */ -static char Shwline = {TRUE}; /* Show line number */ -static int Waft = {0}; /* Window after */ -static int Wbef = {0}; /* Window before */ -static int Wsiz = {0}; /* Window size */ - -regexp *Re; /* Result from reg compilation */ - -int main(argc, argv) -int argc; /* Argument count */ -char **argv; /* Argument values */ - -{ - int i; /* Scratch */ - int n; /* Scratch again */ - int c; /* A character */ - char *aptr; /* Argument pointer */ - int nf; /* number of files on command line */ - - nf = 0; /* No files on line */ - - for (i = 1; i < argc; i++) { /* Look at args */ - if (argv[i][0] != '-') {/* If option */ - if (Pat == NULL) { /* If no pattern yet given */ - Pat = argv[i]; /* point here */ -#ifdef REGEX - if ((Re = re_comp(Pat)) != NULL) { - fprintf(stderr, "cgrep: %s\n", re); - exit(1); - } -#endif /* REGEX */ - -#ifdef REGCMP - if ((Re = regcomp(Pat)) == NULL) { - fprintf(stderr, "cgrep: error in regular expression.\n"); - exit(1); - } -#endif /* REGCMP */ - - } else { /* This must be a file to search */ - nf++; /* Count it */ - dosrch(argv[i]); /* Search */ - } - } else { /* Option char */ - c = argv[i][1]; /* Get option char */ - if (isupper(c)) /* Trap idiot definition of tolower */ - c = tolower(c); /* Don't care about case */ - n = i; - aptr = NULL; /* Find arg, if any */ - if (argv[i][2] != NUL) { - aptr = &argv[i][2]; - n = i; /* Where to set i if we use this arg */ - } else if (i < argc - 1) { /* use next.. */ - n = i + 1; - aptr = argv[n]; - } - switch (c) { /* Process the option */ - case 'a': /* Lines after */ - Waft = atoi(aptr); - Lines = NULL; - i = n; - break; - - case 'b': /* Lines before */ - Wbef = atoi(aptr); - Lines = NULL; - i = n; - break; - -/* Disable debug output - case 'd': Debug = TRUE; break; -*/ - - case 'f': /* Suppress filename on output */ - Shwfile = FALSE; - break; - - case 'l': /* Line length */ - Linlen = atoi(aptr); - Lines = NULL; - i = n; - break; - - case 'n': /* Suppress line number on output */ - Shwline = FALSE; - break; - - case 'w': /* Window: lines before and after */ - Waft = Wbef = atoi(aptr); - Lines = NULL; - i = n; - break; - - default: - fprintf(stderr, "Invalid option %s\n", argv[i]); - exit(1); - } - } - } - - if (Pat == NULL) { /* If no pattern given */ - fprintf(stderr, - "Usage: cgrep [-a n] [-b n] [-f] [-l n] [-n] [-w n] pattern [filename... ]\n"); - exit(1); - } - if (nf == 0) /* No files processed ? */ - dosrch((char *)NULL); /* Do standard input */ - return(0); -} - - /* Dosrch (ifnm) Perform the search - * Accepts : - * - * ifn Input file name - * - * - * Returns : - * - * - */ - -void dosrch(ifnm) -char *ifnm; /* Input filelname */ - -{ - FILE *ifp; /* Input fp */ - char *lptr; /* Line pointer */ - int i; /* Scratch */ - int prtaft; /* Print-after count */ - int linnum; /* Line number */ - int nlb; /* Number of lines buffered */ - - if (ifnm != NULL) { /* If file name given */ - ifp = fopen(ifnm, "r"); /* Open it for read access */ - if (ifp == NULL) { - fprintf(stderr, "Can not open file %s\n", ifnm); - return; - } - } else - ifp = stdin; - - if (Lines == NULL) { /* If no line table allocated.. */ - Wsiz = Wbef + 2; /* Determine total window size */ - Lines = (char **) calloc((size_t)Wsiz, sizeof(char *)); - /* Allocate pointer table */ - for (i = 0; i < Wsiz; i++) /* Allocate line buffers */ - Lines[i] = (char *) calloc((size_t)Linlen, sizeof(char)); - } - Lcur = Lone = 0; /* Setup line pointers */ - nlb = 0; /* No lines buffered */ - linnum = 0; /* Line number is zero */ - prtaft = -(Wbef + 1); /* Make sure separator given first time */ - - for (;;) { /* Loop through the file */ - lptr = Lines[Lcur]; /* Get pointer to current line */ - if (++Lcur == Wsiz) /* Bump curr pointer and wrap */ - Lcur = 0; /* if hit end */ - if (Lone == Lcur) /* If wrapped to beginning of window */ - if (++Lone == Wsiz) /* Bump beginning */ - Lone = 0; /* and wrap if hit end */ - - if (fgets(lptr, Linlen, ifp) != lptr) break; /* if end of file */ - - linnum++; /* Count line number */ - if (matlin(lptr)) { /* If matching line */ - if (prtaft < (-Wbef)) /* Check for separator needed */ - if ((Nmr++ > 0) && ((Wbef > 0) || (Waft > 0))) - printf("----------------------------------------------------------------------------\n"); - while (Lone != Lcur) { /* Until we close the window */ - shwlin(ifnm, linnum - nlb, Lines[Lone]); - /* Show the line */ - if (++Lone == Wsiz) Lone = 0; - nlb--; - } - nlb = 0; /* No lines buffered */ - prtaft = Waft; /* Print n lines after */ - } else { /* Didn't match */ - if (prtaft-- > 0) { /* If must print lines after */ - shwlin(ifnm, linnum, lptr); - /* Show the line */ - Lone = Lcur; /* Match pointers */ - } else if (nlb < Wbef) /* Count lines buffered */ - nlb++; - } - } - - if (ifnm != NULL) fclose(ifp); -} - - /* Shwlin (fnm, linnum, line) Show a matching line - * - * Accepts : - * - * fnm File name - * - * linnum Line number - * - * line Line to show - * - * - * Returns : - * - * - */ - -void shwlin(fnm, linnum, line) -char *fnm; /* File name */ -int linnum; /* Line number */ -char *line; /* Line (with newline at end) to print */ - -{ - if (Shwfile && (fnm != NULL)) printf("%s%s", fnm, Shwline ? " " : ":"); - if (Shwline) printf("@%05d:", linnum); - printf("%s", line); -} - - /* Matlin (line) Perform match against pattern and line - * - * Accepts : - * - * line Address of line to match - * - * - * Returns : - * - * TRUE if match FALSE if not - * - * - */ - - -int matlin(line) -char *line; /* Line to match */ - -{ - int rtncode; /* Return value from this routine */ - - -#ifdef NOREGEXP - char *pptr, *lptr, *tlptr; - int c1, c2; -#endif /* NOREGEXP */ - - if (Debug) printf("Matching %s against %s", Pat, line); - -#ifdef REGEX - rtncode = re_exec(line); /* Hand off to r/e evaluator */ -#endif /* REGEX */ - -#ifdef REGCMP - rtncode = (regexec(Re, line, TRUE) != 0); -#endif /* REGCMP */ - -#ifdef NOREGEX /* Have to do menial comparison.. */ - lptr = line; /* Init line pointer */ - - for (rtncode = -1; rtncode < 0;) { - tlptr = lptr++; /* Get temp ptr to line */ - pptr = Pat; /* Get ptr to pattern */ - while (TRUE) { - if ((c1 = *pptr++) == NUL) { - rtncode = 1; /* GOOD return value */ - break; - } - if ((c2 = *tlptr++) == NUL) { - rtncode = 0; /* BAD return value */ - break; - } - if (isupper(c1)) c1 = tolower(c1); - if (isupper(c2)) c2 = tolower(c2); - if (c1 != c2) break; - } - } -#endif /* NOREGEX */ - - - if (Debug) printf("matlin returned %s\n", rtncode ? "TRUE" : "FALSE"); - return(rtncode); -} - - - -void regerror(s) -const char *s; -{ - printf("%s\n", (char *) s); - exit(1); -} diff --git a/commands/fgrep/Makefile b/commands/fgrep/Makefile deleted file mode 100644 index 104d00cb6..000000000 --- a/commands/fgrep/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -PROG= fgrep -MAN= - -.include diff --git a/commands/fgrep/fgrep.c b/commands/fgrep/fgrep.c deleted file mode 100644 index 64c04087c..000000000 --- a/commands/fgrep/fgrep.c +++ /dev/null @@ -1,354 +0,0 @@ -/* fgrep - fast grep Author: Bert Gijsbers */ - -/* Copyright (c) 1991 by Bert Gijsbers. All rights reserved. - * Permission to use and redistribute this software is hereby granted provided - * that this copyright notice remains intact and that any modifications are - * clearly marked as such. - * - * syntax: - * fgrep -chlnsv <[-e string] ... [-f file] ... | string> [file] ... - * options: - * -c : print the number of matching lines - * -h : don't print file name headers if more than one file - * -l : print only the file names of the files containing a match - * -n : print line numbers - * -s : don't print, return status only - * -v : reverse, lines not containing one of the strings match - * -e string : search for this string - * -f file : file contains strings to search for - * notes: - * Options are processed by getopt(3). - * Multiple strings per command line are supported, eg. - * fgrep -e str1 -e str2 *.c - * Instead of a filename - is allowed, meaning standard input. - */ - -/* #include */ -#include -#include -#include -#include -#include -#include - -#define MAX_STR_LEN 256 /* maximum length of strings to search for */ -#define BYTE 0xFF /* convert from char to int */ -#define READ_SIZE 4096 /* read() request size */ -#define BUF_SIZE (2*READ_SIZE) /* size of buffer */ - -typedef struct test_str { - struct test_str *next; /* linked list */ - char *str; /* string to be found */ - char *str_end; /* points to last character */ - int len; /* string length */ - char *bufp; /* pointer into input buffer */ - unsigned char table[256]; /* table for Boyer-Moore algorithm */ -} test_str; - -test_str *strings; -char *prog_name; -int cflag, hflag, lflag, nflag, sflag, vflag; -unsigned line_num; /* line number in current file */ - -int fd_in, eof_seen; /* file descriptor for input and eof status */ -char input_buffer[BUF_SIZE + 2];/* buffer + sentinel margin */ -#define buffer (&input_buffer[2]) - -/* Pointers into the input buffer */ -char *input; /* points to current input char */ -char *max_input; /* points to first invalid char */ -char *buf_end; /* points to first char not read */ - -/* Error messages */ -char no_mem[] = "not enough memory"; -char no_arg[] = "argument missing"; - -extern char *optarg; -extern int optind; - -_PROTOTYPE(int main, (int argc, char **argv)); -_PROTOTYPE(char *search_str, (test_str * ts)); -_PROTOTYPE(int fill_buffer, (void)); -_PROTOTYPE(void failure, (char *mesg)); -_PROTOTYPE(void file_open, (void)); -_PROTOTYPE(void usage, (void)); -_PROTOTYPE(char *get_line, (void)); -_PROTOTYPE(void string_file, (void)); -_PROTOTYPE(void add_string, (char *str)); - -int main(argc, argv) -int argc; -char **argv; -{ - char *line; - int c; - unsigned count; /* number of matching lines in current file */ - unsigned found_one = 0; /* was there any match in any file at all ? */ - -#ifdef noperprintf - noperprintf(stdout); -#else - static char outbuf[BUFSIZ]; - - setvbuf(stdout, outbuf, _IOFBF, sizeof outbuf); -#endif - - prog_name = argv[0]; - if (argc == 1) usage(); - while ((c = getopt(argc, argv, "ce:f:hlnsv")) != EOF) { - switch (c) { - case 'c': cflag++; break; - case 'e': add_string(optarg); break; - case 'f': string_file(); break; - case 'h': hflag++; break; - case 'l': lflag++; break; - case 'n': nflag++; break; - case 's': sflag++; break; - case 'v': vflag++; break; - default: usage(); break; - } - } - - /* If no -e or -f option is used take a string from the command line. */ - if (strings == (test_str *) NULL) { - if (optind == argc) failure(no_arg); - add_string(argv[optind++]); - } - if (argc - optind < 2) - hflag++; /* don't print filenames if less than two - * files */ - - /* Handle every matching line according to the flags. */ - do { - optarg = argv[optind]; - file_open(); - count = 0; - while ((line = get_line()) != (char *) NULL) { - count++; - if (sflag) return 0; - if (lflag) { - printf("%s\n", optarg); - fflush(stdout); - break; - } - if (cflag) continue; - if (hflag == 0) printf("%s:", optarg); - if (nflag) printf("%u:", line_num); - do { - putchar(*line); - } while (++line < input); - fflush(stdout); - } - found_one |= count; - if (cflag) { - if (hflag == 0) printf("%s: ", optarg); - printf("%u\n", count); - fflush(stdout); - } - close(fd_in); - } while (++optind < argc); - - /* Exit nonzero if no match is found. */ - return found_one ? 0 : 1; -} - -void usage() -{ - fprintf(stderr, - "Usage: %s -chlnsv <[-e string] ... [-f file] ... | string> [file] ...\n", - prog_name); - exit(2); -} - -void failure(mesg) -char *mesg; -{ - fprintf(stderr, "%s: %s\n", prog_name, mesg); - exit(1); -} - -/* Add a string to search for to the global linked list `strings'. */ -void add_string(str) -char *str; -{ - test_str *ts; - int len; - - if (str == (char *) NULL || (len = strlen(str)) == 0) return; - if (len > MAX_STR_LEN) failure("string too long"); - if ((ts = (test_str *) malloc(sizeof(*ts))) == (test_str *) NULL) - failure(no_mem); - - /* Initialize Boyer-Moore table. */ - memset(ts->table, len, sizeof(ts->table)); - ts->len = len; - ts->str = str; - ts->str_end = str + len - 1; - for (; --len >= 0; str++) ts->table[*str & BYTE] = len; - - /* Put it on the list */ - ts->next = strings; - strings = ts; -} - -/* Open a file for reading. Initialize input buffer pointers. */ -void file_open() -{ - /* Use stdin if no file arguments are given on the command line. */ - if (optarg == (char *) NULL || strcmp(optarg, "-") == 0) { - fd_in = 0; - optarg = "stdin"; - } else if ((fd_in = open(optarg, O_RDONLY)) == -1) { - fprintf(stderr, "%s: can't open %s\n", prog_name, optarg); - exit(1); - } - input = max_input = buf_end = buffer; - buffer[-1] = '\n'; /* sentinel */ - eof_seen = 0; - line_num = 0; -} - -/* Move any leftover characters to the head of the buffer. - * Read characters into the rest of the buffer. - * Round off the available input to whole lines. - * Return the number of valid input characters. - */ -int fill_buffer() -{ - char *bufp; - int size; - - if (eof_seen) return 0; - - size = buf_end - max_input; - memmove(buffer, max_input, size); - bufp = &buffer[size]; - - do { - if ((size = read(fd_in, bufp, READ_SIZE)) <= 0) { - if (size != 0) failure("read error"); - eof_seen++; - if (bufp == buffer) /* no input left */ - return 0; - /* Make sure the last char of a file is '\n'. */ - *bufp++ = '\n'; - break; - } - bufp += size; - } while (bufp - buffer < READ_SIZE && bufp[-1] != '\n'); - - buf_end = bufp; - while (*--bufp != '\n'); - if (++bufp == buffer) { - /* Line too long. */ - *buf_end++ = '\n'; - bufp = buf_end; - } - max_input = bufp; - input = buffer; - - return max_input - buffer; -} - -/* Read strings from a file. Give duplicates to add_string(). */ -void string_file() -{ - char *str, *p; - - file_open(); - while (input < max_input || fill_buffer() > 0) { - p = (char *) memchr(input, '\n', BUF_SIZE); - *p++ = '\0'; - if ((str = (char *) malloc(p - input)) == (char *) NULL) - failure(no_mem); - memcpy(str, input, p - input); - add_string(str); - input = p; - } - close(fd_in); -} - -/* Scan the rest of the available input for a string using Boyer-Moore. - * Return a pointer to the match or a pointer beyond end of input if no match. - * Record how far the input is scanned. - */ -char *search_str(ts) -test_str *ts; -{ - char *bufp, *prevbufp, *s; - - bufp = input + ts->len - 1; - while (bufp < max_input) { - prevbufp = bufp; - bufp += ts->table[*bufp & BYTE]; - if (bufp > prevbufp) continue; - s = ts->str_end; - do { - if (s == ts->str) { /* match found */ - ts->bufp = bufp; - return bufp; - } - } while (*--bufp == *--s); - bufp = prevbufp + 1; - } - ts->bufp = bufp; - - return bufp; -} - -/* Return the next line in which one of the strings occurs. - * Or, if the -v option is used, the next line without a match. - * Or NULL on EOF. - */ -char *get_line() -{ - test_str *ts; - char *match, *line; - - /* Loop until a line is found. */ - while (1) { - if (input >= max_input && fill_buffer() == 0) { /* EOF */ - line = (char *) NULL; - break; - } - - /* If match is still equal to max_input after the next loop - * then no match is found. */ - match = max_input; - ts = strings; - do { - if (input == buffer) { - if (search_str(ts) < match) match = ts->bufp; - } else if (ts->bufp < match) { - if (ts->bufp >= input || search_str(ts) < match) - match = ts->bufp; - } - } while ((ts = ts->next) != (test_str *) NULL); - - /* Determine if and in what line a match is found. Only do - * line number counting if it is necessary or very easy. */ - if (vflag) { - line_num++; - line = input; - input = 1 + (char *) memchr(line, '\n', BUF_SIZE); - if (input <= match) break; /* no match in current line */ - } else if (nflag) { - do { - line_num++; - line = input; - input = 1 + (char *) memchr(line, '\n', BUF_SIZE); - } while (input < match || - (input == match && match < max_input)); - if (match < max_input) break; /* match found */ - } else if (match < max_input) { - /* Match found. */ - for (line = match; *--line != '\n';); - line++; - input = 1 + (char *) memchr(match, '\n', BUF_SIZE); - break; - } else - input = max_input; - } - - return line; -} diff --git a/commands/grep/Makefile b/commands/grep/Makefile deleted file mode 100644 index 572079233..000000000 --- a/commands/grep/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -PROG= grep -MAN= - -LINKS+= ${BINDIR}/grep ${BINDIR}/egrep - -.include diff --git a/commands/grep/grep.c b/commands/grep/grep.c deleted file mode 100644 index d5aa30a33..000000000 --- a/commands/grep/grep.c +++ /dev/null @@ -1,379 +0,0 @@ -/* grep - search a file for a pattern Author: Norbert Schlenker */ - -/* Norbert Schlenker (nfs@princeton.edu) 1990-02-08 - * Released into the public domain. - * - * Grep searches files for lines containing a pattern, as specified by - * a regular expression, and prints those lines. It is invoked by: - * grep [flags] [pattern] [file ...] - * - * Flags: - * -e pattern useful when pattern begins with '-' - * -c print a count of lines matched - * -i ignore case - * -l prints just file names, no lines (quietly overrides -n) - * -n printed lines are preceded by relative line numbers - * -s prints errors only (quietly overrides -l and -n) - * -v prints lines which don't contain the pattern - * - * Semantic note: - * If both -l and -v are specified, grep prints the names of those - * files which do not contain the pattern *anywhere*. - * - * Exit: - * Grep sets an exit status which can be tested by the caller. - * Note that these settings are not necessarily compatible with - * any other version of grep, especially when -v is specified. - * Possible status values are: - * 0 if any matches are found - * 1 if no matches are found - * 2 if syntax errors are detected or any file cannot be opened - */ - - -/* External interfaces */ -#include -#include /* Thanks to Henry Spencer */ -#include -#include -#include -#include - -/* Internal constants */ -#define MATCH 0 /* exit code: some match somewhere */ -#define NO_MATCH 1 /* exit code: no match on any line */ -#define FAILURE 2 /* exit code: syntax error or bad file name */ - -/* Macros */ -#define SET_FLAG(c) (flags[(c)-'a'] = 1) -#define FLAG(c) (flags[(c)-'a'] != 0) - -#define uppercase(c) (((unsigned) ((c) - 'A')) <= ('Z' - 'A')) -#define downcase(c) ((c) - 'A' + 'a') - -/* Private storage */ -static char *program; /* program name */ -static char flags[26]; /* invocation flags */ -static regexp *expression; /* compiled search pattern */ -static const char *rerr; /* error message */ - -/* External variables. */ -extern int optind; -extern char *optarg; - -/* Internal interfaces */ -_PROTOTYPE(int main, (int argc, char **argv)); -_PROTOTYPE(static int match, (FILE *input, char *label, char *filename)); -_PROTOTYPE(static char *get_line, (FILE *input)); -_PROTOTYPE(static char *map_nocase, (char *line)); -_PROTOTYPE(void regerror , (const char *s ) ); -_PROTOTYPE(static void tov8, (char *v8pattern, char *pattern)); - -int main(argc, argv) -int argc; -char *argv[]; -{ - int opt; /* option letter from getopt() */ - int egrep=0; /* using extended regexp operators */ - char *pattern; /* search pattern */ - char *v8pattern; /* v8 regexp search pattern */ - int exit_status = NO_MATCH; /* exit status for our caller */ - int file_status; /* status of search in one file */ - FILE *input; /* input file (if not stdin) */ - - program = argv[0]; - if (strlen(program)>=5 && strcmp(program+strlen(program)-5,"egrep")==0) egrep=1; - memset(flags, 0, sizeof(flags)); - pattern = NULL; - -/* Process any command line flags. */ - while ((opt = getopt(argc, argv, "e:cilnsv")) != EOF) { - if (opt == '?') - exit_status = FAILURE; - else - if (opt == 'e') - pattern = optarg; - else - SET_FLAG(opt); - } - -/* Detect a few problems. */ - if ((exit_status == FAILURE) || (optind == argc && pattern == NULL)) { - fprintf(stderr,"Usage: %s [-cilnsv] [-e] expression [file ...]\n",program); - exit(FAILURE); - } - -/* Ensure we have a usable pattern. */ - if (pattern == NULL) - pattern = argv[optind++]; - -/* Map pattern to lowercase if -i given. */ - if (FLAG('i')) { - char *p; - for (p = pattern; *p != '\0'; p++) { - if (uppercase(*p)) - *p = downcase(*p); - } - } - - if (!egrep) { - if ((v8pattern=malloc(2*strlen(pattern)))==(char*)0) { - fprintf(stderr,"%s: out of memory\n"); - exit(FAILURE); - } - tov8(v8pattern,pattern); - } else v8pattern=pattern; - - rerr=(char*)0; - if ((expression = regcomp(v8pattern)) == NULL) { - fprintf(stderr,"%s: bad regular expression",program); - if (rerr) fprintf(stderr," (%s)",rerr); - fprintf(stderr,"\n"); - exit(FAILURE); - } - -/* Process the files appropriately. */ - if (optind == argc) { /* no file names - find pattern in stdin */ - exit_status = match(stdin, (char *) NULL, ""); - } - else - if (optind + 1 == argc) { /* one file name - find pattern in it */ - if (strcmp(argv[optind], "-") == 0) { - exit_status = match(stdin, (char *) NULL, "-"); - } else { - if ((input = fopen(argv[optind], "r")) == NULL) { - fprintf(stderr, "%s: couldn't open %s\n", - program, argv[optind]); - exit_status = FAILURE; - } - else { - exit_status = match(input, (char *) NULL, argv[optind]); - } - } - } - else - while (optind < argc) { /* lots of file names - find pattern in all */ - if (strcmp(argv[optind], "-") == 0) { - file_status = match(stdin, "-", "-"); - } else { - if ((input = fopen(argv[optind], "r")) == NULL) { - fprintf(stderr, "%s: couldn't open %s\n", - program, argv[optind]); - exit_status = FAILURE; - } else { - file_status = match(input, argv[optind], argv[optind]); - fclose(input); - } - } - if (exit_status != FAILURE) - exit_status &= file_status; - ++optind; - } - return(exit_status); -} - - -/* match - matches the lines of a file with the regular expression. - * To improve performance when either -s or -l is specified, this - * function handles those cases specially. - */ - -static int match(input, label, filename) -FILE *input; -char *label; -char *filename; -{ - char *line, *testline; /* pointers to input line */ - long int lineno = 0; /* line number */ - long int matchcount = 0; /* lines matched */ - int status = NO_MATCH; /* summary of what was found in this file */ - - if (FLAG('s') || FLAG('l')) { - while ((line = get_line(input)) != NULL) { - testline = FLAG('i') ? map_nocase(line) : line; - if (regexec(expression, testline, 1)) { - status = MATCH; - break; - } - } - if (FLAG('l')) - if ((!FLAG('v') && status == MATCH) || - ( FLAG('v') && status == NO_MATCH)) - puts(filename); - return status; - } - - while ((line = get_line(input)) != NULL) { - ++lineno; - testline = FLAG('i') ? map_nocase(line) : line; - if (regexec(expression, testline, 1)) { - status = MATCH; - if (!FLAG('v')) { - if (label != NULL) - printf("%s:", label); - if (FLAG('n')) - printf("%ld:", lineno); - if (!FLAG('c')) puts(line); - matchcount++; - } - } else { - if (FLAG('v')) { - if (label != NULL) - printf("%s:", label); - if (FLAG('n')) - printf("%ld:", lineno); - if (!FLAG('c')) puts(line); - matchcount++; - } - } - } - if (FLAG('c')) printf("%ld\n", matchcount); - return status; -} - - -/* get_line - fetch a line from the input file - * This function reads a line from the input file into a dynamically - * allocated buffer. If the line is too long for the current buffer, - * attempts will be made to increase its size to accomodate the line. - * The trailing newline is stripped before returning to the caller. - */ - -#define FIRST_BUFFER (size_t)256 /* first buffer size */ - -static char *buf = NULL; /* input buffer */ -static size_t buf_size = 0; /* input buffer size */ - -static char *get_line(input) -FILE *input; -{ - int n; - register char *bp; - register int c; - char *new_buf; - size_t new_size; - - if (buf_size == 0) { - if ((buf = (char *) malloc(FIRST_BUFFER)) == NULL) { - fprintf(stderr,"%s: not enough memory\n",program); - exit(FAILURE); - } - buf_size = FIRST_BUFFER; - } - - bp = buf; - n = buf_size; - while (1) { - while (--n > 0 && (c = getc(input)) != EOF) { - if (c == '\n') { - *bp = '\0'; - return buf; - } - *bp++ = c; - } - if (c == EOF) - return (ferror(input) || bp == buf) ? NULL : buf; - new_size = buf_size << 1; - if ((new_buf = (char *) realloc(buf, new_size)) == NULL) { - fprintf(stderr, "%s: line too long - truncated\n", program); - while ((c = getc(input)) != EOF && c != '\n') ; - *bp = '\0'; - return buf; - } else { - bp = new_buf + (buf_size - 1); - n = buf_size + 1; - buf = new_buf; - buf_size = new_size; - } - } -} - - -/* map_nocase - map a line down to lowercase letters only. - * bad points: assumes line gotten from get_line. - * there is more than A-Z you say? - */ - -static char *map_nocase(line) -char *line; -{ - static char *mapped=(char*)0; - static size_t map_size = 0; - char *mp; - - if (map_size < buf_size) { - if ((mapped=realloc(mapped,map_size=buf_size)) == NULL) { - fprintf(stderr,"%s: not enough memory\n",program); - exit(FAILURE); - } - } - - mp = mapped; - do { - *mp++ = uppercase(*line) ? downcase(*line) : *line; - } while (*line++ != '\0'); - - return mapped; -} - -/* In basic regular expressions, the characters ?, +, |, (, and ) - are taken literally; use the backslashed versions for RE operators. - In v8 regular expressions, things are the other way round, so - we have to swap those characters and their backslashed versions. -*/ -static void tov8(char *v8, char *basic) -{ - while (*basic) switch (*basic) - { - case '?': - case '+': - case '|': - case '(': - case ')': - { - *v8++='\\'; - *v8++=*basic++; - break; - } - case '\\': - { - switch (*(basic+1)) - { - case '?': - case '+': - case '|': - case '(': - case ')': - { - *v8++=*++basic; - ++basic; - break; - } - case '\0': - { - *v8++=*basic++; - break; - } - default: - { - *v8++=*basic++; - *v8++=*basic++; - } - } - break; - } - default: - { - *v8++=*basic++; - } - } - *v8++='\0'; -} - -/* Regular expression code calls this routine to print errors. */ - -void regerror(s) -const char *s; -{ - rerr=s; -}