diff --git a/c/mapping/mlr_dsl_cst.c b/c/mapping/mlr_dsl_cst.c index 2113ef49f..d479f08a0 100644 --- a/c/mapping/mlr_dsl_cst.c +++ b/c/mapping/mlr_dsl_cst.c @@ -96,6 +96,7 @@ static void handle_emitp_lashed_to_file(mlr_dsl_cst_statement_t* s, static void handle_emit_lashed(mlr_dsl_cst_statement_t* s, variables_t* v, cst_outputs_t* o); static void handle_emit_lashed_to_file(mlr_dsl_cst_statement_t* s, variables_t* v, cst_outputs_t* o); static void handle_emit_all(mlr_dsl_cst_statement_t* s, variables_t* v, cst_outputs_t* o); +static void handle_emit_all_to_stdfp(mlr_dsl_cst_statement_t* s, variables_t* v, cst_outputs_t* o); static void handle_emit_all_to_file(mlr_dsl_cst_statement_t* s, variables_t* v, cst_outputs_t* o); static void handle_dump(mlr_dsl_cst_statement_t* s, variables_t* v, cst_outputs_t* o); static void handle_dump_to_file(mlr_dsl_cst_statement_t* s, variables_t* v, cst_outputs_t* o); @@ -883,7 +884,7 @@ static mlr_dsl_cst_statement_t* alloc_emit(mlr_dsl_ast_node_t* pnode, int type_i if (poutput_node->type == MD_AST_NODE_TYPE_STREAM) { pstatement->pnode_handler = output_all ? handle_emit_all : handle_emit; } else if (pfilename_node->type == MD_AST_NODE_TYPE_STDOUT || pfilename_node->type == MD_AST_NODE_TYPE_STDERR) { - pstatement->pnode_handler = handle_emit_to_stdfp; + pstatement->pnode_handler = output_all ? handle_emit_all_to_stdfp : handle_emit_to_stdfp; pstatement->stdfp = (pfilename_node->type == MD_AST_NODE_TYPE_STDOUT) ? stdout : stderr; } else { pstatement->poutput_filename_evaluator = rval_evaluator_alloc_from_ast(pfilename_node, @@ -1983,6 +1984,20 @@ static void handle_emit_to_stdfp( variables_t* pvars, cst_outputs_t* pcst_outputs) { + // xxx handle better, maybe in a class. the opts aren't complete at alloc time so we need to handle them here. + if (pnode->psingle_lrec_writer == NULL) { + cli_opts_t* popts = MLR_GLOBALS.popts; + pnode->psingle_lrec_writer = lrec_writer_alloc(popts->ofile_fmt, popts->ors, popts->ofs, popts->ops, + popts->headerless_csv_output, popts->oquoting, popts->left_align_pprint, + popts->right_justify_xtab_value, popts->json_flatten_separator, popts->quote_json_values_always, + popts->stack_json_output_vertically, popts->wrap_json_output_in_outer_list); + if (pnode->psingle_lrec_writer == NULL) { + fprintf(stderr, "%s: internal coding error detected in file \"%s\" at line %d.\n", + MLR_GLOBALS.bargv0, __FILE__, __LINE__); + exit(1); + } + } + sllv_t* poutrecs = sllv_alloc(); int keys_all_non_null_or_error = TRUE; sllmv_t* pmvkeys = evaluate_list(pnode->pemit_keylist_evaluators, pvars, &keys_all_non_null_or_error); @@ -2176,6 +2191,44 @@ static void handle_emit_all( sllmv_free(pmvnames); } +static void handle_emit_all_to_stdfp( + mlr_dsl_cst_statement_t* pnode, + variables_t* pvars, + cst_outputs_t* pcst_outputs) +{ + // xxx handle better, maybe in a class. the opts aren't complete at alloc time so we need to handle them here. + if (pnode->psingle_lrec_writer == NULL) { + cli_opts_t* popts = MLR_GLOBALS.popts; + pnode->psingle_lrec_writer = lrec_writer_alloc(popts->ofile_fmt, popts->ors, popts->ofs, popts->ops, + popts->headerless_csv_output, popts->oquoting, popts->left_align_pprint, + popts->right_justify_xtab_value, popts->json_flatten_separator, popts->quote_json_values_always, + popts->stack_json_output_vertically, popts->wrap_json_output_in_outer_list); + if (pnode->psingle_lrec_writer == NULL) { + fprintf(stderr, "%s: internal coding error detected in file \"%s\" at line %d.\n", + MLR_GLOBALS.bargv0, __FILE__, __LINE__); + exit(1); + } + } + + // xxx code-dedupe + sllv_t* poutrecs = sllv_alloc(); + int all_non_null_or_error = TRUE; + sllmv_t* pmvnames = evaluate_list(pnode->pemit_oosvar_namelist_evaluators, pvars, &all_non_null_or_error); + if (all_non_null_or_error) { + mlhmmv_all_to_lrecs(pvars->poosvars, pmvnames, poutrecs, + pnode->do_full_prefixing, pcst_outputs->oosvar_flatten_separator); + } + sllmv_free(pmvnames); + + while (poutrecs->phead != NULL) { + lrec_t* poutrec = sllv_pop(poutrecs); + pnode->psingle_lrec_writer->pprocess_func(pnode->stdfp, poutrec, pnode->psingle_lrec_writer->pvstate); + if (pcst_outputs->flush_every_record) + fflush(pnode->stdfp); + } + sllv_free(poutrecs); +} + static void handle_emit_all_to_file( mlr_dsl_cst_statement_t* pnode, variables_t* pvars,