diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2020-06-07 16:37:53 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2020-06-07 16:42:55 -0400 |
commit | 8896f35294649975c1df22a8b57db4333cc56091 (patch) | |
tree | 10eb0664f70cdc1d837a4f469d720149042dc8f9 | |
parent | a9f97adf92f8000a198de2c48132ba4a39ed1d5c (diff) | |
download | bfs-8896f35294649975c1df22a8b57db4333cc56091.tar.xz |
parse: Prohibit actions inside -exclude
-rw-r--r-- | opt.c | 4 | ||||
-rw-r--r-- | parse.c | 20 | ||||
-rwxr-xr-x | tests.sh | 5 |
3 files changed, 28 insertions, 1 deletions
@@ -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; @@ -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, @@ -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' |