feat: hectic C: some sigfault

This commit is contained in:
2025-04-15 04:54:31 +00:00
parent d45307336a
commit 8697b00cfc
5 changed files with 113 additions and 118 deletions

View File

@@ -59,7 +59,9 @@
forAllSystemsWithPkgs [(import rust-overlay)] ({ forAllSystemsWithPkgs [(import rust-overlay)] ({
system, system,
pkgs, pkgs,
}: { }: let
pkgs-unstable = import nixpkgs-unstable { inherit system; };
in {
packages.${system} = let packages.${system} = let
rust = { rust = {
nativeBuildInputs = [ nativeBuildInputs = [
@@ -143,6 +145,15 @@
buildInputs = (with pkgs; [ inotify-tools gdb gcc ]) ++ (with self.packages.${system}; [ c-hectic nvim-pager watch ]); buildInputs = (with pkgs; [ inotify-tools gdb gcc ]) ++ (with self.packages.${system}; [ c-hectic nvim-pager watch ]);
PAGER = "${self.packages.${system}.nvim-pager}/bin/pager"; PAGER = "${self.packages.${system}.nvim-pager}/bin/pager";
}; };
pure-c = pkgs.mkShell {
buildInputs = (with pkgs; [ inotify-tools ]) ++ (with self.packages.${system}; [ nvim-pager ]) ++ (with pkgs-unstable; [ gdb gcc ]);
PAGER = "${self.packages.${system}.nvim-pager}/bin/pager";
shellHook = ''
export PATH=${pkgs-unstable.gcc}/bin:$PATH
export PAGER="${self.packages.${system}.nvim-pager}/bin/pager"
'';
};
default = pkgs.mkShell { default = pkgs.mkShell {
buildInputs = buildInputs =
(with self.packages.${system}; [ (with self.packages.${system}; [

View File

@@ -340,6 +340,10 @@ char *float_to_debug_str__(CTX_DECLARATION, const char *name, double number) {
return arena_strdup_fmt__(CTX(arena), "%s = %f", name, number); return arena_strdup_fmt__(CTX(arena), "%s = %f", name, number);
} }
char *bool_to_debug_str__(CTX_DECLARATION, const char *name, int boolean) {
return arena_strdup_fmt__(CTX(arena), "%s = %s", name, boolean ? "true" : "false");
}
char *size_t_to_debug_str__(CTX_DECLARATION, const char *name, size_t number) { char *size_t_to_debug_str__(CTX_DECLARATION, const char *name, size_t number) {
return arena_strdup_fmt__(CTX(arena), "%s = %zu", name, number); return arena_strdup_fmt__(CTX(arena), "%s = %zu", name, number);
} }
@@ -437,6 +441,7 @@ char *debug_join_debug_strings_v(CTX_DECLARATION, int count, va_list args) {
} }
char *struct_to_debug_str__(CTX_DECLARATION, const char *type, const char *name, const void *ptr, int count, ...) { char *struct_to_debug_str__(CTX_DECLARATION, const char *type, const char *name, const void *ptr, int count, ...) {
printf("ZALUPA\n");
raise_message(LOG_LEVEL_TRACE, POSITION_INFO, "DEBUG STR: type: %s, name: %s, ptr: %p, count: %d", type, name, ptr, count); raise_message(LOG_LEVEL_TRACE, POSITION_INFO, "DEBUG STR: type: %s, name: %s, ptr: %p, count: %d", type, name, ptr, count);
va_list args; va_list args;
@@ -853,7 +858,7 @@ char *json_to_pretty_str__(POSITION_INFO_DECLARATION, Arena *arena, const Json *
if (item->type == JSON_OBJECT) { if (item->type == JSON_OBJECT) {
ptr += sprintf(ptr, "{\n"); ptr += sprintf(ptr, "{\n");
Json *child = item->child; Json *child = item->value.child;
int child_count = 0; int child_count = 0;
raise_message(LOG_LEVEL_TRACE, POSITION_INFO, raise_message(LOG_LEVEL_TRACE, POSITION_INFO,
@@ -892,7 +897,7 @@ char *json_to_pretty_str__(POSITION_INFO_DECLARATION, Arena *arena, const Json *
} else if (item->type == JSON_ARRAY) { } else if (item->type == JSON_ARRAY) {
ptr += sprintf(ptr, "[\n"); ptr += sprintf(ptr, "[\n");
Json *child = item->child; Json *child = item->value.child;
int child_count = 0; int child_count = 0;
raise_message(LOG_LEVEL_TRACE, POSITION_INFO, raise_message(LOG_LEVEL_TRACE, POSITION_INFO,
@@ -928,11 +933,11 @@ char *json_to_pretty_str__(POSITION_INFO_DECLARATION, Arena *arena, const Json *
raise_message(LOG_LEVEL_TRACE, POSITION_INFO, raise_message(LOG_LEVEL_TRACE, POSITION_INFO,
"PRETTY: Array prettification complete with %d elements", child_count); "PRETTY: Array prettification complete with %d elements", child_count);
} else if (item->type == JSON_STRING) { } else if (item->type == JSON_STRING) {
sprintf(ptr, "\"%s\"", item->JsonValue.string ? item->JsonValue.string : ""); sprintf(ptr, "\"%s\"", item->value.string ? item->value.string : "");
} else if (item->type == JSON_NUMBER) { } else if (item->type == JSON_NUMBER) {
sprintf(ptr, "%g", item->JsonValue.number); sprintf(ptr, "%g", item->value.number);
} else if (item->type == JSON_BOOL) { } else if (item->type == JSON_BOOL) {
sprintf(ptr, item->JsonValue.boolean ? "true" : "false"); sprintf(ptr, item->value.boolean ? "true" : "false");
} else if (item->type == JSON_NULL) { } else if (item->type == JSON_NULL) {
sprintf(ptr, "null"); sprintf(ptr, "null");
} }
@@ -1036,8 +1041,8 @@ static Json *json_parse_array__(POSITION_INFO_DECLARATION, const char **s, Arena
raise_message(LOG_LEVEL_DEBUG, POSITION_INFO, "Failed to parse array element"); raise_message(LOG_LEVEL_DEBUG, POSITION_INFO, "Failed to parse array element");
return NULL; return NULL;
} }
if (!array->child) if (!array->value.child)
array->child = element; array->value.child = element;
else else
last->next = element; last->next = element;
last = element; last = element;
@@ -1096,8 +1101,8 @@ static Json *json_parse_object__(POSITION_INFO_DECLARATION, const char **s, Aren
return NULL; return NULL;
} }
value->key = key; // assign key to the value value->key = key; // assign key to the value
if (!object->child) if (!object->value.child)
object->child = value; object->value.child = value;
else else
last->next = value; last->next = value;
last = value; last = value;
@@ -1129,7 +1134,7 @@ static Json *json_parse_value__(POSITION_INFO_DECLARATION, const char **s, Arena
} }
memset(item, 0, sizeof(Json)); memset(item, 0, sizeof(Json));
item->type = JSON_STRING; item->type = JSON_STRING;
item->JsonValue.string = json_parse_string__(POSITION_INFO, s, arena); item->value.string = json_parse_string__(POSITION_INFO, s, arena);
return item; return item;
} else if (strncmp(*s, "null", 4) == 0) { } else if (strncmp(*s, "null", 4) == 0) {
Json *item = arena_alloc__(POSITION_INFO, arena, sizeof(Json)); Json *item = arena_alloc__(POSITION_INFO, arena, sizeof(Json));
@@ -1143,7 +1148,7 @@ static Json *json_parse_value__(POSITION_INFO_DECLARATION, const char **s, Arena
if (!item) return NULL; if (!item) return NULL;
memset(item, 0, sizeof(Json)); memset(item, 0, sizeof(Json));
item->type = JSON_BOOL; item->type = JSON_BOOL;
item->JsonValue.boolean = 1; item->value.boolean = 1;
*s += 4; *s += 4;
return item; return item;
} else if (strncmp(*s, "false", 5) == 0) { } else if (strncmp(*s, "false", 5) == 0) {
@@ -1151,7 +1156,7 @@ static Json *json_parse_value__(POSITION_INFO_DECLARATION, const char **s, Arena
if (!item) return NULL; if (!item) return NULL;
memset(item, 0, sizeof(Json)); memset(item, 0, sizeof(Json));
item->type = JSON_BOOL; item->type = JSON_BOOL;
item->JsonValue.boolean = 0; item->value.boolean = 0;
*s += 5; *s += 5;
return item; return item;
} else if ((**s == '-') || isdigit((unsigned char)**s)) { } else if ((**s == '-') || isdigit((unsigned char)**s)) {
@@ -1162,7 +1167,7 @@ static Json *json_parse_value__(POSITION_INFO_DECLARATION, const char **s, Arena
} }
memset(item, 0, sizeof(Json)); memset(item, 0, sizeof(Json));
item->type = JSON_NUMBER; item->type = JSON_NUMBER;
item->JsonValue.number = json_parse_number__(POSITION_INFO, s); item->value.number = json_parse_number__(POSITION_INFO, s);
return item; return item;
} else if (**s == '[') { } else if (**s == '[') {
return json_parse_array__(POSITION_INFO, s, arena); return json_parse_array__(POSITION_INFO, s, arena);
@@ -1253,7 +1258,7 @@ char *json_to_string_with_opts__(POSITION_INFO_DECLARATION, Arena *arena, const
ptr += sprintf(ptr, "{"); ptr += sprintf(ptr, "{");
type_name = "object"; type_name = "object";
Json *child = item->child; Json *child = item->value.child;
int child_count = 0; int child_count = 0;
raise_message(LOG_LEVEL_TRACE, POSITION_INFO, raise_message(LOG_LEVEL_TRACE, POSITION_INFO,
@@ -1284,7 +1289,7 @@ char *json_to_string_with_opts__(POSITION_INFO_DECLARATION, Arena *arena, const
ptr += sprintf(ptr, "["); ptr += sprintf(ptr, "[");
type_name = "array"; type_name = "array";
Json *child = item->child; Json *child = item->value.child;
int child_count = 0; int child_count = 0;
raise_message(LOG_LEVEL_TRACE, POSITION_INFO, raise_message(LOG_LEVEL_TRACE, POSITION_INFO,
@@ -1312,16 +1317,16 @@ char *json_to_string_with_opts__(POSITION_INFO_DECLARATION, Arena *arena, const
} else if (item->type == JSON_STRING) { } else if (item->type == JSON_STRING) {
type_name = "string"; type_name = "string";
if ((int)raw) { if ((int)raw) {
sprintf(ptr, "%s", item->JsonValue.string ? item->JsonValue.string : ""); sprintf(ptr, "%s", item->value.string ? item->value.string : "");
} else { } else {
sprintf(ptr, "\"%s\"", item->JsonValue.string ? item->JsonValue.string : ""); sprintf(ptr, "\"%s\"", item->value.string ? item->value.string : "");
} }
} else if (item->type == JSON_NUMBER) { } else if (item->type == JSON_NUMBER) {
type_name = "number"; type_name = "number";
sprintf(ptr, "%g", item->JsonValue.number); sprintf(ptr, "%g", item->value.number);
} else if (item->type == JSON_BOOL) { } else if (item->type == JSON_BOOL) {
type_name = "boolean"; type_name = "boolean";
sprintf(ptr, item->JsonValue.boolean ? "true" : "false"); sprintf(ptr, item->value.boolean ? "true" : "false");
} else if (item->type == JSON_NULL) { } else if (item->type == JSON_NULL) {
type_name = "null"; type_name = "null";
sprintf(ptr, "null"); sprintf(ptr, "null");
@@ -1361,7 +1366,7 @@ Json *json_get_object_item__(POSITION_INFO_DECLARATION, const Json * const objec
// Count the total number of keys for debugging // Count the total number of keys for debugging
int total_keys = 0; int total_keys = 0;
Json *debug_scan = object->child; Json *debug_scan = object->value.child;
while (debug_scan) { while (debug_scan) {
total_keys++; total_keys++;
debug_scan = debug_scan->next; debug_scan = debug_scan->next;
@@ -1371,7 +1376,7 @@ Json *json_get_object_item__(POSITION_INFO_DECLARATION, const Json * const objec
"ACCESS: Object has %d key-value pairs", total_keys); "ACCESS: Object has %d key-value pairs", total_keys);
// Perform key search // Perform key search
Json *child = object->child; Json *child = object->value.child;
int position = 0; int position = 0;
while (child) { while (child) {
@@ -1401,75 +1406,29 @@ Json *json_get_object_item__(POSITION_INFO_DECLARATION, const Json * const objec
return NULL; return NULL;
} }
char* json_to_debug_str__(POSITION_INFO_DECLARATION, Arena *arena, Json json) { char *json_value_to_debug_str__(POSITION_INFO_DECLARATION, Arena *arena, const char *name, const JsonValue *self, JsonType active_variant, PtrSet *visited) {
char *child_str = json_to_debug_str__(POSITION_INFO, arena, "child", self->child, visited);
char *result = arena_alloc__(POSITION_INFO, arena, 1024);
UNION_TO_DEBUG_STR(arena, result, JsonValue, name, self, visited, active_variant, 5,
JSON_STRING, string_to_debug_str__(POSITION_INFO, arena, "string", self->string),
JSON_NUMBER, float_to_debug_str__(POSITION_INFO, arena, "number", self->number),
JSON_BOOL, bool_to_debug_str__(POSITION_INFO, arena, "boolean", self->boolean),
JSON_OBJECT, child_str,
JSON_ARRAY, child_str
);
return result;
}
char* json_to_debug_str__(POSITION_INFO_DECLARATION, Arena *arena, const char *name, const Json *self, PtrSet *visited) {
raise_message(LOG_LEVEL_TRACE, POSITION_INFO, "json_to_debug_str(<optimized>, <optimized>)"); raise_message(LOG_LEVEL_TRACE, POSITION_INFO, "json_to_debug_str(<optimized>, <optimized>)");
char meta_buffer[256]; char *result = arena_alloc__(POSITION_INFO, arena, 1024);
STRUCT_TO_DEBUG_STR(arena, result, Json, name, self, visited, 3,
snprintf(meta_buffer, sizeof(meta_buffer), "Json{addr=%p, type=%s, key=%s, child=%p, next=%p, value=", enum_to_debug_str__(POSITION_INFO, arena, "type", self->type, json_type_to_string(self->type)),
(void*)&json, json_type_to_string(json.type), json.key ? json.key : "NULL", (void*)json.child, (void*)json.next); string_to_debug_str__(POSITION_INFO, arena, "key", self->key),
json_value_to_debug_str__(POSITION_INFO, arena, "value", &self->value, self->type, visited),
size_t meta_len = strlen(meta_buffer); json_to_debug_str__(POSITION_INFO, arena, "next", self->next, visited)
char value_buffer[256] = {0}; );
switch (json.type) {
case JSON_NULL:
strcpy(value_buffer, "null");
break;
case JSON_BOOL:
strcpy(value_buffer, json.JsonValue.boolean ? "true" : "false");
break;
case JSON_NUMBER:
snprintf(value_buffer, sizeof(value_buffer), "%g", json.JsonValue.number);
break;
case JSON_STRING: {
if (!json.JsonValue.string) {
strcpy(value_buffer, "null");
} else {
snprintf(value_buffer, sizeof(value_buffer), "\"%s\"", json.JsonValue.string);
}
break;
}
case JSON_ARRAY: {
// For arrays, simply note the number of elements
size_t count = 0;
Json *item = json.child;
while (item) {
count++;
item = item->next;
}
snprintf(value_buffer, sizeof(value_buffer), "[array with %zu elements]", count);
break;
}
case JSON_OBJECT: {
// For objects, note the number of key-value pairs
size_t count = 0;
Json *item = json.child;
while (item) {
count++;
item = item->next;
}
snprintf(value_buffer, sizeof(value_buffer), "{object with %zu key-value pairs}", count);
break;
}
default:
strcpy(value_buffer, "<UNKNOWN JSON TYPE>");
}
// Create final string
size_t result_len = meta_len + strlen(value_buffer) + 2; // +2 for closing brace and null character
char* result = arena_alloc(arena, result_len);
strcpy(result, meta_buffer);
strcat(result, value_buffer);
strcat(result, "}");
return result; return result;
} }
@@ -1611,7 +1570,7 @@ JsonResult debug_str_to_json__(POSITION_INFO_DECLARATION, Arena *arena, const ch
// Extract value as string // Extract value as string
value_start = skip_whitespace(value_start + 1); value_start = skip_whitespace(value_start + 1);
json->JsonValue.string = arena_strdup__(POSITION_INFO, arena, value_start); json->value.string = arena_strdup__(POSITION_INFO, arena, value_start);
// Move pointer to the end // Move pointer to the end
*s += strlen(*s); *s += strlen(*s);
@@ -1659,12 +1618,12 @@ JsonResult debug_str_to_json__(POSITION_INFO_DECLARATION, Arena *arena, const ch
} }
else if (strncmp(value, "true", 4) == 0) { else if (strncmp(value, "true", 4) == 0) {
json->type = JSON_BOOL; json->type = JSON_BOOL;
json->JsonValue.boolean = true; json->value.boolean = true;
*s += 4; *s += 4;
} }
else if (strncmp(value, "false", 5) == 0) { else if (strncmp(value, "false", 5) == 0) {
json->type = JSON_BOOL; json->type = JSON_BOOL;
json->JsonValue.boolean = false; json->value.boolean = false;
*s += 5; *s += 5;
} }
else if (*value == '"') { else if (*value == '"') {
@@ -1679,7 +1638,7 @@ JsonResult debug_str_to_json__(POSITION_INFO_DECLARATION, Arena *arena, const ch
} }
size_t str_len = end_quote - value; size_t str_len = end_quote - value;
json->JsonValue.string = arena_strncpy__(POSITION_INFO, arena, value, str_len); json->value.string = arena_strncpy__(POSITION_INFO, arena, value, str_len);
*s = end_quote + 1; *s = end_quote + 1;
} }
else if (isdigit(*value) || *value == '-' || *value == '+') { else if (isdigit(*value) || *value == '-' || *value == '+') {
@@ -1688,7 +1647,7 @@ JsonResult debug_str_to_json__(POSITION_INFO_DECLARATION, Arena *arena, const ch
// Use strtod to parse the number // Use strtod to parse the number
char *end; char *end;
json->JsonValue.number = strtod(value, &end); json->value.number = strtod(value, &end);
*s = end; *s = end;
} }
else { else {
@@ -1700,7 +1659,7 @@ JsonResult debug_str_to_json__(POSITION_INFO_DECLARATION, Arena *arena, const ch
while (*end && !isspace(*end) && *end != ',' && *end != '}' && *end != ']') end++; while (*end && !isspace(*end) && *end != ',' && *end != '}' && *end != ']') end++;
size_t str_len = end - value; size_t str_len = end - value;
json->JsonValue.string = arena_strncpy__(POSITION_INFO, arena, value, str_len); json->value.string = arena_strncpy__(POSITION_INFO, arena, value, str_len);
*s = end; *s = end;
} }
@@ -2422,10 +2381,10 @@ char *template_text_value_to_debug_str__(POSITION_INFO_DECLARATION, Arena *arena
return result; return result;
} }
char *template_value_to_debug_str__(POSITION_INFO_DECLARATION, Arena *arena, const char *name, const TemplateValue *self, TemplateNodeType type, PtrSet *visited) { char *template_value_to_debug_str__(POSITION_INFO_DECLARATION, Arena *arena, const char *name, const TemplateValue *self, TemplateNodeType active_variant, PtrSet *visited) {
char *result = arena_alloc(arena, MEM_KiB); char *result = arena_alloc(arena, MEM_KiB);
UNION_TO_DEBUG_STR(arena, result, TemplateValue, name, self, visited, type, 5, UNION_TO_DEBUG_STR(arena, result, TemplateValue, name, self, visited, active_variant, 5,
TEMPLATE_NODE_SECTION, template_section_value_to_debug_str__(POSITION_INFO, arena, "section", &self->section, visited), TEMPLATE_NODE_SECTION, template_section_value_to_debug_str__(POSITION_INFO, arena, "section", &self->section, visited),
TEMPLATE_NODE_INTERPOLATE, template_interpolate_value_to_debug_str__(POSITION_INFO, arena, "interpolate", &self->interpolate, visited), TEMPLATE_NODE_INTERPOLATE, template_interpolate_value_to_debug_str__(POSITION_INFO, arena, "interpolate", &self->interpolate, visited),
TEMPLATE_NODE_EXECUTE, template_execute_value_to_debug_str__(POSITION_INFO, arena, "execute", &self->execute, visited), TEMPLATE_NODE_EXECUTE, template_execute_value_to_debug_str__(POSITION_INFO, arena, "execute", &self->execute, visited),

View File

@@ -443,6 +443,8 @@ char *ptr_to_debug_str__(const char *file, const char *func, int line, Arena *ar
char *char_to_debug_str__(const char *file, const char *func, int line, Arena *arena, const char *name, char c); char *char_to_debug_str__(const char *file, const char *func, int line, Arena *arena, const char *name, char c);
char *bool_to_debug_str__(const char *file, const char *func, int line, Arena *arena, const char *name, int boolean);
char *union_to_debug_str__(const char *file, const char *func, int line, Arena *arena, const char *type, const char *name, const void *ptr, size_t active_variant, size_t count, ...); char *union_to_debug_str__(const char *file, const char *func, int line, Arena *arena, const char *type, const char *name, const void *ptr, size_t active_variant, size_t count, ...);
char *struct_to_debug_str__(const char *file, const char *func, int line, Arena *arena, const char *type, const char *name, const void *ptr, int count, ...); char *struct_to_debug_str__(const char *file, const char *func, int line, Arena *arena, const char *type, const char *name, const void *ptr, int count, ...);
@@ -463,6 +465,8 @@ bool debug_ptrset_contains(PtrSet *set, void *ptr);
ptr_to_debug_str__(__FILE__, __func__, __LINE__, arena, name, ptr) ptr_to_debug_str__(__FILE__, __func__, __LINE__, arena, name, ptr)
#define CHAR_TO_DEBUG_STR(arena, name, c) \ #define CHAR_TO_DEBUG_STR(arena, name, c) \
char_to_debug_str__(__FILE__, __func__, __LINE__, arena, name, c) char_to_debug_str__(__FILE__, __func__, __LINE__, arena, name, c)
#define BOOL_TO_DEBUG_STR(arena, name, boolean) \
bool_to_debug_str__(__FILE__, __func__, __LINE__, arena, name, boolean)
#define UNION_TO_DEBUG_STR(arena, buffer, type, name, ptr, visited, active_variant, count, ...) do { \ #define UNION_TO_DEBUG_STR(arena, buffer, type, name, ptr, visited, active_variant, count, ...) do { \
if (!name) \ if (!name) \
@@ -566,6 +570,8 @@ char *log_rules_to_debug_str__(const char *file, const char *func, int line, Are
// -- Json -- // -- Json --
// ---------- // ----------
typedef struct Json Json;
typedef enum { typedef enum {
JSON_NORAW = 0, JSON_NORAW = 0,
JSON_RAW = 1, JSON_RAW = 1,
@@ -580,18 +586,20 @@ typedef enum {
JSON_OBJECT, JSON_OBJECT,
} JsonType; } JsonType;
typedef union {
double number;
char *string;
int boolean;
Json *child; /* Child element (for arrays/objects) */
} JsonValue;
/* Full JSON structure */ /* Full JSON structure */
typedef struct Json { struct Json {
struct Json *next; /* Next sibling */ struct Json *next; /* Next sibling */
struct Json *child; /* Child element (for arrays/objects) */
JsonType type; JsonType type;
JsonValue value;
char *key; /* Key if item is in an object */ char *key; /* Key if item is in an object */
union { };
double number;
char *string;
int boolean;
} JsonValue;
} Json;
RESULT(Json, Json); RESULT(Json, Json);
@@ -609,9 +617,9 @@ Json *json_get_object_item__(const char* file, const char* func, int line, const
#define json_get_object_item(object, key) json_get_object_item__(__FILE__, __func__, __LINE__, object, key) #define json_get_object_item(object, key) json_get_object_item__(__FILE__, __func__, __LINE__, object, key)
char* json_to_debug_str__(const char* file, const char* func, int line, Arena *arena, Json json); char* json_to_debug_str__(const char* file, const char* func, int line, Arena *arena, const char *name, const Json *self, PtrSet *visited);
#define json_to_debug_str(arena, json) json_to_debug_str__(__FILE__, __func__, __LINE__, arena, json) #define JSON_TO_DEBUG_STR(arena, name, json) json_to_debug_str__(__FILE__, __func__, __LINE__, arena, name, json, ptrset_init(arena))
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);

View File

@@ -82,7 +82,7 @@ void test_struct_to_debug_str(Arena *arena) {
raise_notice("result: %s", result); raise_notice("result: %s", result);
char *check = arena_alloc(arena, MEM_KiB); char *check = arena_alloc(arena, MEM_KiB);
sprintf(check, "struct Struct struct = {a = 1, b = 2, struct Struct next = {a = 1, b = 2, struct Struct next = {cycle detected} %p} %p} %p", (void*)&test_struct, (void*)&test_struct, (void*)&test_struct); sprintf(check, "struct Struct struct = {a = 1, b = 2, struct Struct next = {a = 1, b = 2, struct Struct next = <cycle detected> %p} %p} %p", (void*)&test_struct, (void*)&test_struct, (void*)&test_struct);
raise_notice("check: %s", check); raise_notice("check: %s", check);
assert(strcmp(result, check) == 0); assert(strcmp(result, check) == 0);
} }
@@ -98,7 +98,7 @@ void test_struct2_to_debug_str(Arena *arena) {
char *result = struct2_to_debug_str(arena, "struct2", &test_struct2, visited); char *result = struct2_to_debug_str(arena, "struct2", &test_struct2, visited);
raise_notice("result: %s", result); raise_notice("result: %s", result);
char *check = arena_alloc(arena, MEM_KiB); char *check = arena_alloc(arena, MEM_KiB);
sprintf(check, "struct Struct2 struct2 = {a = 1, f = 3.140000, c = %p \"hello\", struct Struct other = {a = 1, b = 2, struct Struct next = {a = 1, b = 2, struct Struct next = {cycle detected} %p} %p} %p, struct Struct2 left = NULL} %p", (void*)test_struct2.c,(void*)&test_struct, (void*)&test_struct, (void*)&test_struct, (void*)&test_struct2); sprintf(check, "struct Struct2 struct2 = {a = 1, f = 3.140000, c = %p \"hello\", struct Struct other = {a = 1, b = 2, struct Struct next = {a = 1, b = 2, struct Struct next = <cycle detected> %p} %p} %p, struct Struct2 left = NULL} %p", (void*)test_struct2.c,(void*)&test_struct, (void*)&test_struct, (void*)&test_struct, (void*)&test_struct2);
raise_notice("check: %s", check); raise_notice("check: %s", check);
assert(strcmp(result, check) == 0); assert(strcmp(result, check) == 0);
} }

View File

@@ -7,15 +7,18 @@
#define ARENA_SIZE 1024 * 1024 #define ARENA_SIZE 1024 * 1024
#undef PRECOMPILED_LOG_LEVEL
#define PRECOMPILED_LOG_LEVEL LOG_LEVEL_ERROR
// Test 1: Parse JSON object with a string value. // Test 1: Parse JSON object with a string value.
static void test_parse_json_object(Arena *arena) { static void test_parse_json_object(Arena *arena) {
const char *json = "{\"key\":\"value\"}"; const char *json = "{\"key\":\"value\"}";
Json *root = json_parse(arena, &json); Json *root = json_parse(arena, &json);
assert(root->type == JSON_OBJECT); assert(root->type == JSON_OBJECT);
Json *child = root->child; Json *child = root->value.child;
assert(child && strcmp(child->key, "key") == 0); assert(child && strcmp(child->key, "key") == 0);
assert(child->type == JSON_STRING); assert(child->type == JSON_STRING);
assert(strcmp(child->JsonValue.string, "value") == 0); assert(strcmp(child->value.string, "value") == 0);
} }
// Test 2: Parse JSON number. // Test 2: Parse JSON number.
@@ -23,7 +26,7 @@ static void test_parse_json_number(Arena *arena) {
const char *json = "42"; const char *json = "42";
Json *root = json_parse(arena, &json); Json *root = json_parse(arena, &json);
assert(root->type == JSON_NUMBER); assert(root->type == JSON_NUMBER);
assert(root->JsonValue.number == 42); assert(root->value.number == 42);
} }
// Test 3: Parse JSON string. // Test 3: Parse JSON string.
@@ -31,7 +34,7 @@ static void test_parse_json_string(Arena *arena) {
const char *json = "\"hello\""; const char *json = "\"hello\"";
Json *root = json_parse(arena, &json); Json *root = json_parse(arena, &json);
assert(root->type == JSON_STRING); assert(root->type == JSON_STRING);
assert(strcmp(root->JsonValue.string, "hello") == 0); assert(strcmp(root->value.string, "hello") == 0);
} }
// Test 4: Get object items by key. // Test 4: Get object items by key.
@@ -40,10 +43,10 @@ static void test_get_object_items(Arena *arena) {
Json *root = json_parse(arena, &json); Json *root = json_parse(arena, &json);
Json *item_a = json_get_object_item(root, "a"); Json *item_a = json_get_object_item(root, "a");
assert(item_a && item_a->type == JSON_STRING); assert(item_a && item_a->type == JSON_STRING);
assert(strcmp(item_a->JsonValue.string, "1") == 0); assert(strcmp(item_a->value.string, "1") == 0);
Json *item_b = json_get_object_item(root, "b"); Json *item_b = json_get_object_item(root, "b");
assert(item_b && item_b->type == JSON_NUMBER); assert(item_b && item_b->type == JSON_NUMBER);
assert(item_b->JsonValue.number == 2); assert(item_b->value.number == 2);
} }
// Test 5: Print JSON object. // Test 5: Print JSON object.
@@ -88,7 +91,7 @@ static void test_nested_json_object(Arena *arena) {
Json *inner = json_get_object_item(outer, "inner"); Json *inner = json_get_object_item(outer, "inner");
assert(inner != NULL); assert(inner != NULL);
assert(inner->type == JSON_NUMBER); assert(inner->type == JSON_NUMBER);
assert(inner->JsonValue.number == 100); assert(inner->value.number == 100);
} }
@@ -105,14 +108,23 @@ static void test_arena_reset_reuse(Arena *arena) {
assert(strcmp(printed2, "\"another test\"") == 0); assert(strcmp(printed2, "\"another test\"") == 0);
} }
static void test_json_to_debug_str(Arena *arena) {
const char *json = "{\"key\":\"value\", \"num\":3.14}";
Json *root = json_parse(arena, &json);
raise_notice("root: %s", json_to_string(DISPOSABLE_ARENA, root));
char *debug_str = JSON_TO_DEBUG_STR(arena, "root", root);
raise_notice("debug_str: %s", debug_str);
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_string(arena, &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);
} }
@@ -122,6 +134,8 @@ int main(void) {
Arena arena = arena_init(ARENA_SIZE); Arena arena = arena_init(ARENA_SIZE);
logger_level(LOG_LEVEL_WARN);
test_parse_json_object(&arena); test_parse_json_object(&arena);
arena_reset(&arena); arena_reset(&arena);
test_parse_json_number(&arena); test_parse_json_number(&arena);
@@ -140,6 +154,9 @@ int main(void) {
arena_reset(&arena); arena_reset(&arena);
test_arena_reset_reuse(&arena); test_arena_reset_reuse(&arena);
arena_reset(&arena); arena_reset(&arena);
logger_level(LOG_LEVEL_TRACE);
test_json_to_debug_str(&arena);
arena_reset(&arena);
test_debug_str_to_json(&arena); test_debug_str_to_json(&arena);
arena_free(&arena); arena_free(&arena);