diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2017-09-02 17:05:04 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2017-09-02 17:05:04 -0400 |
commit | 84064a0bccf8cbabd54b76afee890df880c5d581 (patch) | |
tree | dc2f9a99cf197afc87a4e2da4582969072c2c688 | |
parent | 2741f580ffb6a05f52f0e2b05fa77ff3a15d967f (diff) | |
download | bfs-84064a0bccf8cbabd54b76afee890df880c5d581.tar.xz |
Implement -D search
-rw-r--r-- | bfs.h | 14 | ||||
-rw-r--r-- | eval.c | 100 | ||||
-rw-r--r-- | parse.c | 3 |
3 files changed, 111 insertions, 6 deletions
@@ -63,17 +63,19 @@ typedef bool eval_fn(const struct expr *expr, struct eval_state *state); */ enum debug_flags { /** Print cost estimates. */ - DEBUG_COST = 1 << 0, + DEBUG_COST = 1 << 0, /** Print executed command details. */ - DEBUG_EXEC = 1 << 1, + DEBUG_EXEC = 1 << 1, /** Print optimization details. */ - DEBUG_OPT = 1 << 2, + DEBUG_OPT = 1 << 2, /** Print rate information. */ - DEBUG_RATES = 1 << 3, + DEBUG_RATES = 1 << 3, + /** Trace the filesystem traversal. */ + DEBUG_SEARCH = 1 << 4, /** Trace all stat() calls. */ - DEBUG_STAT = 1 << 4, + DEBUG_STAT = 1 << 5, /** Print the parse tree. */ - DEBUG_TREE = 1 << 5, + DEBUG_TREE = 1 << 6, }; /** @@ -992,6 +992,59 @@ static void debug_stat(const struct eval_state *state) { } /** + * Dump the bftw_typeflag for -D search. + */ +static const char *dump_bftw_typeflag(enum bftw_typeflag type) { +#define DUMP_BFTW_TYPEFLAG_CASE(flag) \ + case flag: \ + return #flag + + switch (type) { + DUMP_BFTW_TYPEFLAG_CASE(BFTW_BLK); + DUMP_BFTW_TYPEFLAG_CASE(BFTW_CHR); + DUMP_BFTW_TYPEFLAG_CASE(BFTW_DIR); + DUMP_BFTW_TYPEFLAG_CASE(BFTW_DOOR); + DUMP_BFTW_TYPEFLAG_CASE(BFTW_FIFO); + DUMP_BFTW_TYPEFLAG_CASE(BFTW_LNK); + DUMP_BFTW_TYPEFLAG_CASE(BFTW_PORT); + DUMP_BFTW_TYPEFLAG_CASE(BFTW_REG); + DUMP_BFTW_TYPEFLAG_CASE(BFTW_SOCK); + DUMP_BFTW_TYPEFLAG_CASE(BFTW_WHT); + + DUMP_BFTW_TYPEFLAG_CASE(BFTW_ERROR); + + default: + DUMP_BFTW_TYPEFLAG_CASE(BFTW_UNKNOWN); + } +} + +#define DUMP_BFTW_MAP(value) [value] = #value + +/** + * Dump the bftw_visit for -D search. + */ +static const char *dump_bftw_visit(enum bftw_visit visit) { + static const char *visits[] = { + DUMP_BFTW_MAP(BFTW_PRE), + DUMP_BFTW_MAP(BFTW_POST), + }; + return visits[visit]; +} + +/** + * Dump the bftw_action for -D search. + */ +static const char *dump_bftw_action(enum bftw_action action) { + static const char *actions[] = { + DUMP_BFTW_MAP(BFTW_CONTINUE), + DUMP_BFTW_MAP(BFTW_SKIP_SIBLINGS), + DUMP_BFTW_MAP(BFTW_SKIP_SUBTREE), + DUMP_BFTW_MAP(BFTW_STOP), + }; + return actions[action]; +} + +/** * Type passed as the argument to the bftw() callback. */ struct callback_args { @@ -1058,6 +1111,23 @@ done: debug_stat(&state); } + if (cmdline->debug & DEBUG_SEARCH) { + fprintf(stderr, + "cmdline_callback({ " + ".path = \"%s\", " + ".depth = %zu, " + ".visit = %s, " + ".typeflag = %s, " + ".error = %d " + "}) == %s\n", + ftwbuf->path, + ftwbuf->depth, + dump_bftw_visit(ftwbuf->visit), + dump_bftw_typeflag(ftwbuf->typeflag), + ftwbuf->error, + dump_bftw_action(state.action)); + } + return state.action; } @@ -1110,6 +1180,30 @@ static int infer_fdlimit(const struct cmdline *cmdline) { } /** + * Dump the bftw() flags for -D search. + */ +static void dump_bftw_flags(enum bftw_flags flags) { +#define DUMP_BFTW_FLAG(flag) \ + if (flags & flag) { \ + fputs(#flag, stderr); \ + flags ^= flag; \ + if (flags) { \ + fputs(" | ", stderr); \ + } \ + } + + DUMP_BFTW_FLAG(BFTW_STAT); + DUMP_BFTW_FLAG(BFTW_RECOVER); + DUMP_BFTW_FLAG(BFTW_DEPTH); + DUMP_BFTW_FLAG(BFTW_COMFOLLOW); + DUMP_BFTW_FLAG(BFTW_LOGICAL); + DUMP_BFTW_FLAG(BFTW_DETECT_CYCLES); + DUMP_BFTW_FLAG(BFTW_XDEV); + + assert(!flags); +} + +/** * Evaluate the command line. */ int eval_cmdline(const struct cmdline *cmdline) { @@ -1133,6 +1227,12 @@ int eval_cmdline(const struct cmdline *cmdline) { }; for (struct root *root = cmdline->roots; root && !args.quit; root = root->next) { + if (cmdline->debug & DEBUG_SEARCH) { + fprintf(stderr, "bftw(\"%s\", cmdline_callback, %d, ", root->path, nopenfd); + dump_bftw_flags(cmdline->flags); + fprintf(stderr, ", &args)\n"); + } + if (bftw(root->path, cmdline_callback, nopenfd, cmdline->flags, &args) != 0) { args.ret = EXIT_FAILURE; perror("bftw()"); @@ -755,6 +755,7 @@ static struct expr *parse_debug(struct parser_state *state, int arg1, int arg2) printf(" exec: Print executed command details.\n"); printf(" opt: Print optimization details.\n"); printf(" rates: Print predicate success rates.\n"); + printf(" search: Trace the filesystem traversal.\n"); printf(" stat: Trace all stat() calls.\n"); printf(" tree: Print the parse tree.\n"); @@ -768,6 +769,8 @@ static struct expr *parse_debug(struct parser_state *state, int arg1, int arg2) cmdline->debug |= DEBUG_OPT; } else if (strcmp(flag, "rates") == 0) { cmdline->debug |= DEBUG_RATES; + } else if (strcmp(flag, "search") == 0) { + cmdline->debug |= DEBUG_SEARCH; } else if (strcmp(flag, "stat") == 0) { cmdline->debug |= DEBUG_STAT; } else if (strcmp(flag, "tree") == 0) { |