aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2017-05-21 17:57:31 +0200
committerPřemysl Janouch <p.janouch@gmail.com>2017-05-21 17:57:31 +0200
commit9ae0e6dc0e460ca8115f25e8ea7d110714346c2d (patch)
tree2c23834411ce794893792996a7d927aa0aa1f555
parentdae5622955c74ce35cd9b0675313d523bb38eaa4 (diff)
downloadell-9ae0e6dc0e460ca8115f25e8ea7d110714346c2d.tar.gz
ell-9ae0e6dc0e460ca8115f25e8ea7d110714346c2d.tar.xz
ell-9ae0e6dc0e460ca8115f25e8ea7d110714346c2d.zip
Specify argument in which an error happened
-rw-r--r--ell.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/ell.c b/ell.c
index d897aa9..921ff58 100644
--- a/ell.c
+++ b/ell.c
@@ -735,6 +735,14 @@ set_error (struct context *ctx, const char *format, ...) {
}
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;
for (; names; names = names->next) {
@@ -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);