summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2015-11-27 12:25:06 -0500
committerTavian Barnes <tavianator@tavianator.com>2015-11-27 12:25:06 -0500
commitf2023abb0ad5002078d5244e8dc17ac1cead40e4 (patch)
tree7833a4c390c3e17cb0e6804233dee99091a21fd9
parent154dc9258f62af852f91cd5eb1202405f71a50a5 (diff)
downloadbfs-f2023abb0ad5002078d5244e8dc17ac1cead40e4.tar.xz
Implement -path.
-rw-r--r--bfs.c50
-rwxr-xr-xtests.sh15
2 files changed, 44 insertions, 21 deletions
diff --git a/bfs.c b/bfs.c
index 432547d..135f44f 100644
--- a/bfs.c
+++ b/bfs.c
@@ -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) {
diff --git a/tests.sh b/tests.sh
index 65e439b..060448b 100755
--- a/tests.sh
+++ b/tests.sh
@@ -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"