feat: hectic C: debug constructor impruve
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
// ------------
|
||||
|
||||
@@ -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 --
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user