csv2tsv.c - randomcrap - random crap programs of varying quality
 (HTM) git clone git://git.codemadness.org/randomcrap
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       csv2tsv.c (1365B)
       ---
            1 /* CSV to TSV: handles newlines in strings and "" quote escaping */
            2 #include <stdio.h>
            3 
            4 #define GETCHAR getchar_unlocked
            5 #define PUTCHAR putchar_unlocked
            6 
            7 void
            8 put(int c)
            9 {
           10         switch (c) {
           11         case '\\': PUTCHAR('\\'); PUTCHAR('\\'); break;
           12         case '\n': PUTCHAR('\\'); PUTCHAR('n'); break;
           13         case '\t': PUTCHAR('\\'); PUTCHAR('t'); break;
           14         default:
           15                 /* ignore control-characters */
           16                 if ((unsigned char)c < 0x20 || (unsigned char)c == 0x7f)
           17                         break;
           18                 PUTCHAR(c);
           19                 break;
           20         }
           21 }
           22 
           23 int
           24 main(int argc, char *argv[])
           25 {
           26         size_t i, v;
           27         int c, separator = argc > 1 ? argv[1][0] : ','; /* default separator */
           28 
           29         for (i = v = 0; (c = GETCHAR()) != EOF;) {
           30 parse:
           31                 switch (c) {
           32                 case '"':
           33                         while ((c = GETCHAR()) != EOF) {
           34                                 if (c == '"') {
           35                                         if ((c = GETCHAR()) == EOF)
           36                                                 goto end;
           37                                         else if (c != '"')
           38                                                 goto parse;
           39                                 }
           40                                 put(c);
           41                                 v++;
           42                         }
           43                         break;
           44                 case '\n': /* new record */
           45                         PUTCHAR('\n');
           46                         i = v = 0;
           47                         break;
           48                 case '\r': /* ignore CR */
           49                         break;
           50                 default:
           51                         if (c == separator) {
           52                                 PUTCHAR('\t');
           53                                 i++;
           54                         } else {
           55                                 put(c);
           56                                 v++;
           57                         }
           58                 }
           59         }
           60 end:
           61         /* handle end of record without newline */
           62         if (i || v)
           63                 PUTCHAR('\n');
           64 
           65         if (ferror(stdin)) {
           66                 fprintf(stderr, "read error: <stdin>\n");
           67                 return 2;
           68         } else if (fflush(stdout) || ferror(stdout)) {
           69                 fprintf(stderr, "write error: <stdout>\n");
           70                 return 2;
           71         }
           72 
           73         return 0;
           74 }