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 \
+++ /dev/null
-PROG= cgrep
-MAN=
-
-.include <minix.prog.mk>
+++ /dev/null
-/* 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 <sys/types.h>
-#include <sys/dir.h> /* Either here or in sys directory - dro */
-#include <ctype.h>
-#include <limits.h> /* should have this - dro */
-#include <regexp.h> /* should have this - dro */
-#include <stdlib.h>
-#include <stdio.h>
-#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 :
- *
- * <value> 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);
-}
+++ /dev/null
-PROG= fgrep
-MAN=
-
-.include <minix.prog.mk>
+++ /dev/null
-/* 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 <ansi.h> */
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#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;
-}
+++ /dev/null
-PROG= grep
-MAN=
-
-LINKS+= ${BINDIR}/grep ${BINDIR}/egrep
-
-.include <minix.prog.mk>
+++ /dev/null
-/* 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 <sys/types.h>
-#include <regexp.h> /* Thanks to Henry Spencer */
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
-
-/* 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, "<stdin>");
- }
- 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;
-}