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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user