diff options
author | Elliott Hughes <enh@google.com> | 2014-07-22 17:20:15 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2014-07-24 17:20:51 -0700 |
commit | fd4c6b0a3a25921a9fe24691a695d715aecb6afe (patch) | |
tree | b98f7721d38ac93dec6c1a4138843ecee01d991e /toolbox/grep/grep.c | |
parent | 2fd1fec6197e0ede7a404e106e3dc6ce226dca58 (diff) | |
download | system_core-fd4c6b0a3a25921a9fe24691a695d715aecb6afe.zip system_core-fd4c6b0a3a25921a9fe24691a695d715aecb6afe.tar.gz system_core-fd4c6b0a3a25921a9fe24691a695d715aecb6afe.tar.bz2 |
Refresh toolbox.
Use more upstream NetBSD, and update those things that were already NetBSD.
Note that unlike bionic, the upstream-netbsd directory isn't pristine; we have
changes marked by __ANDROID__.
Bug: 16493461
Change-Id: I99762bfe02caa0945ea4a184670888a4b5435a1d
Diffstat (limited to 'toolbox/grep/grep.c')
-rw-r--r-- | toolbox/grep/grep.c | 707 |
1 files changed, 0 insertions, 707 deletions
diff --git a/toolbox/grep/grep.c b/toolbox/grep/grep.c deleted file mode 100644 index 7314e13..0000000 --- a/toolbox/grep/grep.c +++ /dev/null @@ -1,707 +0,0 @@ -/* $NetBSD: grep.c,v 1.11 2012/05/06 22:27:00 joerg Exp $ */ -/* $FreeBSD: head/usr.bin/grep/grep.c 211519 2010-08-19 22:55:17Z delphij $ */ -/* $OpenBSD: grep.c,v 1.42 2010/07/02 22:18:03 tedu Exp $ */ - -/*- - * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav - * Copyright (C) 2008-2009 Gabor Kovesdan <gabor@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if HAVE_NBTOOL_CONFIG_H -#include "nbtool_config.h" -#endif - -#include <sys/cdefs.h> -__RCSID("$NetBSD: grep.c,v 1.11 2012/05/06 22:27:00 joerg Exp $"); - -#include <sys/stat.h> -#include <sys/types.h> - -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <getopt.h> -#include <limits.h> -#include <libgen.h> -#include <locale.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "grep.h" - -#ifndef WITHOUT_NLS -#include <nl_types.h> -nl_catd catalog; -#endif - -/* - * Default messags to use when NLS is disabled or no catalogue - * is found. - */ -const char *errstr[] = { - "", -/* 1*/ "(standard input)", -/* 2*/ "cannot read bzip2 compressed file", -/* 3*/ "unknown %s option", -/* 4*/ "usage: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A num] [-B num] [-C[num]]\n", -/* 5*/ "\t[-e pattern] [-f file] [--binary-files=value] [--color=when]\n", -/* 6*/ "\t[--context[=num]] [--directories=action] [--label] [--line-buffered]\n", -/* 7*/ "\t[pattern] [file ...]\n", -/* 8*/ "Binary file %s matches\n", -/* 9*/ "%s (BSD grep) %s\n", -}; - -/* Flags passed to regcomp() and regexec() */ -int cflags = 0; -int eflags = REG_STARTEND; - -/* Searching patterns */ -unsigned int patterns, pattern_sz; -char **pattern; -regex_t *r_pattern; -fastgrep_t *fg_pattern; - -/* Filename exclusion/inclusion patterns */ -unsigned int fpatterns, fpattern_sz; -unsigned int dpatterns, dpattern_sz; -struct epat *dpattern, *fpattern; - -/* For regex errors */ -char re_error[RE_ERROR_BUF + 1]; - -/* Command-line flags */ -unsigned long long Aflag; /* -A x: print x lines trailing each match */ -unsigned long long Bflag; /* -B x: print x lines leading each match */ -bool Hflag; /* -H: always print file name */ -bool Lflag; /* -L: only show names of files with no matches */ -bool bflag; /* -b: show block numbers for each match */ -bool cflag; /* -c: only show a count of matching lines */ -bool hflag; /* -h: don't print filename headers */ -bool iflag; /* -i: ignore case */ -bool lflag; /* -l: only show names of files with matches */ -bool mflag; /* -m x: stop reading the files after x matches */ -unsigned long long mcount; /* count for -m */ -bool nflag; /* -n: show line numbers in front of matching lines */ -bool oflag; /* -o: print only matching part */ -bool qflag; /* -q: quiet mode (don't output anything) */ -bool sflag; /* -s: silent mode (ignore errors) */ -bool vflag; /* -v: only show non-matching lines */ -bool wflag; /* -w: pattern must start and end on word boundaries */ -bool xflag; /* -x: pattern must match entire line */ -bool lbflag; /* --line-buffered */ -bool nullflag; /* --null */ -bool nulldataflag; /* --null-data */ -unsigned char line_sep = '\n'; /* 0 for --null-data */ -char *label; /* --label */ -const char *color; /* --color */ -int grepbehave = GREP_BASIC; /* -EFGP: type of the regex */ -int binbehave = BINFILE_BIN; /* -aIU: handling of binary files */ -int filebehave = FILE_STDIO; /* -JZ: normal, gzip or bzip2 file */ -int devbehave = DEV_READ; /* -D: handling of devices */ -int dirbehave = DIR_READ; /* -dRr: handling of directories */ -int linkbehave = LINK_READ; /* -OpS: handling of symlinks */ - -bool dexclude, dinclude; /* --exclude-dir and --include-dir */ -bool fexclude, finclude; /* --exclude and --include */ - -enum { - BIN_OPT = CHAR_MAX + 1, - COLOR_OPT, - DECOMPRESS_OPT, - HELP_OPT, - MMAP_OPT, - LINEBUF_OPT, - LABEL_OPT, - R_EXCLUDE_OPT, - R_INCLUDE_OPT, - R_DEXCLUDE_OPT, - R_DINCLUDE_OPT -}; - -static inline const char *init_color(const char *); - -/* Housekeeping */ -int tail; /* lines left to print */ -bool notfound; /* file not found */ - -extern char *__progname; - -/* - * Prints usage information and returns 2. - */ -__dead static void -usage(void) -{ - fprintf(stderr, getstr(4), __progname); - fprintf(stderr, "%s", getstr(5)); - fprintf(stderr, "%s", getstr(6)); - fprintf(stderr, "%s", getstr(7)); - exit(2); -} - -static const char optstr[] = - "0123456789A:B:C:D:EFGHIJLOPSRUVZabcd:e:f:hilm:nopqrsuvwxyz"; - -struct option long_options[] = -{ - {"binary-files", required_argument, NULL, BIN_OPT}, - {"decompress", no_argument, NULL, DECOMPRESS_OPT}, - {"help", no_argument, NULL, HELP_OPT}, - {"mmap", no_argument, NULL, MMAP_OPT}, - {"line-buffered", no_argument, NULL, LINEBUF_OPT}, - {"label", required_argument, NULL, LABEL_OPT}, - {"color", optional_argument, NULL, COLOR_OPT}, - {"colour", optional_argument, NULL, COLOR_OPT}, - {"exclude", required_argument, NULL, R_EXCLUDE_OPT}, - {"include", required_argument, NULL, R_INCLUDE_OPT}, - {"exclude-dir", required_argument, NULL, R_DEXCLUDE_OPT}, - {"include-dir", required_argument, NULL, R_DINCLUDE_OPT}, - {"after-context", required_argument, NULL, 'A'}, - {"text", no_argument, NULL, 'a'}, - {"before-context", required_argument, NULL, 'B'}, - {"byte-offset", no_argument, NULL, 'b'}, - {"context", optional_argument, NULL, 'C'}, - {"count", no_argument, NULL, 'c'}, - {"devices", required_argument, NULL, 'D'}, - {"directories", required_argument, NULL, 'd'}, - {"extended-regexp", no_argument, NULL, 'E'}, - {"regexp", required_argument, NULL, 'e'}, - {"fixed-strings", no_argument, NULL, 'F'}, - {"file", required_argument, NULL, 'f'}, - {"basic-regexp", no_argument, NULL, 'G'}, - {"no-filename", no_argument, NULL, 'h'}, - {"with-filename", no_argument, NULL, 'H'}, - {"ignore-case", no_argument, NULL, 'i'}, - {"bz2decompress", no_argument, NULL, 'J'}, - {"files-with-matches", no_argument, NULL, 'l'}, - {"files-without-match", no_argument, NULL, 'L'}, - {"max-count", required_argument, NULL, 'm'}, - {"line-number", no_argument, NULL, 'n'}, - {"only-matching", no_argument, NULL, 'o'}, - {"quiet", no_argument, NULL, 'q'}, - {"silent", no_argument, NULL, 'q'}, - {"recursive", no_argument, NULL, 'r'}, - {"no-messages", no_argument, NULL, 's'}, - {"binary", no_argument, NULL, 'U'}, - {"unix-byte-offsets", no_argument, NULL, 'u'}, - {"invert-match", no_argument, NULL, 'v'}, - {"version", no_argument, NULL, 'V'}, - {"word-regexp", no_argument, NULL, 'w'}, - {"line-regexp", no_argument, NULL, 'x'}, - {"null", no_argument, NULL, 'Z'}, - {"null-data", no_argument, NULL, 'z'}, - {NULL, no_argument, NULL, 0} -}; - -/* - * Adds a searching pattern to the internal array. - */ -static void -add_pattern(char *pat, size_t len) -{ - - /* TODO: Check for empty patterns and shortcut */ - - /* Increase size if necessary */ - if (patterns == pattern_sz) { - pattern_sz *= 2; - pattern = grep_realloc(pattern, ++pattern_sz * - sizeof(*pattern)); - } - if (len > 0 && pat[len - 1] == '\n') - --len; - /* pat may not be NUL-terminated */ - pattern[patterns] = grep_malloc(len + 1); - memcpy(pattern[patterns], pat, len); - pattern[patterns][len] = '\0'; - ++patterns; -} - -/* - * Adds a file include/exclude pattern to the internal array. - */ -static void -add_fpattern(const char *pat, int mode) -{ - - /* Increase size if necessary */ - if (fpatterns == fpattern_sz) { - fpattern_sz *= 2; - fpattern = grep_realloc(fpattern, ++fpattern_sz * - sizeof(struct epat)); - } - fpattern[fpatterns].pat = grep_strdup(pat); - fpattern[fpatterns].mode = mode; - ++fpatterns; -} - -/* - * Adds a directory include/exclude pattern to the internal array. - */ -static void -add_dpattern(const char *pat, int mode) -{ - - /* Increase size if necessary */ - if (dpatterns == dpattern_sz) { - dpattern_sz *= 2; - dpattern = grep_realloc(dpattern, ++dpattern_sz * - sizeof(struct epat)); - } - dpattern[dpatterns].pat = grep_strdup(pat); - dpattern[dpatterns].mode = mode; - ++dpatterns; -} - -/* - * Reads searching patterns from a file and adds them with add_pattern(). - */ -static void -read_patterns(const char *fn) -{ - FILE *f; - char *line; - size_t len; - ssize_t rlen; - - if ((f = fopen(fn, "r")) == NULL) - err(2, "%s", fn); - line = NULL; - len = 0; - while ((rlen = getline(&line, &len, f)) != -1) - add_pattern(line, *line == '\n' ? 0 : (size_t)rlen); - free(line); - if (ferror(f)) - err(2, "%s", fn); - fclose(f); -} - -static inline const char * -init_color(const char *d) -{ - char *c; - - c = getenv("GREP_COLOR"); - return (c != NULL ? c : d); -} - -int -grep_main(int argc, char *argv[]) -{ - char **aargv, **eargv, *eopts; - char *ep; - unsigned long long l; - unsigned int aargc, eargc, i, j; - int c, lastc, needpattern, newarg, prevoptind; - - setlocale(LC_ALL, ""); - -#ifndef WITHOUT_NLS - catalog = catopen("grep", NL_CAT_LOCALE); -#endif - - /* Check what is the program name of the binary. In this - way we can have all the funcionalities in one binary - without the need of scripting and using ugly hacks. */ - switch (__progname[0]) { - case 'e': - grepbehave = GREP_EXTENDED; - break; - case 'f': - grepbehave = GREP_FIXED; - break; - case 'g': - grepbehave = GREP_BASIC; - break; - case 'z': - filebehave = FILE_GZIP; - switch(__progname[1]) { - case 'e': - grepbehave = GREP_EXTENDED; - break; - case 'f': - grepbehave = GREP_FIXED; - break; - case 'g': - grepbehave = GREP_BASIC; - break; - } - break; - } - - lastc = '\0'; - newarg = 1; - prevoptind = 1; - needpattern = 1; - - eopts = getenv("GREP_OPTIONS"); - - /* support for extra arguments in GREP_OPTIONS */ - eargc = 0; - if (eopts != NULL) { - char *str; - - /* make an estimation of how many extra arguments we have */ - for (j = 0; j < strlen(eopts); j++) - if (eopts[j] == ' ') - eargc++; - - eargv = (char **)grep_malloc(sizeof(char *) * (eargc + 1)); - - eargc = 0; - /* parse extra arguments */ - while ((str = strsep(&eopts, " ")) != NULL) - eargv[eargc++] = grep_strdup(str); - - aargv = (char **)grep_calloc(eargc + argc + 1, - sizeof(char *)); - - aargv[0] = argv[0]; - for (i = 0; i < eargc; i++) - aargv[i + 1] = eargv[i]; - for (j = 1; j < (unsigned int)argc; j++, i++) - aargv[i + 1] = argv[j]; - - aargc = eargc + argc; - } else { - aargv = argv; - aargc = argc; - } - - while (((c = getopt_long(aargc, aargv, optstr, long_options, NULL)) != - -1)) { - switch (c) { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (newarg || !isdigit(lastc)) - Aflag = 0; - else if (Aflag > LLONG_MAX / 10) { - errno = ERANGE; - err(2, NULL); - } - Aflag = Bflag = (Aflag * 10) + (c - '0'); - break; - case 'C': - if (optarg == NULL) { - Aflag = Bflag = 2; - break; - } - /* FALLTHROUGH */ - case 'A': - /* FALLTHROUGH */ - case 'B': - errno = 0; - l = strtoull(optarg, &ep, 10); - if (((errno == ERANGE) && (l == ULLONG_MAX)) || - ((errno == EINVAL) && (l == 0))) - err(2, NULL); - else if (ep[0] != '\0') { - errno = EINVAL; - err(2, NULL); - } - if (c == 'A') - Aflag = l; - else if (c == 'B') - Bflag = l; - else - Aflag = Bflag = l; - break; - case 'a': - binbehave = BINFILE_TEXT; - break; - case 'b': - bflag = true; - break; - case 'c': - cflag = true; - break; - case 'D': - if (strcasecmp(optarg, "skip") == 0) - devbehave = DEV_SKIP; - else if (strcasecmp(optarg, "read") == 0) - devbehave = DEV_READ; - else - errx(2, getstr(3), "--devices"); - break; - case 'd': - if (strcasecmp("recurse", optarg) == 0) { - Hflag = true; - dirbehave = DIR_RECURSE; - } else if (strcasecmp("skip", optarg) == 0) - dirbehave = DIR_SKIP; - else if (strcasecmp("read", optarg) == 0) - dirbehave = DIR_READ; - else - errx(2, getstr(3), "--directories"); - break; - case 'E': - grepbehave = GREP_EXTENDED; - break; - case 'e': - add_pattern(optarg, strlen(optarg)); - needpattern = 0; - break; - case 'F': - grepbehave = GREP_FIXED; - break; - case 'f': - read_patterns(optarg); - needpattern = 0; - break; - case 'G': - grepbehave = GREP_BASIC; - break; - case 'H': - Hflag = true; - break; - case 'h': - Hflag = false; - hflag = true; - break; - case 'I': - binbehave = BINFILE_SKIP; - break; - case 'i': - case 'y': - iflag = true; - cflags |= REG_ICASE; - break; - case 'J': - filebehave = FILE_BZIP; - break; - case 'L': - lflag = false; - Lflag = true; - break; - case 'l': - Lflag = false; - lflag = true; - break; - case 'm': - mflag = true; - errno = 0; - mcount = strtoull(optarg, &ep, 10); - if (((errno == ERANGE) && (mcount == ULLONG_MAX)) || - ((errno == EINVAL) && (mcount == 0))) - err(2, NULL); - else if (ep[0] != '\0') { - errno = EINVAL; - err(2, NULL); - } - break; - case 'n': - nflag = true; - break; - case 'O': - linkbehave = LINK_EXPLICIT; - break; - case 'o': - oflag = true; - break; - case 'p': - linkbehave = LINK_SKIP; - break; - case 'q': - qflag = true; - break; - case 'S': - linkbehave = LINK_READ; - break; - case 'R': - case 'r': - dirbehave = DIR_RECURSE; - Hflag = true; - break; - case 's': - sflag = true; - break; - case 'U': - binbehave = BINFILE_BIN; - break; - case 'u': - case MMAP_OPT: - /* noop, compatibility */ - break; - case 'V': - printf(getstr(9), __progname, VERSION); - exit(0); - case 'v': - vflag = true; - break; - case 'w': - wflag = true; - break; - case 'x': - xflag = true; - break; - case 'Z': - nullflag = true; - break; - case 'z': - nulldataflag = true; - line_sep = '\0'; - break; - case BIN_OPT: - if (strcasecmp("binary", optarg) == 0) - binbehave = BINFILE_BIN; - else if (strcasecmp("without-match", optarg) == 0) - binbehave = BINFILE_SKIP; - else if (strcasecmp("text", optarg) == 0) - binbehave = BINFILE_TEXT; - else - errx(2, getstr(3), "--binary-files"); - break; - case COLOR_OPT: - color = NULL; - if (optarg == NULL || strcasecmp("auto", optarg) == 0 || - strcasecmp("tty", optarg) == 0 || - strcasecmp("if-tty", optarg) == 0) { - char *term; - - term = getenv("TERM"); - if (isatty(STDOUT_FILENO) && term != NULL && - strcasecmp(term, "dumb") != 0) - color = init_color("01;31"); - } else if (strcasecmp("always", optarg) == 0 || - strcasecmp("yes", optarg) == 0 || - strcasecmp("force", optarg) == 0) { - color = init_color("01;31"); - } else if (strcasecmp("never", optarg) != 0 && - strcasecmp("none", optarg) != 0 && - strcasecmp("no", optarg) != 0) - errx(2, getstr(3), "--color"); - break; - case DECOMPRESS_OPT: - filebehave = FILE_GZIP; - break; - case LABEL_OPT: - label = optarg; - break; - case LINEBUF_OPT: - lbflag = true; - break; - case R_INCLUDE_OPT: - finclude = true; - add_fpattern(optarg, INCL_PAT); - break; - case R_EXCLUDE_OPT: - fexclude = true; - add_fpattern(optarg, EXCL_PAT); - break; - case R_DINCLUDE_OPT: - dinclude = true; - add_dpattern(optarg, INCL_PAT); - break; - case R_DEXCLUDE_OPT: - dexclude = true; - add_dpattern(optarg, EXCL_PAT); - break; - case HELP_OPT: - default: - usage(); - } - lastc = c; - newarg = optind != prevoptind; - prevoptind = optind; - } - aargc -= optind; - aargv += optind; - - /* Fail if we don't have any pattern */ - if (aargc == 0 && needpattern) - usage(); - - /* Process patterns from command line */ - if (aargc != 0 && needpattern) { - add_pattern(*aargv, strlen(*aargv)); - --aargc; - ++aargv; - } - - switch (grepbehave) { - case GREP_FIXED: - case GREP_BASIC: - break; - case GREP_EXTENDED: - cflags |= REG_EXTENDED; - break; - default: - /* NOTREACHED */ - usage(); - } - - fg_pattern = grep_calloc(patterns, sizeof(*fg_pattern)); - r_pattern = grep_calloc(patterns, sizeof(*r_pattern)); -/* - * XXX: fgrepcomp() and fastcomp() are workarounds for regexec() performance. - * Optimizations should be done there. - */ - /* Check if cheating is allowed (always is for fgrep). */ - if (grepbehave == GREP_FIXED) { - for (i = 0; i < patterns; ++i) - fgrepcomp(&fg_pattern[i], pattern[i]); - } else { - for (i = 0; i < patterns; ++i) { - if (fastcomp(&fg_pattern[i], pattern[i])) { - /* Fall back to full regex library */ - c = regcomp(&r_pattern[i], pattern[i], cflags); - if (c != 0) { - regerror(c, &r_pattern[i], re_error, - RE_ERROR_BUF); - errx(2, "%s", re_error); - } - } - } - } - - if (lbflag) - setlinebuf(stdout); - - if ((aargc == 0 || aargc == 1) && !Hflag) - hflag = true; - - if (aargc == 0) - exit(!procfile("-")); - - if (dirbehave == DIR_RECURSE) - c = grep_tree(aargv); - else - for (c = 0; aargc--; ++aargv) { - if ((finclude || fexclude) && !file_matching(*aargv)) - continue; - c+= procfile(*aargv); - } - -#ifndef WITHOUT_NLS - catclose(catalog); -#endif - - /* Find out the correct return value according to the - results and the command line option. */ - exit(c ? (notfound ? (qflag ? 0 : 2) : 0) : (notfound ? 2 : 1)); -} |