summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2020-06-07 16:37:53 -0400
committerTavian Barnes <tavianator@tavianator.com>2020-06-07 16:42:55 -0400
commit8896f35294649975c1df22a8b57db4333cc56091 (patch)
tree10eb0664f70cdc1d837a4f469d720149042dc8f9
parenta9f97adf92f8000a198de2c48132ba4a39ed1d5c (diff)
downloadbfs-8896f35294649975c1df22a8b57db4333cc56091.tar.xz
parse: Prohibit actions inside -exclude
-rw-r--r--opt.c4
-rw-r--r--parse.c20
-rwxr-xr-xtests.sh5
3 files changed, 28 insertions, 1 deletions
diff --git a/opt.c b/opt.c
index 6a62790..e305588 100644
--- a/opt.c
+++ b/opt.c
@@ -998,6 +998,10 @@ int optimize_cmdline(struct cmdline *cmdline) {
return -1;
}
+ if (cmdline->exclude->always_true) {
+ bfs_warning(cmdline, "${red}-exclude${rs} applies to all files.\n");
+ }
+
// Only non-excluded files are evaluated
state.facts = state.facts_when_false;
diff --git a/parse.c b/parse.c
index 7bde6d0..4fc06e1 100644
--- a/parse.c
+++ b/parse.c
@@ -308,6 +308,8 @@ struct parser_state {
bool non_option_seen;
/** Whether an information option like -help or -version was passed. */
bool just_info;
+ /** Whether we are currently parsing an -exclude expression. */
+ bool excluding;
/** The last non-path argument. */
const char *last_arg;
@@ -755,11 +757,18 @@ static struct expr *parse_unary_test(struct parser_state *state, eval_fn *eval)
* Parse a single action.
*/
static struct expr *parse_action(struct parser_state *state, eval_fn *eval, size_t argc) {
+ char **argv = state->argv;
+
+ if (state->excluding) {
+ parse_error(state, "The ${blu}%s${rs} action is not supported within ${red}-exclude${rs}.\n", argv[0]);
+ return NULL;
+ }
+
if (eval != eval_prune && eval != eval_quit) {
state->implicit_print = false;
}
- char **argv = parser_advance(state, T_ACTION, argc);
+ parser_advance(state, T_ACTION, argc);
return new_expr(eval, argc, argv);
}
@@ -3145,11 +3154,19 @@ static struct expr *parse_factor(struct parser_state *state) {
} else if (strcmp(arg, "-exclude") == 0) {
parser_advance(state, T_OPERATOR, 1);
+ if (state->excluding) {
+ parse_error(state, "${er}%s${rs} is not supported within ${red}-exclude${rs}.\n", arg);
+ return NULL;
+ }
+ state->excluding = true;
+
struct expr *factor = parse_factor(state);
if (!factor) {
return NULL;
}
+ state->excluding = false;
+
struct cmdline *cmdline = state->cmdline;
cmdline->exclude = new_binary_expr(eval_or, cmdline->exclude, factor, &fake_or_arg);
if (!cmdline->exclude) {
@@ -3595,6 +3612,7 @@ struct cmdline *parse_cmdline(int argc, char *argv[]) {
.implicit_print = true,
.non_option_seen = false,
.just_info = false,
+ .excluding = false,
.last_arg = NULL,
.depth_arg = NULL,
.prune_arg = NULL,
diff --git a/tests.sh b/tests.sh
index 77a5da1..88b6988 100755
--- a/tests.sh
+++ b/tests.sh
@@ -601,6 +601,7 @@ bfs_tests=(
test_exclude_name
test_exclude_depth
test_exclude_mindepth
+ test_exclude_print
# Primaries
@@ -2653,6 +2654,10 @@ function test_exclude_mindepth() {
bfs_diff basic -mindepth 3 -exclude -name foo
}
+function test_exclude_print() {
+ ! invoke_bfs basic -exclude -print 2>/dev/null
+}
+
BOL=
EOL='\n'