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