diff options
| author | Kyle Evans <kevans@FreeBSD.org> | 2019-09-25 17:14:43 +0000 |
|---|---|---|
| committer | Kyle Evans <kevans@FreeBSD.org> | 2019-09-25 17:14:43 +0000 |
| commit | 38325e2ab8f0c7823e31df13bfc52e38e7f6d616 (patch) | |
| tree | c072427d77503a8c6e447ee6e9de504e85d978ff /usr.bin | |
| parent | 2b93f779d22332da86a5398e59b57a5e27b9ffb6 (diff) | |
Notes
Diffstat (limited to 'usr.bin')
| -rw-r--r-- | usr.bin/grep/grep.c | 27 | ||||
| -rw-r--r-- | usr.bin/grep/util.c | 37 |
2 files changed, 35 insertions, 29 deletions
diff --git a/usr.bin/grep/grep.c b/usr.bin/grep/grep.c index 20911c294343..731e46bb112e 100644 --- a/usr.bin/grep/grep.c +++ b/usr.bin/grep/grep.c @@ -218,20 +218,9 @@ static void add_pattern(char *pat, size_t len) { - /* Do not add further pattern is we already match everything */ - if (matchall) - return; - /* Check if we can do a shortcut */ if (len == 0) { matchall = true; - for (unsigned int i = 0; i < patterns; i++) { - free(pattern[i].pat); - } - pattern = grep_realloc(pattern, sizeof(struct pat)); - pattern[0].pat = NULL; - pattern[0].len = 0; - patterns = 1; return; } /* Increase size if necessary */ @@ -654,7 +643,7 @@ main(int argc, char *argv[]) aargv += optind; /* Empty pattern file matches nothing */ - if (!needpattern && (patterns == 0)) + if (!needpattern && (patterns == 0) && !matchall) exit(1); /* Fail if we don't have any pattern */ @@ -701,11 +690,10 @@ main(int argc, char *argv[]) r_pattern = grep_calloc(patterns, sizeof(*r_pattern)); - /* Don't process any patterns if we have a blank one */ #ifdef WITH_INTERNAL_NOSPEC - if (!matchall && grepbehave != GREP_FIXED) { + if (grepbehave != GREP_FIXED) { #else - if (!matchall) { + { #endif /* Check if cheating is allowed (always is for fgrep). */ for (i = 0; i < patterns; ++i) { @@ -737,7 +725,12 @@ main(int argc, char *argv[]) matched = true; } - /* Find out the correct return value according to the - results and the command line option. */ + if (Lflag) + matched = !matched; + + /* + * Calculate the correct return value according to the + * results and the command line option. + */ exit(matched ? (file_err ? (qflag ? 0 : 2) : 0) : (file_err ? 2 : 1)); } diff --git a/usr.bin/grep/util.c b/usr.bin/grep/util.c index 07d9b40cbdcd..33afe4d6b030 100644 --- a/usr.bin/grep/util.c +++ b/usr.bin/grep/util.c @@ -210,7 +210,7 @@ procmatch_match(struct mprintc *mc, struct parsec *pc) while (pc->matchidx >= MAX_MATCHES) { /* Reset matchidx and try again */ pc->matchidx = 0; - if (procline(pc)) + if (procline(pc) == !vflag) printline(pc, ':'); else break; @@ -355,7 +355,7 @@ procfile(const char *fn) return (0); } - line_matched = procline(&pc); + line_matched = procline(&pc) == !vflag; if (line_matched) ++lines; @@ -469,17 +469,32 @@ procline(struct parsec *pc) matchidx = pc->matchidx; - /* Special case: empty pattern with -w flag, check first character */ - if (matchall && wflag) { + /* + * With matchall (empty pattern), we can try to take some shortcuts. + * Emtpy patterns trivially match every line except in the -w and -x + * cases. For -w (whole-word) cases, we only match if the first + * character isn't a word-character. For -x (whole-line) cases, we only + * match if the line is empty. + */ + if (matchall) { if (pc->ln.len == 0) return (true); - wend = L' '; - if (sscanf(&pc->ln.dat[0], "%lc", &wend) != 1 || iswword(wend)) - return (false); - else + if (wflag) { + wend = L' '; + if (sscanf(&pc->ln.dat[0], "%lc", &wend) == 1 && + !iswword(wend)) + return (true); + } else if (!xflag) return (true); - } else if (matchall) - return (true); + + /* + * If we don't have any other patterns, we really don't match. + * If we do have other patterns, we must fall through and check + * them. + */ + if (patterns == 0) + return (false); + } matched = false; st = pc->lnstart; @@ -609,8 +624,6 @@ procline(struct parsec *pc) /* Reflect the new matchidx in the context */ pc->matchidx = matchidx; - if (vflag) - matched = !matched; return matched; } |
