From 36c50e4e77d472e9b7838e1f6385f36ddb52d258 Mon Sep 17 00:00:00 2001 From: Thomas Schmucker Date: Thu, 18 Jun 2020 09:52:14 +0200 Subject: Memory Interface --- csv-test.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 14 deletions(-) (limited to 'csv-test.c') diff --git a/csv-test.c b/csv-test.c index d26fea9..fe8afff 100644 --- a/csv-test.c +++ b/csv-test.c @@ -9,13 +9,42 @@ #define INLINE static inline +/* === CSV-MEMORY Interface === */ + +static void * +csv_mem_allocate(size_t n, size_t sz, void *cb_arg) +{ + (void) cb_arg; + + return calloc(n, sz); +} + +static void * +csv_mem_reallocate(void *ptr, size_t n, size_t sz, void *cb_arg) +{ + (void) cb_arg; + + return reallocarray(ptr, n, sz); +} + +static void +csv_mem_free(void *ptr, void *cb_arg) +{ + (void) cb_arg; + + free(ptr); +} + /* === CSV-OPTIONS Interface === */ typedef struct { char quote_symbol; char sep_symbol; void *cb_arg; - void (*cb_func)(const char *, void *); + void (*cb_error)(const char *, void *); + void *(*cb_allocate)(size_t, size_t, void *); + void *(*cb_reallocate)(void *, size_t, size_t, void *); + void (*cb_free)(void *, void *); } csv_options_t; extern const csv_options_t csv_default_options; @@ -23,7 +52,10 @@ extern const csv_options_t csv_default_options; const csv_options_t csv_default_options = { .quote_symbol = '"', .sep_symbol = ',', - .cb_func = NULL + .cb_error = NULL, + .cb_allocate = csv_mem_allocate, + .cb_reallocate = csv_mem_reallocate, + .cb_free = csv_mem_free }; /* === CSV-ERROR Interface === */ @@ -31,8 +63,8 @@ const csv_options_t csv_default_options = { INLINE void csv_fatal_error(const char *msg, const csv_options_t * const csv_options) { - if ( csv_options->cb_func != NULL ) { - (*csv_options->cb_func)(msg, csv_options->cb_arg); + if ( csv_options->cb_error != NULL ) { + (*csv_options->cb_error)(msg, csv_options->cb_arg); } fprintf(stderr, "fatal error: %s\n", msg); @@ -82,7 +114,7 @@ csv_string_append(csv_string_t *csv_string, char ch, const csv_options_t * const if ( csv_string->pos == csv_string->cap ) { /* grow if needed */ if ( csv_string->str == NULL ) { /* first call? */ - if ( (csv_string->str = malloc(INITIAL_CAP)) == NULL ) { + if ( (csv_string->str = csv_options->cb_allocate(INITIAL_CAP, 1, csv_options->cb_arg)) == NULL ) { csv_fatal_error("out of memory...", csv_options); return; } @@ -91,7 +123,7 @@ csv_string_append(csv_string_t *csv_string, char ch, const csv_options_t * const } else { /* subsequent call */ int cap = (csv_string->cap * 3) / 2; /* *= 1.5 */ - char *str = realloc(csv_string->str, cap); + char *str = csv_options->cb_reallocate(csv_string->str, cap, 1, csv_options->cb_arg); if ( str == NULL ) { csv_fatal_error("out of memory...", csv_options); return; @@ -105,11 +137,12 @@ csv_string_append(csv_string_t *csv_string, char ch, const csv_options_t * const } INLINE void -csv_string_free(csv_string_t *csv_string) +csv_string_free(csv_string_t *csv_string, const csv_options_t * const csv_options) { assert(csv_string != NULL); + assert(csv_options != NULL); - free(csv_string->str); + csv_options->cb_free(csv_string->str, csv_options->cb_arg); /* call *_init() for sane default values; prevent possible double-free */ csv_string_init(csv_string); @@ -150,7 +183,7 @@ csv_field_append(csv_field_t *csv_field, int idx, const csv_options_t * const cs if ( csv_field->pos == csv_field->cap ) { /* grow if needed */ if ( csv_field->fields == NULL ) { - if ( (csv_field->fields = calloc(INITIAL_CAP, sizeof(csv_field->fields[0]))) == NULL ) { + if ( (csv_field->fields = csv_options->cb_allocate(INITIAL_CAP, sizeof(csv_field->fields[0]), csv_options->cb_arg)) == NULL ) { csv_fatal_error("out of memory", csv_options); return; } @@ -159,7 +192,7 @@ csv_field_append(csv_field_t *csv_field, int idx, const csv_options_t * const cs } else { int cap = (csv_field->cap * 3) / 2; /* *= 1.5 */ - int *fields = reallocarray(csv_field->fields, cap, sizeof(csv_field->fields[0])); + int *fields = csv_options->cb_reallocate(csv_field->fields, cap, sizeof(csv_field->fields[0]), csv_options->cb_arg); if ( fields == NULL ) { csv_fatal_error("out of memory", csv_options); return; @@ -173,11 +206,12 @@ csv_field_append(csv_field_t *csv_field, int idx, const csv_options_t * const cs } INLINE void -csv_field_free(csv_field_t *csv_field) +csv_field_free(csv_field_t *csv_field, const csv_options_t * const csv_options) { assert(csv_field != NULL); + assert(csv_options != NULL); - free(csv_field->fields); + csv_options->cb_free(csv_field->fields, csv_options->cb_arg); csv_field_init(csv_field); } @@ -227,8 +261,8 @@ csv_free(csv_t *csv) { assert(csv != NULL); - csv_string_free(&csv->csv_string); - csv_field_free(&csv->csv_field); + csv_string_free(&csv->csv_string, csv->csv_options); + csv_field_free(&csv->csv_field, csv->csv_options); } int -- cgit v1.3