1 // ================================================================
2 // Miller command-line parsing
3 // ================================================================
4 
5 #ifndef MLRCLI_H
6 #define MLRCLI_H
7 
8 #include "lib/context.h"
9 #include "containers/slls.h"
10 #include "containers/sllv.h"
11 #include "cli/quoting.h"
12 #include "cli/comment_handling.h"
13 #include "cli/json_array_ingest.h"
14 #include "containers/lhmsll.h"
15 #include "containers/lhmss.h"
16 #include <unistd.h>
17 
18 // ----------------------------------------------------------------
19 typedef struct _generator_opts_t {
20 	char* field_name;
21 	// xxx to do: convert to mv_t
22 	long long start;
23 	long long stop;
24 	long long step;
25 } generator_opts_t;
26 
27 typedef struct _cli_reader_opts_t {
28 
29 	char* ifile_fmt;
30 	char* irs;
31 	char* ifs;
32 	char* ips;
33 	char* input_json_flatten_separator;
34 	json_array_ingest_t  json_array_ingest;
35 
36 	int   allow_repeat_ifs;
37 	int   allow_repeat_ips;
38 	int   use_implicit_csv_header;
39 	int   allow_ragged_csv_input;
40 
41 	// Command for popen on input, e.g. "zcat -cf <". Can be null in which case
42 	// files are read directly rather than through a pipe.
43 	char* prepipe;
44 
45 	comment_handling_t comment_handling;
46 	char* comment_string;
47 
48 	// Fake internal-data-generator 'reader'
49 	generator_opts_t generator_opts;
50 
51 } cli_reader_opts_t;
52 
53 // ----------------------------------------------------------------
54 typedef struct _cli_writer_opts_t {
55 
56 	char* ofile_fmt;
57 	char* ors;
58 	char* ofs;
59 	char* ops;
60 
61 	int   headerless_csv_output;
62 	int   right_justify_xtab_value;
63 	int   right_align_pprint;
64 	int   pprint_barred;
65 	int   stack_json_output_vertically;
66 	int   wrap_json_output_in_outer_list;
67 	int   json_quote_int_keys;
68 	int   json_quote_non_string_values;
69 	char* output_json_flatten_separator;
70 	char* oosvar_flatten_separator;
71 
72 	quoting_t oquoting;
73 
74 } cli_writer_opts_t;
75 
76 // ----------------------------------------------------------------
77 typedef struct _cli_opts_t {
78 	cli_reader_opts_t reader_opts;
79 	cli_writer_opts_t writer_opts;
80 
81 	// These are used to construct the mapper list. In particular, for in-place mode
82 	// they're reconstructed for each file.  We make copies since each pass through a
83 	// CLI-parser operates destructively, principally by running strtok over
84 	// comma-delimited field-name lists.
85 
86 	char**  original_argv;
87 	char**  non_in_place_argv;
88 	int     argc;
89 	int     mapper_argb;
90 
91 	slls_t* filenames;
92 
93 	char* ofmt;
94 	long long nr_progress_mod;
95 
96 	int do_in_place;
97 
98 	int no_input;
99 	int have_rand_seed;
100 	unsigned rand_seed;
101 
102 } cli_opts_t;
103 
104 // ----------------------------------------------------------------
105 cli_opts_t* parse_command_line(int argc, char** argv, sllv_t** ppmapper_list);
106 
107 // See stream.c. The idea is that the mapper-chain is constructed once for normal stream-over-all-files
108 // mode, but per-file for in-place mode.
109 sllv_t* cli_parse_mappers(char** argv, int* pargi, int argc, cli_opts_t* popts);
110 
111 int cli_handle_reader_options(char** argv, int argc, int *pargi, cli_reader_opts_t* preader_opts);
112 int cli_handle_writer_options(char** argv, int argc, int *pargi, cli_writer_opts_t* pwriter_opts);
113 int cli_handle_reader_writer_options(char** argv, int argc, int *pargi,
114 	cli_reader_opts_t* preader_opts, cli_writer_opts_t* pwriter_opts);
115 
116 void cli_opts_init(cli_opts_t* popts);
117 void cli_reader_opts_init(cli_reader_opts_t* preader_opts);
118 void cli_writer_opts_init(cli_writer_opts_t* pwriter_opts);
119 
120 void cli_apply_defaults(cli_opts_t* popts);
121 void cli_apply_reader_defaults(cli_reader_opts_t* preader_opts);
122 void cli_apply_writer_defaults(cli_writer_opts_t* pwriter_opts);
123 
124 // For mapper join which has its separate input-format overrides:
125 void cli_merge_reader_opts(cli_reader_opts_t* pfunc_opts, cli_reader_opts_t* pmain_opts);
126 
127 // For mapper tee & mapper put which have their separate output-format overrides:
128 void cli_merge_writer_opts(cli_writer_opts_t* pfunc_opts, cli_writer_opts_t* pmain_opts);
129 
130 // Stream context is for lrec-writer drain on tee et al. when using aggregated
131 // output.  E.g. pretty-print output has column widths which are only computable
132 // after all output records have been retained. The free methods are used as
133 // drain triggers.
134 void cli_opts_free(cli_opts_t* popts);
135 
136 // The caller can unconditionally free the return value
137 char* cli_sep_from_arg(char* arg);
138 
139 #endif // MLRCLI_H
140