1 #include "lib/mlrutil.h"
2 #include "lib/mlr_globals.h"
3 #include "multi_out.h"
4
5 // ----------------------------------------------------------------
multi_out_alloc()6 multi_out_t* multi_out_alloc() {
7 multi_out_t* pmo = mlr_malloc_or_die(sizeof(multi_out_t));
8 pmo->pnames_to_fps = lhmsv_alloc();
9 return pmo;
10 }
11
12 // ----------------------------------------------------------------
multi_out_close(multi_out_t * pmo)13 void multi_out_close(multi_out_t* pmo) {
14 for (lhmsve_t* pe = pmo->pnames_to_fps->phead; pe != NULL; pe = pe->pnext) {
15 fp_and_flag_t* pstate = pe->pvvalue;
16 if (pstate->is_popen) {
17 pclose(pstate->output_stream);
18 } else {
19 fclose(pstate->output_stream);
20 }
21 }
22 }
23
24 // ----------------------------------------------------------------
multi_out_free(multi_out_t * pmo)25 void multi_out_free(multi_out_t* pmo) {
26 if (pmo == NULL)
27 return;
28 for (lhmsve_t* pe = pmo->pnames_to_fps->phead; pe != NULL; pe = pe->pnext) {
29 fp_and_flag_t* pstate = pe->pvvalue;
30 free(pstate);
31 }
32 lhmsv_free(pmo->pnames_to_fps);
33 free(pmo);
34 }
35
36 // ----------------------------------------------------------------
multi_out_get(multi_out_t * pmo,char * filename_or_command,file_output_mode_t file_output_mode)37 FILE* multi_out_get(multi_out_t* pmo, char* filename_or_command, file_output_mode_t file_output_mode) {
38 fp_and_flag_t* pstate = lhmsv_get(pmo->pnames_to_fps, filename_or_command);
39 if (pstate == NULL) {
40 pstate = mlr_malloc_or_die(sizeof(fp_and_flag_t));
41 char* mode_string = get_mode_string(file_output_mode);
42 char* mode_desc = get_mode_desc(file_output_mode);
43 if (file_output_mode == MODE_PIPE) {
44 pstate->is_popen = TRUE;
45 pstate->output_stream = popen(filename_or_command, mode_string);
46 if (pstate->output_stream == NULL) {
47 perror("popen");
48 fprintf(stderr, "%s: failed popen for %s of \"%s\".\n",
49 MLR_GLOBALS.bargv0, mode_desc, filename_or_command);
50 exit(1);
51 }
52 } else {
53 pstate->is_popen = FALSE;
54 pstate->output_stream = fopen(filename_or_command, mode_string);
55 if (pstate->output_stream == NULL) {
56 perror("fopen");
57 fprintf(stderr, "%s: failed fopen for %s of \"%s\".\n",
58 MLR_GLOBALS.bargv0, mode_desc, filename_or_command);
59 exit(1);
60 }
61 }
62 lhmsv_put(pmo->pnames_to_fps, mlr_strdup_or_die(filename_or_command), pstate, FREE_ENTRY_KEY);
63 }
64 return pstate->output_stream;
65 }
66