X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=findutils%2Fgrep.c;h=a2c07c52371513e07ad41408eb9140f9230edbb3;hb=bf181b9338152759fd56c8009e9a962a84808e7c;hp=108c879afd07bf5adb7475c13d0d63aecd628152;hpb=e77ae3a2c0328590b43447550bdb1284650b8236;p=oweals%2Fbusybox.git diff --git a/findutils/grep.c b/findutils/grep.c index 108c879af..a2c07c523 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -1,7 +1,8 @@ /* - * Mini grep implementation for busybox + * Mini grep implementation for busybox using libc regex. * - * Copyright (C) 1998 by Erik Andersen + * Copyright (C) 1999,2000 by Lineo, inc. + * Written by Mark Whitley , * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,140 +20,148 @@ * */ -#include "internal.h" #include -#include +#include +#include +#include +#include /* for strerror() */ #include -#include -#include -#include -#include +#include "internal.h" +extern int optind; /* in unistd.h */ +extern int errno; /* for use with strerror() */ -static const char grep_usage[] = -"grep [-ihn]... PATTERN [FILE]...\n" -"Search for PATTERN in each FILE or standard input.\n\n" -"\t-h\tsuppress the prefixing filename on output\n" -"\t-i\tignore case distinctions\n" -"\t-n\tprint line number with output lines\n\n" -"This version of grep matches strings (not full regexps).\n"; +/* options */ +static int ignore_case = 0; +static int print_filename = 0; +static int print_line_num = 0; +static int be_quiet = 0; +static int invert_search = 0; +static int suppress_err_msgs = 0; +/* globals */ +static regex_t regex; /* storage space for compiled regular expression */ +static int nmatches = 0; /* keeps track of the number of matches */ +static char *cur_file = NULL; /* the current file we are reading */ -/* - * See if the specified needle is found in the specified haystack. - */ -static int search (const char *haystack, const char *needle, int ignoreCase) + +static void print_matched_line(char *line, int linenum) { + if (print_filename) + printf("%s:", cur_file); + if (print_line_num) + printf("%i:", linenum); - if (ignoreCase == FALSE) { - haystack = strstr (haystack, needle); - if (haystack == NULL) - return FALSE; - return TRUE; - } else { - int i; - char needle1[BUF_SIZE]; - char haystack1[BUF_SIZE]; - - strncpy( haystack1, haystack, sizeof(haystack1)); - strncpy( needle1, needle, sizeof(needle1)); - for( i=0; i 0) { - name = *argv++; + /* if we found a match but were told to be quiet, stop here and + * return success */ + if (be_quiet) { + regfree(®ex); + exit(0); + } - fp = fopen (name, "r"); - if (fp == NULL) { - perror (name); - continue; - } + nmatches++; - line = 0; + print_matched_line(line, linenum); - while (fgets (buf, sizeof (buf), fp)) { - line++; - cp = &buf[strlen (buf) - 1]; + } else if (ret == REG_NOMATCH && invert_search) { + print_matched_line(line, linenum); + } - if (*cp != '\n') - fprintf (stderr, "%s: Line too long\n", name); + free(line); + } +} - if (search (buf, needle, ignoreCase)==TRUE) { - if (tellName==TRUE) - printf ("%s: ", name); +extern int grep_main(int argc, char **argv) +{ + int opt; + int reflags; - if (tellLine==TRUE) - printf ("%ld: ", line); + /* do special-case option parsing */ + if (argv[1] && (strcmp(argv[1], "--help") == 0)) + usage(grep_usage); - fputs (buf, stdout); - } + /* do normal option parsing */ + while ((opt = getopt(argc, argv, "iHhnqvs")) > 0) { + switch (opt) { + case 'i': + ignore_case++; + break; + case 'H': + print_filename++; + break; + case 'h': + print_filename--; + break; + case 'n': + print_line_num++; + break; + case 'q': + be_quiet++; + break; + case 'v': + invert_search++; + break; + case 's': + suppress_err_msgs++; + break; + } } - if (ferror (fp)) - perror (name); - - fclose (fp); - } - exit( TRUE); -} + /* argv[optind] should be the regex pattern; no pattern, no worky */ + if (argv[optind] == NULL) + usage(grep_usage); + /* compile the regular expression + * we're not going to mess with sub-expressions, and we need to + * treat newlines right. */ + reflags = REG_NOSUB | REG_NEWLINE; + if (ignore_case) + reflags |= REG_ICASE; + xregcomp(®ex, argv[optind], reflags); + + /* argv[(optind+1)..(argc-1)] should be names of file to grep through. If + * there is more than one file to grep, we will print the filenames */ + if ((argc-1) - (optind+1) > 0) + print_filename++; + + /* If no files were specified, or '-' was specified, take input from + * stdin. Otherwise, we grep through all the files specified. */ + if (argv[optind+1] == NULL || (strcmp(argv[optind+1], "-") == 0)) { + grep_file(stdin); + } else { + int i; + FILE *file; + for (i = optind + 1; i < argc; i++) { + cur_file = argv[i]; + file = fopen(cur_file, "r"); + if (file == NULL) { + if (!suppress_err_msgs) + errorMsg("%s: %s\n", cur_file, strerror(errno)); + } else { + grep_file(file); + fclose(file); + } + } + } -/* END CODE */ + regfree(®ex); + if (nmatches == 0) + return 1; + return 0; +}