From 9ae0e6dc0e460ca8115f25e8ea7d110714346c2d Mon Sep 17 00:00:00 2001
From: Přemysl Janouch
Date: Sun, 21 May 2017 17:57:31 +0200
Subject: Specify argument in which an error happened
---
ell.c | 32 +++++++++++++++++++++++---------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/ell.c b/ell.c
index d897aa9..921ff58 100644
--- a/ell.c
+++ b/ell.c
@@ -734,6 +734,14 @@ set_error (struct context *ctx, const char *format, ...) {
return false;
}
+static bool
+can_modify_error (struct context *ctx) {
+ // In that case, `error' is NULL and there's nothing else to do anyway.
+ // Errors starting with an underscore are exceptions and would not work
+ // with stack traces generated this way.
+ return !ctx->memory_failure && ctx->error[0] != '_';
+}
+
static bool
assign_arguments (struct context *ctx, struct item *names) {
struct item *arg = ctx->arguments;
@@ -757,19 +765,28 @@ static bool execute (struct context *ctx, struct item *body, struct item **);
static bool
execute_args (struct context *ctx, struct item *args, struct item **res) {
- // TODO: prepend "(argument %d) ->" to any resulting error
+ size_t i = 0;
for (; args; args = args->next) {
struct item *evaluated = NULL;
- if (!execute_statement (ctx, args, &evaluated))
- return false;
// Arguments should not evaporate, default to a nil value
- if (!evaluated && !check (ctx, (evaluated = new_list (NULL))))
- return false;
+ if (!execute_statement (ctx, args, &evaluated)
+ || (!evaluated && !check (ctx, (evaluated = new_list (NULL)))))
+ goto error;
item_free_list (evaluated->next);
evaluated->next = NULL;
res = &(*res = evaluated)->next;
+ i++;
}
return true;
+error:
+ // Once the code flows like this, at least make some use of it
+ if (can_modify_error (ctx)) {
+ char *tmp = ctx->error;
+ ctx->error = NULL;
+ set_error (ctx, "(argument %zu) -> %s", i, tmp);
+ free (tmp);
+ }
+ return false;
}
static bool
@@ -854,10 +871,7 @@ execute_statement
if (statement->head->type == ITEM_STRING)
name = statement->head->value;
- // In that case, `error' is NULL and there's nothing else to do anyway.
- // Errors starting with an underscore are exceptions and would not work
- // with stack traces generated this way.
- if (!ctx->memory_failure && ctx->error[0] != '_') {
+ if (can_modify_error (ctx)) {
char *tmp = ctx->error;
ctx->error = NULL;
set_error (ctx, "%s -> %s", name, tmp);
--
cgit v1.2.3-70-g09d2