summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2020-06-21 11:28:57 +0200
committerThomas Schmucker <ts@its1.de>2020-06-21 11:28:57 +0200
commit1c5bb82c5e991d71e9ae5a6645c032f220131f5d (patch)
tree6c32d7fa03d83fbbee400ebd91af2d857d6d8167
parentdd7e73ec6c990c23a08d4e82f050804caa9789df (diff)
downloadlibcsv-1c5bb82c5e991d71e9ae5a6645c032f220131f5d.tar.gz
libcsv-1c5bb82c5e991d71e9ae5a6645c032f220131f5d.tar.bz2
libcsv-1c5bb82c5e991d71e9ae5a6645c032f220131f5d.zip
Überarbeitets Error-Handling
-rw-r--r--csv-test.c4
-rw-r--r--csv.c34
-rw-r--r--csv.h11
3 files changed, 36 insertions, 13 deletions
diff --git a/csv-test.c b/csv-test.c
index 3bd6b7b..d14d6c2 100644
--- a/csv-test.c
+++ b/csv-test.c
@@ -61,9 +61,9 @@ test_exception_with_signal(FILE *f)
61} 61}
62 62
63static void 63static void
64my_error_handler(const char *msg, void *env) 64my_error_handler(csv_error_t csv_error, void *env)
65{ 65{
66 fprintf(stderr, "my_error_handler: %s\n", msg); 66 fprintf(stderr, "my_error_handler: %s\n", csv_err_str(csv_error));
67 longjmp(*((jmp_buf *) env), 1); 67 longjmp(*((jmp_buf *) env), 1);
68} 68}
69 69
diff --git a/csv.c b/csv.c
index d8321bd..9c3f895 100644
--- a/csv.c
+++ b/csv.c
@@ -47,13 +47,13 @@ const csv_options_t csv_default_options = {
47/* === CSV-ERROR Interface === */ 47/* === CSV-ERROR Interface === */
48 48
49INLINE void 49INLINE void
50csv_fatal_error(const char *msg, const csv_options_t * const csv_options) 50csv_fatal_error(csv_error_t csv_error, const csv_options_t * const csv_options)
51{ 51{
52 if ( csv_options->cb_error != NULL ) { 52 if ( csv_options->cb_error != NULL ) {
53 (*csv_options->cb_error)(msg, csv_options->cb_error_arg); 53 (*csv_options->cb_error)(csv_error, csv_options->cb_error_arg);
54 } 54 }
55 55
56 fprintf(stderr, "fatal error: %s\n", msg); 56 fprintf(stderr, "fatal error: %s\n", csv_err_str(csv_error));
57 abort(); 57 abort();
58} 58}
59 59
@@ -96,7 +96,7 @@ csv_string_append(csv_string_t *csv_string, char ch, const csv_options_t * const
96 if ( csv_string->pos == csv_string->cap ) { /* grow if needed */ 96 if ( csv_string->pos == csv_string->cap ) { /* grow if needed */
97 if ( csv_string->str == NULL ) { /* first call? */ 97 if ( csv_string->str == NULL ) { /* first call? */
98 if ( (csv_string->str = csv_options->cb_allocate(INITIAL_CAP, 1, csv_options->cb_memory_arg)) == NULL ) { 98 if ( (csv_string->str = csv_options->cb_allocate(INITIAL_CAP, 1, csv_options->cb_memory_arg)) == NULL ) {
99 csv_fatal_error("out of memory...", csv_options); 99 csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options);
100 return; 100 return;
101 } 101 }
102 102
@@ -106,7 +106,7 @@ csv_string_append(csv_string_t *csv_string, char ch, const csv_options_t * const
106 int cap = (csv_string->cap * 3) / 2; /* *= 1.5 */ 106 int cap = (csv_string->cap * 3) / 2; /* *= 1.5 */
107 char *str = csv_options->cb_reallocate(csv_string->str, cap, 1, csv_options->cb_memory_arg); 107 char *str = csv_options->cb_reallocate(csv_string->str, cap, 1, csv_options->cb_memory_arg);
108 if ( str == NULL ) { 108 if ( str == NULL ) {
109 csv_fatal_error("out of memory...", csv_options); 109 csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options);
110 return; 110 return;
111 } 111 }
112 csv_string->str = str; 112 csv_string->str = str;
@@ -160,7 +160,7 @@ csv_field_append(csv_field_t *csv_field, int idx, const csv_options_t * const cs
160 if ( csv_field->pos == csv_field->cap ) { /* grow if needed */ 160 if ( csv_field->pos == csv_field->cap ) { /* grow if needed */
161 if ( csv_field->fields == NULL ) { 161 if ( csv_field->fields == NULL ) {
162 if ( (csv_field->fields = csv_options->cb_allocate(INITIAL_CAP, sizeof(csv_field->fields[0]), csv_options->cb_memory_arg)) == NULL ) { 162 if ( (csv_field->fields = csv_options->cb_allocate(INITIAL_CAP, sizeof(csv_field->fields[0]), csv_options->cb_memory_arg)) == NULL ) {
163 csv_fatal_error("out of memory", csv_options); 163 csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options);
164 return; 164 return;
165 } 165 }
166 166
@@ -170,7 +170,7 @@ csv_field_append(csv_field_t *csv_field, int idx, const csv_options_t * const cs
170 int cap = (csv_field->cap * 3) / 2; /* *= 1.5 */ 170 int cap = (csv_field->cap * 3) / 2; /* *= 1.5 */
171 int *fields = csv_options->cb_reallocate(csv_field->fields, cap, sizeof(csv_field->fields[0]), csv_options->cb_memory_arg); 171 int *fields = csv_options->cb_reallocate(csv_field->fields, cap, sizeof(csv_field->fields[0]), csv_options->cb_memory_arg);
172 if ( fields == NULL ) { 172 if ( fields == NULL ) {
173 csv_fatal_error("out of memory", csv_options); 173 csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options);
174 return; 174 return;
175 } 175 }
176 csv_field->fields = fields; 176 csv_field->fields = fields;
@@ -245,7 +245,7 @@ csv_field(csv_t *csv, int idx)
245 assert(idx >= 0 && idx < csv->csv_field.pos); 245 assert(idx >= 0 && idx < csv->csv_field.pos);
246 246
247 if ( idx < 0 || idx >= csv->csv_field.pos ) { 247 if ( idx < 0 || idx >= csv->csv_field.pos ) {
248 csv_fatal_error("range error", csv->csv_options); 248 csv_fatal_error(CSV_ERR_OUT_OF_RANGE, csv->csv_options);
249 } 249 }
250 250
251 return &csv->csv_string.str[csv->csv_field.fields[idx]]; 251 return &csv->csv_string.str[csv->csv_field.fields[idx]];
@@ -269,7 +269,7 @@ csv_read(csv_t *csv, FILE *in)
269 } 269 }
270 270
271 if ( ferror(in) ) { 271 if ( ferror(in) ) {
272 csv_fatal_error("I/O error", csv->csv_options); 272 csv_fatal_error(CSV_ERR_IO_READ, csv->csv_options);
273 } 273 }
274 274
275 enum { 275 enum {
@@ -394,7 +394,7 @@ csv_read(csv_t *csv, FILE *in)
394 394
395 case STATE_END_FILE: 395 case STATE_END_FILE:
396 if ( ferror(in) ) { 396 if ( ferror(in) ) {
397 csv_fatal_error("I/O error", csv->csv_options); 397 csv_fatal_error(CSV_ERR_IO_READ, csv->csv_options);
398 } 398 }
399 399
400 if ( csv_string_empty(&csv->csv_string) ) { 400 if ( csv_string_empty(&csv->csv_string) ) {
@@ -417,6 +417,20 @@ csv_read(csv_t *csv, FILE *in)
417 /* NOT REACHED */ 417 /* NOT REACHED */
418} 418}
419 419
420const char *
421csv_err_str(csv_error_t csv_error)
422{
423 switch ( csv_error ) {
424 case CSV_ERR_OK: return "no error";
425 case CSV_ERR_OUT_OF_MEMORY: return "out of memory";
426 case CSV_ERR_OUT_OF_RANGE: return "index out of range";
427 case CSV_ERR_IO_READ: return "read errro";
428 case CSV_ERR_IO_WRITE: return "write error";
429 default: return "unknown error";
430 }
431 /* NOT REACHED */
432}
433
420static void 434static void
421csv_write_field(FILE *out, const char *field, const csv_options_t * const csv_options) 435csv_write_field(FILE *out, const char *field, const csv_options_t * const csv_options)
422{ 436{
diff --git a/csv.h b/csv.h
index fe59f5b..a8be413 100644
--- a/csv.h
+++ b/csv.h
@@ -8,11 +8,19 @@
8extern "C" { 8extern "C" {
9#endif 9#endif
10 10
11typedef enum {
12 CSV_ERR_OK = 0,
13 CSV_ERR_OUT_OF_MEMORY = -1,
14 CSV_ERR_OUT_OF_RANGE = -2,
15 CSV_ERR_IO_READ = -3,
16 CSV_ERR_IO_WRITE = -4
17} csv_error_t;
18
11typedef struct { 19typedef struct {
12 char quote_symbol; 20 char quote_symbol;
13 char sep_symbol; 21 char sep_symbol;
14 22
15 void (*cb_error)(const char *, void *); 23 void (*cb_error)(csv_error_t, void *);
16 void *cb_error_arg; 24 void *cb_error_arg;
17 25
18 void *(*cb_allocate)(size_t, size_t, void *); 26 void *(*cb_allocate)(size_t, size_t, void *);
@@ -45,6 +53,7 @@ void csv_cleanup(csv_t *csv);
45int csv_nfields(csv_t *csv); 53int csv_nfields(csv_t *csv);
46const char * csv_field(csv_t *csv, int idx); 54const char * csv_field(csv_t *csv, int idx);
47int csv_read(csv_t *csv, FILE *in); 55int csv_read(csv_t *csv, FILE *in);
56const char * csv_err_str(csv_error_t csv_error);
48void csv_write(FILE *out, int n, const char *fields[], const csv_options_t * const csv_options); 57void csv_write(FILE *out, int n, const char *fields[], const csv_options_t * const csv_options);
49 58
50#ifdef __cplusplus 59#ifdef __cplusplus