From e079370a92766181ff5281c5d6cea03a1fce5b93 Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Fri, 5 Jan 2024 22:51:33 +0100 Subject: initial release Signed-off-by: Anna (navi) Figueiredo Gomes --- src/print.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/print.c (limited to 'src/print.c') diff --git a/src/print.c b/src/print.c new file mode 100644 index 0000000..4b5c72c --- /dev/null +++ b/src/print.c @@ -0,0 +1,112 @@ +#include +#include +#include + +static bool append_printf(char **dest, size_t *size, size_t *index, const char *fmt, ...) { + va_list ap; + int len; + + va_start(ap, fmt); + len = vsnprintf(*dest + *index, *size - *index, fmt, ap); + va_end(ap); + + if (*index + len >= *size) { + *size = *size * 2 > *size + len + 1 ? *size * 2 : *size + len + 1; + *dest = realloc(*dest, *size); + + va_start(ap, fmt); + len = vsnprintf(*dest + *index, *size - *index, fmt, ap); + va_end(ap); + } + + // TODO: Fix this ugly cast + if (len < 0 || len >= (ssize_t)*size) { + free(*dest); + *dest = ""; + return false; + } + + *index += len; + + return true; +} + +void print_item(struct json *json, char **str, size_t *size, size_t *index) { + switch (json->type) { + case JSON_OBJECT: + append_printf(str, size, index, "{"); + for (struct json *j = json->children->items[0]; j; j = j->next) { + append_printf(str, size, index, "\"%s\":", j->key ? j->key : "(null)"); + print_item(j, str, size, index); + if (j->next) + append_printf(str, size, index, ","); + } + append_printf(str, size, index, "}"); + break; + case JSON_ARRAY: + append_printf(str, size, index, "["); + for (size_t i = 0; i < json->children->nitems; i++) { + struct json *j = json->children->items[i]; + print_item(j, str, size, index); + if (i != json->children->nitems - 1) + append_printf(str, size, index, ","); + } + append_printf(str, size, index, "]"); + break; + case JSON_NUMBER: + append_printf(str, size, index, "%lf", json->num); + break; + case JSON_TRUE: + append_printf(str, size, index, "true"); + break; + case JSON_FALSE: + append_printf(str, size, index, "false"); + break; + case JSON_NULL: + append_printf(str, size, index, "null"); + break; + case JSON_STRING: + append_printf(str, size, index, "\""); + for (char *ptr = json->string; *ptr != '\0'; ptr++) { + switch (*ptr) { + case '\\': + append_printf(str, size, index, "%s", "\\\\"); + break; + case '\"': + append_printf(str, size, index, "%s", "\\\""); + break; + case '\n': + append_printf(str, size, index, "%s", "\\n"); + break; + case '\f': + append_printf(str, size, index, "%s", "\\f"); + break; + case '\b': + append_printf(str, size, index, "%s", "\\b"); + break; + case '\r': + append_printf(str, size, index, "%s", "\\r"); + break; + case '\t': + append_printf(str, size, index, "%s", "\\t"); + break; + default: + append_printf(str, size, index, "%c", *ptr); + break; + } + } + append_printf(str, size, index, "\""); + break; + case JSON_INVALID: + break; + } +} + +char *json_print(struct json *json) { + size_t size = 1024; + size_t index = 0; + char *str = calloc(size, sizeof(char)); + print_item(json, &str, &size, &index); + return str; +} + -- cgit v1.2.3