Compare commits

...

4 Commits

2 changed files with 135 additions and 25 deletions

View File

@ -23,6 +23,7 @@
*/
#include <HttpRouter.h>
#include <Http.h>
#include <Memory.h>
#include <HashMap.h>
#include <Str.h>
@ -228,12 +229,15 @@ HttpRouterRoute(HttpRouter * router, char *path, void *args, void **ret)
regmatch_t pmatch[REG_MAX_SUB];
pathPart = HttpUrlDecode(pathPart);
i = 0;
while (HashMapIterateReentrant(node->children, &key, (void **) &val, &i))
{
if (regexec(&val->regex, pathPart, REG_MAX_SUB, pmatch, 0) == 0)
{
Free(pathPart);
break;
}
@ -243,6 +247,7 @@ HttpRouterRoute(HttpRouter * router, char *path, void *args, void **ret)
if (!val)
{
exec = NULL;
Free(pathPart);
break;
}
@ -263,12 +268,14 @@ HttpRouterRoute(HttpRouter * router, char *path, void *args, void **ret)
substr = StrSubstr(pathPart, cpmatch.rm_so, cpmatch.rm_eo);
if (pmatch[i].rm_so == -1)
{
Free(pathPart);
break;
}
ArrayAdd(matches, substr);
}
}
Free(pathPart);
}
Free(path);
}

View File

@ -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)
{
@ -309,7 +336,7 @@ Main(Array * args)
ArrayAdd(requiredTypes, StrDuplicate(type));
}
if (StrEquals(typeType, "struct"))
if (StrEquals(typeType, "struct") || StrEquals(typeType, "union"))
{
typeFieldsVal = HashMapGet(typeObj, "fields");
if (JsonValueType(typeFieldsVal) != JSON_OBJECT)
@ -462,6 +489,7 @@ Main(Array * args)
StreamPrintf(headerFile, "#include <Cytoplasm/Array.h>\n");
StreamPrintf(headerFile, "#include <Cytoplasm/HashMap.h>\n");
StreamPrintf(headerFile, "#include <Cytoplasm/Int64.h>\n");
StreamPrintf(headerFile, "#include <Cytoplasm/Json.h>\n");
StreamPutc(headerFile, '\n');
@ -481,6 +509,7 @@ Main(Array * args)
HashMap *fields;
char *field;
char *info;
HashMap *fieldDesc;
if (!type)
@ -497,9 +526,29 @@ Main(Array * args)
fields = JsonValueAsObject(JsonGet(types, 2, type, "fields"));
StreamPrintf(headerFile, "typedef %s %s\n{\n", typeType, type);
if (StrEquals(typeType, "struct"))
if (StrEquals(typeType, "union"))
{
Array *keys = HashMapKeys(fields);
size_t j;
StreamPrintf(headerFile, "typedef enum %sType\n{\n", type);
for (j = 0; j < ArraySize(keys); j++)
{
char *key = ArrayGet(keys, j);
char *comma = j == ArraySize(keys) - 1 ? "\n" : ",\n";
StreamPrintf(headerFile, " %s_AS_%s%s", type, key, comma);
}
ArrayFree(keys);
StreamPrintf(headerFile, "} %sType;\n\n", type);
}
info = StrEquals(typeType, "union") ? "Union" : "";
StreamPrintf(headerFile, "typedef %s %s%s\n{\n", typeType, type, info);
if (StrEquals(typeType, "struct") || StrEquals(typeType, "union"))
{
while (HashMapIterate(fields, &field, (void **) &fieldDesc))
{
@ -542,7 +591,15 @@ Main(Array * args)
StreamPrintf(headerFile, " %s %s;\n", cType, field);
}
StreamPrintf(headerFile, "} %s;\n\n", type);
StreamPrintf(headerFile, "} %s%s;\n\n", type, info);
if (StrEquals(typeType, "union"))
{
StreamPrintf(headerFile, "typedef struct %s {\n", type);
StreamPrintf(headerFile, " %sType type;\n", type);
StreamPrintf(headerFile, " %s%s value;\n", type, info);
StreamPrintf(headerFile, "} %s;\n\n", type);
}
}
else if (StrEquals(typeType, "enum"))
{
@ -805,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)
{
@ -1075,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);