@@ -42,6 +42,8 @@ extern void jv_tsd_dtoa_ctx_init();
4242
4343int jq_testsuite (jv lib_dirs , int verbose , int argc , char * argv []);
4444
45+ FILE * ofile ;
46+
4547/*
4648 * For a longer help message we could use a better option parsing
4749 * strategy, one that lets stack options.
@@ -81,6 +83,7 @@ static void usage(int code, int keep_it_short) {
8183 " each output;\n"
8284 " -a, --ascii-output output strings by only ASCII characters\n"
8385 " using escape sequences;\n"
86+ " -o, --output-file output to file instead of stdout\n"
8487 " -S, --sort-keys sort keys of each object on output;\n"
8588 " -C, --color-output colorize JSON output;\n"
8689 " -M, --monochrome-output disable colored output;\n"
@@ -179,15 +182,15 @@ static int process(jq_state *jq, jv value, int flags, int dumpopts, int options)
179182 while (jv_is_valid (result = jq_next (jq ))) {
180183 if ((options & RAW_OUTPUT ) && jv_get_kind (result ) == JV_KIND_STRING ) {
181184 if (options & ASCII_OUTPUT ) {
182- jv_dumpf (jv_copy (result ), stdout , JV_PRINT_ASCII );
185+ jv_dumpf (jv_copy (result ), ofile , JV_PRINT_ASCII );
183186 } else if ((options & RAW_OUTPUT0 ) && strlen (jv_string_value (result )) != (unsigned long )jv_string_length_bytes (jv_copy (result ))) {
184187 jv_free (result );
185188 result = jv_invalid_with_msg (jv_string (
186189 "Cannot dump a string containing NUL with --raw-output0 option" ));
187190 break ;
188191 } else {
189192 priv_fwrite (jv_string_value (result ), jv_string_length_bytes (jv_copy (result )),
190- stdout , dumpopts & JV_PRINT_ISATTY );
193+ ofile , dumpopts & JV_PRINT_ISATTY );
191194 }
192195 ret = JQ_OK ;
193196 jv_free (result );
@@ -197,15 +200,15 @@ static int process(jq_state *jq, jv value, int flags, int dumpopts, int options)
197200 else
198201 ret = JQ_OK ;
199202 if (options & SEQ )
200- priv_fwrite ("\036" , 1 , stdout , dumpopts & JV_PRINT_ISATTY );
203+ priv_fwrite ("\036" , 1 , ofile , dumpopts & JV_PRINT_ISATTY );
201204 jv_dump (result , dumpopts );
202205 }
203206 if (!(options & RAW_NO_LF ))
204- priv_fwrite ("\n" , 1 , stdout , dumpopts & JV_PRINT_ISATTY );
207+ priv_fwrite ("\n" , 1 , ofile , dumpopts & JV_PRINT_ISATTY );
205208 if (options & RAW_OUTPUT0 )
206- priv_fwrite ("\0" , 1 , stdout , dumpopts & JV_PRINT_ISATTY );
209+ priv_fwrite ("\0" , 1 , ofile , dumpopts & JV_PRINT_ISATTY );
207210 if (options & UNBUFFERED_OUTPUT )
208- fflush (stdout );
211+ fflush (ofile );
209212 }
210213 if (jq_halted (jq )) {
211214 // jq program invoked `halt` or `halt_error`
@@ -288,6 +291,7 @@ int umain(int argc, char* argv[]) {
288291#else /*}*/
289292int main (int argc , char * argv []) {
290293#endif
294+ ofile = stdout ;
291295 jq_state * jq = NULL ;
292296 jq_util_input_state * input_state = NULL ;
293297 int ret = JQ_OK_NO_OUTPUT ;
@@ -318,9 +322,9 @@ int main(int argc, char* argv[]) {
318322
319323#ifdef WIN32
320324 jv_tsd_dtoa_ctx_init ();
321- fflush (stdout );
325+ fflush (ofile );
322326 fflush (stderr );
323- _setmode (fileno (stdout ), _O_TEXT | _O_U8TEXT );
327+ _setmode (fileno (ofile ), _O_TEXT | _O_U8TEXT );
324328 _setmode (fileno (stderr ), _O_TEXT | _O_U8TEXT );
325329#endif
326330
@@ -419,10 +423,10 @@ int main(int argc, char* argv[]) {
419423 }
420424 } else if (isoption (& text , 'b' , "binary" , is_short )) {
421425#ifdef WIN32
422- fflush (stdout );
426+ fflush (ofile );
423427 fflush (stderr );
424428 _setmode (fileno (stdin ), _O_BINARY );
425- _setmode (fileno (stdout ), _O_BINARY );
429+ _setmode (fileno (ofile ), _O_BINARY );
426430 _setmode (fileno (stderr ), _O_BINARY );
427431#endif
428432 } else if (isoption (& text , 0 , "tab" , is_short )) {
@@ -480,6 +484,20 @@ int main(int argc, char* argv[]) {
480484 program_arguments = jv_object_set (program_arguments , jv_string (argv [i + 1 ]), v );
481485 }
482486 i += 2 ; // skip the next two arguments
487+ } else if (isoption (& text , 'o' , "output-file" , is_short )) {
488+ const char * which = "output-file" ;
489+ if (i >= argc - 1 ) {
490+ fprintf (stderr , "jq: --%s takes one parameter (e.g. --%s filename)\n" , which , which );
491+ die ();
492+ }
493+
494+ ofile = fopen (argv [i + 1 ], "w" );
495+ if (!ofile ) {
496+ fprintf (stderr , "jq: unable to open output-file." );
497+ die ();
498+ }
499+
500+ i += 1 ; // skip the next argument
483501 } else if ((raw = isoption (& text , 0 , "rawfile" , is_short )) ||
484502 isoption (& text , 0 , "slurpfile" , is_short )) {
485503 const char * which = raw ? "rawfile" : "slurpfile" ;
@@ -696,8 +714,8 @@ int main(int argc, char* argv[]) {
696714 ret = JQ_ERROR_SYSTEM ;
697715
698716out :
699- badwrite = ferror (stdout );
700- if (fclose (stdout )!= 0 || badwrite ) {
717+ badwrite = ferror (ofile );
718+ if (fclose (ofile )!= 0 || badwrite ) {
701719 fprintf (stderr ,"jq: error: writing output failed: %s\n" , strerror (errno ));
702720 ret = JQ_ERROR_SYSTEM ;
703721 }
0 commit comments