diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2016-06-09 18:37:58 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2016-06-09 18:37:58 -0400 |
commit | cad5dc5cc50a43203971939fd2806bfbf9a5dac9 (patch) | |
tree | e42db8dbef9c6896945473668534c709f7165b5f | |
parent | ea92e8e4b24ea749e73bc6e9bc17371b07c723a3 (diff) | |
download | bfs-cad5dc5cc50a43203971939fd2806bfbf9a5dac9.tar.xz |
Allow flags like -L before ',' or ')' as pathnames.
-rw-r--r-- | parse.c | 51 | ||||
-rwxr-xr-x | tests.sh | 17 |
2 files changed, 50 insertions, 18 deletions
@@ -193,8 +193,8 @@ struct parser_state { bool implicit_print; /** Whether warnings are enabled (see -warn, -nowarn). */ bool warn; - /** Whether any non-path arguments have been encountered. */ - bool non_path_seen; + /** Whether the expression has started. */ + bool expr_started; /** Whether any non-option arguments have been encountered. */ bool non_option_seen; /** Whether an information option like -help or -version was passed. */ @@ -208,6 +208,8 @@ struct parser_state { * Possible token types. */ enum token_type { + /** A flag. */ + T_FLAG, /** A root path. */ T_PATH, /** An option. */ @@ -281,8 +283,8 @@ static struct expr *parse_expr(struct parser_state *state); * Advance by a single token. */ static char **parser_advance(struct parser_state *state, enum token_type type, size_t argc) { - if (type != T_PATH) { - state->non_path_seen = true; + if (type != T_FLAG && type != T_PATH) { + state->expr_started = true; if (type != T_OPTION) { state->non_option_seen = true; @@ -309,7 +311,7 @@ static const char *skip_paths(struct parser_state *state) { return arg; } - if (state->non_path_seen) { + if (state->expr_started) { // By POSIX, these can be paths. We only treat them as // such at the beginning of the command line if (strcmp(arg, ")") == 0 || strcmp(arg, ",") == 0) { @@ -409,6 +411,28 @@ static const char *parse_icmp(const struct parser_state *state, const char *str, } /** + * Parse a single flag. + */ +static struct expr *parse_flag(struct parser_state *state, size_t argc) { + parser_advance(state, T_FLAG, argc); + return &expr_true; +} + +/** + * Parse a flag that doesn't take a value. + */ +static struct expr *parse_nullary_flag(struct parser_state *state) { + return parse_flag(state, 1); +} + +/** + * Parse a flag that takes a single value. + */ +static struct expr *parse_unary_flag(struct parser_state *state) { + return parse_flag(state, 2); +} + +/** * Parse a single option. */ static struct expr *parse_option(struct parser_state *state, size_t argc) { @@ -455,13 +479,6 @@ static struct expr *parse_nullary_positional_option(struct parser_state *state) } /** - * Parse a positional option that takes a value. - */ -static struct expr *parse_unary_positional_option(struct parser_state *state) { - return parse_positional_option(state, 2); -} - -/** * Parse a single test. */ static struct expr *parse_test(struct parser_state *state, eval_fn *eval, size_t argc) { @@ -585,7 +602,7 @@ static struct expr *parse_debug(struct parser_state *state) { "warning: Unrecognized debug flag '%s'.\n\n", flag); } - return parse_unary_positional_option(state); + return parse_unary_flag(state); } /** @@ -596,7 +613,7 @@ static struct expr *parse_optlevel(struct parser_state *state) { return NULL; } - return parse_nullary_positional_option(state); + return parse_nullary_flag(state); } /** @@ -1181,7 +1198,7 @@ static struct expr *parse_literal(struct parser_state *state) { case 'P': if (strcmp(arg, "-P") == 0) { cmdline->flags &= ~(BFTW_FOLLOW | BFTW_DETECT_CYCLES); - return parse_nullary_positional_option(state); + return parse_nullary_flag(state); } break; @@ -1189,14 +1206,14 @@ static struct expr *parse_literal(struct parser_state *state) { if (strcmp(arg, "-H") == 0) { cmdline->flags &= ~(BFTW_FOLLOW_NONROOT | BFTW_DETECT_CYCLES); cmdline->flags |= BFTW_FOLLOW_ROOT; - return parse_nullary_positional_option(state); + return parse_nullary_flag(state); } break; case 'L': if (strcmp(arg, "-L") == 0) { cmdline->flags |= BFTW_FOLLOW | BFTW_DETECT_CYCLES; - return parse_nullary_positional_option(state); + return parse_nullary_flag(state); } break; @@ -344,6 +344,21 @@ function test_0061() { } function test_0062() { + cd "$weirdnames" + find_diff -L '-' '(-' '!-' ',' ')' './(' './!' \( \! -print , -print \) +} + +function test_0063() { + cd "$weirdnames" + find_diff -L ',' -true +} + +function test_0064() { + cd "$weirdnames" + find_diff -follow ',' -true +} + +function test_0065() { find "$basic" -fprint "$out/out.find" "$BFS" "$basic" -fprint "$out/out.bfs" @@ -352,7 +367,7 @@ function test_0062() { diff -u "$out/out.find" "$out/out.bfs" } -for i in {1..62}; do +for i in {1..65}; do test="test_$(printf '%04d' $i)" ("$test" "$dir") status=$? |