summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/opt.c55
-rw-r--r--src/parse.c56
2 files changed, 61 insertions, 50 deletions
diff --git a/src/opt.c b/src/opt.c
index 934a4b4..c80d584 100644
--- a/src/opt.c
+++ b/src/opt.c
@@ -45,6 +45,7 @@
#include "ctx.h"
#include "diag.h"
#include "eval.h"
+#include "exec.h"
#include "expr.h"
#include "pwcache.h"
#include <assert.h>
@@ -799,6 +800,15 @@ static struct bfs_expr *optimize_empty(struct opt_state *state, struct bfs_expr
return expr;
}
+/** Optimize -{exec,ok}{,dir}. */
+static struct bfs_expr *optimize_exec(struct opt_state *state, struct bfs_expr *expr) {
+ if (expr->exec->flags & BFS_EXEC_MULTI) {
+ expr->always_true = true;
+ }
+
+ return expr;
+}
+
/** Optimize -gid. */
static struct bfs_expr *optimize_gid(struct opt_state *state, struct bfs_expr *expr) {
struct range *range = &state->facts_when_true.ranges[GID_RANGE];
@@ -892,6 +902,34 @@ static bfs_eval_fn *const opt_pure[] = {
};
/**
+ * Table of always-true expressions.
+ */
+static bfs_eval_fn *const opt_always_true[] = {
+ eval_fls,
+ eval_fprint,
+ eval_fprint0,
+ eval_fprintf,
+ eval_fprintx,
+ eval_prune,
+ eval_true,
+
+ // Non-returning
+ eval_exit,
+ eval_quit,
+};
+
+/**
+ * Table of always-false expressions.
+ */
+static bfs_eval_fn *const opt_always_false[] = {
+ eval_false,
+
+ // Non-returning
+ eval_exit,
+ eval_quit,
+};
+
+/**
* Table of simple predicates.
*/
static const struct {
@@ -940,6 +978,7 @@ static const struct {
// Primaries
{eval_access, optimize_access},
{eval_empty, optimize_empty},
+ {eval_exec, optimize_exec},
{eval_gid, optimize_gid},
{eval_samefile, optimize_samefile},
{eval_type, optimize_type},
@@ -964,6 +1003,20 @@ static struct bfs_expr *optimize_expr_lookup(struct opt_state *state, struct bfs
}
}
+ for (size_t i = 0; i < BFS_COUNTOF(opt_always_true); ++i) {
+ if (opt_always_true[i] == expr->eval_fn) {
+ expr->always_true = true;
+ break;
+ }
+ }
+
+ for (size_t i = 0; i < BFS_COUNTOF(opt_always_false); ++i) {
+ if (opt_always_false[i] == expr->eval_fn) {
+ expr->always_false = true;
+ break;
+ }
+ }
+
for (size_t i = 0; i < BFS_COUNTOF(opt_preds); ++i) {
if (opt_preds[i].eval_fn == expr->eval_fn) {
infer_pred_facts(state, opt_preds[i].pred);
@@ -1026,9 +1079,11 @@ static struct bfs_expr *optimize_expr_recursive(struct opt_state *state, struct
}
if (expr->always_true) {
+ expr->probability = 1.0;
set_facts_impossible(&state->facts_when_false);
}
if (expr->always_false) {
+ expr->probability = 0.0;
set_facts_impossible(&state->facts_when_true);
}
diff --git a/src/parse.c b/src/parse.c
index 0b4224c..5766237 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -86,26 +86,15 @@ struct bfs_expr *bfs_expr_new(bfs_eval_fn *eval_fn, size_t argc, char **argv) {
expr->persistent_fds = 0;
expr->ephemeral_fds = 0;
expr->pure = false;
+ expr->always_true = false;
+ expr->always_false = false;
expr->cost = FAST_COST;
+ expr->probability = 0.5;
expr->evaluations = 0;
expr->successes = 0;
expr->elapsed.tv_sec = 0;
expr->elapsed.tv_nsec = 0;
- if (eval_fn == eval_true) {
- expr->always_true = true;
- expr->always_false = false;
- expr->probability = 1.0;
- } else if (eval_fn == eval_false) {
- expr->always_true = false;
- expr->always_false = true;
- expr->probability = 0.0;
- } else {
- expr->always_true = false;
- expr->always_false = false;
- expr->probability = 0.5;
- }
-
// Prevent bfs_expr_free() from freeing uninitialized pointers on error paths
if (bfs_expr_is_parent(expr)) {
expr->lhs = NULL;
@@ -197,21 +186,6 @@ static struct bfs_expr *new_binary_expr(bfs_eval_fn *eval_fn, struct bfs_expr *l
}
/**
- * Set an expression to always return true.
- */
-static void expr_set_always_true(struct bfs_expr *expr) {
- expr->always_true = true;
- expr->probability = 1.0;
-}
-
-/**
- * Set an expression to never return.
- */
-static void expr_set_never_returns(struct bfs_expr *expr) {
- expr->always_true = expr->always_false = true;
-}
-
-/**
* Color use flags.
*/
enum use_color {
@@ -462,7 +436,6 @@ static bool parse_expr_warning(const struct parser_state *state, const struct bf
* Fill in a "-print"-type expression.
*/
static void init_print_expr(struct parser_state *state, struct bfs_expr *expr) {
- expr_set_always_true(expr);
expr->cost = PRINT_COST;
expr->cfile = state->ctx->cout;
expr->path = NULL;
@@ -1359,9 +1332,7 @@ static struct bfs_expr *parse_exec(struct parser_state *state, int flags, int ar
expr->exec = execbuf;
- if (execbuf->flags & BFS_EXEC_MULTI) {
- expr_set_always_true(expr);
- } else {
+ if (!(execbuf->flags & BFS_EXEC_MULTI)) {
expr->cost = 1000000.0;
}
@@ -1395,7 +1366,6 @@ static struct bfs_expr *parse_exit(struct parser_state *state, int arg1, int arg
struct bfs_expr *expr = parse_action(state, eval_exit, argc);
if (expr) {
- expr_set_never_returns(expr);
expr->num = status;
}
return expr;
@@ -1525,7 +1495,6 @@ static struct bfs_expr *parse_fls(struct parser_state *state, int arg1, int arg2
goto fail;
}
- expr_set_always_true(expr);
expr->cost = PRINT_COST;
return expr;
@@ -1540,7 +1509,6 @@ fail:
static struct bfs_expr *parse_fprint(struct parser_state *state, int arg1, int arg2) {
struct bfs_expr *expr = parse_unary_action(state, eval_fprint);
if (expr) {
- expr_set_always_true(expr);
expr->cost = PRINT_COST;
if (expr_open(state, expr, expr->argv[1]) != 0) {
goto fail;
@@ -1559,7 +1527,6 @@ fail:
static struct bfs_expr *parse_fprint0(struct parser_state *state, int arg1, int arg2) {
struct bfs_expr *expr = parse_unary_action(state, eval_fprint0);
if (expr) {
- expr_set_always_true(expr);
expr->cost = PRINT_COST;
if (expr_open(state, expr, expr->argv[1]) != 0) {
goto fail;
@@ -1595,8 +1562,6 @@ static struct bfs_expr *parse_fprintf(struct parser_state *state, int arg1, int
return NULL;
}
- expr_set_always_true(expr);
-
expr->cost = PRINT_COST;
if (expr_open(state, expr, file) != 0) {
@@ -2373,23 +2338,14 @@ static struct bfs_expr *parse_printx(struct parser_state *state, int arg1, int a
*/
static struct bfs_expr *parse_prune(struct parser_state *state, int arg1, int arg2) {
state->prune_arg = state->argv;
-
- struct bfs_expr *expr = parse_nullary_action(state, eval_prune);
- if (expr) {
- expr_set_always_true(expr);
- }
- return expr;
+ return parse_nullary_action(state, eval_prune);
}
/**
* Parse -quit.
*/
static struct bfs_expr *parse_quit(struct parser_state *state, int arg1, int arg2) {
- struct bfs_expr *expr = parse_nullary_action(state, eval_quit);
- if (expr) {
- expr_set_never_returns(expr);
- }
- return expr;
+ return parse_nullary_action(state, eval_quit);
}
/**