X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=findutils%2Fgrep.c;h=a2c07c52371513e07ad41408eb9140f9230edbb3;hb=bf181b9338152759fd56c8009e9a962a84808e7c;hp=84bb99667373720d1fcbb0108a89988d691e2ca7;hpb=d73dc5b07390fb90e7f605871c993a28eedf1d46;p=oweals%2Fbusybox.git diff --git a/findutils/grep.c b/findutils/grep.c index 84bb99667..a2c07c523 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -1,9 +1,8 @@ /* - * Mini grep implementation for busybox + * Mini grep implementation for busybox using libc regex. * - * - * Copyright (C) 1999 by Lineo, inc. - * Written 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 @@ -21,125 +20,148 @@ * */ -#include "internal.h" -#include "regexp.h" #include -#include +#include +#include +#include +#include /* for strerror() */ #include -#include -#include -#include -#include - -static const char grep_usage[] = -"grep [OPTIONS]... PATTERN [FILE]...\n\n" -"Search for PATTERN in each FILE or standard input.\n\n" -"OPTIONS:\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" -#if defined BB_REGEXP -"This version of grep matches full regular expresions.\n"; -#else -"This version of grep matches strings (not regular expresions).\n"; -#endif - - -static void do_grep(FILE *fp, char* needle, char *fileName, int tellName, int ignoreCase, int tellLine) -{ - char *cp; - long line = 0; - char haystack[BUF_SIZE]; +#include "internal.h" - while (fgets (haystack, sizeof (haystack), fp)) { - line++; - cp = &haystack[strlen (haystack) - 1]; +extern int optind; /* in unistd.h */ +extern int errno; /* for use with strerror() */ - if (*cp != '\n') - fprintf (stderr, "%s: Line too long\n", fileName); +/* 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; - if (find_match(haystack, needle, ignoreCase) == TRUE) { - if (tellName==TRUE) - printf ("%s:", fileName); +/* 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 */ - if (tellLine==TRUE) - printf ("%ld:", line); - fputs (haystack, stdout); - } - } -} +static void print_matched_line(char *line, int linenum) +{ + if (print_filename) + printf("%s:", cur_file); + if (print_line_num) + printf("%i:", linenum); + printf("%s", line); +} -extern int grep_main (int argc, char **argv) +static void grep_file(FILE *file) { - FILE *fp; - char *cp; - char *needle; - char *fileName; - int tellName=FALSE; - int ignoreCase=FALSE; - int tellLine=FALSE; - - - ignoreCase = FALSE; - tellLine = FALSE; - - argc--; - argv++; - if (argc < 1) { - usage(grep_usage); - } - - if (**argv == '-') { - argc--; - cp = *argv++; - - while (*++cp) - switch (*cp) { - case 'i': - ignoreCase = TRUE; - break; - - case 'h': - tellName = TRUE; - break; - - case 'n': - tellLine = TRUE; - break; - - default: - usage(grep_usage); - } - } + char *line = NULL; + int ret; + int linenum = 0; + + while ((line = get_line_from_file(file)) != NULL) { + linenum++; + ret = regexec(®ex, line, 0, NULL, 0); + if (ret == 0 && !invert_search) { /* match */ - needle = *argv++; - argc--; + /* if we found a match but were told to be quiet, stop here and + * return success */ + if (be_quiet) { + regfree(®ex); + exit(0); + } - if (argc==0) { - do_grep( stdin, needle, "stdin", FALSE, ignoreCase, tellLine); - } else { - while (argc-- > 0) { - fileName = *argv++; + nmatches++; - fp = fopen (fileName, "r"); - if (fp == NULL) { - perror (fileName); - continue; - } + print_matched_line(line, linenum); - do_grep( fp, needle, fileName, tellName, ignoreCase, tellLine); + } else if (ret == REG_NOMATCH && invert_search) { + print_matched_line(line, linenum); + } - if (ferror (fp)) - perror (fileName); - fclose (fp); + free(line); } - } - exit( TRUE); } +extern int grep_main(int argc, char **argv) +{ + int opt; + int reflags; + + /* do special-case option parsing */ + if (argv[1] && (strcmp(argv[1], "--help") == 0)) + usage(grep_usage); + + /* 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; + } + } -/* END CODE */ + /* 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); + } + } + } + regfree(®ex); + if (nmatches == 0) + return 1; + + return 0; +}