Specify argument in which an error happened

This commit is contained in:
Přemysl Eric Janouch 2017-05-21 17:57:31 +02:00
parent dae5622955
commit 9ae0e6dc0e
Signed by: p
GPG Key ID: B715679E3A361BE6
1 changed files with 23 additions and 9 deletions

32
ell.c
View File

@ -734,6 +734,14 @@ set_error (struct context *ctx, const char *format, ...) {
return false; 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 static bool
assign_arguments (struct context *ctx, struct item *names) { assign_arguments (struct context *ctx, struct item *names) {
struct item *arg = ctx->arguments; struct item *arg = ctx->arguments;
@ -757,19 +765,28 @@ static bool execute (struct context *ctx, struct item *body, struct item **);
static bool static bool
execute_args (struct context *ctx, struct item *args, struct item **res) { 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) { for (; args; args = args->next) {
struct item *evaluated = NULL; struct item *evaluated = NULL;
if (!execute_statement (ctx, args, &evaluated))
return false;
// Arguments should not evaporate, default to a nil value // Arguments should not evaporate, default to a nil value
if (!evaluated && !check (ctx, (evaluated = new_list (NULL)))) if (!execute_statement (ctx, args, &evaluated)
return false; || (!evaluated && !check (ctx, (evaluated = new_list (NULL)))))
goto error;
item_free_list (evaluated->next); item_free_list (evaluated->next);
evaluated->next = NULL; evaluated->next = NULL;
res = &(*res = evaluated)->next; res = &(*res = evaluated)->next;
i++;
} }
return true; 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 static bool
@ -854,10 +871,7 @@ execute_statement
if (statement->head->type == ITEM_STRING) if (statement->head->type == ITEM_STRING)
name = statement->head->value; name = statement->head->value;
// In that case, `error' is NULL and there's nothing else to do anyway. if (can_modify_error (ctx)) {
// Errors starting with an underscore are exceptions and would not work
// with stack traces generated this way.
if (!ctx->memory_failure && ctx->error[0] != '_') {
char *tmp = ctx->error; char *tmp = ctx->error;
ctx->error = NULL; ctx->error = NULL;
set_error (ctx, "%s -> %s", name, tmp); set_error (ctx, "%s -> %s", name, tmp);