diff options
-rw-r--r-- | jim-json.c | 12 | ||||
-rw-r--r-- | tests/json.test | 16 |
2 files changed, 26 insertions, 2 deletions
@@ -38,6 +38,8 @@ typedef enum { } json_schema_t; struct json_state { + Jim_Obj *fileNameObj; + int line; Jim_Obj *nullObj; const char *json; jsmntok_t *tok; @@ -219,6 +221,7 @@ json_decode_dump_value(Jim_Interp *interp, struct json_state *state, Jim_Obj *li Jim_Obj *elem; int len = t->end - t->start; const char *p = state->json + t->start; + int set_source = 1; if (t->type == JSMN_STRING) { /* Do we need to process backslash escapes? */ if (state->need_subst == 0 && memchr(p, '\\', len) != NULL) { @@ -227,6 +230,7 @@ json_decode_dump_value(Jim_Interp *interp, struct json_state *state, Jim_Obj *li elem = Jim_NewStringObj(interp, p, len); } else if (p[0] == 'n') { /* null */ elem = state->nullObj; + set_source = 0; } else if (p[0] == 'I') { elem = Jim_NewStringObj(interp, "Inf", -1); } else if (p[0] == '-' && p[1] == 'I') { @@ -234,6 +238,10 @@ json_decode_dump_value(Jim_Interp *interp, struct json_state *state, Jim_Obj *li } else { /* number, true or false */ elem = Jim_NewStringObj(interp, p, len); } + if (set_source) { + /* Note we need to subtract 1 because both are 1-based values */ + Jim_SetSourceInfo(interp, elem, state->fileNameObj, state->line + t->line - 1); + } Jim_ListAppendElement(interp, list, elem); state->tok++; @@ -371,6 +379,10 @@ json_decode(Jim_Interp *interp, int argc, Jim_Obj *const argv[]) Jim_SetResultString(interp, "empty JSON string", -1); goto done; } + + /* Save any source information from the original string */ + state.fileNameObj = Jim_GetSourceInfo(interp, argv[argc - 1], &state.line); + if ((tokens = json_decode_tokenize(interp, state.json, len)) == NULL) { goto done; } diff --git a/tests/json.test b/tests/json.test index 78a19fa..09c002c 100644 --- a/tests/json.test +++ b/tests/json.test @@ -3,7 +3,8 @@ source [file dirname [info script]]/testing.tcl needs cmd json::decode json needs cmd json::encode json -set json { +# Create a json string as though it was read from data.json +set json [info source { { "fossil":"9c65b5432e4aeecf3556e5550c338ce93fd861cc", "timestamp":1435827337, @@ -24,7 +25,7 @@ set json { "tags":["trunk"] }] } -}} +}} data.json 1] test json-decode-001 {top level keys} { lsort [dict keys [json::decode $json]] @@ -122,6 +123,17 @@ test json-3.4 {-index array with -schema 2} { } "{outer {0 {key value} 1 {key2 value2}}}\ {obj outer {mixed {obj key str} {obj key2 str}}}" +test json-4.1 {source info preserved} -body { + info source [dict get [json::decode $json] fossil] +} -result {data.json 3} + +test json-4.2 {source info preserved} -body { + info source [dict get [json::decode $json] procTimeUs] +} -result {data.json 6} + +test json-4.3 {source info preserved} -body { + info source [dict get [lindex [dict get [json::decode $json] payload timeline] 0] comment] +} -result {data.json 17} unset -nocomplain json |