aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Schmucker <ts@its1.de>2020-06-17 15:24:04 +0200
committerThomas Schmucker <ts@its1.de>2020-06-17 15:24:04 +0200
commit2873f39e5e1f41d79f689994948196a77da47671 (patch)
tree2638206458f99a722e763f89e14b8d4abdeeee49
parentdacba96a56a325d6aa431c64553dd34d5d99b642 (diff)
downloadlibcsv-2873f39e5e1f41d79f689994948196a77da47671.tar.gz
libcsv-2873f39e5e1f41d79f689994948196a77da47671.tar.bz2
libcsv-2873f39e5e1f41d79f689994948196a77da47671.zip
Zwischenstand...
-rw-r--r--csv-test.c130
1 files 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 {
16} csv_string_t; 16} csv_string_t;
17 17
18INLINE bool 18INLINE bool
19csv_string_init(csv_string_t *csv_string, jmp_buf env) 19csv_string_init(csv_string_t *csv_string)
20{ 20{
21 assert(csv_string != NULL); 21 assert(csv_string != NULL);
22 22
23 static const int INITIAL_CAP = 16; 23 static const int INITIAL_CAP = 16;
24 24
25 if ( (csv_string->str = malloc(INITIAL_CAP)) == NULL ) { 25 if ( (csv_string->str = malloc(INITIAL_CAP)) == NULL ) {
26 if ( env ) {
27 longjmp(env, 66);
28 }
29 return false; 26 return false;
30 } 27 }
31 28
@@ -52,7 +49,7 @@ csv_string_empty(csv_string_t *csv_string)
52} 49}
53 50
54INLINE bool 51INLINE bool
55csv_string_append(csv_string_t *csv_string, char ch, jmp_buf env) 52csv_string_append(csv_string_t *csv_string, char ch)
56{ 53{
57 assert(csv_string != NULL); 54 assert(csv_string != NULL);
58 55
@@ -60,9 +57,6 @@ csv_string_append(csv_string_t *csv_string, char ch, jmp_buf env)
60 int cap = (csv_string->cap * 3) / 2; /* *= 1.5 */ 57 int cap = (csv_string->cap * 3) / 2; /* *= 1.5 */
61 char *str = realloc(csv_string->str, cap); 58 char *str = realloc(csv_string->str, cap);
62 if ( str == NULL ) { 59 if ( str == NULL ) {
63 if ( env ) {
64 longjmp(env, 68);
65 }
66 return false; 60 return false;
67 } 61 }
68 csv_string->str = str; 62 csv_string->str = str;
@@ -90,16 +84,13 @@ typedef struct {
90} csv_field_t; 84} csv_field_t;
91 85
92INLINE bool 86INLINE bool
93csv_field_init(csv_field_t *csv_field, jmp_buf env) 87csv_field_init(csv_field_t *csv_field)
94{ 88{
95 assert(csv_field != NULL); 89 assert(csv_field != NULL);
96 90
97 static const size_t INITIAL_CAP = 16; 91 static const size_t INITIAL_CAP = 16;
98 92
99 if ( (csv_field->fields = calloc(INITIAL_CAP, sizeof(csv_field->fields[0]))) == NULL ) { 93 if ( (csv_field->fields = calloc(INITIAL_CAP, sizeof(csv_field->fields[0]))) == NULL ) {
100 if ( env ) {
101 longjmp(env, 88);
102 }
103 return false; 94 return false;
104 } 95 }
105 96
@@ -118,7 +109,7 @@ csv_field_reset(csv_field_t *csv_field)
118} 109}
119 110
120INLINE bool 111INLINE bool
121csv_field_append(csv_field_t *csv_field, int idx, jmp_buf env) 112csv_field_append(csv_field_t *csv_field, int idx)
122{ 113{
123 assert(csv_field != NULL); 114 assert(csv_field != NULL);
124 115
@@ -126,9 +117,6 @@ csv_field_append(csv_field_t *csv_field, int idx, jmp_buf env)
126 int cap = (csv_field->cap * 3) / 2; /* *= 1.5 */ 117 int cap = (csv_field->cap * 3) / 2; /* *= 1.5 */
127 int *fields = reallocarray(csv_field->fields, cap, sizeof(csv_field->fields[0])); 118 int *fields = reallocarray(csv_field->fields, cap, sizeof(csv_field->fields[0]));
128 if ( fields == NULL ) { 119 if ( fields == NULL ) {
129 if ( env ) {
130 longjmp(env, 66);
131 }
132 return false; 120 return false;
133 } 121 }
134 csv_field->fields = fields; 122 csv_field->fields = fields;
@@ -176,6 +164,45 @@ const char * csv_field(csv_t *csv, int idx);
176int csv_read(csv_t *csv); 164int csv_read(csv_t *csv);
177void csv_write(csv_t *csv, int n, const char *fields[], FILE *out); 165void csv_write(csv_t *csv, int n, const char *fields[], FILE *out);
178 166
167int csv_try(csv_t *csv, FILE *in);
168void csv_throw(csv_t *csv, int x);
169
170#define CSV_NO_MEMORY_EXCEPTION (1)
171#define CSV_OUT_OF_BOUND_EXCEPTION (2)
172
173
174#if 0
175#define TRY do { jmp_buf ex_buf__; switch( setjmp(ex_buf__) ) { case 0: while(1) {
176#define CATCH(x) break; case x:
177#define FINALLY break; } default: {
178#define ETRY break; } } }while(0)
179#define THROW(x) longjmp(ex_buf__, x)
180#endif
181
182#define CSV_TRY(csv, in) do{ switch( csv_try(csv, in) ){ case 0: while(1) {
183#define CSV_CATCH(x) break; case x:
184#define CSV_FINALLY break; } default: {
185#define CSV_ETRY break; } } } while(0)
186#define CSV_THROW(csv, x) csv_throw(csv, x)
187
188int
189csv_try(csv_t *csv, FILE *in)
190{
191 int err = csv_init(csv, in);
192 if ( err ) {
193 return err;
194 }
195 err = setjmp(csv->env);
196 return err;
197}
198
199void
200csv_throw(csv_t *csv, int x)
201{
202 longjmp(csv->env, x);
203 printf("d\n");
204}
205
179int 206int
180csv_init(csv_t *csv, FILE *in) 207csv_init(csv_t *csv, FILE *in)
181{ 208{
@@ -193,21 +220,15 @@ csv_init_opt(csv_t *csv, FILE *in, csv_options_t *csv_options)
193 csv->in = in; 220 csv->in = in;
194 csv->csv_options = ( csv_options != NULL ) ? csv_options : &default_csv_options; 221 csv->csv_options = ( csv_options != NULL ) ? csv_options : &default_csv_options;
195 222
196 int err = setjmp(csv->env); 223 if ( !csv_string_init(&csv->csv_string) ) {
197 224 return -1;
198 if ( !err ) {
199 if ( !csv_string_init(&csv->csv_string, NULL) ) {
200 return -1;
201 }
202 if ( !csv_field_init(&csv->csv_field, NULL) ) {
203 csv_string_free(&csv->csv_string);
204 return -2;
205 }
206 } 225 }
207 else { 226 if ( !csv_field_init(&csv->csv_field) ) {
208 csv_free(csv); 227 csv_string_free(&csv->csv_string);
228 return -1;
209 } 229 }
210 return err; 230
231 return 0;
211} 232}
212 233
213void 234void
@@ -234,13 +255,15 @@ const char *
234csv_field(csv_t *csv, int idx) 255csv_field(csv_t *csv, int idx)
235{ 256{
236 assert(csv != NULL); 257 assert(csv != NULL);
237 assert(idx >= 0 && idx < csv->csv_field.pos); 258 //assert(idx >= 0 && idx < csv->csv_field.pos);
238 259
239 if ( idx >= 0 && idx < csv->csv_field.pos) { 260 if ( idx < 0 || idx >= csv->csv_field.pos) {
240 return &csv->csv_string.str[csv->csv_field.fields[idx]]; 261 printf("idx: %d\n", idx);
262 CSV_THROW(csv, CSV_OUT_OF_BOUND_EXCEPTION);
263 return NULL;
241 } 264 }
242 else { 265 else {
243 return NULL; 266 return &csv->csv_string.str[csv->csv_field.fields[idx]];
244 } 267 }
245} 268}
246 269
@@ -269,7 +292,7 @@ csv_read(csv_t *csv)
269 292
270 switch ( state ) { 293 switch ( state ) {
271 case STATE_START_FIELD: 294 case STATE_START_FIELD:
272 csv_field_append(&csv->csv_field, csv->csv_string.pos, csv->env); 295 csv_field_append(&csv->csv_field, csv->csv_string.pos);
273 296
274 ch = getc(csv->in); 297 ch = getc(csv->in);
275 if ( ch == EOF ) { 298 if ( ch == EOF ) {
@@ -292,7 +315,7 @@ csv_read(csv_t *csv)
292 state = STATE_QUOTED_FIELD; 315 state = STATE_QUOTED_FIELD;
293 } 316 }
294 else { 317 else {
295 csv_string_append(&csv->csv_string, ch, csv->env); 318 csv_string_append(&csv->csv_string, ch);
296 state = STATE_SIMPLE_FIELD; 319 state = STATE_SIMPLE_FIELD;
297 } 320 }
298 break; 321 break;
@@ -309,7 +332,7 @@ csv_read(csv_t *csv)
309 state = STATE_END_FILE; 332 state = STATE_END_FILE;
310 } 333 }
311 else if ( ch == QUOTE ) { 334 else if ( ch == QUOTE ) {
312 csv_string_append(&csv->csv_string, QUOTE, csv->env); 335 csv_string_append(&csv->csv_string, QUOTE);
313 } 336 }
314 else if ( ch == SEP ) { 337 else if ( ch == SEP ) {
315 state = STATE_END_FIELD; 338 state = STATE_END_FIELD;
@@ -325,12 +348,12 @@ csv_read(csv_t *csv)
325 state = STATE_END_LINE; 348 state = STATE_END_LINE;
326 } 349 }
327 else { 350 else {
328 csv_string_append(&csv->csv_string, QUOTE, csv->env); 351 csv_string_append(&csv->csv_string, QUOTE);
329 ungetc(ch, csv->in); /* zuviel gelesenes Zeichen zurückstellen */ 352 ungetc(ch, csv->in); /* zuviel gelesenes Zeichen zurückstellen */
330 } 353 }
331 } 354 }
332 else { 355 else {
333 csv_string_append(&csv->csv_string, ch, csv->env); 356 csv_string_append(&csv->csv_string, ch);
334 } 357 }
335 } while ( state == STATE_QUOTED_FIELD ); 358 } while ( state == STATE_QUOTED_FIELD );
336 break; 359 break;
@@ -355,18 +378,18 @@ csv_read(csv_t *csv)
355 state = STATE_END_LINE; 378 state = STATE_END_LINE;
356 } 379 }
357 else { 380 else {
358 csv_string_append(&csv->csv_string, ch, csv->env); 381 csv_string_append(&csv->csv_string, ch);
359 } 382 }
360 } while ( state == STATE_SIMPLE_FIELD ); 383 } while ( state == STATE_SIMPLE_FIELD );
361 break; 384 break;
362 385
363 case STATE_END_FIELD: 386 case STATE_END_FIELD:
364 csv_string_append(&csv->csv_string, '\0', csv->env); 387 csv_string_append(&csv->csv_string, '\0');
365 state = STATE_START_FIELD; 388 state = STATE_START_FIELD;
366 break; 389 break;
367 390
368 case STATE_END_LINE: 391 case STATE_END_LINE:
369 csv_string_append(&csv->csv_string, '\0', csv->env); 392 csv_string_append(&csv->csv_string, '\0');
370 return csv->csv_field.pos; 393 return csv->csv_field.pos;
371 394
372 case STATE_END_FILE: 395 case STATE_END_FILE:
@@ -376,7 +399,7 @@ csv_read(csv_t *csv)
376 399
377 /* EOF wurde gelesen, allerdings sind Daten zur Vearbeitung vorhanden! */ 400 /* EOF wurde gelesen, allerdings sind Daten zur Vearbeitung vorhanden! */
378 /* => aktuelles Feld abschließen... */ 401 /* => aktuelles Feld abschließen... */
379 csv_string_append(&csv->csv_string, '\0', csv->env); 402 csv_string_append(&csv->csv_string, '\0');
380 403
381 /* ... und die Anzahl der Felder zurückliefern! */ 404 /* ... und die Anzahl der Felder zurückliefern! */
382 return csv->csv_field.pos; 405 return csv->csv_field.pos;
@@ -441,12 +464,33 @@ main(void)
441 464
442 clock_t start = clock(); 465 clock_t start = clock();
443 466
444 if ( csv_init(csv, stdin) == CSV_OK ) { 467 CSV_TRY(csv, stdin)
468 {
445 while ( (n = csv_read(csv)) != -1 ) { 469 while ( (n = csv_read(csv)) != -1 ) {
470 csv_field(csv, -1);
446 ++line; 471 ++line;
447 } 472 }
473 }
474 CSV_CATCH( CSV_NO_MEMORY_EXCEPTION )
475 {
476 fprintf(stderr, "out of memory!");
448 csv_free(csv); 477 csv_free(csv);
478 return EXIT_FAILURE;
449 } 479 }
480 CSV_CATCH( CSV_OUT_OF_BOUND_EXCEPTION )
481 {
482 fprintf(stderr, "out of bound!!\n");
483 csv_free(csv);
484 return EXIT_FAILURE;
485 }
486 CSV_FINALLY
487 {
488 printf("finally...\n");
489 csv_free(csv);
490 }
491 CSV_ETRY;
492
493 // http://groups.di.unipi.it/~nids/docs/longjump_try_trow_catch.html
450 494
451 clock_t end = clock(); 495 clock_t end = clock();
452 496