aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--findutils/grep.c29
-rwxr-xr-xtestsuite/grep.tests8
2 files changed, 22 insertions, 15 deletions
diff --git a/findutils/grep.c b/findutils/grep.c
index 55e9c0a8f..b456ed467 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -167,13 +167,11 @@ enum {
OPT_z = IF_EXTRA_COMPAT( (1 << OPTBIT_z)) + 0,
};
-#define PRINT_FILES_WITH_MATCHES (option_mask32 & OPT_l)
#define PRINT_LINE_NUM (option_mask32 & OPT_n)
#define BE_QUIET (option_mask32 & OPT_q)
#define SUPPRESS_ERR_MSGS (option_mask32 & OPT_s)
#define PRINT_MATCH_COUNTS (option_mask32 & OPT_c)
#define FGREP_FLAG (option_mask32 & OPT_F)
-#define PRINT_FILES_WITHOUT_MATCHES (option_mask32 & OPT_L)
#define NUL_DELIMITED (option_mask32 & OPT_z)
struct globals {
@@ -476,13 +474,13 @@ static int grep_file(FILE *file)
* even if errors were detected" */
exit(EXIT_SUCCESS);
}
- /* if we're just printing filenames, we stop after the first match */
- if (PRINT_FILES_WITH_MATCHES) {
+ /* -l "print filenames with matches": stop after the first match */
+ if (option_mask32 & OPT_l) {
puts(cur_file);
- /* fall through to "return 1" */
+ return 1;
}
- /* OPT_L aka PRINT_FILES_WITHOUT_MATCHES: return early */
- return 1; /* one match */
+ /* -L "print filenames without matches": return early too */
+ return 0; /* 0: we do not print fname, hence it's "not a match" */
}
#if ENABLE_FEATURE_GREP_CONTEXT
@@ -602,15 +600,16 @@ static int grep_file(FILE *file)
printf("%d\n", nmatches);
}
- /* grep -L: print just the filename */
- if (PRINT_FILES_WITHOUT_MATCHES) {
+ /* grep -L: "print filenames without matches" */
+ if (option_mask32 & OPT_L) {
/* nmatches is zero, no need to check it:
- * we return 1 early if we detected a match
- * and PRINT_FILES_WITHOUT_MATCHES is set */
+ * we return 0 early if -L and we detect a match
+ */
puts(cur_file);
+ return 1; /* 1: we printed fname, hence it's "a match" */
}
- return nmatches;
+ return nmatches != 0; /* we return not a count, but a boolean */
}
#if ENABLE_FEATURE_CLEAN_UP
@@ -687,7 +686,7 @@ static int FAST_FUNC file_action_grep(const char *filename,
return 0;
}
cur_file = filename;
- *(int*)matched += grep_file(file);
+ *(int*)matched |= grep_file(file);
fclose(file);
return 1;
}
@@ -844,7 +843,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv)
if (stat(cur_file, &st) == 0 && S_ISDIR(st.st_mode)) {
if (!(option_mask32 & OPT_h))
print_filename = 1;
- matched += grep_dir(cur_file);
+ matched |= grep_dir(cur_file);
goto grep_done;
}
}
@@ -857,7 +856,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv)
continue;
}
}
- matched += grep_file(file);
+ matched |= grep_file(file);
fclose_if_not_stdin(file);
grep_done: ;
} while (*argv && *++argv);
diff --git a/testsuite/grep.tests b/testsuite/grep.tests
index e38278810..66498a989 100755
--- a/testsuite/grep.tests
+++ b/testsuite/grep.tests
@@ -96,6 +96,14 @@ testing "grep -x -F (partial match 1)" "grep -x -F foo input ; echo \$?" \
testing "grep -x -F (partial match 2)" "grep -x -F foo input ; echo \$?" \
"1\n" "bar foo\n" ""
+# -L "show filenames which do not match" has inverted exitcode (if it printed something, it's "success")
+testing "grep -L exitcode 0" "grep -L qwe input; echo \$?" \
+ "input\n0\n" "asd\n" ""
+testing "grep -L exitcode 0 #2" "grep -L qwe input -; echo \$?" \
+ "(standard input)\n0\n" "qwe\n" "asd\n"
+testing "grep -L exitcode 1" "grep -L qwe input; echo \$?" \
+ "1\n" "qwe\n" ""
+
optional EGREP
testing "grep -E supports extended regexps" "grep -E fo+" "foo\n" "" \
"b\ar\nfoo\nbaz"