fix: json eval

This commit is contained in:
2025-03-22 04:15:58 +00:00
parent 27e42e9010
commit aeea41b0e1
4 changed files with 46 additions and 37 deletions

View File

@@ -267,19 +267,24 @@ Json *json_parse(Arena *arena, const char **s) {
return json_parse_value__(s, arena);
}
/* Minimal JSON printer.
For simplicity, a fixed-size buffer is used.
In production youd dynamically size or use the arena. */
char *json_print(Arena *arena, Json *item) {
char *json_to_string(Arena *arena, Json *item) {
return json_to_string_with_opts(arena, item, 0);
}
/* Minimal JSON printer with raw output option.
When raw is non-zero and the item is a JSON_STRING, it is printed without quotes.
*/
char *json_to_string_with_opts(Arena *arena, Json *item, int raw) {
char *out = arena_alloc(arena, 1024);
if (!out) return NULL;
if (!out)
return NULL;
char *ptr = out;
if (item->type == JSON_OBJECT) {
ptr += sprintf(ptr, "{");
Json *child = item->child;
while (child) {
ptr += sprintf(ptr, "\"%s\":", child->key ? child->key : "");
char *child_str = json_print(arena, child);
char *child_str = json_to_string_with_opts(arena, child, raw);
ptr += sprintf(ptr, "%s", child_str);
if (child->next)
ptr += sprintf(ptr, ",");
@@ -290,7 +295,7 @@ char *json_print(Arena *arena, Json *item) {
ptr += sprintf(ptr, "[");
Json *child = item->child;
while (child) {
char *child_str = json_print(arena, child);
char *child_str = json_to_string_with_opts(arena, child, raw);
ptr += sprintf(ptr, "%s", child_str);
if (child->next)
ptr += sprintf(ptr, ",");
@@ -298,13 +303,16 @@ char *json_print(Arena *arena, Json *item) {
}
sprintf(ptr, "]");
} else if (item->type == JSON_STRING) {
sprintf(out, "\"%s\"", item->string);
if (raw)
sprintf(ptr, "%s", item->string);
else
sprintf(ptr, "\"%s\"", item->string);
} else if (item->type == JSON_NUMBER) {
sprintf(out, "%g", item->number);
sprintf(ptr, "%g", item->number);
} else if (item->type == JSON_BOOL) {
sprintf(out, item->boolean ? "true" : "false");
sprintf(ptr, item->boolean ? "true" : "false");
} else if (item->type == JSON_NULL) {
sprintf(out, "null");
sprintf(ptr, "null");
}
return out;
}

View File

@@ -226,10 +226,9 @@ typedef struct Json {
Json *json_parse(Arena *arena, const char **s);
/* Minimal JSON printer.
For simplicity, a fixed-size buffer is used.
In production youd dynamically size or use the arena. */
char *json_print(Arena *arena, Json *item);
char *json_to_string(Arena *arena, Json *item);
char *json_to_string_with_opts(Arena *arena, Json *item, int raw);
/* Retrieve an object item by key (case-sensitive) */
Json *json_get_object_item(Json *object, const char *key);

View File

@@ -59,7 +59,7 @@ static void test_print_json_object(void) {
Arena arena = arena_init(ARENA_SIZE);
const char *json = "{\"key\":\"value\", \"num\":3.14}";
Json *root = json_parse(&arena, &json);
char *printed = json_print(&arena, root);
char *printed = json_to_string(&arena, root);
assert(strstr(printed, "\"key\":") != NULL);
assert(strstr(printed, "\"value\"") != NULL);
assert(strstr(printed, "\"num\":") != NULL);
@@ -72,7 +72,7 @@ static void test_print_json_number(void) {
Arena arena = arena_init(ARENA_SIZE);
const char *json = "123.456";
Json *root = json_parse(&arena, &json);
char *printed = json_print(&arena, root);
char *printed = json_to_string(&arena, root);
double val = atof(printed);
assert(val == 123.456);
arena_free(&arena);
@@ -83,7 +83,7 @@ static void test_print_json_string(void) {
Arena arena = arena_init(ARENA_SIZE);
const char *json = "\"test string\"";
Json *root = json_parse(&arena, &json);
char *printed = json_print(&arena, root);
char *printed = json_to_string(&arena, root);
assert(strcmp(printed, "\"test string\"") == 0);
arena_free(&arena);
}
@@ -113,11 +113,11 @@ static void test_arena_reset_reuse(void) {
Arena arena = arena_init(ARENA_SIZE);
const char *json1 = "{\"key\":\"value\"}";
Json *root1 = json_parse(&arena, &json1);
char *printed1 = json_print(&arena, root1);
char *printed1 = json_to_string(&arena, root1);
arena_reset(&arena);
const char *json2 = "\"another test\"";
Json *root2 = json_parse(&arena, &json2);
char *printed2 = json_print(&arena, root2);
char *printed2 = json_to_string(&arena, root2);
assert(strcmp(printed2, "\"another test\"") == 0);
arena_free(&arena);
}