diff --git a/package/c/hectic/hectic.c b/package/c/hectic/hectic.c index 0fa3252..91720f4 100644 --- a/package/c/hectic/hectic.c +++ b/package/c/hectic/hectic.c @@ -198,9 +198,9 @@ char* raise_message( // -- debug -- // ----------- -PtrSet *ptrset_init(Arena *arena) { - PtrSet *set = arena_alloc(arena, sizeof(PtrSet)); - set->data = arena_alloc(arena, 4 * sizeof(void*)); +PtrSet *ptrset_init__(POSITION_INFO_DECLARATION, Arena *arena) { + PtrSet *set = arena_alloc__(POSITION_INFO, arena, sizeof(PtrSet)); + set->data = arena_alloc__(POSITION_INFO, arena, 4 * sizeof(void*)); set->size = 0; set->capacity = 4; return set; @@ -267,17 +267,13 @@ 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, void *ptr, int count, ...) { raise_message(LOG_LEVEL_TRACE, POSITION_INFO, "DEBUG STR: type: %s, name: %s, ptr: %p, count: %d", type, name, ptr, count); - char *result; - if ((ptr) == NULL) { - result = arena_strdup_fmt__(CTX(arena), "%s %s = NULL", type, name); - } else { - va_list args; - va_start(args, count); - char *joined = debug_join_debug_strings_v(CTX(arena), count, args); - va_end(args); - result = arena_strdup_fmt__(CTX(arena), "%s %s = {%s} %p", type, name, joined, ptr); - } - return result; + + va_list args; + va_start(args, count); + char *joined = debug_join_debug_strings_v(CTX(arena), count, args); + va_end(args); + + return arena_strdup_fmt__(CTX(arena), "%s %s = {%s} %p", type, name, joined, ptr); } // ------------ diff --git a/package/c/hectic/hectic.h b/package/c/hectic/hectic.h index 7410806..f36a9a2 100644 --- a/package/c/hectic/hectic.h +++ b/package/c/hectic/hectic.h @@ -352,7 +352,9 @@ typedef struct PtrSet { size_t capacity; } PtrSet; -PtrSet *ptrset_init(Arena *arena); +PtrSet *ptrset_init__(const char *file, const char *func, int line, Arena *arena); +#define ptrset_init(arena) ptrset_init__(__FILE__, __func__, __LINE__, arena) + bool debug_ptrset_contains__(PtrSet *set, void *ptr); void debug_ptrset_add__(const char *file, const char *func, int line, Arena *arena, PtrSet *set, void *ptr); @@ -384,20 +386,23 @@ char *struct_to_debug_str__(const char *file, const char *func, int line, Arena string_to_debug_str__(__FILE__, __func__, __LINE__, arena, name, string) #define NUMBER_TO_DEBUG_STR(arena, name, number) \ number_to_debug_str__(__FILE__, __func__, __LINE__, arena, name, number) -#define STRUCT_TO_DEBUG_STR(arena, type, name, self, count, ...) \ - struct_to_debug_str__(__FILE__, __func__, __LINE__, arena, #type, name, self, count, ##__VA_ARGS__) bool debug_ptrset_contains(PtrSet *set, void *ptr); -#define debug_check_cycle__(file, func, line, arena, type, name, self, visited) __extension__ ({ \ - if (debug_ptrset_contains__(visited, self)) \ - return struct_to_debug_str__(file, func, line, arena, \ - #type, name, self, 1, "cycle detected"); \ - debug_ptrset_add__(file, func, line, arena, visited, self); \ -}) - -#define DEBUG_CHECK_CYCLE(arena, type, name, self, visited) \ - debug_check_cycle__(__FILE__, __func__, __LINE__, arena, type, name, self, visited) +#define STRUCT_TO_DEBUG_STR(arena, buffer, type, name, ptr, visited, count, ...) do { \ + if (!name) \ + name = "$1"; \ + \ + if (debug_ptrset_contains__(visited, ptr)) \ + return arena_strdup_fmt__(__FILE__, __func__, __LINE__, arena, "%s %s = {cycle detected} %p", #type, name, ptr); \ + \ + if (!ptr) \ + return arena_strdup_fmt__(__FILE__, __func__, __LINE__, arena, "%s %s = NULL", #type, name); \ + \ + debug_ptrset_add__(__FILE__, __func__, __LINE__, arena, visited, ptr); \ + \ + buffer = struct_to_debug_str__(__FILE__, __func__, __LINE__, arena, #type, name, ptr, count, ##__VA_ARGS__); \ +} while (0) // ---------- // -- Json -- diff --git a/package/c/hectic/test/01-debug.c b/package/c/hectic/test/01-debug.c index 23939ee..dc4a612 100755 --- a/package/c/hectic/test/01-debug.c +++ b/package/c/hectic/test/01-debug.c @@ -19,33 +19,33 @@ struct TestStruct2 { TestStruct *other; }; -#define test_struct_to_debug_str(arena, name, self) test_struct_to_debug_str__(arena, name, self, ptrset_init(arena)) +char *test_struct_to_debug_str(Arena *arena, char *name, TestStruct *self, PtrSet *visited) { + raise_trace("test_struct_to_debug_str: name: %s, self: %p, visited: %p", name, self, visited); -char *test_struct_to_debug_str__(Arena *arena, char *name, TestStruct *self, PtrSet *visited) { - if (name == NULL) { - name = "$1"; - } - - DEBUG_CHECK_CYCLE(arena, TestStruct, name, self, visited); - - char *result = STRUCT_TO_DEBUG_STR(arena, TestStruct, name, self, 3, + char *result = arena_alloc(arena, MEM_KiB); + STRUCT_TO_DEBUG_STR(arena, result, TestStruct, name, self, visited, 3, NUMBER_TO_DEBUG_STR(arena, "a", self->a), NUMBER_TO_DEBUG_STR(arena, "b", self->b), - test_struct_to_debug_str__(arena, "next", self->next, visited) + test_struct_to_debug_str(arena, "next", self->next, visited) ); return result; } -//char *test_struct_to_debug_str__(Arena *arena, char *name, char *type, TestStruct *self) { -// char *result = arena_strdup_fmt(arena, "%s %s{", name, type); -// -// result = arena_strdup_fmt(arena, "%s%s", result, NUMBER_TO_DEBUG_STR(arena, "a", self->a)); -// result = arena_strdup_fmt(arena, "%s%s", result, NUMBER_TO_DEBUG_STR(arena, "b", self->b)); -// result = arena_strdup_fmt(arena, "%s%s", result, test_struct_to_debug_str__(arena, "next", TestStruct, self->next)); -// -// result = arena_strdup_fmt(arena, "%s} (%p)", result, self); -// return result; -//} +char *test_struct2_to_debug_str(Arena *arena, char *name, TestStruct2 *self, PtrSet *visited) { + raise_trace("test_struct2_to_debug_str: name: %s, self: %p, visited: %p", name, self, visited); + + char *result = arena_alloc(arena, MEM_KiB); + STRUCT_TO_DEBUG_STR(arena, result, TestStruct, name, self, visited, 5, + NUMBER_TO_DEBUG_STR(arena, "a", self->a), + NUMBER_TO_DEBUG_STR(arena, "f", self->f), + STRING_TO_DEBUG_STR(arena, "c", self->c), + test_struct_to_debug_str(arena, "other", self->other, visited), + test_struct2_to_debug_str(arena, "left", self->left, visited) + ); + + raise_trace("returning result"); + return result; +} int main(void) { printf("%sRunning %s%s%s\n", OPTIONAL_COLOR(COLOR_GREEN), OPTIONAL_COLOR(COLOR_CYAN), __FILE__, OPTIONAL_COLOR(COLOR_RESET)); @@ -53,8 +53,16 @@ int main(void) { TestStruct test_struct = {.a = 1, .b = 2, .next = NULL}; test_struct.next = &test_struct; - raise_notice("%s", test_struct_to_debug_str(DISPOSABLE_ARENA, "test_struct", &test_struct)); + Arena lifetime = arena_init(MEM_MiB); + PtrSet *visited = ptrset_init(&lifetime); + raise_notice("%s", test_struct_to_debug_str(&lifetime, "test_struct", &test_struct, visited)); + TestStruct2 test_struct2 = {.a = 1, .c = "hello", .f = 3.14, .left = NULL, .other = &test_struct}; + visited = ptrset_init(&lifetime); + raise_notice("%s", test_struct2_to_debug_str(&lifetime, "test_struct2", &test_struct2, visited)); + + + arena_free(&lifetime); printf("%sAll tests passed %s%s%s\n", OPTIONAL_COLOR(COLOR_GREEN), OPTIONAL_COLOR(COLOR_CYAN), __FILE__, OPTIONAL_COLOR(COLOR_RESET)); return 0; } \ No newline at end of file