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