@@ -301,6 +301,9 @@ void setclvar(char *s) /* set var=value from s */
301
301
Cell * q ;
302
302
double result ;
303
303
304
+ /* commit f3d9187d4e0f02294fb1b0e31152070506314e67 broke T.argv test */
305
+ /* I don't understand why it was changed. */
306
+
304
307
for (p = s ; * p != '=' ; p ++ )
305
308
;
306
309
e = p ;
@@ -324,7 +327,7 @@ void fldbld(void) /* create fields from current record */
324
327
/* possibly with a final trailing \0 not associated with any field */
325
328
char * r , * fr , sep ;
326
329
Cell * p ;
327
- int i , j , n ;
330
+ int i , j , n , quote ;
328
331
329
332
if (donefld )
330
333
return ;
@@ -363,6 +366,57 @@ void fldbld(void) /* create fields from current record */
363
366
* fr ++ = 0 ;
364
367
}
365
368
* fr = 0 ;
369
+ } else if ((sep = * inputFS ) == ',' ) { /* CSV: handle quotes, \x, etc. */
370
+ for (i = 0 ; * r != '\0' ; ) {
371
+ i ++ ;
372
+ if (i > nfields )
373
+ growfldtab (i );
374
+ if (freeable (fldtab [i ]))
375
+ xfree (fldtab [i ]-> sval );
376
+ fldtab [i ]-> sval = fr ;
377
+ fldtab [i ]-> tval = FLD | STR | DONTFREE ;
378
+
379
+ /* printf("fldbld 1 [%s] [%d:] [%s]\n", r, i, fr); */
380
+
381
+ if (* r == '"' /* || *r == '\'' */ ) { /* "..."; do not include '...' */
382
+ quote = * r ++ ;
383
+ for ( ; * r != '\0' ; ) {
384
+ /* printf("fldbld 2 [%s]\n", r); */
385
+ if (* r == quote && r [1 ] != '\0' && r [1 ] == quote ) {
386
+ r += 2 ; /* doubled quote */
387
+ * fr ++ = quote ;
388
+ } else if (* r == '\\' ) { /* BUG: off end? */
389
+ r ++ ; /* backslashes inside "..." ??? */
390
+ * fr ++ = * r ++ ;
391
+ } else if (* r == quote && (r [1 ] == '\0' || r [1 ] == ',' )) {
392
+ r ++ ;
393
+ if (* r == ',' )
394
+ r ++ ;
395
+ break ;
396
+ } else {
397
+ * fr ++ = * r ++ ;
398
+ }
399
+ }
400
+ * fr ++ = 0 ;
401
+ continue ;
402
+ }
403
+
404
+ /* unquoted field */
405
+ for ( ; * r != '\0' ; ) {
406
+ if (* r == ',' ) { /* bare comma ends field */
407
+ r ++ ;
408
+ * fr ++ = 0 ;
409
+ break ;
410
+ } else if (* r == '\\' ) { /* BUG: could walk off end */
411
+ r ++ ;
412
+ * fr ++ = * r ++ ;
413
+ } else {
414
+ * fr ++ = * r ++ ;
415
+ }
416
+ }
417
+ * fr ++ = 0 ;
418
+ }
419
+ * fr = 0 ;
366
420
} else if ((sep = * inputFS ) == 0 ) { /* new: FS="" => 1 char/field */
367
421
for (i = 0 ; * r != '\0' ; r += n ) {
368
422
char buf [MB_LEN_MAX + 1 ];
@@ -797,11 +851,11 @@ bool is_valid_number(const char *s, bool trailing_stuff_ok,
797
851
while (isspace (* s ))
798
852
s ++ ;
799
853
800
- // no hex floating point, sorry
854
+ /* no hex floating point, sorry */
801
855
if (s [0 ] == '0' && tolower (s [1 ]) == 'x' )
802
856
return false;
803
857
804
- // allow +nan, -nan, +inf, -inf, any other letter, no
858
+ /* allow +nan, -nan, +inf, -inf, any other letter, no */
805
859
if (s [0 ] == '+' || s [0 ] == '-' ) {
806
860
is_nan = (strncasecmp (s + 1 , "nan" , 3 ) == 0 );
807
861
is_inf = (strncasecmp (s + 1 , "inf" , 3 ) == 0 );
@@ -835,7 +889,7 @@ bool is_valid_number(const char *s, bool trailing_stuff_ok,
835
889
if (no_trailing != NULL )
836
890
* no_trailing = (* ep == '\0' );
837
891
838
- // return true if found the end, or trailing stuff is allowed
892
+ /* return true if found the end, or trailing stuff is allowed */
839
893
retval = * ep == '\0' || trailing_stuff_ok ;
840
894
841
895
return retval ;
0 commit comments