diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2015-11-27 12:25:06 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2015-11-27 12:25:06 -0500 |
commit | f2023abb0ad5002078d5244e8dc17ac1cead40e4 (patch) | |
tree | 7833a4c390c3e17cb0e6804233dee99091a21fd9 | |
parent | 154dc9258f62af852f91cd5eb1202405f71a50a5 (diff) | |
download | bfs-f2023abb0ad5002078d5244e8dc17ac1cead40e4.tar.xz |
Implement -path.
-rw-r--r-- | bfs.c | 50 | ||||
-rwxr-xr-x | tests.sh | 15 |
2 files changed, 44 insertions, 21 deletions
@@ -357,6 +357,14 @@ static bool eval_name(const expression *expr, eval_state *state) { } /** + * -path test. + */ +static bool eval_path(const expression *expr, eval_state *state) { + struct BFTW *ftwbuf = state->ftwbuf; + return fnmatch(expr->sdata, ftwbuf->path, 0) == 0; +} + +/** * -print action. */ static bool eval_print(const expression *expr, eval_state *state) { @@ -417,6 +425,21 @@ static expression *new_action(parser_state *state, eval_fn *eval) { } /** + * Parse any option that takes a string argument. + */ +static expression *parse_sdata(parser_state *state, eval_fn *fn) { + const char *arg = state->argv[state->i]; + if (!arg) { + fprintf(stderr, "%s needs a value.\n", state->argv[state->i - 1]); + return NULL; + } + + ++state->i; + + return new_expression_sdata(fn, arg); +} + +/** * Parse an integer. */ static bool parse_int(const char *str, int *value) { @@ -438,10 +461,10 @@ static bool parse_int(const char *str, int *value) { /** * Parse -{min,max}depth N. */ -static expression *parse_depth(parser_state *state, int *depth, const char *option) { +static expression *parse_depth(parser_state *state, int *depth) { const char *arg = state->argv[state->i]; if (!arg) { - fprintf(stderr, "%s needs a value.\n", option); + fprintf(stderr, "%s needs a value.\n", state->argv[state->i - 1]); return NULL; } @@ -456,21 +479,6 @@ static expression *parse_depth(parser_state *state, int *depth, const char *opti } /** - * Parse -name 'pattern'. - */ -static expression *parse_name(parser_state *state) { - const char *arg = state->argv[state->i]; - if (!arg) { - fputs("-name needs a value.\n", stderr); - return NULL; - } - - ++state->i; - - return new_expression_sdata(eval_name, arg); -} - -/** * Parse -type [bcdpfls]. */ static expression *parse_type(parser_state *state) { @@ -544,11 +552,13 @@ static expression *parse_literal(parser_state *state) { } else if (strcmp(arg, "-nohidden") == 0) { return new_action(state, eval_nohidden); } else if (strcmp(arg, "-mindepth") == 0) { - return parse_depth(state, &state->cl->mindepth, arg); + return parse_depth(state, &state->cl->mindepth); } else if (strcmp(arg, "-maxdepth") == 0) { - return parse_depth(state, &state->cl->maxdepth, arg); + return parse_depth(state, &state->cl->maxdepth); } else if (strcmp(arg, "-name") == 0) { - return parse_name(state); + return parse_sdata(state, eval_name); + } else if (strcmp(arg, "-path") == 0 || strcmp(arg, "-wholename") == 0) { + return parse_sdata(state, eval_path); } else if (strcmp(arg, "-print") == 0) { return new_action(state, eval_print); } else if (strcmp(arg, "-print0") == 0) { @@ -13,6 +13,9 @@ function basic_structure() { touchp "$1/e/f" mkdir -p "$1/g/h" mkdir -p "$1/i" + touchp "$1/j/foo" + touchp "$1/k/foo/bar" + touchp "$1/l/foo/bar/baz" } # Checks for any (order-independent) differences between bfs and find @@ -67,7 +70,17 @@ function test_0009() { find_diff "$1" -maxdepth 2 -depth } -for i in {1..9}; do +function test_0010() { + basic_structure "$1" + find_diff "$1" -name '*f*' +} + +function test_0011() { + basic_structure "$1" + find_diff "$1" -path "$1/*f*" +} + +for i in {1..11}; do dir="$(mktemp -d "${TMPDIR:-/tmp}"/bfs.XXXXXXXXXX)" test="test_$(printf '%04d' $i)" "$test" "$dir" |