feat!: many work useles with hemar
This commit is contained in:
47
package/c/hectic/expected.log
Normal file
47
package/c/hectic/expected.log
Normal file
@@ -0,0 +1,47 @@
|
||||
[
|
||||
{
|
||||
"type": "SECTION",
|
||||
"content": {
|
||||
"iterator": "item",
|
||||
"collection": "items"
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "INTERPOLATE",
|
||||
"content": {
|
||||
"key": "name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "TEXT",
|
||||
"content": {
|
||||
"content": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "INTERPOLATE",
|
||||
"content": {
|
||||
"key": "item.name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "TEXT",
|
||||
"content": {
|
||||
"content": " "
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "TEXT",
|
||||
"content": {
|
||||
"content": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "INTERPOLATE",
|
||||
"content": {
|
||||
"key": "name2"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1429,14 +1429,14 @@ Json *json_parse__(POSITION_INFO_DECLARATION, Arena *arena, const char **s) {
|
||||
return result;
|
||||
}
|
||||
|
||||
char *json_to_string__(POSITION_INFO_DECLARATION, Arena *arena, const Json * const item) {
|
||||
return json_to_string_with_opts__(POSITION_INFO, arena, item, JSON_NORAW);
|
||||
char *json_to_str__(POSITION_INFO_DECLARATION, Arena *arena, const Json * const item) {
|
||||
return json_to_str_with_opts__(POSITION_INFO, arena, item, JSON_NORAW);
|
||||
}
|
||||
|
||||
/* 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__(POSITION_INFO_DECLARATION, Arena *arena, const Json * const item, JsonRawOpt raw) {
|
||||
char *json_to_str_with_opts__(POSITION_INFO_DECLARATION, Arena *arena, const Json * const item, JsonRawOpt raw) {
|
||||
// Function entry with DEBUG level
|
||||
raise_message(LOG_LEVEL_DEBUG, POSITION_INFO,
|
||||
"FORMAT: Starting JSON conversion to string (item: %p, raw_mode: %s)",
|
||||
@@ -1479,7 +1479,7 @@ char *json_to_string_with_opts__(POSITION_INFO_DECLARATION, Arena *arena, const
|
||||
|
||||
while (child) {
|
||||
ptr += sprintf(ptr, "\"%s\":", child->key ? child->key : "");
|
||||
char *child_str = json_to_string_with_opts__(POSITION_INFO, arena, child, raw);
|
||||
char *child_str = json_to_str_with_opts__(POSITION_INFO, arena, child, raw);
|
||||
if (child_str) {
|
||||
ptr += sprintf(ptr, "%s", child_str);
|
||||
} else {
|
||||
@@ -1509,7 +1509,7 @@ char *json_to_string_with_opts__(POSITION_INFO_DECLARATION, Arena *arena, const
|
||||
"FORMAT: Processing JSON array elements");
|
||||
|
||||
while (child) {
|
||||
char *child_str = json_to_string_with_opts__(POSITION_INFO, arena, child, raw);
|
||||
char *child_str = json_to_str_with_opts__(POSITION_INFO, arena, child, raw);
|
||||
if (child_str) {
|
||||
ptr += sprintf(ptr, "%s", child_str);
|
||||
} else {
|
||||
@@ -2280,8 +2280,8 @@ TemplateConfig template_default_config__(POSITION_INFO_DECLARATION, Arena *arena
|
||||
},
|
||||
.Section = {
|
||||
.control = string_to_view_ptr__(POSITION_INFO, arena, "for "),
|
||||
.source = string_to_view_ptr__(POSITION_INFO, arena, " in "),
|
||||
.begin = string_to_view_ptr__(POSITION_INFO, arena, " do ")
|
||||
.source = string_to_view_ptr__(POSITION_INFO, arena, "in "),
|
||||
.begin = string_to_view_ptr__(POSITION_INFO, arena, "do ")
|
||||
},
|
||||
.Interpolate = {
|
||||
.invoke = string_to_view_ptr__(POSITION_INFO, arena, "")
|
||||
@@ -2862,6 +2862,84 @@ char *template_node_to_json_str__(POSITION_INFO_DECLARATION, Arena *arena, const
|
||||
return result;
|
||||
}
|
||||
|
||||
// ----------
|
||||
// -- diff --
|
||||
// ----------
|
||||
|
||||
//int diff_str__(POSITION_INFO_DECLARATION, Arena *arena, const char **str1, const char **str2) {
|
||||
// if (!str1 || !str2) {
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// const char *s1 = *str1;
|
||||
// const char *s2 = *str2;
|
||||
//
|
||||
// int diff = 0;
|
||||
//
|
||||
// while (*s1 && *s2) {
|
||||
// if (*s1 != *s2) {
|
||||
// diff++;
|
||||
// }
|
||||
// s1++;
|
||||
// s2++;
|
||||
// }
|
||||
//
|
||||
// return diff;
|
||||
//}
|
||||
|
||||
// --------------
|
||||
// -- Colorize --
|
||||
// --------------
|
||||
|
||||
char *colorize_partial_patterns(char *output, const char *input, PatternHighlight *patterns, size_t pattern_count) {
|
||||
size_t len = strlen(input);
|
||||
if (!output) return NULL;
|
||||
size_t out_idx = 0;
|
||||
|
||||
for (size_t i = 0; i < len;) {
|
||||
int matched = 0;
|
||||
for (size_t j = 0; j < pattern_count; j++) {
|
||||
size_t pat_len = strlen(patterns[j].pattern);
|
||||
if (strncmp(&input[i], patterns[j].pattern, pat_len) == 0) {
|
||||
const char *pre = &input[i];
|
||||
const char *hl_start = &input[i + patterns[j].highlight_start];
|
||||
const char *hl_end = &input[i + patterns[j].highlight_start + patterns[j].highlight_len];
|
||||
|
||||
// Copy pre-highlight part
|
||||
size_t pre_len = patterns[j].highlight_start;
|
||||
memcpy(&output[out_idx], pre, pre_len);
|
||||
out_idx += pre_len;
|
||||
|
||||
// Add color code and highlighted part
|
||||
size_t color_len = strlen(patterns[j].color);
|
||||
memcpy(&output[out_idx], patterns[j].color, color_len);
|
||||
out_idx += color_len;
|
||||
|
||||
memcpy(&output[out_idx], hl_start, patterns[j].highlight_len);
|
||||
out_idx += patterns[j].highlight_len;
|
||||
|
||||
memcpy(&output[out_idx], "\033[0m", 4);
|
||||
out_idx += 4;
|
||||
|
||||
// Copy post-highlight part
|
||||
size_t post_len = pat_len - patterns[j].highlight_start - patterns[j].highlight_len;
|
||||
memcpy(&output[out_idx], hl_end, post_len);
|
||||
out_idx += post_len;
|
||||
|
||||
i += pat_len;
|
||||
matched = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!matched) {
|
||||
output[out_idx++] = input[i++];
|
||||
}
|
||||
}
|
||||
|
||||
output[out_idx] = '\0';
|
||||
return output;
|
||||
}
|
||||
|
||||
// ---------
|
||||
// -- End --
|
||||
// ---------
|
||||
|
||||
@@ -427,6 +427,8 @@ char* arena_strncpy__(const char *file, const char *func, int line, Arena *arena
|
||||
|
||||
static Arena disposable_arena __attribute__((unused)) = {0};
|
||||
|
||||
#define DISPOSABLE_ARENA_FREE arena_free(&disposable_arena)
|
||||
|
||||
#define DISPOSABLE_ARENA __extension__ ({ \
|
||||
if (disposable_arena.begin == NULL) { \
|
||||
disposable_arena = arena_init__(__FILE__, __func__, __LINE__, MEM_MiB * 8); \
|
||||
@@ -653,11 +655,11 @@ RESULT(Json, Json);
|
||||
Json *json_parse__(const char* file, const char* func, int line, Arena *arena, const char **s);
|
||||
#define json_parse(arena, s) json_parse__(__FILE__, __func__, __LINE__, arena, s)
|
||||
|
||||
char *json_to_string__(const char* file, const char* func, int line, Arena *arena, const Json * const item);
|
||||
#define json_to_string(arena, item) json_to_string__(__FILE__, __func__, __LINE__, arena, item)
|
||||
char *json_to_str__(const char* file, const char* func, int line, Arena *arena, const Json * const item);
|
||||
#define JSON_TO_STR(arena, item) json_to_str__(__FILE__, __func__, __LINE__, arena, item)
|
||||
|
||||
#define json_to_string_with_opts(arena, item, raw) json_to_string_with_opts__(__FILE__, __func__, __LINE__, arena, item, raw)
|
||||
char *json_to_string_with_opts__(const char* file, const char* func, int line, Arena *arena, const Json * const item, JsonRawOpt raw);
|
||||
char *json_to_str_with_opts__(const char* file, const char* func, int line, Arena *arena, const Json * const item, JsonRawOpt raw);
|
||||
#define JSON_TO_STR_WITH_OPTS(arena, item, raw) json_to_str_with_opts__(__FILE__, __func__, __LINE__, arena, item, raw)
|
||||
|
||||
/* Retrieve an object item by key (case-sensitive) */
|
||||
Json *json_get_object_item__(const char* file, const char* func, int line, const Json * const object, const char * const key);
|
||||
@@ -839,4 +841,31 @@ TemplateNode init_template_node__(const char *file, const char *func, int line,
|
||||
#define init_template_node(arena, type) \
|
||||
init_template_node__(__FILE__, __func__, __LINE__, arena, type)
|
||||
|
||||
#endif // EPRINTF_H
|
||||
#define TEMPLATE_NODE_DISPOSABLE_JSON(node) __extension__ ({ \
|
||||
Arena *debug_arena = DISPOSABLE_ARENA; \
|
||||
const char *json_str = TEMPLATE_NODE_TO_JSON_STR(debug_arena, &node); \
|
||||
Json *json = json_parse(debug_arena, &json_str); \
|
||||
arena_strdup(debug_arena, JSON_TO_PRETTY_STR(debug_arena, json)); \
|
||||
})
|
||||
|
||||
#define TEMPLATE_NODE_PRETTY_JSON(node, arena) __extension__ ({ \
|
||||
Arena *debug_arena = DISPOSABLE_ARENA; \
|
||||
const char *json_str = TEMPLATE_NODE_TO_JSON_STR(debug_arena, &node); \
|
||||
Json *json = json_parse(debug_arena, &json_str); \
|
||||
arena_strdup(arena, JSON_TO_PRETTY_STR(debug_arena, json)); \
|
||||
})
|
||||
|
||||
// --------------
|
||||
// -- Colorize --
|
||||
// --------------
|
||||
|
||||
typedef struct {
|
||||
const char *pattern;
|
||||
int highlight_start;
|
||||
int highlight_len;
|
||||
const char *color;
|
||||
} PatternHighlight;
|
||||
|
||||
char *colorize_partial_patterns(char *output, const char *input, PatternHighlight *patterns, size_t pattern_count);
|
||||
|
||||
#endif // EPRINTF_H
|
||||
|
||||
47
package/c/hectic/result.log
Normal file
47
package/c/hectic/result.log
Normal file
@@ -0,0 +1,47 @@
|
||||
[
|
||||
{
|
||||
"type": "SECTION",
|
||||
"content": {
|
||||
"iterator": "item",
|
||||
"collection": "items"
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "INTERPOLATE",
|
||||
"content": {
|
||||
"key": "name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "TEXT",
|
||||
"content": {
|
||||
"content": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "INTERPOLATE",
|
||||
"content": {
|
||||
"key": "item.name"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "TEXT",
|
||||
"content": {
|
||||
"content": " "
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "TEXT",
|
||||
"content": {
|
||||
"content": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "INTERPOLATE",
|
||||
"content": {
|
||||
"key": "name2"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -53,7 +53,7 @@ static void test_get_object_items(Arena *arena) {
|
||||
static void test_print_json_object(Arena *arena) {
|
||||
const char *json = "{\"key\":\"value\", \"num\":3.14}";
|
||||
Json *root = json_parse(arena, &json);
|
||||
char *printed = json_to_string(arena, root);
|
||||
char *printed = JSON_TO_STR(arena, root);
|
||||
assert(strstr(printed, "\"key\":") != NULL);
|
||||
assert(strstr(printed, "\"value\"") != NULL);
|
||||
assert(strstr(printed, "\"num\":") != NULL);
|
||||
@@ -64,7 +64,7 @@ static void test_print_json_object(Arena *arena) {
|
||||
static void test_print_json_number(Arena *arena) {
|
||||
const char *json = "123.456";
|
||||
Json *root = json_parse(arena, &json);
|
||||
char *printed = json_to_string(arena, root);
|
||||
char *printed = JSON_TO_STR(arena, root);
|
||||
double val = atof(printed);
|
||||
assert(val == 123.456);
|
||||
}
|
||||
@@ -73,7 +73,7 @@ static void test_print_json_number(Arena *arena) {
|
||||
static void test_print_json_string(Arena *arena) {
|
||||
const char *json = "\"test string\"";
|
||||
Json *root = json_parse(arena, &json);
|
||||
char *printed = json_to_string(arena, root);
|
||||
char *printed = JSON_TO_STR(arena, root);
|
||||
assert(strcmp(printed, "\"test string\"") == 0);
|
||||
}
|
||||
|
||||
@@ -99,12 +99,12 @@ static void test_nested_json_object(Arena *arena) {
|
||||
static void test_arena_reset_reuse(Arena *arena) {
|
||||
const char *json1 = "{\"key\":\"value\"}";
|
||||
Json *root1 = json_parse(arena, &json1);
|
||||
char *printed1 = json_to_string(arena, root1);
|
||||
char *printed1 = JSON_TO_STR(arena, root1);
|
||||
assert(strcmp(printed1, "{\"key\":\"value\"}") == 0);
|
||||
arena_reset(arena);
|
||||
const char *json2 = "\"another test\"";
|
||||
Json *root2 = json_parse(arena, &json2);
|
||||
char *printed2 = json_to_string(arena, root2);
|
||||
char *printed2 = JSON_TO_STR(arena, root2);
|
||||
assert(strcmp(printed2, "\"another test\"") == 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -233,12 +233,87 @@ static void simplest_separator_test_template_parse(Arena *arena, TemplateConfig
|
||||
|
||||
TemplateNode node = RESULT_SOME_VALUE(template_result);
|
||||
|
||||
char *result_str = TEMPLATE_NODE_PRETTY_JSON(node, arena);
|
||||
|
||||
char *expected_result_str = arena_strdup(arena,
|
||||
"[\n"
|
||||
" {\n"
|
||||
" \"type\": \"SECTION\",\n"
|
||||
" \"content\": {\n"
|
||||
" \"iterator\": \"item\",\n"
|
||||
" \"collection\": \"items\"\n"
|
||||
" },\n"
|
||||
" \"body\": [\n"
|
||||
" {\n"
|
||||
" \"type\": \"INTERPOLATE\",\n"
|
||||
" \"content\": {\n"
|
||||
" \"key\": \"name\"\n"
|
||||
" }\n"
|
||||
" },\n"
|
||||
" {\n"
|
||||
" \"type\": \"TEXT\",\n"
|
||||
" \"content\": {\n"
|
||||
" \"content\": \" \"\n"
|
||||
" }\n"
|
||||
" },\n"
|
||||
" {\n"
|
||||
" \"type\": \"INTERPOLATE\",\n"
|
||||
" \"content\": {\n"
|
||||
" \"key\": \"item.name\"\n"
|
||||
" }\n"
|
||||
" },\n"
|
||||
" {\n"
|
||||
" \"type\": \"TEXT\",\n"
|
||||
" \"content\": {\n"
|
||||
" \"content\": \" \"\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" ]\n"
|
||||
" },\n"
|
||||
" {\n"
|
||||
" \"type\": \"TEXT\",\n"
|
||||
" \"content\": {\n"
|
||||
" \"content\": \" \"\n"
|
||||
" }\n"
|
||||
" },\n"
|
||||
" {\n"
|
||||
" \"type\": \"INTERPOLATE\",\n"
|
||||
" \"content\": {\n"
|
||||
" \"key\": \"name2\"\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
"]");
|
||||
|
||||
raise_log("result_str: \n%s", result_str);
|
||||
|
||||
assert(strcmp(result_str, expected_result_str) == 0);
|
||||
}
|
||||
|
||||
static void simplest_execute_test_template_parse(Arena *arena, TemplateConfig *config) {
|
||||
const char *template_str =
|
||||
"{% %}"
|
||||
"{% execute RETURN 'aaaaaa' %}"
|
||||
"{% name %}"
|
||||
"{% name2 %}"
|
||||
"{% name3 %}";
|
||||
|
||||
TemplateResult template_result = template_parse(arena, &template_str, config);
|
||||
|
||||
if (IS_RESULT_ERROR(template_result)) {
|
||||
raise_exception("template_parse failed");
|
||||
return;
|
||||
}
|
||||
|
||||
TemplateNode node = RESULT_SOME_VALUE(template_result);
|
||||
|
||||
//char *result_str;
|
||||
{ // some debug output
|
||||
Arena *debug_arena = DISPOSABLE_ARENA;
|
||||
const char *json_str = TEMPLATE_NODE_TO_JSON_STR(debug_arena, &node);
|
||||
raise_log("json_str: \n%s", json_str);
|
||||
Json *json = json_parse(debug_arena, &json_str);
|
||||
raise_notice("json_str: \n%s", JSON_TO_PRETTY_STR(debug_arena, json));
|
||||
//result_str = arena_strdup(arena, JSON_TO_PRETTY_STR(debug_arena, json));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,9 +349,13 @@ int main(void) {
|
||||
printf("%sTest 4: simplest_separator_test_template_parse passed%s\n", OPTIONAL_COLOR(COLOR_GREEN), OPTIONAL_COLOR(COLOR_RESET));
|
||||
arena_reset(&arena);
|
||||
|
||||
simplest_execute_test_template_parse(&arena, &config);
|
||||
printf("%sTest 5: simplest_execute_test_template_parse passed%s\n", OPTIONAL_COLOR(COLOR_GREEN), OPTIONAL_COLOR(COLOR_RESET));
|
||||
arena_reset(&arena);
|
||||
|
||||
logger_free();
|
||||
arena_free(&config_arena);
|
||||
arena_free(&arena);
|
||||
printf("%sall tests passed %s%s%s\n", OPTIONAL_COLOR(COLOR_GREEN), OPTIONAL_COLOR(COLOR_CYAN), __FILE__, OPTIONAL_COLOR(COLOR_RESET));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
17
package/c/hemar/default.nix
Executable file
17
package/c/hemar/default.nix
Executable file
@@ -0,0 +1,17 @@
|
||||
{ postgresql, pkg-config, patchelf }:
|
||||
buildPostgresqlExtension { inherit postgresql; } {
|
||||
pname = "hemar";
|
||||
version = "0.1";
|
||||
src = ./.;
|
||||
|
||||
nativeBuildInputs = [pkg-config c-hectic];
|
||||
|
||||
dontShrinkRPath = true;
|
||||
|
||||
postFixup = ''
|
||||
echo ">>> postFixup running..."
|
||||
${patchelf}/bin/patchelf --set-rpath ${c-hectic}/lib $out/lib/hemar.so
|
||||
'';
|
||||
|
||||
preInstall = ''mkdir $out'';
|
||||
};
|
||||
@@ -40,7 +40,7 @@ RETURNS void
|
||||
AS 'hemar', 'pg_test_log_2'
|
||||
LANGUAGE C STRICT;
|
||||
|
||||
CREATE FUNCTION "hemar"."template_parse"(text)
|
||||
RETURNS void
|
||||
CREATE FUNCTION "hemar"."parse"("template" text)
|
||||
RETURNS text
|
||||
AS 'hemar', 'pg_template_parse'
|
||||
LANGUAGE C STRICT;
|
||||
|
||||
@@ -14,14 +14,14 @@ PG_MODULE_MAGIC;
|
||||
|
||||
#define INIT \
|
||||
logger_init(); \
|
||||
logger_level(LOG_LEVEL_TRACE); \
|
||||
logger_set_file(LOG_FILE); \
|
||||
logger_set_output_mode(LOG_OUTPUT_BOTH); \
|
||||
Arena arena = arena_init(MEM_MiB);
|
||||
|
||||
#define FREE \
|
||||
DISPOSABLE_ARENA_FREE; \
|
||||
arena_free(&arena); \
|
||||
logger_free();
|
||||
logger_free();
|
||||
|
||||
/* helper function to get a JSON value by key path */
|
||||
static Json *json_get_by_path(Arena *arena, const Json *context, const char *key_path) {
|
||||
@@ -66,7 +66,7 @@ static char *json_value_to_string(Arena *arena, const Json *json) {
|
||||
return "";
|
||||
case JSON_ARRAY:
|
||||
case JSON_OBJECT:
|
||||
return json_to_string(arena, json);
|
||||
return JSON_TO_STR(arena, json);
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
@@ -81,7 +81,7 @@ static char *render_text_node(Arena *arena, const TemplateNode *node) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return node->value.text.content;
|
||||
return node->value->text.content;
|
||||
}
|
||||
|
||||
/* Render an interpolation node */
|
||||
@@ -93,7 +93,7 @@ static char *render_interpolation_node(Arena *arena, const TemplateNode *node, c
|
||||
return "";
|
||||
}
|
||||
|
||||
key = node->value.interpolate.key;
|
||||
key = node->value->interpolate.key;
|
||||
value = json_get_by_path(arena, context, key);
|
||||
|
||||
if (!value) {
|
||||
@@ -129,9 +129,9 @@ static char *render_section_node(Arena *arena, const TemplateNode *node, const J
|
||||
return "";
|
||||
}
|
||||
|
||||
collection_key = node->value.section.collection;
|
||||
iterator_name = node->value.section.iterator;
|
||||
body = node->value.section.body;
|
||||
collection_key = node->value->section.collection;
|
||||
iterator_name = node->value->section.iterator;
|
||||
body = node->value->section.body;
|
||||
|
||||
collection = json_get_by_path(arena, context, collection_key);
|
||||
|
||||
@@ -191,7 +191,7 @@ static char *render_include_node(Arena *arena, const TemplateNode *node, const J
|
||||
if (!node || node->type != TEMPLATE_NODE_INCLUDE || !context) {
|
||||
return "";
|
||||
}
|
||||
include_key = node->value.include.key;
|
||||
include_key = node->value->include.key;
|
||||
include_value = json_get_by_path(arena, context, include_key);
|
||||
|
||||
if (!include_value || include_value->type != JSON_ARRAY) {
|
||||
@@ -213,7 +213,7 @@ static char *render_include_node(Arena *arena, const TemplateNode *node, const J
|
||||
const char *template_str = template_json->value.string;
|
||||
const Json *include_context = context_json ? context_json : context;
|
||||
|
||||
TemplateConfig config = template_default_config();
|
||||
TemplateConfig config = template_default_config(arena);
|
||||
TemplateResult template_result = template_parse(arena, &template_str, &config);
|
||||
|
||||
if (!IS_RESULT_ERROR(template_result)) {
|
||||
@@ -290,19 +290,6 @@ static char *render_template_node(Arena *arena, const TemplateNode *node, const
|
||||
strcpy(output + output_pos, rendered);
|
||||
output_pos += rendered_len;
|
||||
|
||||
if (current->children) {
|
||||
char *children_rendered = render_template_node(arena, current->children, context);
|
||||
size_t children_len = strlen(children_rendered);
|
||||
|
||||
if (output_pos + children_len + 1 > buffer_size) {
|
||||
buffer_size = (output_pos + children_len + 1) * 2;
|
||||
output = arena_realloc(arena, output, buffer_size / 2, buffer_size);
|
||||
}
|
||||
|
||||
strcpy(output + output_pos, children_rendered);
|
||||
output_pos += children_len;
|
||||
}
|
||||
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
@@ -338,7 +325,6 @@ Datum pg_render(PG_FUNCTION_ARGS)
|
||||
|
||||
TemplateNode root_node;
|
||||
TemplateResult template_result;
|
||||
TemplateConfig config;
|
||||
|
||||
Json *context;
|
||||
|
||||
@@ -349,6 +335,7 @@ Datum pg_render(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Parse the JSON context */
|
||||
const char *json_ptr = context_str;
|
||||
TemplateConfig config = template_default_config(&arena);
|
||||
context = json_parse(&arena, &json_ptr);
|
||||
|
||||
if (!context) {
|
||||
@@ -359,7 +346,6 @@ Datum pg_render(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Parse the template text */
|
||||
template_ptr = template_str;
|
||||
config = template_default_config();
|
||||
template_result = template_parse(&arena, &template_ptr, &config);
|
||||
|
||||
if (IS_RESULT_ERROR(template_result)) {
|
||||
@@ -411,13 +397,16 @@ PG_FUNCTION_INFO_V1(pg_template_parse);
|
||||
Datum pg_template_parse(PG_FUNCTION_ARGS) {
|
||||
INIT;
|
||||
|
||||
TemplateConfig config;
|
||||
text *context_text = PG_GETARG_TEXT_PP(0);
|
||||
char *content = text_to_cstring(context_text);
|
||||
|
||||
const char *template_ptr;
|
||||
TemplateResult template_result;
|
||||
TemplateConfig config = template_default_config(&arena);
|
||||
|
||||
template_ptr = "{{ name }}";
|
||||
config = template_default_config();
|
||||
raise_info("start parsing....");
|
||||
template_result = template_parse(&arena, &template_ptr, &config);
|
||||
raise_info("parsing finished....");
|
||||
|
||||
if (IS_RESULT_ERROR(template_result)) {
|
||||
FREE;
|
||||
@@ -426,9 +415,18 @@ Datum pg_template_parse(PG_FUNCTION_ARGS) {
|
||||
RESULT_ERROR_MESSAGE(template_result))));
|
||||
}
|
||||
|
||||
const char *json_str = "{\"a\": 1}";
|
||||
Jsonb *jb = DatumGetJsonbP(DirectFunctionCall1(jsonb_in, CStringGetDatum(json_str)));
|
||||
const char *json_str = TEMPLATE_NODE_TO_JSON_STR(&arena, &(RESULT_SOME_VALUE(template_result)));
|
||||
Json *json = json_parse(&arena, &json_str); \
|
||||
|
||||
char *result_str = JSON_TO_STR(&arena, json);
|
||||
|
||||
raise_notice("%s", result_str);
|
||||
|
||||
char *result_str_clone = malloc(strlen(result_str) + 1);
|
||||
if (result_str_clone) strcpy(result_str_clone, result_str);
|
||||
|
||||
FREE;
|
||||
PG_RETURN_VOID();
|
||||
}
|
||||
|
||||
text *result = cstring_to_text(result_str_clone);
|
||||
PG_RETURN_TEXT_P(result);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user