|
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 - download
Length: 6739 (0x1a53) Types: TextFile Notes: UNIX file Names: »grep1.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─ ⟦this⟧ »cmd/grep/grep1.c«
/* * Grep - search a file for a pattern * This code uses the regexp.c code which is * also used by AWK. */ #include <stdio.h> #include <ctype.h> #include "grep.h" #define MAXLINE 400 /* Maximum input line length */ #define NEXP 50 /* Maximum number of regular expressions */ #define BSIZE BUFSIZ /* Assume block size if buffer size */ char line[MAXLINE]; struct exps { union { char *u_cp; RE *u_re; } e_un; int (*e_mfun)(); } exps[NEXP+1]; char usage[] = "Usage: grep [-abchlnsvxy] [-e exp] [-f efile] [expression] [file ...]"; char mre[] = "Missing regular expression"; char nospace[] = "Out of space for regular expressions"; char *fname; /* Current filename */ int vflag; /* Reverse sense of match */ int cflag; /* Print only count of lines */ int lflag; /* Only filenames with matching lines */ int nflag; /* precede lines by line number in file */ int bflag; /* print block number of match */ int sflag; /* No output, only status */ int hflag; /* Never print filenames */ int xflag; /* Exact match only */ int some; /* non-zero if some matches */ int outfile; /* Output filename if match flag */ int lineno; /* Input line # */ unsigned blkno; /* Block number for `-b' */ long lmatch; /* Lines matching */ int yflag; /* Dual case comparisons */ int (*mfun)(); /* Match function */ int rematch(); int dirmatch(); int reinterp(); int ematch(); int yematch(); main(argc, argv) char *argv[]; { register RE *rp; register char *cp; register i; struct exps *epp; FILE *fp; mfun = rematch; while (argc>1 && *argv[1]=='-') { for (cp = &argv[1][1]; *cp; cp++) switch (*cp) { case 'a': refull = 1; break; case 'b': bflag = 1; break; case 'c': cflag = 1; break; case 'e': if (argc < 3) err(mre); expsave(argv[2]); argc--; argv++; break; case 'f': if (argc < 3) err("Missing expression filename"); if ((fp = fopen(argv[2], "r")) == NULL) err("Cannot open %s", argv[2]); argv++; argc--; while (fgets(line, MAXLINE, fp) != NULL) { i = strlen(line); line[i-1] = '\0'; expsave(line); } fclose(fp); break; case 'h': hflag = 1; break; case 'l': lflag = 1; break; case 'n': nflag = 1; break; case 's': sflag = 1; break; case 'v': vflag = 1; break; case 'x': xflag = 1; mfun = dirmatch; break; case 'y': redual = 1; yflag = 1; break; default: err(usage); } argv++; argc--; } if (exps[0].e_un.u_cp == NULL) { if (argc-- < 2) err(usage); expsave(argv[1]); argv++; } expsave(NULL); if (!xflag) for (epp = &exps[0]; (cp = epp->e_un.u_cp) != NULL; epp++) { rp = epp->e_un.u_re = reparse(cp, '\0'); if (reerror != NULL) err(reerror); for (; rp != NULL; rp = rp->r_next) if (rp->r_op != CONC) break; if (rp != NULL) { /* hard RE */ free(cp); epp->e_mfun = reinterp; } else { rp = epp->e_un.u_re; epp->e_un.u_cp = cp; epp->e_mfun = yflag ? yematch : ematch; for ( ; rp!=NULL; rp = rp->r_next) { *cp = rp->r_left.u_ival; cp++; } *cp = '\0'; } } if (argc < 3) /* Fewer than 2 files? */ hflag = 1; if (argc == 1) { fname = "(stdin)"; grep(stdin); } else for (i=1; i<argc; i++) { if ((fp = fopen(argv[i], "r")) == NULL) err("Cannot open %s", argv[i]); fname = argv[i]; grep(fp); fclose(fp); } if (cflag) printf("%ld\n", lmatch); exit(!some); } /* * Save regular expression. */ expsave(s) register char *s; { static struct exps *epp; if (epp == NULL) epp = &exps[0]; if (epp >= &exps[NEXP-1]) err("Too many regular expressions"); if (s == NULL) epp->e_un.u_cp = NULL; else { if ((epp->e_un.u_cp = malloc(strlen(s)+1)) == NULL) err(nospace); strcpy(epp->e_un.u_cp, s); } epp++; } /* * Called for each input file * to drive the pattern matches. */ grep(ifp) FILE *ifp; { register unsigned n; register c; register char *cp; outfile = 0; blkno = 0; n = BSIZE; lineno = 0; for (cp = line; (c = getc(ifp)) != EOF; ) { if (n-- == 0) { n = BSIZE; blkno++; } if (c=='\n' || cp>=&line[MAXLINE-1]) { *cp = '\0'; lineno++; (*mfun)(cp = line); } else *cp++ = c; } if (outfile) printf("%s\n", fname); } /* * Called when a match occurred in input */ amatch(s) char *s; { some = 1; if (sflag) return; if (!lflag && !cflag) { if (!hflag) printf("%s: ", fname); if (bflag) printf("%d:\t", blkno); else if (nflag) printf("%d:\t", lineno); printf("%s\n", s); } else if (lflag) outfile = 1; else if (cflag) lmatch++; } /* * try to match each line with all the * regular expressions. * An attempt is made to make expressions * with no metacharacters run faster. */ rematch(s) char *s; { register struct exps *epp; register int m; m = 0; for (epp = &exps[0]; epp->e_un.u_re!=NULL && m==0; epp++) if ((*epp->e_mfun)(epp->e_un.u_re, s) != NULL) m = 1; if (vflag) m = !m; if (m) amatch(s); return (m); } /* * Direct match function (for `-x' option) */ dirmatch(s) char *s; { register struct exps *epp; register m; m = 0; for (epp = &exps[0]; epp->u_cp!=NULL && !m; epp++) m = yflag ? yseq(epp->u_cp, s) : seq(epp->u_cp, s); if (vflag) m = !m; if (m) amatch(s); return (m); } /* * Easy match * For non -y grep. */ ematch(p, s) char *p; register char *s; { register char *xp, *xs; do { xp = p; xs = s; while (*xp != '\0') { if (*xs == '\0') return (0); if (*xp != *xs++) break; xp++; } if (*xp == '\0') return (1); } while (*s++ != '\0'); return (0); } /* * Version of `ematch' for `-y' option * of grep. */ yematch(p, s) char *p; register char *s; { register char *xp, *xs; register int c; do { xp = p; xs = s; while (*xp != '\0') { if (*xs == '\0') return (0); if (islower(*xp) && isupper(*xs)) c = tolower(*xs++); else c = *xs++; if (*xp != c) break; xp++; } if (*xp == '\0') return (1); } while (*s++ != '\0'); return (0); } /* * String comparison for `-x' option * without `-y' (dual) flag. */ seq(p, s) register char *p; register char *s; { while (*s == *p++) if (*s++ == '\0') return (1); return (0); } /* * Version of `seq' for the `-y' option. * First argument is the pattern, the second * is the input string. */ yseq(p, s) register char *p; register char *s; { register int c; while ((c = *s++) != '\0') { if (islower(*p) && isupper(c)) c = tolower(c); if (c != *p++) return (0); } if (*p != '\0') return (0); return (1); } err(s) { if (!sflag) { fprintf(stderr, "%r", &s); fprintf(stderr, "\n"); } exit(2); }