From 2873f39e5e1f41d79f689994948196a77da47671 Mon Sep 17 00:00:00 2001 From: Thomas Schmucker Date: Wed, 17 Jun 2020 15:24:04 +0200 Subject: Zwischenstand... --- csv-test.c | 130 +++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 87 insertions(+), 43 deletions(-) diff --git a/csv-test.c b/csv-test.c index 68903de..55a41bc 100644 --- a/csv-test.c +++ b/csv-test.c @@ -16,16 +16,13 @@ typedef struct { } csv_string_t; INLINE bool -csv_string_init(csv_string_t *csv_string, jmp_buf env) +csv_string_init(csv_string_t *csv_string) { assert(csv_string != NULL); static const int INITIAL_CAP = 16; if ( (csv_string->str = malloc(INITIAL_CAP)) == NULL ) { - if ( env ) { - longjmp(env, 66); - } return false; } @@ -52,7 +49,7 @@ csv_string_empty(csv_string_t *csv_string) } INLINE bool -csv_string_append(csv_string_t *csv_string, char ch, jmp_buf env) +csv_string_append(csv_string_t *csv_string, char ch) { assert(csv_string != NULL); @@ -60,9 +57,6 @@ csv_string_append(csv_string_t *csv_string, char ch, jmp_buf env) int cap = (csv_string->cap * 3) / 2; /* *= 1.5 */ char *str = realloc(csv_string->str, cap); if ( str == NULL ) { - if ( env ) { - longjmp(env, 68); - } return false; } csv_string->str = str; @@ -90,16 +84,13 @@ typedef struct { } csv_field_t; INLINE bool -csv_field_init(csv_field_t *csv_field, jmp_buf env) +csv_field_init(csv_field_t *csv_field) { assert(csv_field != NULL); static const size_t INITIAL_CAP = 16; if ( (csv_field->fields = calloc(INITIAL_CAP, sizeof(csv_field->fields[0]))) == NULL ) { - if ( env ) { - longjmp(env, 88); - } return false; } @@ -118,7 +109,7 @@ csv_field_reset(csv_field_t *csv_field) } INLINE bool -csv_field_append(csv_field_t *csv_field, int idx, jmp_buf env) +csv_field_append(csv_field_t *csv_field, int idx) { assert(csv_field != NULL); @@ -126,9 +117,6 @@ csv_field_append(csv_field_t *csv_field, int idx, jmp_buf env) int cap = (csv_field->cap * 3) / 2; /* *= 1.5 */ int *fields = reallocarray(csv_field->fields, cap, sizeof(csv_field->fields[0])); if ( fields == NULL ) { - if ( env ) { - longjmp(env, 66); - } return false; } csv_field->fields = fields; @@ -176,6 +164,45 @@ const char * csv_field(csv_t *csv, int idx); int csv_read(csv_t *csv); void csv_write(csv_t *csv, int n, const char *fields[], FILE *out); +int csv_try(csv_t *csv, FILE *in); +void csv_throw(csv_t *csv, int x); + +#define CSV_NO_MEMORY_EXCEPTION (1) +#define CSV_OUT_OF_BOUND_EXCEPTION (2) + + +#if 0 +#define TRY do { jmp_buf ex_buf__; switch( setjmp(ex_buf__) ) { case 0: while(1) { +#define CATCH(x) break; case x: +#define FINALLY break; } default: { +#define ETRY break; } } }while(0) +#define THROW(x) longjmp(ex_buf__, x) +#endif + +#define CSV_TRY(csv, in) do{ switch( csv_try(csv, in) ){ case 0: while(1) { +#define CSV_CATCH(x) break; case x: +#define CSV_FINALLY break; } default: { +#define CSV_ETRY break; } } } while(0) +#define CSV_THROW(csv, x) csv_throw(csv, x) + +int +csv_try(csv_t *csv, FILE *in) +{ + int err = csv_init(csv, in); + if ( err ) { + return err; + } + err = setjmp(csv->env); + return err; +} + +void +csv_throw(csv_t *csv, int x) +{ + longjmp(csv->env, x); + printf("d\n"); +} + int csv_init(csv_t *csv, FILE *in) { @@ -193,21 +220,15 @@ csv_init_opt(csv_t *csv, FILE *in, csv_options_t *csv_options) csv->in = in; csv->csv_options = ( csv_options != NULL ) ? csv_options : &default_csv_options; - int err = setjmp(csv->env); - - if ( !err ) { - if ( !csv_string_init(&csv->csv_string, NULL) ) { - return -1; - } - if ( !csv_field_init(&csv->csv_field, NULL) ) { - csv_string_free(&csv->csv_string); - return -2; - } + if ( !csv_string_init(&csv->csv_string) ) { + return -1; } - else { - csv_free(csv); + if ( !csv_field_init(&csv->csv_field) ) { + csv_string_free(&csv->csv_string); + return -1; } - return err; + + return 0; } void @@ -234,13 +255,15 @@ const char * csv_field(csv_t *csv, int idx) { assert(csv != NULL); - assert(idx >= 0 && idx < csv->csv_field.pos); + //assert(idx >= 0 && idx < csv->csv_field.pos); - if ( idx >= 0 && idx < csv->csv_field.pos) { - return &csv->csv_string.str[csv->csv_field.fields[idx]]; + if ( idx < 0 || idx >= csv->csv_field.pos) { + printf("idx: %d\n", idx); + CSV_THROW(csv, CSV_OUT_OF_BOUND_EXCEPTION); + return NULL; } else { - return NULL; + return &csv->csv_string.str[csv->csv_field.fields[idx]]; } } @@ -269,7 +292,7 @@ csv_read(csv_t *csv) switch ( state ) { case STATE_START_FIELD: - csv_field_append(&csv->csv_field, csv->csv_string.pos, csv->env); + csv_field_append(&csv->csv_field, csv->csv_string.pos); ch = getc(csv->in); if ( ch == EOF ) { @@ -292,7 +315,7 @@ csv_read(csv_t *csv) state = STATE_QUOTED_FIELD; } else { - csv_string_append(&csv->csv_string, ch, csv->env); + csv_string_append(&csv->csv_string, ch); state = STATE_SIMPLE_FIELD; } break; @@ -309,7 +332,7 @@ csv_read(csv_t *csv) state = STATE_END_FILE; } else if ( ch == QUOTE ) { - csv_string_append(&csv->csv_string, QUOTE, csv->env); + csv_string_append(&csv->csv_string, QUOTE); } else if ( ch == SEP ) { state = STATE_END_FIELD; @@ -325,12 +348,12 @@ csv_read(csv_t *csv) state = STATE_END_LINE; } else { - csv_string_append(&csv->csv_string, QUOTE, csv->env); + csv_string_append(&csv->csv_string, QUOTE); ungetc(ch, csv->in); /* zuviel gelesenes Zeichen zurückstellen */ } } else { - csv_string_append(&csv->csv_string, ch, csv->env); + csv_string_append(&csv->csv_string, ch); } } while ( state == STATE_QUOTED_FIELD ); break; @@ -355,18 +378,18 @@ csv_read(csv_t *csv) state = STATE_END_LINE; } else { - csv_string_append(&csv->csv_string, ch, csv->env); + csv_string_append(&csv->csv_string, ch); } } while ( state == STATE_SIMPLE_FIELD ); break; case STATE_END_FIELD: - csv_string_append(&csv->csv_string, '\0', csv->env); + csv_string_append(&csv->csv_string, '\0'); state = STATE_START_FIELD; break; case STATE_END_LINE: - csv_string_append(&csv->csv_string, '\0', csv->env); + csv_string_append(&csv->csv_string, '\0'); return csv->csv_field.pos; case STATE_END_FILE: @@ -376,7 +399,7 @@ csv_read(csv_t *csv) /* EOF wurde gelesen, allerdings sind Daten zur Vearbeitung vorhanden! */ /* => aktuelles Feld abschließen... */ - csv_string_append(&csv->csv_string, '\0', csv->env); + csv_string_append(&csv->csv_string, '\0'); /* ... und die Anzahl der Felder zurückliefern! */ return csv->csv_field.pos; @@ -441,12 +464,33 @@ main(void) clock_t start = clock(); - if ( csv_init(csv, stdin) == CSV_OK ) { + CSV_TRY(csv, stdin) + { while ( (n = csv_read(csv)) != -1 ) { + csv_field(csv, -1); ++line; } + } + CSV_CATCH( CSV_NO_MEMORY_EXCEPTION ) + { + fprintf(stderr, "out of memory!"); csv_free(csv); + return EXIT_FAILURE; } + CSV_CATCH( CSV_OUT_OF_BOUND_EXCEPTION ) + { + fprintf(stderr, "out of bound!!\n"); + csv_free(csv); + return EXIT_FAILURE; + } + CSV_FINALLY + { + printf("finally...\n"); + csv_free(csv); + } + CSV_ETRY; + + // http://groups.di.unipi.it/~nids/docs/longjump_try_trow_catch.html clock_t end = clock(); -- cgit v1.3