|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 4375 (0x1117) Types: TextFile Notes: UNIX file Names: »egrep.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─⟦this⟧ »cmd/egrep/egrep.c«
/* * egrep -- pattern matcher * * Lines of input are searched for the user-supplied extended * regular expression. Command line options determine what "egrep" * does on a match: usually the line is printed. Lines over BUFSIZ * chars in length may be fatal when read from pipes or raw devices. * The implementation goal is speed and, to this end, a DFA is * employed. Two key strategies reduce the time spent constructing * the DFA by a factor of 100, in typical cases: (1) the use of * equivalence classes, (2) construction of the DFA dynamically. * These strategies win because of the way "egrep" tends to be used. * Most patterns use only 10-20 characters in the ASCII set of 128. * Most input exercises only 10% of the total possible transitions * (so why compute the remaining 90%?). As a side benefit, these * strategies reduce "egrep"'s gigantic appetite for memory to merely * huge. Strategy (2) has the important psychological effect of making * "egrep" appear to start running instantly; the inevitable time spent * constructing the DFA is amortized over the running time of the * program. */ #include "egrep.h" #include "dragon.h" #include <access.h> bool eflag; /* next arg is regular expression */ bool fflag; /* next arg is file containing rex */ bool vflag; /* line matches if rex NOT found */ bool cflag; /* only print # matches */ bool lflag; /* only print name of files that match */ bool nflag; /* also print line # */ bool bflag; /* also print block # */ bool sflag; /* only provide exit status */ bool hflag; /* do not print file names */ bool yflag; /* lower case also matches upper case input */ /* * egrep * Return 0 if any matches found in the input files, else 1. */ main( argc, argv) register char **argv; { register struct newt *np; register struct dragon *dp; struct newt *makenfa( ); struct newt *npolish( ); struct dragon *initdfa( ); int status; int i = 0; char **init( ); bool search( ); argv = init( argc, argv); np = makenfa( ); ncheck( initdfa( np)->d_s); np = npolish( np); dp = initdfa( np); status = 1; while (*argv) { if (access(*argv, AREAD)) { fprintf(stderr, "egrep: can't open %s\n", *argv); *argv[0] = 0; /* flag arg as invalid */ } i++; /* count arg */ argv++; /* advance to next arg */ } argv -= i; /* back to start of filename args to process */ if (*argv) do { if (*argv[0] == 0) /* arg to skip? */ continue; /* yes */ if (freopen( *argv, "r", stdin) == NULL) { fprintf(stderr, "egrep: can't open %s\n", *argv); continue; } if (search( *argv, dp, np)) status = 0; } while (*++argv); else if (search( "(stdin)", dp, np)) status = 0; return (status); } /* * initialization * Process command line. Return `argv' pointing to first file arg. */ static char ** init( argc, argv) char **argv; { register char **av, *a; register bool gotrex; extern char *regexp; extern FILE *rexf; gotrex = FALSE; av = &argv[1]; while (a = *av++) { if (*a != '-') { if (not gotrex) { gotrex = TRUE; regexp = a; a = *av++; } break; } while (*++a) switch (*a) { case 'e': if (gotrex) onlyone( ); if (*av == NULL) fatal( "missing arg to -e"); regexp = *av++; gotrex = TRUE; break; case 'f': if (gotrex) onlyone( ); if (*av == NULL) fatal( "missing arg to -f"); rexf = fopen( *av, "r"); if (rexf == NULL) fatal( "can't open %s", *av); ++av; gotrex = TRUE; break; case 'v': vflag = TRUE; break; case 'c': cflag = TRUE; break; case 'l': lflag = TRUE; break; case 'n': nflag = TRUE; break; case 'b': bflag = TRUE; break; case 's': sflag = TRUE; break; case 'h': hflag = TRUE; break; case 'y': yflag = TRUE; break; default: fatal( "no such flag -%c", *a); } } if (not gotrex) { fprintf(stderr, "Usage: egrep [ -bcefhlnsvy ] pattern [ file ...]\n"); exit(2); } --av; if (argc-(av-argv) <= 1) hflag = TRUE; return (av); } static onlyone( ) { fatal( "exactly one pattern required"); } nomem( ) { fatal( "out of mem"); } /* * fatal error */ fatal( arg0) char *arg0; { fflush( stdout); fprintf( stderr, "egrep: %r\n", &arg0); exit( 2); }