1414char * colsep = "\t" ;
1515char * rowsep = "\n" ;
1616int left_join = 1 ;
17+ int csv_output = 0 ;
18+
19+ char * unescape_string (char * );
1720
1821/*
1922 * helpers
@@ -66,13 +69,34 @@ void *jrealloc(void *ptr, size_t size) {
6669 return ret ;
6770}
6871
72+ char * csv_str (char * raw ) {
73+ char * in , * inp , * out , * outp ;
74+
75+ inp = in = unescape_string (raw );
76+ free (raw );
77+
78+ outp = out = jmalloc (strlen (in ) * 2 + 3 );
79+ * (outp ++ ) = '"' ;
80+
81+ while (* inp != '\0' ) {
82+ * (outp ++ ) = * inp ;
83+ if (* (inp ++ ) == '"' ) * (outp ++ ) = '"' ;
84+ }
85+
86+ * (outp ++ ) = '"' ;
87+ * outp = '\0' ;
88+ free (in );
89+
90+ return out ;
91+ }
92+
6993char * str (const char * fmt , ...) {
70- char * s ;
94+ char * s = NULL ;
7195 va_list ap ;
7296 va_start (ap , fmt );
7397 if (vasprintf (& s , fmt , ap ) < 0 ) die_mem ();
7498 va_end (ap );
75- return s ;
99+ return csv_output ? csv_str ( s ) : s ;
76100}
77101
78102FILE * open (const char * path , const char * mode ) {
@@ -191,25 +215,24 @@ unsigned long read_code_point(char **s) {
191215 return high ;
192216}
193217
194- unsigned long utf_tag [7 ] = { 0x00 , 0x00 , 0xc0 , 0xe0 , 0xf0 , 0xf8 , 0xfc };
218+ unsigned long utf_tag [4 ] = { 0x00 , 0xc0 , 0xe0 , 0xf0 };
195219
196220void encode_u_escaped (char * * in , char * * out ) {
197221 unsigned long p = read_code_point (in );
198- int len = (p < 0x80 ) ? 1 : (p < 0x800 ) ? 2 : (p < 0x1000 ) ? 3 : 4 ;
199-
222+ int len = (p < 0x80 ) ? 1 : ((p < 0x800 ) ? 2 : ((p < 0x1000 ) ? 3 : 4 ));
200223 * out += len ;
201224 switch (len ) {
202225 case 4 : * -- (* out ) = ((p | 0x80 ) & 0xbf ); p >>= 6 ;
203226 case 3 : * -- (* out ) = ((p | 0x80 ) & 0xbf ); p >>= 6 ;
204227 case 2 : * -- (* out ) = ((p | 0x80 ) & 0xbf ); p >>= 6 ;
205- case 1 : * -- (* out ) = (p | utf_tag [len ]);
228+ case 1 : * -- (* out ) = (p | utf_tag [len - 1 ]);
206229 }
207230 * out += len ;
208231}
209232
210233char * unescape_string (char * in ) {
211234 char * inp = in , * outp , * out ;
212- outp = out = malloc (strlen (in ) + 1 );
235+ outp = out = jmalloc (strlen (in ) + 1 );
213236
214237 while (* inp != '\0' ) {
215238 if (* inp != '\\' ) {
@@ -401,9 +424,10 @@ int run(char *js, int argc, char *argv[]) {
401424
402425void usage (int status ) {
403426 fprintf (stderr , "jt %s - transform JSON data into tab delimited lines of text.\n\n" , JT_VERSION );
404- fprintf (stderr , "Usage: jt [-h]\n" );
405- fprintf (stderr , " jt [-u <string>]\n" );
406- fprintf (stderr , " jt [-hjs] [-i <file>] [-o <file>] [-F <char>] [-R <char>] [COMMAND ...]\n\n" );
427+ fprintf (stderr , "Usage: jt -h\n" );
428+ fprintf (stderr , " jt -u <string>\n" );
429+ fprintf (stderr , " jt -c [-js] [-i <file>] [-o <file>] COMMAND ...\n" );
430+ fprintf (stderr , " jt [-js] [-i <file>] [-o <file>] [-F <char>] [-R <char>] COMMAND ...\n\n" );
407431 fprintf (stderr , "Where COMMAND is one of `[', `]', `%%', `?', `^', or a property name.\n" );
408432 exit (status );
409433}
@@ -419,11 +443,15 @@ int main(int argc, char *argv[]) {
419443 infile = stdin ;
420444 outfile = stdout ;
421445
422- while ((opt = getopt (argc , argv , "+hjsi :o:u:F:R:" )) != -1 ) {
446+ while ((opt = getopt (argc , argv , "+hjsci :o:u:F:R:" )) != -1 ) {
423447 switch (opt ) {
424448 case 'h' :
425449 usage (0 );
426450 break ;
451+ case 'c' :
452+ csv_output = 1 ;
453+ colsep = "," ;
454+ break ;
427455 case 'j' :
428456 left_join = 0 ;
429457 break ;
0 commit comments