test: hectic C: templater interpolation
This commit is contained in:
@@ -2484,6 +2484,83 @@ char *template_node_to_debug_str__(POSITION_INFO_DECLARATION, Arena *arena, cons
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *template_node_to_json_str__(POSITION_INFO_DECLARATION, Arena *arena, const TemplateNode *node, int depth) {
|
||||||
|
if (!node) return arena_strncpy__(POSITION_INFO, arena, "", 0);
|
||||||
|
|
||||||
|
if (depth > TEMPLATE_NODE_MAX_DEBUG_DEPTH) {
|
||||||
|
return arena_strncpy__(POSITION_INFO, arena, "...", 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use a temporary buffer on the stack for building the string
|
||||||
|
char temp_buf[MEM_MiB];
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
#define APPEND(...) do { \
|
||||||
|
int written = snprintf(temp_buf + len, sizeof(temp_buf) - len, ##__VA_ARGS__); \
|
||||||
|
if (written < 0) return NULL; \
|
||||||
|
len += written; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
if (depth == 0) {
|
||||||
|
APPEND("[");
|
||||||
|
}
|
||||||
|
|
||||||
|
APPEND("{\"type\":\"%s\",", template_node_type_to_string(node->type));
|
||||||
|
|
||||||
|
switch (node->type) {
|
||||||
|
case TEMPLATE_NODE_SECTION:
|
||||||
|
APPEND("\"content\":{\"iterator\":\"%s\",\"collection\"=\"%s\"}",
|
||||||
|
node->value.section.iterator,
|
||||||
|
node->value.section.collection);
|
||||||
|
char *body_str = template_node_to_json_str__(POSITION_INFO, arena, node->value.section.body, depth + 1);
|
||||||
|
if (body_str) {
|
||||||
|
APPEND(",\"body\":%s", body_str);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TEMPLATE_NODE_INTERPOLATE:
|
||||||
|
APPEND("\"content\":{\"key\":\"%s\"}", node->value.interpolate.key);
|
||||||
|
break;
|
||||||
|
case TEMPLATE_NODE_EXECUTE:
|
||||||
|
APPEND("\"content\":{\"code\":\"%s\"}", node->value.execute.code);
|
||||||
|
break;
|
||||||
|
case TEMPLATE_NODE_INCLUDE:
|
||||||
|
APPEND("\"content\":{\"key\":\"%s\"}", node->value.include.key);
|
||||||
|
break;
|
||||||
|
case TEMPLATE_NODE_TEXT:
|
||||||
|
APPEND("\"content\":{\"content\":\"%s\"}", node->value.text.content);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->children) {
|
||||||
|
APPEND(",\"children\":[");
|
||||||
|
char *child_str = template_node_to_json_str__(POSITION_INFO, arena, node->children, depth + 1);
|
||||||
|
if (child_str) {
|
||||||
|
APPEND(",%s", child_str);
|
||||||
|
}
|
||||||
|
APPEND("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
APPEND("}");
|
||||||
|
|
||||||
|
if (node->next) {
|
||||||
|
char *next_str = template_node_to_json_str__(POSITION_INFO, arena, node->next, depth + 1);
|
||||||
|
if (next_str) {
|
||||||
|
APPEND(",%s", next_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depth == 0) {
|
||||||
|
APPEND("]");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the final string to arena-allocated memory
|
||||||
|
char *result = arena_strncpy__(POSITION_INFO, arena, temp_buf, len);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------
|
// ---------
|
||||||
// -- End --
|
// -- End --
|
||||||
// ---------
|
// ---------
|
||||||
|
|||||||
@@ -623,6 +623,8 @@ char* json_to_debug_str__(const char* file, const char* func, int line, Arena *a
|
|||||||
|
|
||||||
char *json_to_pretty_str__(const char* file, const char* func, int line, Arena *arena, const Json * const item, int indent_level);
|
char *json_to_pretty_str__(const char* file, const char* func, int line, Arena *arena, const Json * const item, int indent_level);
|
||||||
|
|
||||||
|
#define JSON_TO_PRETTY_STR(arena, json) json_to_pretty_str__(__FILE__, __func__, __LINE__, arena, json, 0)
|
||||||
|
|
||||||
// Prettify a flat debug string by adding line breaks and structure
|
// Prettify a flat debug string by adding line breaks and structure
|
||||||
char *debug_to_pretty_str__(const char* file, const char* func, int line, Arena *arena, const char *flat_str);
|
char *debug_to_pretty_str__(const char* file, const char* func, int line, Arena *arena, const char *flat_str);
|
||||||
#define debug_to_pretty_str(arena, str) debug_to_pretty_str__(__FILE__, __func__, __LINE__, arena, str)
|
#define debug_to_pretty_str(arena, str) debug_to_pretty_str__(__FILE__, __func__, __LINE__, arena, str)
|
||||||
@@ -764,6 +766,8 @@ TemplateConfig template_default_config__(const char *file, const char *func, int
|
|||||||
|
|
||||||
char *template_node_to_debug_str__(const char *file, const char *func, int line, Arena *arena, const char *name, const TemplateNode *self, PtrSet *visited);
|
char *template_node_to_debug_str__(const char *file, const char *func, int line, Arena *arena, const char *name, const TemplateNode *self, PtrSet *visited);
|
||||||
|
|
||||||
|
char *template_node_to_json_str__(const char *file, const char *func, int line, Arena *arena, const TemplateNode *node, int depth);
|
||||||
|
|
||||||
#define template_parse(arena, s, config) template_parse__(__FILE__, __func__, __LINE__, arena, s, config)
|
#define template_parse(arena, s, config) template_parse__(__FILE__, __func__, __LINE__, arena, s, config)
|
||||||
|
|
||||||
#define template_default_config() template_default_config__(__FILE__, __func__, __LINE__)
|
#define template_default_config() template_default_config__(__FILE__, __func__, __LINE__)
|
||||||
@@ -771,4 +775,7 @@ char *template_node_to_debug_str__(const char *file, const char *func, int line,
|
|||||||
#define TEMPLATE_NODE_TO_DEBUG_STR(arena, name, node) \
|
#define TEMPLATE_NODE_TO_DEBUG_STR(arena, name, node) \
|
||||||
template_node_to_debug_str__(__FILE__, __func__, __LINE__, arena, name, node, ptrset_init(arena))
|
template_node_to_debug_str__(__FILE__, __func__, __LINE__, arena, name, node, ptrset_init(arena))
|
||||||
|
|
||||||
|
#define TEMPLATE_NODE_TO_JSON_STR(arena, node) \
|
||||||
|
template_node_to_json_str__(__FILE__, __func__, __LINE__, arena, node, 0)
|
||||||
|
|
||||||
#endif // EPRINTF_H
|
#endif // EPRINTF_H
|
||||||
@@ -118,16 +118,16 @@ static void test_arena_reset_reuse(Arena *arena) {
|
|||||||
// assert(strcmp(debug_str, "struct Json root = {type = JSON_OBJECT, key = \"key\", value = struct JsonValue = {string = \"value\"}, next = NULL}") == 0);
|
// assert(strcmp(debug_str, "struct Json root = {type = JSON_OBJECT, key = \"key\", value = struct JsonValue = {string = \"value\"}, next = NULL}") == 0);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
static void test_debug_str_to_json(Arena *arena) {
|
//static void test_debug_str_to_json(Arena *arena) {
|
||||||
const char *debug_str = "struct SomeStruct struct_name = {name = \"value\", next = NULL, value = 123}";
|
// const char *debug_str = "struct SomeStruct struct_name = {name = \"value\", next = NULL, value = 123}";
|
||||||
JsonResult result = DEBUG_STR_TO_JSON(arena, &debug_str);
|
// JsonResult result = DEBUG_STR_TO_JSON(arena, &debug_str);
|
||||||
if (IS_RESULT_ERROR(result)) {
|
// if (IS_RESULT_ERROR(result)) {
|
||||||
raise_exception("DEBUG_STR_TO_JSON: %s", &RESULT_ERROR_MESSAGE(result));
|
// raise_exception("DEBUG_STR_TO_JSON: %s", &RESULT_ERROR_MESSAGE(result));
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
raise_notice("result: %s", JSON_TO_DEBUG_STR(arena, "result", &RESULT_SOME_VALUE(result)));
|
// raise_notice("result: %s", JSON_TO_DEBUG_STR(arena, "result", &RESULT_SOME_VALUE(result)));
|
||||||
assert(RESULT_SOME_VALUE(result).type == JSON_OBJECT);
|
// assert(RESULT_SOME_VALUE(result).type == JSON_OBJECT);
|
||||||
}
|
//}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
printf("%sRunning %s%s%s\n", OPTIONAL_COLOR(COLOR_GREEN), OPTIONAL_COLOR(COLOR_CYAN), __FILE__, OPTIONAL_COLOR(COLOR_RESET));
|
printf("%sRunning %s%s%s\n", OPTIONAL_COLOR(COLOR_GREEN), OPTIONAL_COLOR(COLOR_CYAN), __FILE__, OPTIONAL_COLOR(COLOR_RESET));
|
||||||
@@ -154,8 +154,8 @@ int main(void) {
|
|||||||
test_arena_reset_reuse(&arena);
|
test_arena_reset_reuse(&arena);
|
||||||
//arena_reset(&arena);
|
//arena_reset(&arena);
|
||||||
//test_json_to_debug_str(&arena);
|
//test_json_to_debug_str(&arena);
|
||||||
arena_reset(&arena);
|
//arena_reset(&arena);
|
||||||
test_debug_str_to_json(&arena);
|
//test_debug_str_to_json(&arena);
|
||||||
|
|
||||||
arena_free(&arena);
|
arena_free(&arena);
|
||||||
logger_free();
|
logger_free();
|
||||||
|
|||||||
@@ -4,18 +4,38 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "hectic.h"
|
#include "hectic.h"
|
||||||
|
|
||||||
#define ARENA_SIZE 1024 * 1024
|
#define ARENA_SIZE MEM_MiB
|
||||||
|
|
||||||
|
#define TEST_TEMPLATE_NODE_TO_DEBUG_STR \
|
||||||
|
"struct TemplateNode root = {\n" \
|
||||||
|
" enum type = TEXT 0 ,\n" \
|
||||||
|
" union TemplateValue value = {\n" \
|
||||||
|
" struct TemplateTextValue text = {\n" \
|
||||||
|
" content = %p \"Hello\"\n" \
|
||||||
|
" } %p\n" \
|
||||||
|
" } %p,\n" \
|
||||||
|
" struct TemplateNode children = NULL,\n" \
|
||||||
|
" struct TemplateNode next = {\n" \
|
||||||
|
" enum type = INTERPOLATE 1 ,\n" \
|
||||||
|
" union TemplateValue value = {\n" \
|
||||||
|
" struct TemplateInterpolateValue interpolate = {\n" \
|
||||||
|
" key = %p \"name\"\n" \
|
||||||
|
" } %p\n" \
|
||||||
|
" } %p,\n" \
|
||||||
|
" struct TemplateNode children = NULL,\n" \
|
||||||
|
" struct TemplateNode next = {\n" \
|
||||||
|
" enum type = TEXT 0 ,\n" \
|
||||||
|
" union TemplateValue value = {\n" \
|
||||||
|
" struct TemplateTextValue text = {\n" \
|
||||||
|
" content = %p \"!\"\n" \
|
||||||
|
" } %p\n" \
|
||||||
|
" } %p,\n" \
|
||||||
|
" struct TemplateNode children = NULL,\n" \
|
||||||
|
" struct TemplateNode next = NULL\n" \
|
||||||
|
" } %p\n" \
|
||||||
|
" } %p\n" \
|
||||||
|
"} %p\n"
|
||||||
|
|
||||||
//static char *remove_all_spaces(char *s) {
|
|
||||||
// char *new_s = NULL;
|
|
||||||
// while (*s) {
|
|
||||||
// if (*s != ' ' && *s != '\t' && *s != '\n') {
|
|
||||||
// new_s = s;
|
|
||||||
// }
|
|
||||||
// s++;
|
|
||||||
// }
|
|
||||||
// return new_s;
|
|
||||||
//}
|
|
||||||
|
|
||||||
static void test_template_node_to_debug_str(Arena *arena) {
|
static void test_template_node_to_debug_str(Arena *arena) {
|
||||||
TemplateNode *root = arena_alloc(arena, sizeof(TemplateNode));
|
TemplateNode *root = arena_alloc(arena, sizeof(TemplateNode));
|
||||||
@@ -30,57 +50,40 @@ static void test_template_node_to_debug_str(Arena *arena) {
|
|||||||
root->next->next->type = TEMPLATE_NODE_TEXT;
|
root->next->next->type = TEMPLATE_NODE_TEXT;
|
||||||
root->next->next->value.text.content = arena_strncpy(arena, "!", 1);
|
root->next->next->value.text.content = arena_strncpy(arena, "!", 1);
|
||||||
|
|
||||||
char *debug_str = TEMPLATE_NODE_TO_DEBUG_STR(arena, "root", root);
|
char *debug_str = debug_to_pretty_str(arena, TEMPLATE_NODE_TO_DEBUG_STR(arena, "root", root));
|
||||||
|
raise_log("debug_str: \n%s", debug_str);
|
||||||
|
|
||||||
raise_notice("debug_str: %s", debug_str);
|
{ // some debug output
|
||||||
char *expected;
|
Arena *debug_arena = DISPOSABLE_ARENA;
|
||||||
//sprintf(expected, "struct TemplateNode root = {enum type = TEXT 0, union TemplateValue value = {struct TemplateTextValue text = {content = %p \"Hello\"} %p} %p, struct TemplateNode children = NULL, struct TemplateNode next = {enum type = INTERPOLATE 1, union TemplateValue value = {struct TemplateInterpolateValue interpolate = {key = %p \"name\"} %p} %p, struct TemplateNode children = NULL, struct TemplateNode next = {enum type = TEXT 0, union TemplateValue value = {struct TemplateTextValue text = {content = %p \"!\"} %p} %p, struct TemplateNode children = NULL, struct TemplateNode next = NULL} %p} %p} %p",
|
const char *json_str = TEMPLATE_NODE_TO_JSON_STR(debug_arena, root);
|
||||||
// root.value.text.content,
|
Json *json = json_parse(debug_arena, &json_str);
|
||||||
// root.value.text,
|
raise_notice("json_str: \n%s", JSON_TO_PRETTY_STR(debug_arena, json));
|
||||||
// root.value,
|
}
|
||||||
// root.next.value.interpolate.key,
|
|
||||||
// root.next.value.interpolate,
|
|
||||||
// root.next.value,
|
|
||||||
|
|
||||||
|
char *expected_debug_str = arena_alloc(arena, MEM_KiB);
|
||||||
|
sprintf(expected_debug_str, TEST_TEMPLATE_NODE_TO_DEBUG_STR,
|
||||||
|
(void*)root->value.text.content,
|
||||||
|
(void*)&root->value.text,
|
||||||
|
(void*)&root->value,
|
||||||
|
(void*)root->next->value.interpolate.key,
|
||||||
|
(void*)&root->next->value.interpolate,
|
||||||
|
(void*)&root->next->value,
|
||||||
|
(void*)root->next->next->value.text.content,
|
||||||
|
(void*)&root->next->next->value.text,
|
||||||
|
(void*)&root->next->next->value,
|
||||||
|
(void*)root->next->next,
|
||||||
|
(void*)root->next,
|
||||||
|
(void*)root
|
||||||
|
);
|
||||||
|
|
||||||
//assert(strcmp(
|
raise_log("expected_debug_str: \n%s", expected_debug_str);
|
||||||
// remove_all_spaces(debug_str),
|
|
||||||
// remove_all_spaces(""
|
assert(strcmp(debug_str, expected_debug_str) == 0);
|
||||||
// "["
|
|
||||||
// " {"
|
|
||||||
// " \"type\":\"TEXT\","
|
|
||||||
// " \"content\":{"
|
|
||||||
// " \"content\":\"Hello\""
|
|
||||||
// " }"
|
|
||||||
// " },"
|
|
||||||
// " {"
|
|
||||||
// " \"type\":\"INTERPOLATE\","
|
|
||||||
// " \"content\":{"
|
|
||||||
// " \"key\":\"name\""
|
|
||||||
// " }"
|
|
||||||
// " },"
|
|
||||||
// " {"
|
|
||||||
// " \"type\":\"TEXT\","
|
|
||||||
// " \"content\":{"
|
|
||||||
// " \"content\":\"!\""
|
|
||||||
// " }"
|
|
||||||
// " }"
|
|
||||||
// "]")) == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//static void test_template_parse(Arena *arena, TemplateConfig *config) {
|
|
||||||
// const char *template = "Hello {% name %}!";
|
|
||||||
// TemplateResult *result = template_parse(arena, &template, config);
|
|
||||||
//
|
|
||||||
// Arena *debug_arena = DISPOSABLE_ARENA;
|
|
||||||
// const char *debug_str = template_node_to_debug_str(debug_arena, &result->Result.node);
|
|
||||||
// raise_notice("debug_str: %s", debug_str);
|
|
||||||
// raise_notice("result: %s", json_to_pretty_str(debug_arena, json_parse(debug_arena, &debug_str)));
|
|
||||||
// assert(result->type == TEMPLATE_RESULT_NODE);
|
|
||||||
//}
|
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
printf("%sRunning %s%s%s\n", OPTIONAL_COLOR(COLOR_GREEN), OPTIONAL_COLOR(COLOR_CYAN), __FILE__, OPTIONAL_COLOR(COLOR_RESET));
|
printf("%sRunning %s%s%s\n", OPTIONAL_COLOR(COLOR_GREEN), OPTIONAL_COLOR(COLOR_CYAN), __FILE__, OPTIONAL_COLOR(COLOR_RESET));
|
||||||
|
debug_color_mode = COLOR_MODE_DISABLE;
|
||||||
logger_init();
|
logger_init();
|
||||||
|
|
||||||
Arena arena = arena_init(ARENA_SIZE);
|
Arena arena = arena_init(ARENA_SIZE);
|
||||||
|
|||||||
Reference in New Issue
Block a user