Add name to alloc_tracker

This commit is contained in:
jun 2025-05-14 17:08:15 +02:00
parent 37f9011166
commit 894d9e8fc4
10 changed files with 127 additions and 56 deletions

View File

@ -84,11 +84,12 @@ static inline guf_allocator *guf_libc_allocator_init(guf_allocator *a, guf_libc_
return a; return a;
} }
static guf_allocator guf_allocator_libc = { static inline guf_allocator guf_libc_allocator_new(guf_libc_alloc_ctx *ctx)
.alloc = guf_libc_alloc, {
.realloc = guf_libc_realloc, guf_allocator a;
.free = guf_libc_free, guf_libc_allocator_init(&a, ctx);
.ctx = NULL return a;
}; }
#endif #endif

View File

@ -9,9 +9,11 @@
#include <stdio.h> #include <stdio.h>
#include "guf_common.h" #include "guf_common.h"
#include "guf_str_view_type.h"
typedef struct guf_alloc_tracker { typedef struct guf_alloc_tracker {
FILE *log, *err_log; FILE *log, *err_log;
const char *name;
size_t alloc_count, realloc_count, free_count; size_t alloc_count, realloc_count, free_count;
ptrdiff_t allocated_bytes; ptrdiff_t allocated_bytes;
uint32_t id; uint32_t id;
@ -19,9 +21,11 @@ typedef struct guf_alloc_tracker {
} guf_alloc_tracker; } guf_alloc_tracker;
#if !defined(GUF_ALLOC_TRACKER_IMPL_STATIC) && !defined(GUF_ALLOC_TRACKER_IMPL) #if !defined(GUF_ALLOC_TRACKER_IMPL_STATIC) && !defined(GUF_ALLOC_TRACKER_IMPL)
GUF_ALLOC_TRACKER_KWRDS guf_alloc_tracker *guf_alloc_tracker_init(guf_alloc_tracker *t, uint32_t id, FILE *log, FILE *err_log); GUF_ALLOC_TRACKER_KWRDS guf_alloc_tracker *guf_alloc_tracker_init(guf_alloc_tracker *t, uint32_t id, const char* name, FILE *log, FILE *err_log);
GUF_ALLOC_TRACKER_KWRDS guf_alloc_tracker guf_alloc_tracker_new(uint32_t id, const char* name, FILE *log, FILE *err_log);
GUF_ALLOC_TRACKER_KWRDS void guf_alloc_tracker_print(const guf_alloc_tracker *t, FILE *f); GUF_ALLOC_TRACKER_KWRDS void guf_alloc_tracker_print(const guf_alloc_tracker *t, FILE *f);
GUF_ALLOC_TRACKER_KWRDS bool guf_alloc_tracker_found_leak(guf_alloc_tracker *t); GUF_ALLOC_TRACKER_KWRDS bool guf_alloc_tracker_found_leak(const guf_alloc_tracker *t);
GUF_ALLOC_TRACKER_KWRDS bool guf_track_alloc(guf_alloc_tracker *t, ptrdiff_t size); GUF_ALLOC_TRACKER_KWRDS bool guf_track_alloc(guf_alloc_tracker *t, ptrdiff_t size);
GUF_ALLOC_TRACKER_KWRDS bool guf_track_realloc(guf_alloc_tracker *t, ptrdiff_t old_size, ptrdiff_t new_size); GUF_ALLOC_TRACKER_KWRDS bool guf_track_realloc(guf_alloc_tracker *t, ptrdiff_t old_size, ptrdiff_t new_size);
@ -34,19 +38,27 @@ typedef struct guf_alloc_tracker {
#define GUF_MATH_CKDINT_IMPL_STATIC #define GUF_MATH_CKDINT_IMPL_STATIC
#include "guf_math_ckdint.h" #include "guf_math_ckdint.h"
GUF_ALLOC_TRACKER_KWRDS guf_alloc_tracker *guf_alloc_tracker_init(guf_alloc_tracker *t, uint32_t id, FILE *log, FILE *err_log) GUF_ALLOC_TRACKER_KWRDS guf_alloc_tracker *guf_alloc_tracker_init(guf_alloc_tracker *t, uint32_t id, const char* name, FILE *log, FILE *err_log)
{ {
GUF_ASSERT_RELEASE(t); GUF_ASSERT_RELEASE(t);
t->log = log; t->log = log;
t->err_log = err_log; t->err_log = err_log;
t->alloc_count = t->realloc_count = t->free_count = 0; t->alloc_count = t->realloc_count = t->free_count = 0;
t->allocated_bytes = 0; t->allocated_bytes = 0;
t->name = name;
t->id = id; t->id = id;
t->enabled = true; t->enabled = true;
return t; return t;
} }
GUF_ALLOC_TRACKER_KWRDS bool guf_alloc_tracker_found_leak(guf_alloc_tracker *t) GUF_ALLOC_TRACKER_KWRDS guf_alloc_tracker guf_alloc_tracker_new(uint32_t id, const char* name, FILE *log, FILE *err_log)
{
guf_alloc_tracker t;
guf_alloc_tracker_init(&t, id, name, log, err_log);
return t;
}
GUF_ALLOC_TRACKER_KWRDS bool guf_alloc_tracker_found_leak(const guf_alloc_tracker *t)
{ {
GUF_ASSERT_RELEASE(t); GUF_ASSERT_RELEASE(t);
return (t->allocated_bytes != 0) || (t->alloc_count != t->free_count); return (t->allocated_bytes != 0) || (t->alloc_count != t->free_count);
@ -66,12 +78,12 @@ GUF_ALLOC_TRACKER_KWRDS void guf_alloc_tracker_print(const guf_alloc_tracker *t,
} }
fprintf(f, fprintf(f,
"guf_alloc_tracker (id = %" PRIu32 "):\n" "guf_alloc_tracker (name '%s' id = %" PRIu32 "):\n"
"allocated_bytes: %td\n" "allocated_bytes: %td\n"
"alloc_count: %zu\n" "alloc_count: %zu\n"
"realloc_count: %zu\n" "realloc_count: %zu\n"
"free_count: %zu\n", "free_count: %zu\n",
t->id, t->allocated_bytes, t->alloc_count, t->realloc_count, t->free_count t->name ? t->name : "unnamed", t->id, t->allocated_bytes, t->alloc_count, t->realloc_count, t->free_count
); );
} }
@ -84,25 +96,25 @@ GUF_ALLOC_TRACKER_KWRDS bool guf_track_alloc(guf_alloc_tracker *t, ptrdiff_t siz
bool success = true; bool success = true;
if (guf_saturating_add_size_t(t->alloc_count, 1, &t->alloc_count) != GUF_MATH_CKD_SUCCESS && t->err_log) { if (guf_saturating_add_size_t(t->alloc_count, 1, &t->alloc_count) != GUF_MATH_CKD_SUCCESS && t->err_log) {
fprintf(t->err_log, "WARNING in guf_track_alloc (id %" PRIu32 "): alloc_count reached SIZE_MAX\n", t->id); fprintf(t->err_log, "WARNING in guf_track_alloc (name '%s' id %" PRIu32 "): alloc_count reached SIZE_MAX\n", t->name ? t->name : "unnamed", t->id);
} }
if (guf_saturating_add_ptrdiff_t(t->allocated_bytes, size, &t->allocated_bytes) != GUF_MATH_CKD_SUCCESS) { if (guf_saturating_add_ptrdiff_t(t->allocated_bytes, size, &t->allocated_bytes) != GUF_MATH_CKD_SUCCESS) {
if (t->err_log) { if (t->err_log) {
fprintf(t->err_log, "ERROR in guf_track_alloc (id %" PRIu32 "): allocated_byte overflow\n", t->id); fprintf(t->err_log, "ERROR in guf_track_alloc (name '%s' id %" PRIu32 "): allocated_byte overflow\n", t->name ? t->name : "unnamed", t->id);
} }
success = false; success = false;
} }
if (t->allocated_bytes < 0) { if (t->allocated_bytes < 0) {
if (t->err_log) { if (t->err_log) {
fprintf(t->err_log, "ERROR in guf_track_alloc (id %" PRIu32 "): allocated_bytes < 0\n", t->id); fprintf(t->err_log, "ERROR in guf_track_alloc (name '%s' id %" PRIu32 "): allocated_bytes < 0\n", t->name ? t->name : "unnamed", t->id);
} }
success = false; success = false;
} }
if (t->log) { if (t->log) {
fprintf(t->log, "guf_alloc_tracker (id %" PRIu32 "): alloc (%td bytes) %s\n", t->id, size, success ? "SUCCESS" : "FAILURE"); fprintf(t->log, "guf_alloc_tracker (name '%s' id %" PRIu32 "): alloc (%td bytes) %s\n", t->name ? t->name : "unnamed", t->id, size, success ? "SUCCESS" : "FAILURE");
} }
return success; return success;
} }
@ -115,40 +127,40 @@ GUF_ALLOC_TRACKER_KWRDS bool guf_track_realloc(guf_alloc_tracker *t, ptrdiff_t o
bool success = true; bool success = true;
if (guf_saturating_add_size_t(t->realloc_count, 1, &t->realloc_count) && t->err_log) { if (guf_saturating_add_size_t(t->realloc_count, 1, &t->realloc_count) && t->err_log) {
fprintf(t->err_log, "WARNING in guf_track_realloc (id %" PRIu32 "): realloc_count reached SIZE_MAX\n", t->id); fprintf(t->err_log, "WARNING in guf_track_realloc (name '%s' id %" PRIu32 "): realloc_count reached SIZE_MAX\n", t->name ? t->name : "unnamed", t->id);
} }
if (old_size < 0 || new_size < 0) { if (old_size < 0 || new_size < 0) {
success = false; success = false;
if (t->err_log) { if (t->err_log) {
fprintf(t->err_log, "ERROR in guf_track_realloc (id %" PRIu32 "): old_size < 0 or new_size < 0\n", t->id); fprintf(t->err_log, "ERROR in guf_track_realloc (name '%s' id %" PRIu32 "): old_size < 0 or new_size < 0\n", t->name ? t->name : "unnamed", t->id);
} }
} }
if (guf_saturating_sub_ptrdiff_t(t->allocated_bytes, old_size, &t->allocated_bytes)) { if (guf_saturating_sub_ptrdiff_t(t->allocated_bytes, old_size, &t->allocated_bytes)) {
success = false; success = false;
if (t->err_log) { if (t->err_log) {
fprintf(t->err_log, "ERROR in guf_track_realloc (id %" PRIu32 "): allocated_bytes - old_size under/overflows\n", t->id); fprintf(t->err_log, "ERROR in guf_track_realloc (name '%s' id %" PRIu32 "): allocated_bytes - old_size under/overflows\n", t->name ? t->name : "unnamed", t->id);
} }
} }
if (t->allocated_bytes < 0) { if (t->allocated_bytes < 0) {
success = false; success = false;
fprintf(t->err_log, "ERROR in guf_track_realloc (id %" PRIu32 "): allocated_bytes < 0 after subtracting old_size\n", t->id); fprintf(t->err_log, "ERROR in guf_track_realloc (name '%s' id %" PRIu32 "): allocated_bytes < 0 after subtracting old_size\n", t->name ? t->name : "unnamed", t->id);
} }
if (guf_saturating_add_ptrdiff_t(t->allocated_bytes, new_size, &t->allocated_bytes)) { if (guf_saturating_add_ptrdiff_t(t->allocated_bytes, new_size, &t->allocated_bytes)) {
success = false; success = false;
if (t->err_log) { if (t->err_log) {
fprintf(t->err_log, "ERROR in guf_track_realloc (id %" PRIu32 "): allocated_bytes overflow \n", t->id); fprintf(t->err_log, "ERROR in guf_track_realloc (name '%s' id %" PRIu32 "): allocated_bytes overflow \n", t->name ? t->name : "unnamed", t->id);
} }
} }
if (t->allocated_bytes < 0) { if (t->allocated_bytes < 0) {
success = false; success = false;
fprintf(t->err_log, "ERROR in guf_track_realloc (id %" PRIu32 "): allocated_bytes < 0 after adding new_size\n", t->id); fprintf(t->err_log, "ERROR in guf_track_realloc (name '%s' id %" PRIu32 "): allocated_bytes < 0 after adding new_size\n", t->name ? t->name : "unnamed", t->id);
} }
if (t->log) { if (t->log) {
fprintf(t->log, "guf_alloc_tracker (id %" PRIu32 "): realloc (from %td to %td bytes) %s\n", t->id, old_size, new_size, (success ? "SUCCESS" : "FAILURE")); fprintf(t->log, "guf_alloc_tracker (name '%s' id %" PRIu32 "): realloc (from %td to %td bytes) %s\n", t->name ? t->name : "unnamed", t->id, old_size, new_size, (success ? "SUCCESS" : "FAILURE"));
} }
return success; return success;
@ -161,31 +173,31 @@ GUF_ALLOC_TRACKER_KWRDS bool guf_track_free(guf_alloc_tracker *t, ptrdiff_t size
bool success = true; bool success = true;
if (guf_saturating_add_size_t(t->free_count, 1, &t->free_count) && t->err_log) { if (guf_saturating_add_size_t(t->free_count, 1, &t->free_count) && t->err_log) {
fprintf(t->err_log, "WARNING in guf_track_free (id %" PRIu32 "): free_count reached SIZE_MAX\n", t->id); fprintf(t->err_log, "WARNING in guf_track_free (name '%s' id %" PRIu32 "): free_count reached SIZE_MAX\n", t->name ? t->name : "unnamed", t->id);
} }
if (size < 0) { if (size < 0) {
success = false; success = false;
if (t->err_log) { if (t->err_log) {
fprintf(t->err_log, "ERROR in guf_track_free (id %" PRIu32 "): size < 0\n", t->id); fprintf(t->err_log, "ERROR in guf_track_free (name '%s' id %" PRIu32 "): size < 0\n", t->name ? t->name : "unnamed", t->id);
} }
} }
if (t->allocated_bytes < size) { if (t->allocated_bytes < size) {
success = false; success = false;
if (t->err_log) { if (t->err_log) {
fprintf(t->err_log, "ERROR in guf_track_free (id %" PRIu32 "): freed more bytes than allocated\n", t->id); fprintf(t->err_log, "ERROR in guf_track_free (name '%s' id %" PRIu32 "): freed more bytes than allocated\n", t->name ? t->name : "unnamed", t->id);
} }
} }
if (guf_saturating_sub_ptrdiff_t(t->allocated_bytes, size, &t->allocated_bytes)) { if (guf_saturating_sub_ptrdiff_t(t->allocated_bytes, size, &t->allocated_bytes)) {
success = false; success = false;
if (t->err_log) { if (t->err_log) {
fprintf(t->err_log, "ERROR in guf_track_free (id %" PRIu32 "): allocated_bytes - size under/overflows\n", t->id); fprintf(t->err_log, "ERROR in guf_track_free (name '%s' id %" PRIu32 "): allocated_bytes - size under/overflows\n", t->name ? t->name : "unnamed", t->id);
} }
} }
if (t->log) { if (t->log) {
fprintf(t->log, "guf_alloc_tracker (id %" PRIu32 "): free (%td bytes) %s\n", t->id, size, (success ? "SUCCESS" : "FAILURE")); fprintf(t->log, "guf_alloc_tracker (name '%s' id %" PRIu32 "): free (%td bytes) %s\n", t->name ? t->name : "unnamed", t->id, size, (success ? "SUCCESS" : "FAILURE"));
} }
return success; return success;

View File

@ -54,16 +54,24 @@
int main(void) int main(void)
{ {
guf_allocator allocator;
guf_libc_alloc_ctx allocator_ctx;
guf_alloc_tracker_init(&allocator_ctx.tracker, 1, "example_allocator", NULL, NULL);
allocator_ctx.zero_init = false;
guf_libc_allocator_init(&allocator, &allocator_ctx);
printf("libguf example: " GUF_PLATFORM_STRING "\n"); printf("libguf example: " GUF_PLATFORM_STRING "\n");
guf_platform_assert_endianness(); guf_platform_assert_endianness();
guf_platform_assert_native_word_bits(); guf_platform_assert_native_word_bits();
guf_allocator test_allocator = guf_allocator_libc; guf_allocator zero_init_allocator;
guf_libc_alloc_ctx test_allocator_ctx = {.zero_init = true, .tracker = (guf_alloc_tracker){.enabled = false}}; guf_libc_alloc_ctx zero_init_allocator_ctx;
test_allocator.ctx = &test_allocator_ctx; guf_alloc_tracker_init(&zero_init_allocator_ctx.tracker, 2, "example_zero_init_allocator", stdout, stderr);
zero_init_allocator_ctx.zero_init = true;
guf_libc_allocator_init(&zero_init_allocator, &zero_init_allocator_ctx);
dict_cstr_int ht; dict_cstr_int ht;
dict_cstr_int_init(&ht, &test_allocator); dict_cstr_int_init(&ht, &zero_init_allocator);
dict_cstr_int_insert_val_arg(&ht, "Hello", 42, GUF_CPY_VALUE, GUF_CPY_VALUE); dict_cstr_int_insert_val_arg(&ht, "Hello", 42, GUF_CPY_VALUE, GUF_CPY_VALUE);
dict_cstr_int_insert_val_arg(&ht, "World", 64, GUF_CPY_VALUE, GUF_CPY_VALUE); dict_cstr_int_insert_val_arg(&ht, "World", 64, GUF_CPY_VALUE, GUF_CPY_VALUE);
@ -100,7 +108,7 @@ int main(void)
GUF_CNT_LIFETIME_BLOCK(dbuf_float, floats, { GUF_CNT_LIFETIME_BLOCK(dbuf_float, floats, {
floats = dbuf_float_new(&guf_allocator_libc); floats = dbuf_float_new(&allocator);
for (int i = 0; i <= 16; ++i) { for (int i = 0; i <= 16; ++i) {
dbuf_float_push_val(&floats, i % 2 ? i * -2.f : i * 2.f); dbuf_float_push_val(&floats, i % 2 ? i * -2.f : i * 2.f);
@ -119,7 +127,7 @@ int main(void)
} }
}) })
dbuf_heap_cstr strings = dbuf_heap_cstr_new(&guf_allocator_libc); dbuf_heap_cstr strings = dbuf_heap_cstr_new(&allocator);
dbuf_heap_cstr_push_val_cpy(&strings, "Foo 1"); dbuf_heap_cstr_push_val_cpy(&strings, "Foo 1");
dbuf_heap_cstr_push_val_cpy(&strings, "Bar 2"); dbuf_heap_cstr_push_val_cpy(&strings, "Bar 2");
char *move_me = strdup("Baz 3"); char *move_me = strdup("Baz 3");
@ -149,7 +157,7 @@ int main(void)
} }
dbuf_heap_cstr_free(&strings, NULL); dbuf_heap_cstr_free(&strings, NULL);
dbuf_const_cstr const_strings = dbuf_const_cstr_new(&guf_allocator_libc); dbuf_const_cstr const_strings = dbuf_const_cstr_new(&allocator);
dbuf_const_cstr_push_val(&const_strings, "Const 1"); dbuf_const_cstr_push_val(&const_strings, "Const 1");
dbuf_const_cstr_push_val(&const_strings, "Const 2"); dbuf_const_cstr_push_val(&const_strings, "Const 2");
const char *foo = "Const 3"; const char *foo = "Const 3";
@ -165,7 +173,7 @@ int main(void)
} }
dbuf_const_cstr_free(&const_strings, NULL); dbuf_const_cstr_free(&const_strings, NULL);
dbuf_int integers = dbuf_int_new(&guf_allocator_libc); dbuf_int integers = dbuf_int_new(&allocator);
dbuf_int_push_val(&integers, 420); dbuf_int_push_val(&integers, 420);
dbuf_int_push_val(&integers, 520); dbuf_int_push_val(&integers, 520);
dbuf_int_push_val(&integers, 620); dbuf_int_push_val(&integers, 620);
@ -294,5 +302,17 @@ int main(void)
guf_mat4x4_print_with_precision(&mat_inv, stdout, 8); guf_mat4x4_print_with_precision(&mat_inv, stdout, 8);
} }
return EXIT_SUCCESS; bool leak = false;
if (guf_alloc_tracker_found_leak(&allocator_ctx.tracker)) {
printf("Found memory leak:\n");
guf_alloc_tracker_print(&allocator_ctx.tracker, stderr);
leak = true;
}
if (guf_alloc_tracker_found_leak(&zero_init_allocator_ctx.tracker)) {
printf("Found memory leak:\n");
guf_alloc_tracker_print(&zero_init_allocator_ctx.tracker, stderr);
leak = true;
}
return leak ? EXIT_FAILURE: EXIT_SUCCESS;
} }

View File

@ -6,7 +6,6 @@ extern "C"
{ {
#include "guf_alloc_libc.h" #include "guf_alloc_libc.h"
#include "impls/dbuf_impl.h" #include "impls/dbuf_impl.h"
#include "guf_alloc_libc.h"
} }
struct DbufIntTest : public Test struct DbufIntTest : public Test
@ -14,7 +13,7 @@ struct DbufIntTest : public Test
DbufIntTest(const std::string& name) : Test(name) DbufIntTest(const std::string& name) : Test(name)
{ {
allocator_ctx.zero_init = false; allocator_ctx.zero_init = false;
guf_alloc_tracker_init(&allocator_ctx.tracker, 1, NULL, NULL); guf_alloc_tracker_init(&allocator_ctx.tracker, 1, "DbufIntTest_allocator", NULL, NULL);
guf_libc_allocator_init(&allocator, &allocator_ctx); guf_libc_allocator_init(&allocator, &allocator_ctx);
} }
@ -35,7 +34,7 @@ struct DbufCstringTest : public Test
DbufCstringTest(std::string name) : Test(name) DbufCstringTest(std::string name) : Test(name)
{ {
allocator_ctx.zero_init = false; allocator_ctx.zero_init = false;
guf_alloc_tracker_init(&allocator_ctx.tracker, 2, NULL, NULL); guf_alloc_tracker_init(&allocator_ctx.tracker, 2, "DbufCstringTest_allocator", NULL, NULL);
guf_libc_allocator_init(&allocator, &allocator_ctx); guf_libc_allocator_init(&allocator, &allocator_ctx);
} }

View File

@ -40,6 +40,9 @@ void DictSvToIntTest::run()
} }
free_file(); free_file();
pop_check_name(); pop_check_name();
//guf_alloc_tracker_print(&allocator_ctx.tracker, NULL);
TEST_CHECK(!guf_alloc_tracker_found_leak(&allocator_ctx.tracker));
} }
void DictSvToIntTest::insert_lookup(std::optional<ptrdiff_t> inital_dict_cap) void DictSvToIntTest::insert_lookup(std::optional<ptrdiff_t> inital_dict_cap)
@ -47,12 +50,12 @@ void DictSvToIntTest::insert_lookup(std::optional<ptrdiff_t> inital_dict_cap)
std::unordered_map<std::string_view, int32_t> word_cnt_map {}; std::unordered_map<std::string_view, int32_t> word_cnt_map {};
dict_sv_i32 word_cnt_dict {}; dict_sv_i32 word_cnt_dict {};
if (inital_dict_cap) { if (inital_dict_cap) {
dict_sv_i32_init_with_capacity(&word_cnt_dict, &guf_allocator_libc, inital_dict_cap.value()); dict_sv_i32_init_with_capacity(&word_cnt_dict, &allocator, inital_dict_cap.value());
} else { } else {
dict_sv_i32_init(&word_cnt_dict, &guf_allocator_libc); dict_sv_i32_init(&word_cnt_dict, &allocator);
} }
dbuf_str_view delims = dbuf_str_view_new(&guf_allocator_libc); dbuf_str_view delims = dbuf_str_view_new(&allocator);
for (size_t i = 0; i < GUF_ARR_SIZE(GUF_UTF8_WHITESPACE); ++i) { for (size_t i = 0; i < GUF_ARR_SIZE(GUF_UTF8_WHITESPACE); ++i) {
guf_str_view d = {.len = (ptrdiff_t)strlen(GUF_UTF8_WHITESPACE[i]), .str = GUF_UTF8_WHITESPACE[i]}; guf_str_view d = {.len = (ptrdiff_t)strlen(GUF_UTF8_WHITESPACE[i]), .str = GUF_UTF8_WHITESPACE[i]};
dbuf_str_view_push_val(&delims, d); dbuf_str_view_push_val(&delims, d);
@ -345,7 +348,7 @@ bool DictSvToIntTest::load_file(const char *fname)
GUF_ASSERT_RELEASE(in_file); GUF_ASSERT_RELEASE(in_file);
dbuf_char_init(&text_buf, 128, &guf_allocator_libc); dbuf_char_init(&text_buf, 128, &allocator);
int c = EOF; int c = EOF;
while ((c = fgetc(in_file)) != EOF) { while ((c = fgetc(in_file)) != EOF) {

View File

@ -7,14 +7,24 @@
extern "C" extern "C"
{ {
#include "impls/dbuf_impl.h" #include "impls/dbuf_impl.h"
#include "guf_alloc_libc.h"
} }
struct DictSvToIntTest : public Test struct DictSvToIntTest : public Test
{ {
DictSvToIntTest(const std::string& name) : Test(name) {}; DictSvToIntTest(const std::string& name) : Test(name)
{
allocator_ctx.zero_init = false;
guf_alloc_tracker_init(&allocator_ctx.tracker, 3, "DictSvToIntTest_allocator", NULL, NULL);
guf_libc_allocator_init(&allocator, &allocator_ctx);
};
void run() override; void run() override;
private: private:
guf_allocator allocator;
guf_libc_alloc_ctx allocator_ctx;
dbuf_char text_buf {}; dbuf_char text_buf {};
std::vector<char> text_vec {}; std::vector<char> text_vec {};

View File

@ -184,16 +184,19 @@ void StrTest::run()
TEST_CHECK(tok_result.at(0) == "age" && tok_result.at(1) == "28" && tok_result.at(2) == "occupation" && tok_result.at(3) == "NULL" && TEST_CHECK(tok_result.at(0) == "age" && tok_result.at(1) == "28" && tok_result.at(2) == "occupation" && tok_result.at(3) == "NULL" &&
tok_result.at(4) == "crayons_eaten" && tok_result.at(5) == "256"); tok_result.at(4) == "crayons_eaten" && tok_result.at(5) == "256");
pop_check_name(); pop_check_name();
// guf_alloc_tracker_print(&allocator_ctx.tracker, NULL);
TEST_CHECK(!guf_alloc_tracker_found_leak(&allocator_ctx.tracker));
} }
void StrTest::test_init_free(std::string str) void StrTest::test_init_free(std::string str)
{ {
guf_str s0; guf_str s0;
guf_str_init(&s0, GUF_CSTR_TO_VIEW_CPP(str.c_str()), &guf_allocator_libc); guf_str_init(&s0, GUF_CSTR_TO_VIEW_CPP(str.c_str()), &allocator);
guf_str s1 = guf_str_new(GUF_CSTR_TO_VIEW_CPP(str.c_str()), &guf_allocator_libc); guf_str s1 = guf_str_new(GUF_CSTR_TO_VIEW_CPP(str.c_str()), &allocator);
guf_str s2; guf_str s2;
guf_str_init_from_cstr(&s2, str.c_str(), &guf_allocator_libc); guf_str_init_from_cstr(&s2, str.c_str(), &allocator);
TEST_CHECK(guf_str_equal(&s0, &s1)); TEST_CHECK(guf_str_equal(&s0, &s1));
TEST_CHECK(guf_str_equal(&s0, &s2)); TEST_CHECK(guf_str_equal(&s0, &s2));
@ -223,7 +226,7 @@ void StrTest::test_init_empty()
{ {
std::string str = ""; std::string str = "";
guf_str s = GUF_STR_UNINITIALISED_CPP; guf_str s = GUF_STR_UNINITIALISED_CPP;
guf_str_init_empty(&s, &guf_allocator_libc); guf_str_init_empty(&s, &allocator);
TEST_CHECK(guf_str_len(&s) == 0); TEST_CHECK(guf_str_len(&s) == 0);
TEST_CHECK(str == guf_str_const_cstr(&s)); TEST_CHECK(str == guf_str_const_cstr(&s));
@ -265,7 +268,7 @@ void StrTest::test_init_empty()
void StrTest::test_append_char(std::string str, bool include_null) void StrTest::test_append_char(std::string str, bool include_null)
{ {
guf_str s0 = guf_str_new(guf_str_view{.str = str.c_str(), .len = (ptrdiff_t)str.size()}, &guf_allocator_libc); guf_str s0 = guf_str_new(guf_str_view{.str = str.c_str(), .len = (ptrdiff_t)str.size()}, &allocator);
TEST_CHECK((ptrdiff_t)str.size() == guf_str_len(&s0)); TEST_CHECK((ptrdiff_t)str.size() == guf_str_len(&s0));
TEST_CHECK((str == std::string_view{guf_str_const_cstr(&s0), (size_t)guf_str_len(&s0)})); TEST_CHECK((str == std::string_view{guf_str_const_cstr(&s0), (size_t)guf_str_len(&s0)}));
@ -297,7 +300,7 @@ void StrTest::test_append_char(std::string str, bool include_null)
void StrTest::append_str(const std::string& a, const std::string& b) void StrTest::append_str(const std::string& a, const std::string& b)
{ {
std::string str0 = a; std::string str0 = a;
guf_str s0 = guf_str_new(guf_str_view{.str = str0.c_str(), .len = (ptrdiff_t)str0.size()}, &guf_allocator_libc); guf_str s0 = guf_str_new(guf_str_view{.str = str0.c_str(), .len = (ptrdiff_t)str0.size()}, &allocator);
TEST_CHECK(guf_str_len(&s0) == (ptrdiff_t)str0.size()); TEST_CHECK(guf_str_len(&s0) == (ptrdiff_t)str0.size());
TEST_CHECK((str0 == std::string_view{guf_str_const_cstr(&s0), (size_t)guf_str_len(&s0)})); TEST_CHECK((str0 == std::string_view{guf_str_const_cstr(&s0), (size_t)guf_str_len(&s0)}));
TEST_CHECK((str0 == std::string_view{guf_str_cstr(&s0), (size_t)guf_str_len(&s0)})); TEST_CHECK((str0 == std::string_view{guf_str_cstr(&s0), (size_t)guf_str_len(&s0)}));

View File

@ -6,14 +6,24 @@
extern "C" extern "C"
{ {
#include "guf_str.h" #include "guf_str.h"
#include "guf_alloc_libc.h"
} }
struct StrTest : public Test struct StrTest : public Test
{ {
StrTest(const std::string& name) : Test(name) {}; StrTest(const std::string& name) : Test(name)
{
allocator_ctx.zero_init = false;
guf_alloc_tracker_init(&allocator_ctx.tracker, 4, "StrTest_allocator", NULL, NULL);
guf_libc_allocator_init(&allocator, &allocator_ctx);
};
void run() override; void run() override;
private: private:
guf_allocator allocator;
guf_libc_alloc_ctx allocator_ctx;
void test_init_free(std::string str); void test_init_free(std::string str);
void test_init_empty(); void test_init_empty();
void test_append_char(std::string str, bool include_null = false); void test_append_char(std::string str, bool include_null = false);

View File

@ -25,7 +25,7 @@ void UTF8Test::run()
pop_check_name(); pop_check_name();
push_check_name("count_words"); push_check_name("count_words");
dbuf_str_view delims = dbuf_str_view_new(&guf_allocator_libc); dbuf_str_view delims = dbuf_str_view_new(&allocator);
for (size_t i = 0; i < GUF_ARR_SIZE(GUF_UTF8_WHITESPACE); ++i) { for (size_t i = 0; i < GUF_ARR_SIZE(GUF_UTF8_WHITESPACE); ++i) {
guf_str_view d = {.len = (ptrdiff_t)strlen(GUF_UTF8_WHITESPACE[i]), .str = GUF_UTF8_WHITESPACE[i]}; guf_str_view d = {.len = (ptrdiff_t)strlen(GUF_UTF8_WHITESPACE[i]), .str = GUF_UTF8_WHITESPACE[i]};
dbuf_str_view_push_val(&delims, d); dbuf_str_view_push_val(&delims, d);
@ -50,6 +50,9 @@ void UTF8Test::run()
encode_decode_file(TEST_DATA_DIR "/" "utf8-test.txt"); encode_decode_file(TEST_DATA_DIR "/" "utf8-test.txt");
encode_decode_file(TEST_DATA_DIR "/" "bartleby.txt"); encode_decode_file(TEST_DATA_DIR "/" "bartleby.txt");
pop_check_name(); pop_check_name();
//guf_alloc_tracker_print(&allocator_ctx.tracker, NULL);
TEST_CHECK(!guf_alloc_tracker_found_leak(&allocator_ctx.tracker));
} }
@ -64,7 +67,7 @@ bool UTF8Test::load_text(const char *fname)
return false; return false;
} }
dbuf_char_init(&text_buf, 128, &guf_allocator_libc); dbuf_char_init(&text_buf, 128, &allocator);
int c = EOF; int c = EOF;
while ((c = fgetc(in_file)) != EOF) { while ((c = fgetc(in_file)) != EOF) {
@ -157,7 +160,7 @@ void UTF8Test::encode_decode_file(const char *fname)
{ {
GUF_ASSERT_RELEASE(load_text(fname)); GUF_ASSERT_RELEASE(load_text(fname));
dbuf_i32 cp_buf = dbuf_i32_new(&guf_allocator_libc); dbuf_i32 cp_buf = dbuf_i32_new(&allocator);
ptrdiff_t valid_chars = 0, invalid_chars = 0; ptrdiff_t valid_chars = 0, invalid_chars = 0;
guf_str_view input_str = {.str = text_buf.data, .len = text_buf.size}; guf_str_view input_str = {.str = text_buf.data, .len = text_buf.size};

View File

@ -4,14 +4,24 @@
extern "C" extern "C"
{ {
#include "impls/dbuf_impl.h" #include "impls/dbuf_impl.h"
#include "guf_alloc_libc.h"
} }
struct UTF8Test : public Test struct UTF8Test : public Test
{ {
UTF8Test(const std::string& name) : Test(name) {}; UTF8Test(const std::string& name) : Test(name)
{
allocator_ctx.zero_init = false;
guf_alloc_tracker_init(&allocator_ctx.tracker, 5, "UTF8Test_allocator", NULL, NULL);
guf_libc_allocator_init(&allocator, &allocator_ctx);
};
void run() override; void run() override;
private: private:
guf_allocator allocator;
guf_libc_alloc_ctx allocator_ctx;
dbuf_char text_buf {}; dbuf_char text_buf {};
std::vector<char> text_vec; std::vector<char> text_vec;