/* * gh.c: * GREP with hilighting. * * Copyright (c) 2002 Chris Lightfoot. All rights reserved. * Email: chris@ex-parrot.com; WWW: http://www.ex-parrot.com/~chris/ * */ static const char rcsid[] = "$Id: gh.c,v 1.3 2003/01/18 17:02:29 chris Exp $"; #include #include #include #include void usage(FILE *fp) { fprintf(fp, "gh - grep with hilight\n" "\n" "Usage: gh [options] pattern [file] ...\n" "\n" "Options: -h display this message\n" " -i case-insensitive pattern match\n" " -n print line numbers\n" " -p pass-through; print all lines, whether or not they match\n" "\n" ); } int print_line_number, print_file_name, pass_through; regex_t R; int grep_line(const char *line, const char *name, const int n) { int a; regmatch_t match; if ((a = regexec(&R, line, 1, &match, 0)) == 0 || pass_through) { if (print_file_name) printf("%s:", name); if (print_line_number) printf("%d:", n); if (a == 0) { printf("%.*s\x1b[7m%.*s\x1b[0m%s\n", match.rm_so, line, match.rm_eo - match.rm_so, line + match.rm_so, line + match.rm_eo); return 1; } else printf("%s\n", line); } return 0; } int grep_stream(FILE *fp, const char *name) { static char *buf; static size_t blen; int i, c, res = 0, n; if (!buf) buf = malloc(blen = 1024); i = 0; n = 1; while ((c = fgetc(fp)) != EOF) { if (c != '\n') buf[i++] = (char)c; else { buf[i] = 0; if (grep_line(buf, name, n)) res = 1; i = 0; ++n; } if (i == blen) buf = realloc(buf, blen *= 2); } if (ferror(fp)) perror(name); else if (i > 0) { /* grep partial last line... */ buf[i] = 0; if (grep_line(buf, name, n)) res = 1; } return res; } char optstr[] = "+hinp"; int main(int argc, char *argv[]) { int c, err, ret = 1; int Rflags = REG_EXTENDED; opterr = 0; while ((c = getopt(argc, argv, optstr)) != EOF) { switch (c) { case 'h': usage(stdout); return 0; case 'i': Rflags |= REG_ICASE; break; case 'n': print_line_number = 1; break; case 'p': pass_through = 1; break; case '?': default: fprintf(stderr, "bad option -%c\n", optopt); usage(stderr); return 1; } } if (!argv[optind]) { usage(stderr); return -1; } if ((err = regcomp(&R, argv[optind], Rflags))) { char e[1024]; regerror(err, &R, e, sizeof e); fprintf(stderr, "gh: %s: %s\n", argv[1], e); return -1; } ++optind; if (!argv[optind]) { grep_stream(stdin, "standard input"); } else { if (argc - optind > 1) print_file_name = 1; while (argv[optind]) { FILE *fp; if (!(fp = fopen(argv[optind], "rt"))) perror(argv[optind]); else { if (grep_stream(fp, argv[optind])) ret = 0; fclose(fp); } ++optind; } } return ret; }