diff options
-rw-r--r-- | builtin.c | 9 | ||||
-rw-r--r-- | execute.c | 12 | ||||
-rw-r--r-- | jv.h | 1 | ||||
-rw-r--r-- | jv_print.c | 16 | ||||
-rw-r--r-- | tests/all.test | 12 |
5 files changed, 44 insertions, 6 deletions
@@ -22,17 +22,22 @@ static jv type_error(jv bad, const char* msg) { - jv err = jv_invalid_with_msg(jv_string_fmt("%s %s", + char errbuf[15]; + jv err = jv_invalid_with_msg(jv_string_fmt("%s (%s) %s", jv_kind_name(jv_get_kind(bad)), + jv_dump_string_trunc(jv_copy(bad), errbuf, sizeof(errbuf)), msg)); jv_free(bad); return err; } static jv type_error2(jv bad1, jv bad2, const char* msg) { - jv err = jv_invalid_with_msg(jv_string_fmt("%s and %s %s", + char errbuf1[15],errbuf2[15]; + jv err = jv_invalid_with_msg(jv_string_fmt("%s (%s) and %s (%s) %s", jv_kind_name(jv_get_kind(bad1)), + jv_dump_string_trunc(jv_copy(bad1), errbuf1, sizeof(errbuf1)), jv_kind_name(jv_get_kind(bad2)), + jv_dump_string_trunc(jv_copy(bad2), errbuf2, sizeof(errbuf2)), msg)); jv_free(bad1); jv_free(bad2); @@ -423,8 +423,10 @@ jv jq_next(jq_state *jq) { stack_push(jq, jv_object_set(objv, k, v)); stack_push(jq, stktop); } else { - set_error(jq, jv_invalid_with_msg(jv_string_fmt("Cannot use %s as object key", - jv_kind_name(jv_get_kind(k))))); + char errbuf[15]; + set_error(jq, jv_invalid_with_msg(jv_string_fmt("Cannot use %s (%s) as object key", + jv_kind_name(jv_get_kind(k)), + jv_dump_string_trunc(jv_copy(k), errbuf, sizeof(errbuf))))); jv_free(stktop); jv_free(v); jv_free(k); @@ -634,9 +636,11 @@ jv jq_next(jq_state *jq) { } else { assert(opcode == EACH || opcode == EACH_OPT); if (opcode == EACH) { + char errbuf[15]; set_error(jq, - jv_invalid_with_msg(jv_string_fmt("Cannot iterate over %s", - jv_kind_name(jv_get_kind(container))))); + jv_invalid_with_msg(jv_string_fmt("Cannot iterate over %s (%s)", + jv_kind_name(jv_get_kind(container)), + jv_dump_string_trunc(jv_copy(container), errbuf, sizeof(errbuf))))); } keep_going = 0; } @@ -171,6 +171,7 @@ void jv_dumpf(jv, FILE *f, int flags); void jv_dump(jv, int flags); void jv_show(jv, int flags); jv jv_dump_string(jv, int flags); +char *jv_dump_string_trunc(jv x, char *outbuf, size_t bufsize); enum { JV_PARSE_SEQ = 1, @@ -313,3 +313,19 @@ jv jv_dump_string(jv x, int flags) { jvp_dtoa_context_free(&C); return s; } + +char *jv_dump_string_trunc(jv x, char *outbuf, size_t bufsize) { + x = jv_dump_string(x,0); + const char* p = jv_string_value(x); + const size_t len = strlen(p); + strncpy(outbuf, p, bufsize); + outbuf[bufsize - 1] = 0; + if (len > bufsize - 1 && bufsize >= 4) { + // Indicate truncation with '...' + outbuf[bufsize - 2]='.'; + outbuf[bufsize - 3]='.'; + outbuf[bufsize - 4]='.'; + } + jv_free(x); + return outbuf; +} diff --git a/tests/all.test b/tests/all.test index 106afaa4..950801ab 100644 --- a/tests/all.test +++ b/tests/all.test @@ -1173,3 +1173,15 @@ import "test_bind_order" as check; check::check null true +try -. catch . +"very-long-string" +"string (\"very-long-...) cannot be negated" + +try join(",") catch . +["1",2] +"string (\",\") and number (2) cannot be added" + +try join(",") catch . +["1","2",{"a":{"b":{"c":33}}}] +"string (\",\") and object ({\"a\":{\"b\":{...) cannot be added" + |