From 8423712c911085b5f0cf6fe51ce87d4b58e3db96 Mon Sep 17 00:00:00 2001 From: lda Date: Mon, 11 Dec 2023 21:24:09 +0100 Subject: [PATCH] [MOD/WIP] Start actually parsing unions in j2s. --- tools/j2s.c | 119 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 96 insertions(+), 23 deletions(-) diff --git a/tools/j2s.c b/tools/j2s.c index c3cbdd1..a0eea3f 100644 --- a/tools/j2s.c +++ b/tools/j2s.c @@ -45,6 +45,33 @@ Trim(char c, char *str) return str; } +static char * +JsonTypeFunction(JsonType jsonType) +{ + char *func; + + switch (jsonType) + { + case JSON_STRING: + func = "String"; + break; + case JSON_INTEGER: + func = "Integer"; + break; + case JSON_FLOAT: + func = "Float"; + break; + case JSON_BOOLEAN: + func = "Boolean"; + break; + default: + /* Should not happen */ + func = NULL; + break; + } + return func; +} + static JsonType TypeToJsonType(char *type) { @@ -462,6 +489,7 @@ Main(Array * args) StreamPrintf(headerFile, "#include \n"); StreamPrintf(headerFile, "#include \n"); StreamPrintf(headerFile, "#include \n"); + StreamPrintf(headerFile, "#include \n"); StreamPutc(headerFile, '\n'); @@ -514,7 +542,7 @@ Main(Array * args) StreamPrintf(headerFile, " %s_AS_%s%s", type, key, comma); } - Free(keys); + ArrayFree(keys); StreamPrintf(headerFile, "} %sType;\n\n", type); } info = StrEquals(typeType, "union") ? "Union" : ""; @@ -565,7 +593,6 @@ Main(Array * args) StreamPrintf(headerFile, "} %s%s;\n\n", type, info); - /* TODO: Add extra "type" enum or something*/ if (StrEquals(typeType, "union")) { StreamPrintf(headerFile, "typedef struct %s {\n", type); @@ -835,27 +862,7 @@ Main(Array * args) } else { - char *func; - - switch (jsonType) - { - case JSON_STRING: - func = "String"; - break; - case JSON_INTEGER: - func = "Integer"; - break; - case JSON_FLOAT: - func = "Float"; - break; - case JSON_BOOLEAN: - func = "Boolean"; - break; - default: - /* Should not happen */ - func = NULL; - break; - } + char *func = JsonTypeFunction(jsonType); if (jsonType == JSON_STRING) { @@ -1105,6 +1112,72 @@ Main(Array * args) StreamPrintf(implFile, "}\n\n"); StreamPutc(headerFile, '\n'); } + else if (StrEquals(typeType, "union")) + { + StreamPrintf(headerFile, "extern int %sFromValue(JsonValue *, %s *, char **);\n", type, type); + StreamPrintf(implFile, "int\n%sFromValue(JsonValue *val, %s *out, char **errp)\n{\n", type, type); + StreamPrintf(implFile, " if (!val || !out)\n"); + StreamPrintf(implFile, " {\n"); + StreamPrintf(implFile, " *errp = \"Invalid values passed to %sFromValue\";\n", type); + StreamPrintf(implFile, " return 0;\n"); + StreamPrintf(implFile, " }\n\n"); + + for (i = 0; i < ArraySize(keys); i++) + { + char *key = ArrayGet(keys, i); + char *fieldType = JsonValueAsString(JsonGet(fields, 2, key, "type")); + int isSimple = StrEquals(fieldType, "string") || + StrEquals(fieldType, "boolean") || + StrEquals(fieldType, "integer") || + StrEquals(fieldType, "float") ; + int ignore = JsonValueAsBoolean(JsonGet(fields, 2, key, "ignore")); + if (isSimple) + { + JsonType actualType = TypeToJsonType(fieldType); + char *func = JsonTypeFunction(actualType); + + StreamPrintf(implFile, " if (JsonValueType(val) == %s)\n", JsonTypeToStr(actualType)); + StreamPrintf(implFile, " {\n"); + StreamPrintf(implFile, " out->type = %s_AS_%s;\n", type, key); + StreamPrintf(implFile, " out->value.%s = JsonValueAs%s(val);\n\n", key, func); + StreamPrintf(implFile, " return 1;\n"); + StreamPrintf(implFile, " }\n"); + continue; + } + if (StrEquals(fieldType, "array")) + { + StreamPrintf(implFile, " if (JsonValueType(val) == JSON_ARRAY)\n"); + StreamPrintf(implFile, " {\n"); + StreamPrintf(implFile, " out->type = %s_AS_%s;\n", type, key); + StreamPrintf(implFile, " out->value.%s = JsonValueAsArray(val);\n\n", key); + StreamPrintf(implFile, " return 1;\n"); + StreamPrintf(implFile, " }\n"); + continue; + } + if (ignore) + { + continue; + } + StreamPrintf(implFile, " if (JsonValueType(val) == JSON_OBJECT)\n"); + StreamPrintf(implFile, " {\n"); + StreamPrintf(implFile, " HashMap *json = JsonValueAsObject(val);\n"); + StreamPrintf(implFile, " if (!%sFromJson(json, &out->value.%s, errp))\n", fieldType, key, fieldType); + StreamPrintf(implFile, " {\n"); + StreamPrintf(implFile, " /* errp is already set */\n"); + StreamPrintf(implFile, " return 0;\n"); + StreamPrintf(implFile, " }\n"); + StreamPrintf(implFile, " out->type = %s_AS_%s;\n", type, key); + StreamPrintf(implFile, " return 1;\n"); + StreamPrintf(implFile, " }\n"); + + /* TODO */ + } + + StreamPrintf(implFile, " \n"); + StreamPrintf(implFile, " *errp = \"Invalid type for %s\";\n", type); + StreamPrintf(implFile, " return 0;\n"); + StreamPrintf(implFile, "}\n"); + } else if (StrEquals(typeType, "enum")) { StreamPrintf(headerFile, "extern int %sFromStr(char *);\n", type);