summaryrefslogtreecommitdiffstats
path: root/src/opt.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2024-07-02 16:16:32 -0400
committerTavian Barnes <tavianator@tavianator.com>2024-08-12 16:18:31 -0400
commit1234d764ba3059eb2314cb50a2790240ed7ac630 (patch)
tree792bc5659fcaf0ad2a327393c15b09f5cb8ee458 /src/opt.c
parent11e309670b83e997d1dc2569faf002647f70a73b (diff)
downloadbfs-1234d764ba3059eb2314cb50a2790240ed7ac630.tar.xz
opt: Warn about ignored expressions after dangerous actions
For example, `bfs -delete -type f` is almost certainly a mistake. Link: https://savannah.gnu.org/bugs/?65895
Diffstat (limited to 'src/opt.c')
-rw-r--r--src/opt.c61
1 files changed, 49 insertions, 12 deletions
diff --git a/src/opt.c b/src/opt.c
index f735924..2609c77 100644
--- a/src/opt.c
+++ b/src/opt.c
@@ -615,21 +615,25 @@ static bool is_const(const struct bfs_expr *expr) {
/** Warn about an expression. */
_printf(3, 4)
-static void opt_warning(const struct bfs_opt *opt, const struct bfs_expr *expr, const char *format, ...) {
+static bool opt_warning(const struct bfs_opt *opt, const struct bfs_expr *expr, const char *format, ...) {
if (!opt->warn) {
- return;
+ return false;
}
if (bfs_expr_is_parent(expr) || is_const(expr)) {
- return;
+ return false;
}
- if (bfs_expr_warning(opt->ctx, expr)) {
- va_list args;
- va_start(args, format);
- bfs_vwarning(opt->ctx, format, args);
- va_end(args);
+ if (!bfs_expr_warning(opt->ctx, expr)) {
+ return false;
}
+
+ va_list args;
+ va_start(args, format);
+ bfs_vwarning(opt->ctx, format, args);
+ va_end(args);
+
+ return true;
}
/** Remove and return an expression's children. */
@@ -1807,11 +1811,38 @@ static struct bfs_expr *data_flow_leave(struct bfs_opt *opt, struct bfs_expr *ex
return visit_leave(opt, expr, visitor);
}
+/**
+ * Warn about an ignored expression.
+ *
+ * @return
+ * True to continue optimizing, false to cancel.
+ */
+static bool opt_ignore(struct bfs_opt *opt, struct bfs_expr *expr) {
+ struct bfs_ctx *ctx = opt->ctx;
+
+ if (opt_warning(opt, expr, "The result of this expression is ignored.\n")) {
+ if (ctx->interactive && ctx->dangerous) {
+ bfs_warning(ctx, "Do you want to continue? ");
+ if (ynprompt() == 0) {
+ errno = 0;
+ return false;
+ }
+ }
+
+ fprintf(stderr, "\n");
+ }
+
+ return true;
+}
+
/** Data flow visitor function. */
static struct bfs_expr *data_flow_visit(struct bfs_opt *opt, struct bfs_expr *expr, const struct visitor *visitor) {
if (opt->ignore_result && expr->pure) {
opt_debug(opt, "ignored result\n");
- opt_warning(opt, expr, "The result of this expression is ignored.\n\n");
+ if (!opt_ignore(opt, expr)) {
+ return NULL;
+ }
+
expr = opt_const(opt, false);
if (!expr) {
return NULL;
@@ -1987,7 +2018,9 @@ static struct bfs_expr *simplify_and(struct bfs_opt *opt, struct bfs_expr *expr,
if (ignore) {
opt_delete(opt, "%pe [ignored result]\n", child);
- opt_warning(opt, child, "The result of this expression is ignored.\n\n");
+ if (!opt_ignore(opt, child)) {
+ return NULL;
+ }
continue;
}
@@ -2035,7 +2068,9 @@ static struct bfs_expr *simplify_or(struct bfs_opt *opt, struct bfs_expr *expr,
if (ignore) {
opt_delete(opt, "%pe [ignored result]\n", child);
- opt_warning(opt, child, "The result of this expression is ignored.\n\n");
+ if (!opt_ignore(opt, child)) {
+ return NULL;
+ }
continue;
}
@@ -2076,7 +2111,9 @@ static struct bfs_expr *simplify_comma(struct bfs_opt *opt, struct bfs_expr *exp
if (opt->level >= 2 && child->pure && !SLIST_EMPTY(&children)) {
opt_delete(opt, "%pe [ignored result]\n", child);
- opt_warning(opt, child, "The result of this expression is ignored.\n\n");
+ if (!opt_ignore(opt, child)) {
+ return NULL;
+ }
continue;
}