From 4280f0df9597613170196da94cd5a8c0af56f3fc Mon Sep 17 00:00:00 2001 From: yukkop Date: Mon, 24 Mar 2025 14:12:55 +0000 Subject: [PATCH] refactor(hectic C): fix warnings --- package/c/hectic/hectic.c | 117 ++++++++++++++++++++++++- package/c/hectic/hectic.h | 144 +++++++++---------------------- package/c/hectic/test/01-arena.c | 8 +- package/c/hectic/test/02-json.c | 13 +-- package/c/hmpl/hmpl.c | 19 +--- 5 files changed, 171 insertions(+), 130 deletions(-) diff --git a/package/c/hectic/hectic.c b/package/c/hectic/hectic.c index e5e9442..9a31a89 100644 --- a/package/c/hectic/hectic.c +++ b/package/c/hectic/hectic.c @@ -55,7 +55,7 @@ void init_logger(void) { current_log_level = log_level_from_string(getenv("LOG_LEVEL")); } -char* log_message(LogLevel level, char *file, int line, const char *format, ...) { +char* raise_message(LogLevel level, const char *file, int line, const char *format, ...) { if (level < current_log_level) { return NULL; } @@ -78,11 +78,124 @@ char* log_message(LogLevel level, char *file, int line, const char *format, ...) return timeStr; } +// ----------- +// -- arena -- +// ----------- + +Arena arena_init__(const char *file, int line, size_t size) { + Arena arena; + arena.begin = malloc(size); + memset(arena.begin, 0, size); + arena.current = arena.begin; + arena.capacity = size; + raise_message(LOG_LEVEL_DEBUG, file, line, + "Initialized arena at %p with capacity %zu", arena.begin, size); + return arena; +} + +void* arena_alloc_or_null__(const char *file, int line, Arena *arena, size_t size) { + raise_message(LOG_LEVEL_TRACE, file, line, "arena_alloc_or_null(%p, %zu)", arena, size); + void *mem = NULL; + if (arena->begin == 0) { + *arena = arena_init__(file, line, 1024); // ARENA_DEFAULT_SIZE assumed as 1024 + } + size_t current = (size_t)arena->current - (size_t)arena->begin; + if (arena->capacity <= current || arena->capacity - current < size) { + raise_message(LOG_LEVEL_DEBUG, file, line, + "Arena %p (capacity %zu) used %zu cannot allocate %zu bytes", + arena->begin, arena->capacity, current, size); + return NULL; + } else { + raise_message(LOG_LEVEL_DEBUG, file, line, + "Arena %p (capacity %zu) used %zu will allocate %zu bytes", + arena->begin, arena->capacity, current, size); + mem = arena->current; + arena->current = (char*)arena->current + size; + } + raise_message(LOG_LEVEL_DEBUG, file, line, "Allocated at %p", mem); + return mem; +} + +void* arena_alloc__(const char *file, int line, Arena *arena, size_t size) { + void *mem = arena_alloc_or_null__(file, line, arena, size); + if (!mem) { + raise_message(LOG_LEVEL_DEBUG, file, line, + "Arena out of memory when trying to allocate %zu bytes", size); + raise_message(LOG_LEVEL_EXCEPTION, file, line, + "Arena out of memory"); + exit(1); + } + return mem; +} + +void arena_reset__(const char *file, int line, Arena *arena) { + arena->current = arena->begin; + raise_message(LOG_LEVEL_DEBUG, file, line, + "Arena %p reset", arena->begin); +} + +void arena_free__(const char *file, int line, Arena *arena) { + raise_message(LOG_LEVEL_DEBUG, file, line, + "Freeing arena at %p", arena->begin); + free(arena->begin); +} + +char* arena_strdup__(const char *file, int line, Arena *arena, const char *s) { + char *result; + if (s) { + size_t len = strlen(s) + 1; + result = (char*)arena_alloc__(file, line, arena, len); + memcpy(result, s, len); + } else { + result = NULL; + } + return result; +} + +char* arena_repstr__(const char *file, int line, Arena *arena, + const char *src, size_t start, size_t len, const char *rep) { + int src_len = strlen(src); + int rep_len = strlen(rep); + int new_len = src_len - (int)len + rep_len; + char *new_str = (char*)arena_alloc__(file, line, arena, new_len + 1); + memcpy(new_str, src, start); + memcpy(new_str + start, rep, rep_len); + strcpy(new_str + start + rep_len, src + start + len); + return new_str; +} + +void* arena_realloc_copy__(const char *file, int line, Arena *arena, + void *old_ptr, size_t old_size, size_t new_size) { + void *new_ptr = NULL; + if (old_ptr == NULL) { + new_ptr = arena_alloc__(file, line, arena, new_size); + } else if (new_size <= old_size) { + new_ptr = old_ptr; + } else { + new_ptr = arena_alloc_or_null__(file, line, arena, new_size); + if (new_ptr) + memcpy(new_ptr, old_ptr, old_size); + } + return new_ptr; +} + // ---------- // -- misc -- // ---------- -//void fomatBytes(size_t bytes, char ) +void substr_clone(const char *src, char *dest, size_t start, size_t len) { + raise_debug("substr_cloneing %s (%p) from %p to %zu", src, src, start, len); + size_t srclen = strlen(src); + if (start >= srclen) { + dest[0] = '\0'; + return; + } + if (start + len > srclen) + len = srclen - start; + strncpy(dest, src + start, len); + dest[len] = '\0'; + raise_trace("%s", dest); +} // ---------- // -- Json -- diff --git a/package/c/hectic/hectic.h b/package/c/hectic/hectic.h index ec64370..de1e027 100644 --- a/package/c/hectic/hectic.h +++ b/package/c/hectic/hectic.h @@ -80,23 +80,15 @@ void logger_level(LogLevel level); LogLevel log_level_from_string(const char *level_str); -char* log_message(LogLevel level, char *file, int line, const char *format, ...); +char* raise_message(LogLevel level, const char *file, int line, const char *format, ...); -#define raise_trace_with_opt(file, line, fmt, ...) log_message(LOG_LEVEL_TRACE, file, line, fmt, ##__VA_ARGS__) -#define raise_debug_with_opt(file, line, fmt, ...) log_message(LOG_LEVEL_DEBUG, file, line, fmt, ##__VA_ARGS__) -#define raise_log_with_opt(file, line, fmt, ...) log_message(LOG_LEVEL_LOG, file, line, fmt, ##__VA_ARGS__) -#define raise_info_with_opt(file, line, fmt, ...) log_message(LOG_LEVEL_INFO, file, line, fmt, ##__VA_ARGS__) -#define raise_notice_with_opt(file, line, fmt, ...) log_message(LOG_LEVEL_NOTICE, file, line, fmt, ##__VA_ARGS__) -#define raise_warn_with_opt(file, line, fmt, ...) log_message(LOG_LEVEL_WARN, file, line, fmt, ##__VA_ARGS__) -#define raise_exception_with_opt(file, line, fmt, ...) log_message(LOG_LEVEL_EXCEPTION, file, line, fmt, ##__VA_ARGS__) - -#define raise_trace(fmt, ...) log_message(LOG_LEVEL_TRACE, __FILE__, __LINE__, fmt, ##__VA_ARGS__) -#define raise_debug(fmt, ...) log_message(LOG_LEVEL_DEBUG, __FILE__, __LINE__, fmt, ##__VA_ARGS__) -#define raise_log(fmt, ...) log_message(LOG_LEVEL_LOG, __FILE__, __LINE__, fmt, ##__VA_ARGS__) -#define raise_info(fmt, ...) log_message(LOG_LEVEL_INFO, __FILE__, __LINE__, fmt, ##__VA_ARGS__) -#define raise_notice(fmt, ...) log_message(LOG_LEVEL_NOTICE, __FILE__, __LINE__, fmt, ##__VA_ARGS__) -#define raise_warn(fmt, ...) log_message(LOG_LEVEL_WARN, __FILE__, __LINE__, fmt, ##__VA_ARGS__) -#define raise_exception(fmt, ...) log_message(LOG_LEVEL_EXCEPTION, __FILE__, __LINE__, fmt, ##__VA_ARGS__) +#define raise_trace(fmt, ...) raise_message(LOG_LEVEL_TRACE, __FILE__, __LINE__, fmt, ##__VA_ARGS__) +#define raise_debug(fmt, ...) raise_message(LOG_LEVEL_DEBUG, __FILE__, __LINE__, fmt, ##__VA_ARGS__) +#define raise_log(fmt, ...) raise_message(LOG_LEVEL_LOG, __FILE__, __LINE__, fmt, ##__VA_ARGS__) +#define raise_info(fmt, ...) raise_message(LOG_LEVEL_INFO, __FILE__, __LINE__, fmt, ##__VA_ARGS__) +#define raise_notice(fmt, ...) raise_message(LOG_LEVEL_NOTICE, __FILE__, __LINE__, fmt, ##__VA_ARGS__) +#define raise_warn(fmt, ...) raise_message(LOG_LEVEL_WARN, __FILE__, __LINE__, fmt, ##__VA_ARGS__) +#define raise_exception(fmt, ...) raise_message(LOG_LEVEL_EXCEPTION, __FILE__, __LINE__, fmt, ##__VA_ARGS__) // ----------- // -- arena -- @@ -110,101 +102,49 @@ typedef struct { size_t capacity; } Arena; +Arena arena_init__(const char *file, int line, size_t size); + +void* arena_alloc_or_null__(const char *file, int line, Arena *arena, size_t size); + +void* arena_alloc__(const char *file, int line, Arena *arena, size_t size); + +void arena_reset__(const char *file, int line, Arena *arena); + +void arena_free__(const char *file, int line, Arena *arena); + +char* arena_strdup__(const char *file, int line, Arena *arena, const char *s); + +char* arena_repstr__(const char *file, int line, Arena *arena, + const char *src, size_t start, size_t len, const char *rep); + +void* arena_realloc_copy__(const char *file, int line, Arena *arena, + void *old_ptr, size_t old_size, size_t new_size); + // NOTE(yukkop): This macro is used to define procedures so that `__LINE__` and `__FILE__` // in `raise_debug` reflect the location where the macro is called, not where it's defined. -#define arena_alloc_or_null(arena, size) __extension__ ({ \ - raise_trace("arena_alloc_or_null(%p, %zu)", (arena), (size)); \ - void *mem__ = NULL; \ - if ((arena)->begin == 0) { \ - *(arena) = arena_init(ARENA_DEFAULT_SIZE); \ - } \ - size_t current__ = (size_t)(arena)->current - (size_t)(arena)->begin; \ - if ((arena)->capacity <= current__ || (arena)->capacity - current__ < (size)) {\ - raise_debug("Arena %p (capacity %zu) used %zu cannot allocate %zu bytes", \ - (arena)->begin, (arena)->capacity, current__, (size)); \ - } else { \ - raise_debug("Arena %p (capacity %zu) used %zu will allocate %zu bytes", \ - (arena)->begin, (arena)->capacity, current__, (size)); \ - mem__ = (arena)->current; \ - (arena)->current = (char*)(arena)->current + (size); \ - } \ - raise_debug("Allocated at %p", mem__); \ - mem__; \ -}) +#define arena_alloc_or_null(arena, size) \ + arena_alloc_or_null__(__FILE__, __LINE__, arena, size) -#define arena_init(size) __extension__ ({ \ - Arena arena__; \ - arena__.begin = malloc(size); \ - memset(arena__.begin, 0, size); \ - arena__.current = arena__.begin; \ - arena__.capacity = size; \ - raise_debug("Initialized arena at %p with capacity %zu", arena__.begin, size); \ - arena__; \ -}) +#define arena_init(size) \ + arena_init__(__FILE__, __LINE__, size) -#define arena_reset(arena) __extension__ ({ \ - (arena)->current = (arena)->begin; \ - raise_debug("Arena %p reset", (arena)->begin); \ -}) +#define arena_reset(arena) \ + arena_reset__(__FILE__, __LINE__, arena) -#define arena_free(arena) __extension__ ({ \ - raise_debug("Freeing arena at %p", (arena)->begin); \ - free((arena)->begin); \ -}) +#define arena_free(arena) \ + arena_free__(__FILE__, __LINE__, arena) -#define arena_alloc(arena, size) __extension__ ({ \ - void *mem__ = arena_alloc_or_null((arena), (size)); \ - if (!mem__) { \ - raise_debug("Arena out of memory when trying to allocate %zu bytes", (size)); \ - raise_exception("Arena out of memory"); \ - exit(1); \ - } \ - mem__; \ -}) +#define arena_alloc(arena, size) \ + arena_alloc__(__FILE__, __LINE__, arena, size) -#define arena_strdup(arena, s) __extension__ ({ \ - const char *s__ = (s); \ - char *result__; \ - if (s__) { \ - size_t len__ = strlen(s__) + 1; \ - result__ = (char *)arena_alloc(arena, len__); \ - memcpy(result__, s__, len__); \ - } else { \ - result__ = NULL; \ - } \ - result__; \ -}) +#define arena_strdup(arena, s) \ + arena_strdup__(__FILE__, __LINE__, arena, s) -#define arena_repstr(arena, src, start, len, rep) __extension__ ({ \ - const char *src__ = (src); \ - const char *rep__ = (rep); \ - size_t start__ = (start); \ - size_t len__ = (len); \ - int src_len__ = strlen(src__); \ - int rep_len__ = strlen(rep__); \ - int new_len__ = src_len__ - len__ + 1 + rep_len__; \ - char *new_str__ = (char *)arena_alloc(arena, new_len__ + 1); \ - memcpy(new_str__, src__, start__); \ - memcpy(new_str__ + start__, rep__, rep_len__); \ - strcpy(new_str__ + start__ + rep_len__, src__ + start__ + len__ + 1); \ - new_str__; \ -}) +#define arena_repstr(arena, src, start, len, rep) \ + arena_repstr__(__FILE__, __LINE__, arena, src, start, len, rep) -#define arena_realloc_copy(arena, old_ptr, old_size, new_size) __extension__ ({ \ - void *old__ = (old_ptr); \ - size_t old_size__ = (old_size); \ - size_t new_size__ = (new_size); \ - void *new__ = NULL; \ - if (old__ == NULL) { \ - new__ = arena_alloc((arena), new_size__); \ - } else if (new_size__ <= old_size__) { \ - new__ = old__; \ - } else { \ - new__ = arena_alloc_or_null((arena), new_size__); \ - if (new__) memcpy(new__, old__, old_size__); \ - } \ - new__; \ -}) +#define arena_realloc_copy(arena, old_ptr, old_size, new_size) \ + arena_realloc_copy__(__FILE__, __LINE__, arena, old_ptr, old_size, new_size) // ---------- // -- misc -- diff --git a/package/c/hectic/test/01-arena.c b/package/c/hectic/test/01-arena.c index 9b14ebf..e0f774b 100644 --- a/package/c/hectic/test/01-arena.c +++ b/package/c/hectic/test/01-arena.c @@ -60,10 +60,10 @@ void test_arena_repstr() { Arena arena = arena_init(128); const char *original = "Hello, World!"; // Replace substr_cloneing starting at index 5, length 3 (", W") with " -" - // According to the macro logic, the suffix is taken from original[5+3+1] onward. - // That results in: "Hello" + " -" + "rld!" = "Hello -rld!" + // That results in: "Hello" + " -" + "orld!" = "Hello -orld!" char *result = arena_repstr(&arena, original, 5, 3, " -"); - assert(strcmp(result, "Hello -rld!") == 0); + raise_debug("%s", result); + assert(strcmp(result, "Hello -orld!") == 0); arena_free(&arena); } @@ -81,7 +81,7 @@ void test_arena_overwrite_detection() { // Force allocation near capacity void *large = arena_alloc_or_null(&arena, 100); - assert(large != NULL || arena.current == arena.begin + arena.capacity); // If NULL, out of memory + assert(large != NULL || (size_t)arena.current == (size_t)arena.begin + arena.capacity); // If NULL, out of memory // Check strings again assert(strcmp(s1, "hello") == 0); diff --git a/package/c/hectic/test/02-json.c b/package/c/hectic/test/02-json.c index d15abf1..866bbe2 100644 --- a/package/c/hectic/test/02-json.c +++ b/package/c/hectic/test/02-json.c @@ -16,7 +16,7 @@ static void test_parse_json_object(void) { Json *child = root->child; assert(child && strcmp(child->key, "key") == 0); assert(child->type == JSON_STRING); - assert(strcmp(child->string, "value") == 0); + assert(strcmp(child->JsonValue.string, "value") == 0); arena_free(&arena); } @@ -26,7 +26,7 @@ static void test_parse_json_number(void) { const char *json = "42"; Json *root = json_parse(&arena, &json); assert(root->type == JSON_NUMBER); - assert(root->number == 42); + assert(root->JsonValue.number == 42); arena_free(&arena); } @@ -36,7 +36,7 @@ static void test_parse_json_string(void) { const char *json = "\"hello\""; Json *root = json_parse(&arena, &json); assert(root->type == JSON_STRING); - assert(strcmp(root->string, "hello") == 0); + assert(strcmp(root->JsonValue.string, "hello") == 0); arena_free(&arena); } @@ -47,10 +47,10 @@ static void test_get_object_items(void) { Json *root = json_parse(&arena, &json); Json *item_a = json_get_object_item(root, "a"); assert(item_a && item_a->type == JSON_STRING); - assert(strcmp(item_a->string, "1") == 0); + assert(strcmp(item_a->JsonValue.string, "1") == 0); Json *item_b = json_get_object_item(root, "b"); assert(item_b && item_b->type == JSON_NUMBER); - assert(item_b->number == 2); + assert(item_b->JsonValue.number == 2); arena_free(&arena); } @@ -103,7 +103,7 @@ static void test_nested_json_object(void) { Json *inner = json_get_object_item(outer, "inner"); assert(inner != NULL); assert(inner->type == JSON_NUMBER); - assert(inner->number == 100); + assert(inner->JsonValue.number == 100); arena_free(&arena); } @@ -114,6 +114,7 @@ static void test_arena_reset_reuse(void) { const char *json1 = "{\"key\":\"value\"}"; Json *root1 = json_parse(&arena, &json1); char *printed1 = json_to_string(&arena, root1); + assert(strcmp(printed1, "{\"key\":\"value\"}") == 0); arena_reset(&arena); const char *json2 = "\"another test\""; Json *root2 = json_parse(&arena, &json2); diff --git a/package/c/hmpl/hmpl.c b/package/c/hmpl/hmpl.c index 84a7953..03fd28f 100644 --- a/package/c/hmpl/hmpl.c +++ b/package/c/hmpl/hmpl.c @@ -132,20 +132,6 @@ void hmpl_render_interpolation_tags(Arena *arena, char **text_ptr, Json *context // RETURN result; // END $$; -void substr_clone(const char *src, char *dest, size_t start, size_t len) { - raise_debug("substr_cloneing %s (%p) from %p to %zu", src, src, start, len); - size_t srclen = strlen(src); - if (start >= srclen) { - dest[0] = '\0'; - return; - } - if (start + len > srclen) - len = srclen - start; - strncpy(dest, src + start, len); - dest[len] = '\0'; - raise_trace("%s", dest); -} - // {{#array_key}} void hmpl_render_section_tags(Arena *arena, char **text_ptr, Json *context, const char * const prefix_start, const char * const prefix_end, const char * const separator_pattern){ raise_debug("hmpl_render_section_tags"); @@ -198,12 +184,13 @@ void hmpl_render_section_tags(Arena *arena, char **text_ptr, Json *context, cons int key_length = (opening_tag_separator - current_text) - relative_key_start; assert(key_length > 0); printf('key'); + char *key = arena_alloc(arena, key_length + 1); - printf('key'); //substr_clone(current_text, key, relative_key_start, key_length); + printf('key'); key[2] = 'c'; char c=key[2]; - printf('key'); + printf('ksdjfoejisvjmeiw'); printf('key: %d\n', c); printf('key: %p\n', key[2]); printf('key: %p\n', key);