summaryrefslogtreecommitdiffstats
path: root/src/diag.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/diag.c')
-rw-r--r--src/diag.c145
1 files changed, 104 insertions, 41 deletions
diff --git a/src/diag.c b/src/diag.c
index 27848f1..deb6f26 100644
--- a/src/diag.c
+++ b/src/diag.c
@@ -1,40 +1,80 @@
-/****************************************************************************
- * bfs *
- * Copyright (C) 2019-2022 Tavian Barnes <tavianator@tavianator.com> *
- * *
- * Permission to use, copy, modify, and/or distribute this software for any *
- * purpose with or without fee is hereby granted. *
- * *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES *
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF *
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR *
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES *
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN *
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
- ****************************************************************************/
+// Copyright © Tavian Barnes <tavianator@tavianator.com>
+// SPDX-License-Identifier: 0BSD
+#include "prelude.h"
#include "diag.h"
-#include "ctx.h"
+#include "alloc.h"
+#include "bfstd.h"
#include "color.h"
+#include "ctx.h"
+#include "dstring.h"
#include "expr.h"
-#include "util.h"
-#include <assert.h>
#include <errno.h>
#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/** bfs_diagf() implementation. */
+attr(printf(2, 0))
+static void bfs_vdiagf(const struct bfs_loc *loc, const char *format, va_list args) {
+ fprintf(stderr, "%s: %s@%s:%d: ", xgetprogname(), loc->func, loc->file, loc->line);
+ vfprintf(stderr, format, args);
+ fprintf(stderr, "\n");
+}
+
+void bfs_diagf(const struct bfs_loc *loc, const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ bfs_vdiagf(loc, format, args);
+ va_end(args);
+}
+
+noreturn void bfs_abortf(const struct bfs_loc *loc, const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ bfs_vdiagf(loc, format, args);
+ va_end(args);
+
+ abort();
+}
+
+const char *debug_flag_name(enum debug_flags flag) {
+ switch (flag) {
+ case DEBUG_COST:
+ return "cost";
+ case DEBUG_EXEC:
+ return "exec";
+ case DEBUG_OPT:
+ return "opt";
+ case DEBUG_RATES:
+ return "rates";
+ case DEBUG_SEARCH:
+ return "search";
+ case DEBUG_STAT:
+ return "stat";
+ case DEBUG_TREE:
+ return "tree";
+
+ case DEBUG_ALL:
+ break;
+ }
+
+ bfs_bug("Unrecognized debug flag");
+ return "???";
+}
void bfs_perror(const struct bfs_ctx *ctx, const char *str) {
bfs_error(ctx, "%s: %m.\n", str);
}
-void bfs_error(const struct bfs_ctx *ctx, const char *format, ...) {
+void bfs_error(const struct bfs_ctx *ctx, const char *format, ...) {
va_list args;
va_start(args, format);
bfs_verror(ctx, format, args);
va_end(args);
}
-bool bfs_warning(const struct bfs_ctx *ctx, const char *format, ...) {
+bool bfs_warning(const struct bfs_ctx *ctx, const char *format, ...) {
va_list args;
va_start(args, format);
bool ret = bfs_vwarning(ctx, format, args);
@@ -42,7 +82,7 @@ bool bfs_warning(const struct bfs_ctx *ctx, const char *format, ...) {
return ret;
}
-bool bfs_debug(const struct bfs_ctx *ctx, enum debug_flags flag, const char *format, ...) {
+bool bfs_debug(const struct bfs_ctx *ctx, enum debug_flags flag, const char *format, ...) {
va_list args;
va_start(args, format);
bool ret = bfs_vdebug(ctx, flag, format, args);
@@ -83,13 +123,18 @@ bool bfs_vdebug(const struct bfs_ctx *ctx, enum debug_flags flag, const char *fo
}
}
+/** Get the command name without any leading directories. */
+static const char *bfs_cmd(const struct bfs_ctx *ctx) {
+ return ctx->argv[0] + xbaseoff(ctx->argv[0]);
+}
+
void bfs_error_prefix(const struct bfs_ctx *ctx) {
- cfprintf(ctx->cerr, "${bld}%s:${rs} ${err}error:${rs} ", xbasename(ctx->argv[0]));
+ cfprintf(ctx->cerr, "${bld}%s:${rs} ${err}error:${rs} ", bfs_cmd(ctx));
}
bool bfs_warning_prefix(const struct bfs_ctx *ctx) {
if (ctx->warn) {
- cfprintf(ctx->cerr, "${bld}%s:${rs} ${wrn}warning:${rs} ", xbasename(ctx->argv[0]));
+ cfprintf(ctx->cerr, "${bld}%s:${rs} ${wrn}warning:${rs} ", bfs_cmd(ctx));
return true;
} else {
return false;
@@ -98,7 +143,7 @@ bool bfs_warning_prefix(const struct bfs_ctx *ctx) {
bool bfs_debug_prefix(const struct bfs_ctx *ctx, enum debug_flags flag) {
if (ctx->debug & flag) {
- cfprintf(ctx->cerr, "${bld}%s:${rs} ${cyn}-D %s${rs}: ", xbasename(ctx->argv[0]), debug_flag_name(flag));
+ cfprintf(ctx->cerr, "${bld}%s:${rs} ${cyn}-D %s${rs}: ", bfs_cmd(ctx), debug_flag_name(flag));
return true;
} else {
return false;
@@ -106,32 +151,33 @@ bool bfs_debug_prefix(const struct bfs_ctx *ctx, enum debug_flags flag) {
}
/** Recursive part of highlight_expr(). */
-static bool highlight_expr_recursive(const struct bfs_ctx *ctx, const struct bfs_expr *expr, bool *args) {
+static bool highlight_expr_recursive(const struct bfs_ctx *ctx, const struct bfs_expr *expr, bool args[]) {
if (!expr) {
return false;
}
bool ret = false;
- if (!expr->synthetic) {
- size_t i = expr->argv - ctx->argv;
- for (size_t j = 0; j < expr->argc; ++j) {
- assert(i + j < ctx->argc);
- args[i + j] = true;
- ret = true;
+ for (size_t i = 0; i < ctx->argc; ++i) {
+ if (&ctx->argv[i] == expr->argv) {
+ for (size_t j = 0; j < expr->argc; ++j) {
+ bfs_assert(i + j < ctx->argc);
+ args[i + j] = true;
+ ret = true;
+ }
+ break;
}
}
- if (bfs_expr_has_children(expr)) {
- ret |= highlight_expr_recursive(ctx, expr->lhs, args);
- ret |= highlight_expr_recursive(ctx, expr->rhs, args);
+ for (struct bfs_expr *child = bfs_expr_children(expr); child; child = child->next) {
+ ret |= highlight_expr_recursive(ctx, child, args);
}
return ret;
}
/** Highlight an expression in the command line. */
-static bool highlight_expr(const struct bfs_ctx *ctx, const struct bfs_expr *expr, bool *args) {
+static bool highlight_expr(const struct bfs_ctx *ctx, const struct bfs_expr *expr, bool args[]) {
for (size_t i = 0; i < ctx->argc; ++i) {
args[i] = false;
}
@@ -140,13 +186,24 @@ static bool highlight_expr(const struct bfs_ctx *ctx, const struct bfs_expr *exp
}
/** Print a highlighted portion of the command line. */
-static void bfs_argv_diag(const struct bfs_ctx *ctx, const bool *args, bool warning) {
+static void bfs_argv_diag(const struct bfs_ctx *ctx, const bool args[], bool warning) {
if (warning) {
bfs_warning_prefix(ctx);
} else {
bfs_error_prefix(ctx);
}
+ dchar **argv = ZALLOC_ARRAY(dchar *, ctx->argc);
+ if (!argv) {
+ return;
+ }
+
+ for (size_t i = 0; i < ctx->argc; ++i) {
+ if (dstrescat(&argv[i], ctx->argv[i], WESC_SHELL | WESC_TTY) != 0) {
+ goto done;
+ }
+ }
+
size_t max_argc = 0;
for (size_t i = 0; i < ctx->argc; ++i) {
if (i > 0) {
@@ -155,9 +212,9 @@ static void bfs_argv_diag(const struct bfs_ctx *ctx, const bool *args, bool warn
if (args[i]) {
max_argc = i + 1;
- cfprintf(ctx->cerr, "${bld}%s${rs}", ctx->argv[i]);
+ cfprintf(ctx->cerr, "${bld}%s${rs}", argv[i]);
} else {
- cfprintf(ctx->cerr, "%s", ctx->argv[i]);
+ cfprintf(ctx->cerr, "%s", argv[i]);
}
}
@@ -186,7 +243,7 @@ static void bfs_argv_diag(const struct bfs_ctx *ctx, const bool *args, bool warn
}
}
- size_t len = xstrwidth(ctx->argv[i]);
+ size_t len = xstrwidth(argv[i]);
for (size_t j = 0; j < len; ++j) {
if (args[i]) {
cfprintf(ctx->cerr, "~");
@@ -201,9 +258,15 @@ static void bfs_argv_diag(const struct bfs_ctx *ctx, const bool *args, bool warn
}
cfprintf(ctx->cerr, "\n");
+
+done:
+ for (size_t i = 0; i < ctx->argc; ++i) {
+ dstrfree(argv[i]);
+ }
+ free(argv);
}
-void bfs_argv_error(const struct bfs_ctx *ctx, const bool *args) {
+void bfs_argv_error(const struct bfs_ctx *ctx, const bool args[]) {
bfs_argv_diag(ctx, args, false);
}
@@ -214,7 +277,7 @@ void bfs_expr_error(const struct bfs_ctx *ctx, const struct bfs_expr *expr) {
}
}
-bool bfs_argv_warning(const struct bfs_ctx *ctx, const bool *args) {
+bool bfs_argv_warning(const struct bfs_ctx *ctx, const bool args[]) {
if (!ctx->warn) {
return false;
}