/* * gngp - globally match newsgroup pattern and print * like grep, but for newsgroup patterns instead of regular expressions */ #include #include #include #include #include "libc.h" #include "news.h" #include "fgetfln.h" #include "ngmatch.h" /* imports */ extern FILE *efopen(); char *progname; int debug = 0; /* * if true, match only ng at start of line, followed by whitespace or newline. */ static int anchored = 0; static int reverse = 0; /* iff true, reverse argument & file roles */ static int exclude = 0; /* iff true, print lines *not* matched */ static NGPAT *ngpat; /* * main - parse arguments and handle options */ main(argc, argv) int argc; char *argv[]; { int c, status = 0, errflg = 0; char *patarg; progname = argv[0]; while ((c = getopt(argc, argv, "adrv")) != EOF) switch (c) { case 'a': /* anchored at start of line */ anchored++; break; case 'd': matchdebug(1); /* all debugging on */ debug++; break; case 'r': /* reverse roles: ngs in arg., patterns in file */ reverse++; break; case 'v': exclude++; break; default: errflg++; break; } if (errflg || optind == argc) { (void) fprintf(stderr, "usage: %s [-adrv] ng_pattern [file...]\n", progname); exit(2); } patarg = argv[optind]; if (!reverse) { ngpat = ngparse(patarg); if (ngpat == NULL) error("can't parse pattern `%s'", patarg); } if (optind == argc-1) status |= process(patarg, stdin, "stdin"); else { while (++optind < argc) { FILE *in = efopen(argv[optind], "r"); status |= process(patarg, in, argv[optind]); (void) fclose(in); } } exit(status != 0? 0: 1); } /* * process - process input file */ process(pattern, in, inname) register char *pattern; register FILE *in; char *inname; { register char *line; register int status = 0; while ((line = fgetln(in)) != NULL) if (anchored) status |= gngp(pattern, line); else { register char *start; for (start = line; *start != '\0'; start++) status |= gngp(pattern, start); } return status; } int gngp(pattern, text) register char *pattern, *text; { register int returned; register char *whitesp; register char savewhite; if (anchored) /* strpbrk(text, " \t\n") is too slow; do it long-hand */ for (whitesp = text; (savewhite = *whitesp) != '\0'; whitesp++) if (isascii(savewhite) && isspace(savewhite)) { *whitesp = '\0'; break; } if (!reverse) returned = ngpatmat(ngpat, text); else returned = ngmatch(text, pattern); if (exclude) returned = !returned; if (anchored) *whitesp = savewhite; if (returned) (void) fputs(text, stdout); return returned; }