diff options
author | Jo-Philipp Wich <jo@mein.io> | 2020-10-06 17:21:54 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2020-10-06 17:52:33 +0200 |
commit | 8fb8da605419c427605ca91c67b367c9a4cd0eec (patch) | |
tree | 5033b34dcf71742e5c0e7b32a5bc58fb57fff127 /ast.c | |
parent | 5f19e5870007d57034adea5f124e3c87413a1aaf (diff) |
treewide: rework exception context formatting
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'ast.c')
-rw-r--r-- | ast.c | 48 |
1 files changed, 48 insertions, 0 deletions
@@ -370,6 +370,54 @@ ut_new_func(struct ut_state *s, struct ut_op *decl, struct ut_scope *scope) } static void +exception_free(struct json_object *v, void *ud) +{ + free(ud); +} + +__attribute__((format(printf, 3, 0))) struct json_object * +ut_new_exception(struct ut_state *s, uint32_t off, const char *fmt, ...) +{ + struct ut_op *op, *failing_op; + va_list ap; + ssize_t sz; + char *p; + + sz = ALIGN(sizeof(*op)); + + if (s->filename) + sz += ALIGN(strlen(s->filename) + 1); + + failing_op = ut_get_op(s, off); + + op = xalloc(sz); + op->type = T_EXCEPTION; + op->off = failing_op ? failing_op->off : 0; + + if (s->filename) { + p = (char *)op + ALIGN(sizeof(*op)); + op->tag.data = strcpy(p, s->filename); + } + + va_start(ap, fmt); + sz = xvasprintf(&p, fmt, ap); + va_end(ap); + + op->val = xjs_new_string_len(p, sz); + free(p); + + json_object_set_userdata(op->val, op, exception_free); + + if (s->error.code == UT_ERROR_EXCEPTION) + json_object_put(s->error.info.exception); + + s->error.code = UT_ERROR_EXCEPTION; + s->error.info.exception = op->val; + + return json_object_get(op->val); +} + +static void scope_free(struct json_object *v, void *ud) { struct ut_scope *sc = ud; |