From: Stephen Dolan Date: Mon, 10 Sep 2012 15:07:03 +0000 (+0100) Subject: Sensible error messages when a silly addition is performed. X-Git-Tag: jq-1.1~62 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e718bd50b63380a0be2c8f9ae7cb837bcf01c48e;p=jq Sensible error messages when a silly addition is performed. Fix a test to no longer perform an invalid addition. --- diff --git a/c/builtin.c b/c/builtin.c index 2669868..45056fc 100644 --- a/c/builtin.c +++ b/c/builtin.c @@ -27,7 +27,9 @@ static void f_plus(jv input[], jv output[]) { } else if (jv_get_kind(a) == JV_KIND_OBJECT && jv_get_kind(b) == JV_KIND_OBJECT) { output[0] = jv_object_merge(a, b); } else { - output[0] = jv_string("wtf gaize"); + output[0] = jv_invalid_with_msg(jv_string_fmt("Attempted to add %s and %s", + jv_kind_name(jv_get_kind(a)), + jv_kind_name(jv_get_kind(b)))); jv_free(a); jv_free(b); } diff --git a/c/execute.c b/c/execute.c index c8505bf..f59e156 100644 --- a/c/execute.c +++ b/c/execute.c @@ -376,7 +376,16 @@ jv jq_next() { struct cfunction* func = &frame_current_bytecode(&frame_stk)->globals->cfunctions[*pc++]; func->fptr(cfunc_input, cfunc_output); top.value = cfunc_output[0]; - stack_push(top); + if (jv_is_valid(top.value)) { + stack_push(top); + } else { + jv msg = jv_invalid_get_msg(top.value); + if (jv_get_kind(msg) == JV_KIND_STRING) { + fprintf(stderr, "jq: error: %s\n", jv_string_value(msg)); + } + jv_free(msg); + goto do_backtrack; + } break; } @@ -393,7 +402,16 @@ jv jq_next() { struct cfunction* func = &frame_current_bytecode(&frame_stk)->globals->cfunctions[*pc++]; func->fptr(cfunc_input, cfunc_output); top.value = cfunc_output[0]; - stack_push(top); + if (jv_is_valid(top.value)) { + stack_push(top); + } else { + jv msg = jv_invalid_get_msg(top.value); + if (jv_get_kind(msg) == JV_KIND_STRING) { + fprintf(stderr, "jq: error: %s\n", jv_string_value(msg)); + } + jv_free(msg); + goto do_backtrack; + } break; } diff --git a/c/jv.c b/c/jv.c index 73805a0..8c0c034 100644 --- a/c/jv.c +++ b/c/jv.c @@ -38,6 +38,21 @@ jv_kind jv_get_kind(jv x) { return x.kind; } +const char* jv_kind_name(jv_kind k) { + switch (k) { + case JV_KIND_INVALID: return ""; + case JV_KIND_NULL: return "null"; + case JV_KIND_FALSE: return "boolean"; + case JV_KIND_TRUE: return "boolean"; + case JV_KIND_NUMBER: return "number"; + case JV_KIND_STRING: return "string"; + case JV_KIND_ARRAY: return "array"; + case JV_KIND_OBJECT: return "object"; + } + assert(0); + return ""; +} + static const jv JV_NULL = {JV_KIND_NULL, {0}}; static const jv JV_FALSE = {JV_KIND_FALSE, {0}}; static const jv JV_TRUE = {JV_KIND_TRUE, {0}}; diff --git a/c/jv.h b/c/jv.h index c415ee2..9aadd41 100644 --- a/c/jv.h +++ b/c/jv.h @@ -41,6 +41,7 @@ typedef struct { */ jv_kind jv_get_kind(jv); +const char* jv_kind_name(jv_kind); static int jv_is_valid(jv x) { return jv_get_kind(x) != JV_KIND_INVALID; } jv jv_copy(jv); diff --git a/c/testdata b/c/testdata index f80249e..11684dd 100644 --- a/c/testdata +++ b/c/testdata @@ -207,7 +207,7 @@ def id(x):x; 2000 as $x | def f(x):1 as $x | id([$x, x, x]); def g(x): 100 as $x # test backtracking through function calls and returns # this test is *evil* [[20,10][1,0] as $x | def f: (100,200) as $y | def g: [$x + $y, .]; . + $x | g; f[0] | [f][0][1] | f] -"woo, testing!" +999999999 [[110.0, 130.0], [210.0, 130.0], [110.0, 230.0], [210.0, 230.0], [120.0, 160.0], [220.0, 160.0], [120.0, 260.0], [220.0, 260.0]] #