From 1c755492eab68257420c6824a36892cdeacb970a Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 23 Feb 2016 11:11:47 -0500 Subject: Implement -O. --- bfs.h | 2 + eval.c | 4 ++ parse.c | 128 +++++++++++++++++++++++++++++++++++++++------------------------- 3 files changed, 85 insertions(+), 49 deletions(-) diff --git a/bfs.h b/bfs.h index 0f8e397..b83da2f 100644 --- a/bfs.h +++ b/bfs.h @@ -82,6 +82,8 @@ struct cmdline { /** bftw() flags. */ enum bftw_flags flags; + /** Optimization level. */ + int optlevel; /** Debugging flags. */ enum debugflags debug; diff --git a/eval.c b/eval.c index f69c890..b8e9a1b 100644 --- a/eval.c +++ b/eval.c @@ -651,6 +651,10 @@ int eval_cmdline(const struct cmdline *cmdline) { return 0; } + if (cmdline->optlevel >= 3 && cmdline->expr->eval == eval_false) { + return 0; + } + int nopenfd = infer_fdlimit(); struct callback_args args = { diff --git a/parse.c b/parse.c index 9888418..0db2572 100644 --- a/parse.c +++ b/parse.c @@ -151,6 +151,9 @@ struct parser_state { /** The name of this program. */ const char *command; + /** The optimization level. */ + int optlevel; + /** Whether a -print action is implied. */ bool implicit_print; /** Whether warnings are enabled (see -warn, -nowarn). */ @@ -423,6 +426,17 @@ static struct expr *parse_debug(struct parser_state *state) { return parse_unary_positional_option(state); } +/** + * Parse -On. + */ +static struct expr *parse_optlevel(struct parser_state *state) { + if (!parse_int(state, state->args[0] + 2, &state->cmdline->optlevel)) { + return NULL; + } + + return parse_nullary_positional_option(state); +} + /** * Parse -executable, -readable, -writable */ @@ -776,6 +790,9 @@ static struct expr *parse_literal(struct parser_state *state) { } break; + case 'O': + return parse_optlevel(state); + case 'P': if (strcmp(arg, "-P") == 0) { cmdline->flags &= ~(BFTW_FOLLOW | BFTW_DETECT_CYCLES); @@ -1012,19 +1029,21 @@ static struct expr *parse_literal(struct parser_state *state) { /** * Create a "not" expression. */ -static struct expr *new_not_expr(struct expr *rhs, char **args) { - if (rhs == &expr_true) { - return &expr_false; - } else if (rhs == &expr_false) { - return &expr_true; - } else if (rhs->eval == eval_not) { - struct expr *expr = rhs->rhs; - rhs->rhs = NULL; - free_expr(rhs); - return expr; - } else { - return new_unary_expr(eval_not, rhs, args); +static struct expr *new_not_expr(const struct parser_state *state, struct expr *rhs, char **args) { + if (state->cmdline->optlevel >= 1) { + if (rhs == &expr_true) { + return &expr_false; + } else if (rhs == &expr_false) { + return &expr_true; + } else if (rhs->eval == eval_not) { + struct expr *expr = rhs->rhs; + rhs->rhs = NULL; + free_expr(rhs); + return expr; + } } + + return new_unary_expr(eval_not, rhs, args); } /** @@ -1063,7 +1082,7 @@ static struct expr *parse_factor(struct parser_state *state) { return NULL; } - return new_not_expr(factor, args); + return new_not_expr(state, factor, args); } else { return parse_literal(state); } @@ -1072,20 +1091,22 @@ static struct expr *parse_factor(struct parser_state *state) { /** * Create an "and" expression. */ -static struct expr *new_and_expr(struct expr *lhs, struct expr *rhs, char **args) { - if (lhs == &expr_true) { - return rhs; - } else if (lhs == &expr_false) { - free_expr(rhs); - return lhs; - } else if (rhs == &expr_true) { - return lhs; - } else if (rhs == &expr_false && lhs->pure) { - free_expr(lhs); - return rhs; - } else { - return new_binary_expr(eval_and, lhs, rhs, args); +static struct expr *new_and_expr(const struct parser_state *state, struct expr *lhs, struct expr *rhs, char **args) { + if (state->cmdline->optlevel >= 1) { + if (lhs == &expr_true) { + return rhs; + } else if (lhs == &expr_false) { + free_expr(rhs); + return lhs; + } else if (rhs == &expr_true) { + return lhs; + } else if (rhs == &expr_false && lhs->pure) { + free_expr(lhs); + return rhs; + } } + + return new_binary_expr(eval_and, lhs, rhs, args); } /** @@ -1121,7 +1142,7 @@ static struct expr *parse_term(struct parser_state *state) { return NULL; } - term = new_and_expr(lhs, rhs, args); + term = new_and_expr(state, lhs, rhs, args); } return term; @@ -1130,20 +1151,22 @@ static struct expr *parse_term(struct parser_state *state) { /** * Create an "or" expression. */ -static struct expr *new_or_expr(struct expr *lhs, struct expr *rhs, char **args) { - if (lhs == &expr_true) { - free_expr(rhs); - return lhs; - } else if (lhs == &expr_false) { - return rhs; - } else if (rhs == &expr_true && lhs->pure) { - free_expr(lhs); - return rhs; - } else if (rhs == &expr_false) { - return lhs; - } else { - return new_binary_expr(eval_or, lhs, rhs, args); +static struct expr *new_or_expr(const struct parser_state *state, struct expr *lhs, struct expr *rhs, char **args) { + if (state->cmdline->optlevel >= 1) { + if (lhs == &expr_true) { + free_expr(rhs); + return lhs; + } else if (lhs == &expr_false) { + return rhs; + } else if (rhs == &expr_true && lhs->pure) { + free_expr(lhs); + return rhs; + } else if (rhs == &expr_false) { + return lhs; + } } + + return new_binary_expr(eval_or, lhs, rhs, args); } /** @@ -1173,7 +1196,7 @@ static struct expr *parse_clause(struct parser_state *state) { return NULL; } - clause = new_or_expr(lhs, rhs, args); + clause = new_or_expr(state, lhs, rhs, args); } return clause; @@ -1182,13 +1205,15 @@ static struct expr *parse_clause(struct parser_state *state) { /** * Create a "comma" expression. */ -static struct expr *new_comma_expr(struct expr *lhs, struct expr *rhs, char **args) { - if (lhs->pure) { - free_expr(lhs); - return rhs; - } else { - return new_binary_expr(eval_comma, lhs, rhs, args); +static struct expr *new_comma_expr(const struct parser_state *state, struct expr *lhs, struct expr *rhs, char **args) { + if (state->cmdline->optlevel >= 1) { + if (lhs->pure) { + free_expr(lhs); + return rhs; + } } + + return new_binary_expr(eval_comma, lhs, rhs, args); } /** @@ -1217,7 +1242,7 @@ static struct expr *parse_expr(struct parser_state *state) { return NULL; } - expr = new_comma_expr(lhs, rhs, args); + expr = new_comma_expr(state, lhs, rhs, args); } return expr; @@ -1261,6 +1286,10 @@ static void dump_cmdline(const struct cmdline *cmdline) { fputs("-P ", stderr); } + if (cmdline->optlevel != 1) { + fprintf(stderr, "-O%d ", cmdline->optlevel); + } + if (cmdline->debug & DEBUG_STAT) { fputs("-D stat ", stderr); } @@ -1309,6 +1338,7 @@ struct cmdline *parse_cmdline(int argc, char *argv[]) { cmdline->mindepth = 0; cmdline->maxdepth = INT_MAX; cmdline->flags = BFTW_RECOVER; + cmdline->optlevel = 1; cmdline->debug = 0; cmdline->expr = &expr_true; @@ -1354,7 +1384,7 @@ struct cmdline *parse_cmdline(int argc, char *argv[]) { goto fail; } - cmdline->expr = new_and_expr(cmdline->expr, print, &fake_and_arg); + cmdline->expr = new_and_expr(&state, cmdline->expr, print, &fake_and_arg); if (!cmdline->expr) { goto fail; } -- cgit v1.2.3