From 30ce56dc76f3a098c42c7ac9701fc4a223847fa2 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 13 Feb 2016 17:14:03 -0500 Subject: Implement -iname and -ipath. --- Makefile | 2 +- eval.c | 8 ++++---- parse.c | 49 +++++++++++++++++++++++++++++++++++++++++++++---- tests.sh | 10 +++++++++- 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 #include +#include #include #include #include @@ -417,6 +418,42 @@ static struct expr *parse_depth(struct parser_state *state, const char *option, return new_option(state, 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. */ @@ -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=$? -- cgit v1.2.3