diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2022-03-27 12:54:11 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2022-03-27 12:54:11 -0400 |
commit | 954a39edd99cc0a9d426fb48848fd5b1135fa65b (patch) | |
tree | 1fcb39b3294982fbb00c3e5f885c3d379048a2c4 /exec.c | |
parent | 4846e61080c575a67ebe9805a2332d8dd2b90555 (diff) | |
download | bfs-954a39edd99cc0a9d426fb48848fd5b1135fa65b.tar.xz |
parse: Highlight command line errors
Diffstat (limited to 'exec.c')
-rw-r--r-- | exec.c | 50 |
1 files changed, 38 insertions, 12 deletions
@@ -116,6 +116,27 @@ static size_t bfs_exec_arg_max(const struct bfs_exec *execbuf) { return arg_max; } +/** Highlight part of the command line as an error. */ +static void bfs_exec_parse_error(const struct bfs_ctx *ctx, const struct bfs_exec *execbuf) { + char **argv = execbuf->tmpl_argv - 1; + size_t argc = execbuf->tmpl_argc + 1; + if (argv[argc]) { + ++argc; + } + + bool args[ctx->argc]; + for (size_t i = 0; i < ctx->argc; ++i) { + args[i] = false; + } + + size_t i = argv - ctx->argv; + for (size_t j = 0; j < argc; ++j) { + args[i + j] = true; + } + + bfs_argv_error(ctx, args); +} + struct bfs_exec *bfs_exec_parse(const struct bfs_ctx *ctx, char **argv, enum bfs_exec_flags flags) { struct bfs_exec *execbuf = malloc(sizeof(*execbuf)); if (!execbuf) { @@ -125,6 +146,8 @@ struct bfs_exec *bfs_exec_parse(const struct bfs_ctx *ctx, char **argv, enum bfs execbuf->flags = flags; execbuf->ctx = ctx; + execbuf->tmpl_argv = argv + 1; + execbuf->tmpl_argc = 0; execbuf->argv = NULL; execbuf->argc = 0; execbuf->argv_cap = 0; @@ -136,31 +159,33 @@ struct bfs_exec *bfs_exec_parse(const struct bfs_ctx *ctx, char **argv, enum bfs execbuf->wd_len = 0; execbuf->ret = 0; - size_t i; - for (i = 1; ; ++i) { - const char *arg = argv[i]; + while (true) { + const char *arg = execbuf->tmpl_argv[execbuf->tmpl_argc]; if (!arg) { if (execbuf->flags & BFS_EXEC_CONFIRM) { - bfs_error(ctx, "%s: Expected '... ;'.\n", argv[0]); + bfs_exec_parse_error(ctx, execbuf); + bfs_error(ctx, "Expected '... ;'.\n"); } else { - bfs_error(ctx, "%s: Expected '... ;' or '... {} +'.\n", argv[0]); + bfs_exec_parse_error(ctx, execbuf); + bfs_error(ctx, "Expected '... ;' or '... {} +'.\n"); } goto fail; } else if (strcmp(arg, ";") == 0) { break; } else if (strcmp(arg, "+") == 0) { - if (!(execbuf->flags & BFS_EXEC_CONFIRM) && strcmp(argv[i - 1], "{}") == 0) { + const char *prev = execbuf->tmpl_argv[execbuf->tmpl_argc - 1]; + if (!(execbuf->flags & BFS_EXEC_CONFIRM) && strcmp(prev, "{}") == 0) { execbuf->flags |= BFS_EXEC_MULTI; break; } } - } - execbuf->tmpl_argv = argv + 1; - execbuf->tmpl_argc = i - 1; + ++execbuf->tmpl_argc; + } if (execbuf->tmpl_argc == 0) { - bfs_error(ctx, "%s: Missing command.\n", argv[0]); + bfs_exec_parse_error(ctx, execbuf); + bfs_error(ctx, "Missing command.\n"); goto fail; } @@ -172,10 +197,11 @@ struct bfs_exec *bfs_exec_parse(const struct bfs_ctx *ctx, char **argv, enum bfs } if (execbuf->flags & BFS_EXEC_MULTI) { - for (i = 0; i < execbuf->tmpl_argc - 1; ++i) { + for (size_t i = 0; i < execbuf->tmpl_argc - 1; ++i) { char *arg = execbuf->tmpl_argv[i]; if (strstr(arg, "{}")) { - bfs_error(ctx, "%s ... +: Only one '{}' is supported.\n", argv[0]); + bfs_exec_parse_error(ctx, execbuf); + bfs_error(ctx, "Only one '{}' is supported.\n"); goto fail; } execbuf->argv[i] = arg; |