From 1c5bb82c5e991d71e9ae5a6645c032f220131f5d Mon Sep 17 00:00:00 2001 From: Thomas Schmucker Date: Sun, 21 Jun 2020 11:28:57 +0200 Subject: Überarbeitets Error-Handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- csv-test.c | 4 ++-- csv.c | 34 ++++++++++++++++++++++++---------- csv.h | 11 ++++++++++- 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) } static void -my_error_handler(const char *msg, void *env) +my_error_handler(csv_error_t csv_error, void *env) { - fprintf(stderr, "my_error_handler: %s\n", msg); + fprintf(stderr, "my_error_handler: %s\n", csv_err_str(csv_error)); longjmp(*((jmp_buf *) env), 1); } 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 = { /* === CSV-ERROR Interface === */ INLINE void -csv_fatal_error(const char *msg, const csv_options_t * const csv_options) +csv_fatal_error(csv_error_t csv_error, const csv_options_t * const csv_options) { if ( csv_options->cb_error != NULL ) { - (*csv_options->cb_error)(msg, csv_options->cb_error_arg); + (*csv_options->cb_error)(csv_error, csv_options->cb_error_arg); } - fprintf(stderr, "fatal error: %s\n", msg); + fprintf(stderr, "fatal error: %s\n", csv_err_str(csv_error)); abort(); } @@ -96,7 +96,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 = csv_options->cb_allocate(INITIAL_CAP, 1, csv_options->cb_memory_arg)) == NULL ) { - csv_fatal_error("out of memory...", csv_options); + csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); return; } @@ -106,7 +106,7 @@ csv_string_append(csv_string_t *csv_string, char ch, const csv_options_t * const int cap = (csv_string->cap * 3) / 2; /* *= 1.5 */ char *str = csv_options->cb_reallocate(csv_string->str, cap, 1, csv_options->cb_memory_arg); if ( str == NULL ) { - csv_fatal_error("out of memory...", csv_options); + csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); return; } csv_string->str = str; @@ -160,7 +160,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 = csv_options->cb_allocate(INITIAL_CAP, sizeof(csv_field->fields[0]), csv_options->cb_memory_arg)) == NULL ) { - csv_fatal_error("out of memory", csv_options); + csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); return; } @@ -170,7 +170,7 @@ csv_field_append(csv_field_t *csv_field, int idx, const csv_options_t * const cs int cap = (csv_field->cap * 3) / 2; /* *= 1.5 */ int *fields = csv_options->cb_reallocate(csv_field->fields, cap, sizeof(csv_field->fields[0]), csv_options->cb_memory_arg); if ( fields == NULL ) { - csv_fatal_error("out of memory", csv_options); + csv_fatal_error(CSV_ERR_OUT_OF_MEMORY, csv_options); return; } csv_field->fields = fields; @@ -245,7 +245,7 @@ csv_field(csv_t *csv, int idx) assert(idx >= 0 && idx < csv->csv_field.pos); if ( idx < 0 || idx >= csv->csv_field.pos ) { - csv_fatal_error("range error", csv->csv_options); + csv_fatal_error(CSV_ERR_OUT_OF_RANGE, csv->csv_options); } return &csv->csv_string.str[csv->csv_field.fields[idx]]; @@ -269,7 +269,7 @@ csv_read(csv_t *csv, FILE *in) } if ( ferror(in) ) { - csv_fatal_error("I/O error", csv->csv_options); + csv_fatal_error(CSV_ERR_IO_READ, csv->csv_options); } enum { @@ -394,7 +394,7 @@ csv_read(csv_t *csv, FILE *in) case STATE_END_FILE: if ( ferror(in) ) { - csv_fatal_error("I/O error", csv->csv_options); + csv_fatal_error(CSV_ERR_IO_READ, csv->csv_options); } if ( csv_string_empty(&csv->csv_string) ) { @@ -417,6 +417,20 @@ csv_read(csv_t *csv, FILE *in) /* NOT REACHED */ } +const char * +csv_err_str(csv_error_t csv_error) +{ + switch ( csv_error ) { + case CSV_ERR_OK: return "no error"; + case CSV_ERR_OUT_OF_MEMORY: return "out of memory"; + case CSV_ERR_OUT_OF_RANGE: return "index out of range"; + case CSV_ERR_IO_READ: return "read errro"; + case CSV_ERR_IO_WRITE: return "write error"; + default: return "unknown error"; + } + /* NOT REACHED */ +} + static void csv_write_field(FILE *out, const char *field, const csv_options_t * const csv_options) { diff --git a/csv.h b/csv.h index fe59f5b..a8be413 100644 --- a/csv.h +++ b/csv.h @@ -8,11 +8,19 @@ extern "C" { #endif +typedef enum { + CSV_ERR_OK = 0, + CSV_ERR_OUT_OF_MEMORY = -1, + CSV_ERR_OUT_OF_RANGE = -2, + CSV_ERR_IO_READ = -3, + CSV_ERR_IO_WRITE = -4 +} csv_error_t; + typedef struct { char quote_symbol; char sep_symbol; - void (*cb_error)(const char *, void *); + void (*cb_error)(csv_error_t, void *); void *cb_error_arg; void *(*cb_allocate)(size_t, size_t, void *); @@ -45,6 +53,7 @@ void csv_cleanup(csv_t *csv); int csv_nfields(csv_t *csv); const char * csv_field(csv_t *csv, int idx); int csv_read(csv_t *csv, FILE *in); +const char * csv_err_str(csv_error_t csv_error); void csv_write(FILE *out, int n, const char *fields[], const csv_options_t * const csv_options); #ifdef __cplusplus -- cgit v1.3