summaryrefslogtreecommitdiff
path: root/csv-test.c
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2020-06-18 09:52:14 +0200
committerThomas Schmucker <ts@its1.de>2020-06-18 09:52:14 +0200
commit36c50e4e77d472e9b7838e1f6385f36ddb52d258 (patch)
tree26e000165e35feeca136b83eaf112697b6902415 /csv-test.c
parentfe5ecb5f7d0d57019d4c28605fab23d2c3163a80 (diff)
downloadlibcsv-36c50e4e77d472e9b7838e1f6385f36ddb52d258.tar.gz
libcsv-36c50e4e77d472e9b7838e1f6385f36ddb52d258.tar.bz2
libcsv-36c50e4e77d472e9b7838e1f6385f36ddb52d258.zip
Memory Interface
Diffstat (limited to 'csv-test.c')
-rw-r--r--csv-test.c62
1 files changed, 48 insertions, 14 deletions
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 @@
9 9
10#define INLINE static inline 10#define INLINE static inline
11 11
12/* === CSV-MEMORY Interface === */
13
14static void *
15csv_mem_allocate(size_t n, size_t sz, void *cb_arg)
16{
17 (void) cb_arg;
18
19 return calloc(n, sz);
20}
21
22static void *
23csv_mem_reallocate(void *ptr, size_t n, size_t sz, void *cb_arg)
24{
25 (void) cb_arg;
26
27 return reallocarray(ptr, n, sz);
28}
29
30static void
31csv_mem_free(void *ptr, void *cb_arg)
32{
33 (void) cb_arg;
34
35 free(ptr);
36}
37
12/* === CSV-OPTIONS Interface === */ 38/* === CSV-OPTIONS Interface === */
13 39
14typedef struct { 40typedef struct {
15 char quote_symbol; 41 char quote_symbol;
16 char sep_symbol; 42 char sep_symbol;
17 void *cb_arg; 43 void *cb_arg;
18 void (*cb_func)(const char *, void *); 44 void (*cb_error)(const char *, void *);
45 void *(*cb_allocate)(size_t, size_t, void *);
46 void *(*cb_reallocate)(void *, size_t, size_t, void *);
47 void (*cb_free)(void *, void *);
19} csv_options_t; 48} csv_options_t;
20 49
21extern const csv_options_t csv_default_options; 50extern const csv_options_t csv_default_options;
@@ -23,7 +52,10 @@ extern const csv_options_t csv_default_options;
23const csv_options_t csv_default_options = { 52const csv_options_t csv_default_options = {
24 .quote_symbol = '"', 53 .quote_symbol = '"',
25 .sep_symbol = ',', 54 .sep_symbol = ',',
26 .cb_func = NULL 55 .cb_error = NULL,
56 .cb_allocate = csv_mem_allocate,
57 .cb_reallocate = csv_mem_reallocate,
58 .cb_free = csv_mem_free
27}; 59};
28 60
29/* === CSV-ERROR Interface === */ 61/* === CSV-ERROR Interface === */
@@ -31,8 +63,8 @@ const csv_options_t csv_default_options = {
31INLINE void 63INLINE void
32csv_fatal_error(const char *msg, const csv_options_t * const csv_options) 64csv_fatal_error(const char *msg, const csv_options_t * const csv_options)
33{ 65{
34 if ( csv_options->cb_func != NULL ) { 66 if ( csv_options->cb_error != NULL ) {
35 (*csv_options->cb_func)(msg, csv_options->cb_arg); 67 (*csv_options->cb_error)(msg, csv_options->cb_arg);
36 } 68 }
37 69
38 fprintf(stderr, "fatal error: %s\n", msg); 70 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
82 114
83 if ( csv_string->pos == csv_string->cap ) { /* grow if needed */ 115 if ( csv_string->pos == csv_string->cap ) { /* grow if needed */
84 if ( csv_string->str == NULL ) { /* first call? */ 116 if ( csv_string->str == NULL ) { /* first call? */
85 if ( (csv_string->str = malloc(INITIAL_CAP)) == NULL ) { 117 if ( (csv_string->str = csv_options->cb_allocate(INITIAL_CAP, 1, csv_options->cb_arg)) == NULL ) {
86 csv_fatal_error("out of memory...", csv_options); 118 csv_fatal_error("out of memory...", csv_options);
87 return; 119 return;
88 } 120 }
@@ -91,7 +123,7 @@ csv_string_append(csv_string_t *csv_string, char ch, const csv_options_t * const
91 } 123 }
92 else { /* subsequent call */ 124 else { /* subsequent call */
93 int cap = (csv_string->cap * 3) / 2; /* *= 1.5 */ 125 int cap = (csv_string->cap * 3) / 2; /* *= 1.5 */
94 char *str = realloc(csv_string->str, cap); 126 char *str = csv_options->cb_reallocate(csv_string->str, cap, 1, csv_options->cb_arg);
95 if ( str == NULL ) { 127 if ( str == NULL ) {
96 csv_fatal_error("out of memory...", csv_options); 128 csv_fatal_error("out of memory...", csv_options);
97 return; 129 return;
@@ -105,11 +137,12 @@ csv_string_append(csv_string_t *csv_string, char ch, const csv_options_t * const
105} 137}
106 138
107INLINE void 139INLINE void
108csv_string_free(csv_string_t *csv_string) 140csv_string_free(csv_string_t *csv_string, const csv_options_t * const csv_options)
109{ 141{
110 assert(csv_string != NULL); 142 assert(csv_string != NULL);
143 assert(csv_options != NULL);
111 144
112 free(csv_string->str); 145 csv_options->cb_free(csv_string->str, csv_options->cb_arg);
113 146
114 /* call *_init() for sane default values; prevent possible double-free */ 147 /* call *_init() for sane default values; prevent possible double-free */
115 csv_string_init(csv_string); 148 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
150 183
151 if ( csv_field->pos == csv_field->cap ) { /* grow if needed */ 184 if ( csv_field->pos == csv_field->cap ) { /* grow if needed */
152 if ( csv_field->fields == NULL ) { 185 if ( csv_field->fields == NULL ) {
153 if ( (csv_field->fields = calloc(INITIAL_CAP, sizeof(csv_field->fields[0]))) == NULL ) { 186 if ( (csv_field->fields = csv_options->cb_allocate(INITIAL_CAP, sizeof(csv_field->fields[0]), csv_options->cb_arg)) == NULL ) {
154 csv_fatal_error("out of memory", csv_options); 187 csv_fatal_error("out of memory", csv_options);
155 return; 188 return;
156 } 189 }
@@ -159,7 +192,7 @@ csv_field_append(csv_field_t *csv_field, int idx, const csv_options_t * const cs
159 } 192 }
160 else { 193 else {
161 int cap = (csv_field->cap * 3) / 2; /* *= 1.5 */ 194 int cap = (csv_field->cap * 3) / 2; /* *= 1.5 */
162 int *fields = reallocarray(csv_field->fields, cap, sizeof(csv_field->fields[0])); 195 int *fields = csv_options->cb_reallocate(csv_field->fields, cap, sizeof(csv_field->fields[0]), csv_options->cb_arg);
163 if ( fields == NULL ) { 196 if ( fields == NULL ) {
164 csv_fatal_error("out of memory", csv_options); 197 csv_fatal_error("out of memory", csv_options);
165 return; 198 return;
@@ -173,11 +206,12 @@ csv_field_append(csv_field_t *csv_field, int idx, const csv_options_t * const cs
173} 206}
174 207
175INLINE void 208INLINE void
176csv_field_free(csv_field_t *csv_field) 209csv_field_free(csv_field_t *csv_field, const csv_options_t * const csv_options)
177{ 210{
178 assert(csv_field != NULL); 211 assert(csv_field != NULL);
212 assert(csv_options != NULL);
179 213
180 free(csv_field->fields); 214 csv_options->cb_free(csv_field->fields, csv_options->cb_arg);
181 215
182 csv_field_init(csv_field); 216 csv_field_init(csv_field);
183} 217}
@@ -227,8 +261,8 @@ csv_free(csv_t *csv)
227{ 261{
228 assert(csv != NULL); 262 assert(csv != NULL);
229 263
230 csv_string_free(&csv->csv_string); 264 csv_string_free(&csv->csv_string, csv->csv_options);
231 csv_field_free(&csv->csv_field); 265 csv_field_free(&csv->csv_field, csv->csv_options);
232} 266}
233 267
234int 268int