aboutsummaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorKyle Evans <kevans@FreeBSD.org>2019-09-25 17:14:43 +0000
committerKyle Evans <kevans@FreeBSD.org>2019-09-25 17:14:43 +0000
commit38325e2ab8f0c7823e31df13bfc52e38e7f6d616 (patch)
treec072427d77503a8c6e447ee6e9de504e85d978ff /usr.bin
parent2b93f779d22332da86a5398e59b57a5e27b9ffb6 (diff)
Notes
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/grep/grep.c27
-rw-r--r--usr.bin/grep/util.c37
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;
}