summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2016-02-13 17:14:03 -0500
committerTavian Barnes <tavianator@tavianator.com>2016-02-13 17:14:03 -0500
commit30ce56dc76f3a098c42c7ac9701fc4a223847fa2 (patch)
tree15e8a0aed66d93fb26c9a819846527eada1a0905
parent4cd28ed2aa3f098a1d35dd44ecec27002fadb89b (diff)
downloadbfs-30ce56dc76f3a098c42c7ac9701fc4a223847fa2.tar.xz
Implement -iname and -ipath.
-rw-r--r--Makefile2
-rw-r--r--eval.c8
-rw-r--r--parse.c49
-rwxr-xr-xtests.sh10
4 files changed, 59 insertions, 10 deletions
diff --git a/Makefile b/Makefile
index d6e7870..02f6554 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ LDFLAGS ?=
DEPFLAGS ?= -MD -MP -MF $(@:.o=.d)
RM ?= rm -f
-LOCAL_CPPFLAGS := -D_DEFAULT_SOURCE
+LOCAL_CPPFLAGS := -D_DEFAULT_SOURCE -D_GNU_SOURCE
LOCAL_CFLAGS := -std=c99
ALL_CPPFLAGS = $(LOCAL_CPPFLAGS) $(CPPFLAGS)
diff --git a/eval.c b/eval.c
index cd9b2e5..d0c8b04 100644
--- a/eval.c
+++ b/eval.c
@@ -308,7 +308,7 @@ bool eval_links(const struct expr *expr, struct eval_state *state) {
}
/**
- * -name test.
+ * -i?name test.
*/
bool eval_name(const struct expr *expr, struct eval_state *state) {
struct BFTW *ftwbuf = state->ftwbuf;
@@ -333,17 +333,17 @@ bool eval_name(const struct expr *expr, struct eval_state *state) {
}
}
- bool ret = fnmatch(expr->sdata, name, 0) == 0;
+ bool ret = fnmatch(expr->sdata, name, expr->idata) == 0;
free(copy);
return ret;
}
/**
- * -path test.
+ * -i?path test.
*/
bool eval_path(const struct expr *expr, struct eval_state *state) {
struct BFTW *ftwbuf = state->ftwbuf;
- return fnmatch(expr->sdata, ftwbuf->path, 0) == 0;
+ return fnmatch(expr->sdata, ftwbuf->path, expr->idata) == 0;
}
/**
diff --git a/parse.c b/parse.c
index 6272ba0..f894d5b 100644
--- a/parse.c
+++ b/parse.c
@@ -12,6 +12,7 @@
#include "bfs.h"
#include <errno.h>
#include <fcntl.h>
+#include <fnmatch.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
@@ -418,6 +419,42 @@ static struct expr *parse_depth(struct parser_state *state, const char *option,
}
/**
+ * Set the FNM_CASEFOLD flag, if supported.
+ */
+static struct expr *set_fnm_casefold(struct expr *expr, bool casefold) {
+ if (expr) {
+ if (casefold) {
+#ifdef FNM_CASEFOLD
+ expr->idata = FNM_CASEFOLD;
+#else
+ fprintf(stderr, "%s is missing platform support.\n", option);
+ free(expr);
+ expr = NULL;
+#endif
+ } else {
+ expr->idata = 0;
+ }
+ }
+ return expr;
+}
+
+/**
+ * Parse -i?name.
+ */
+static struct expr *parse_name(struct parser_state *state, const char *option, bool casefold) {
+ struct expr *expr = parse_test_sdata(state, option, eval_name);
+ return set_fnm_casefold(expr, casefold);
+}
+
+/**
+ * Parse -i?path, -i?wholename.
+ */
+static struct expr *parse_path(struct parser_state *state, const char *option, bool casefold) {
+ struct expr *expr = parse_test_sdata(state, option, eval_path);
+ return set_fnm_casefold(expr, casefold);
+}
+
+/**
* Parse -samefile FILE.
*/
static struct expr *parse_samefile(struct parser_state *state, const char *option) {
@@ -585,8 +622,12 @@ static struct expr *parse_literal(struct parser_state *state) {
break;
case 'i':
- if (strcmp(arg, "-inum") == 0) {
+ if (strcmp(arg, "-iname") == 0) {
+ return parse_name(state, arg, true);
+ } else if (strcmp(arg, "-inum") == 0) {
return parse_test_icmp(state, arg, eval_inum);
+ } else if (strcmp(arg, "-ipath") == 0 || strcmp(arg, "-iwholename") == 0) {
+ return parse_path(state, arg, true);
}
break;
@@ -610,7 +651,7 @@ static struct expr *parse_literal(struct parser_state *state) {
case 'n':
if (strcmp(arg, "-name") == 0) {
- return parse_test_sdata(state, arg, eval_name);
+ return parse_name(state, arg, false);
} else if (strcmp(arg, "-newer") == 0) {
return parse_acnewer(state, arg, MTIME);
} else if (strcmp(arg, "-nocolor") == 0) {
@@ -626,7 +667,7 @@ static struct expr *parse_literal(struct parser_state *state) {
case 'p':
if (strcmp(arg, "-path") == 0) {
- return parse_test_sdata(state, arg, eval_path);
+ return parse_path(state, arg, false);
} else if (strcmp(arg, "-print") == 0) {
return new_action(state, eval_print);
} else if (strcmp(arg, "-print0") == 0) {
@@ -672,7 +713,7 @@ static struct expr *parse_literal(struct parser_state *state) {
state->warn = true;
return new_positional_option(state);
} else if (strcmp(arg, "-wholename") == 0) {
- return parse_test_sdata(state, arg, eval_path);
+ return parse_path(state, arg, false);
} else if (strcmp(arg, "-writable") == 0) {
return new_test_idata(state, eval_access, W_OK);
}
diff --git a/tests.sh b/tests.sh
index 97d274b..cbfefcb 100755
--- a/tests.sh
+++ b/tests.sh
@@ -215,7 +215,15 @@ function test_0036() {
find_diff "//" -maxdepth 0 -name '/' 2>/dev/null
}
-for i in {1..36}; do
+function test_0037() {
+ find_diff "$basic" -iname '*F*'
+}
+
+function test_0038() {
+ find_diff "$basic" -ipath "$basic/*F*"
+}
+
+for i in {1..38}; do
test="test_$(printf '%04d' $i)"
"$test" "$dir"
status=$?