mlrrc iterate

This commit is contained in:
John Kerl 2020-08-19 08:27:16 -04:00
parent 435c9d4bb1
commit 99db69dfca
3 changed files with 103 additions and 85 deletions

View file

@ -113,10 +113,12 @@ static int mapper_lookup_table_length = sizeof(mapper_lookup_table) / sizeof(map
// ----------------------------------------------------------------
static void cli_load_mlrrc_or_die(cli_opts_t* popts);
static int cli_try_load_mlrrc(cli_opts_t* popts, char* path);
static int handle_mlrrc_line_1(cli_opts_t* popts, char* line, char* path, int lineno);
static int handle_mlrrc_line_2(cli_opts_t* popts, char* line, char* path, int lineno);
static int handle_mlrrc_line_3(cli_opts_t* popts, char* line, char* path, int lineno);
static int handle_mlrrc_line_4(cli_opts_t* popts, char** argv, int argc, char* path, int lineno);
static int handle_mlrrc_line_1(cli_opts_t* popts, char* line);
static int handle_mlrrc_line_2(cli_opts_t* popts, char* line);
static int handle_mlrrc_line_3(cli_opts_t* popts, char* line);
static int handle_mlrrc_line_4(cli_opts_t* popts, char** argv, int argc);
static int cli_handle_misc_options(char** argv, int argc, int *pargi, cli_opts_t* popts);
static lhmss_t* get_desc_to_chars_map();
static lhmsll_t* get_default_repeat_ifses();
@ -178,10 +180,6 @@ cli_opts_t* parse_command_line(int argc, char** argv, sllv_t** ppmapper_list) {
cli_load_mlrrc_or_die(popts);
}
int no_input = FALSE;
int have_rand_seed = FALSE;
unsigned rand_seed = 0;
for (; argi < argc; /* variable increment: 1 or 2 depending on flag */) {
if (argv[argi][0] != '-') {
@ -194,60 +192,10 @@ cli_opts_t* parse_command_line(int argc, char** argv, sllv_t** ppmapper_list) {
// handled
} else if (cli_handle_reader_writer_options(argv, argc, &argi, &popts->reader_opts, &popts->writer_opts)) {
// handled
} else if (streq(argv[argi], "-I")) {
popts->do_in_place = TRUE;
argi += 1;
} else if (streq(argv[argi], "-n")) {
no_input = TRUE;
argi += 1;
} else if (streq(argv[argi], "--from")) {
check_arg_count(argv, argi, argc, 2);
slls_append(popts->filenames, argv[argi+1], NO_FREE);
argi += 2;
} else if (streq(argv[argi], "--ofmt")) {
check_arg_count(argv, argi, argc, 2);
popts->ofmt = argv[argi+1];
argi += 2;
} else if (streq(argv[argi], "--nr-progress-mod")) {
check_arg_count(argv, argi, argc, 2);
if (sscanf(argv[argi+1], "%lld", &popts->nr_progress_mod) != 1) {
fprintf(stderr,
"%s: --nr-progress-mod argument must be a positive integer; got \"%s\".\n",
MLR_GLOBALS.bargv0, argv[argi+1]);
main_usage_short(stderr, MLR_GLOBALS.bargv0);
exit(1);
}
if (popts->nr_progress_mod <= 0) {
fprintf(stderr,
"%s: --nr-progress-mod argument must be a positive integer; got \"%s\".\n",
MLR_GLOBALS.bargv0, argv[argi+1]);
main_usage_short(stderr, MLR_GLOBALS.bargv0);
exit(1);
}
argi += 2;
} else if (streq(argv[argi], "--seed")) {
check_arg_count(argv, argi, argc, 2);
if (sscanf(argv[argi+1], "0x%x", &rand_seed) == 1) {
have_rand_seed = TRUE;
} else if (sscanf(argv[argi+1], "%u", &rand_seed) == 1) {
have_rand_seed = TRUE;
} else {
fprintf(stderr,
"%s: --seed argument must be a decimal or hexadecimal integer; got \"%s\".\n",
MLR_GLOBALS.bargv0, argv[argi+1]);
main_usage_short(stderr, MLR_GLOBALS.bargv0);
exit(1);
}
argi += 2;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
} else if (cli_handle_misc_options(argv, argc, &argi, popts)) {
// handled
} else {
// unhandled
usage_unrecognized_verb(MLR_GLOBALS.bargv0, argv[argi]);
}
}
@ -292,13 +240,13 @@ cli_opts_t* parse_command_line(int argc, char** argv, sllv_t** ppmapper_list) {
popts->original_argv = argv;
popts->non_in_place_argv = copy_argv(argv);
popts->argc = argc;
*ppmapper_list = cli_parse_mappers(popts->non_in_place_argv, &argi, argc, popts, &no_input);
*ppmapper_list = cli_parse_mappers(popts->non_in_place_argv, &argi, argc, popts);
for ( ; argi < argc; argi++) {
slls_append(popts->filenames, argv[argi], NO_FREE);
}
if (no_input) {
if (popts->no_input) {
slls_free(popts->filenames);
popts->filenames = NULL;
}
@ -308,8 +256,8 @@ cli_opts_t* parse_command_line(int argc, char** argv, sllv_t** ppmapper_list) {
exit(1);
}
if (have_rand_seed) {
mtrand_init(rand_seed);
if (popts->have_rand_seed) {
mtrand_init(popts->rand_seed);
} else {
mtrand_init_default();
}
@ -320,7 +268,7 @@ cli_opts_t* parse_command_line(int argc, char** argv, sllv_t** ppmapper_list) {
// ----------------------------------------------------------------
// Returns a list of mappers, from the starting point in argv given by *pargi. Bumps *pargi to
// point to remaining post-mapper-setup args, i.e. filenames.
sllv_t* cli_parse_mappers(char** argv, int* pargi, int argc, cli_opts_t* popts, int* pno_input) {
sllv_t* cli_parse_mappers(char** argv, int* pargi, int argc, cli_opts_t* popts) {
sllv_t* pmapper_list = sllv_alloc();
int argi = *pargi;
@ -372,7 +320,7 @@ sllv_t* cli_parse_mappers(char** argv, int* pargi, int argc, cli_opts_t* popts,
if (pmapper_setup->ignores_input && pmapper_list->length == 0) {
// e.g. then-chain starts with seqgen
*pno_input = TRUE;
popts->no_input = TRUE;
}
sllv_append(pmapper_list, pmapper);
@ -1112,6 +1060,10 @@ void cli_opts_init(cli_opts_t* popts) {
popts->nr_progress_mod = 0LL;
popts->do_in_place = FALSE;
popts->no_input = FALSE;
popts->have_rand_seed = FALSE;
popts->rand_seed = 0;
}
// ----------------------------------------------------------------
@ -1154,7 +1106,7 @@ static int cli_try_load_mlrrc(cli_opts_t* popts, char* path) {
while ((rc = getline(&line, &linecap, fp)) != -1) {
lineno++;
char* line_to_destroy = strdup(line);
if (!handle_mlrrc_line_1(popts, line_to_destroy, path, lineno)) {
if (!handle_mlrrc_line_1(popts, line_to_destroy)) {
fprintf(stderr, "Parse error at file \"%s\" line %d: %s\n",
path, lineno, line);
exit(1);
@ -1171,7 +1123,7 @@ static int cli_try_load_mlrrc(cli_opts_t* popts, char* path) {
}
// Chomps trailing CR, LF, or CR/LF; comment-strips; left-right trims.
static int handle_mlrrc_line_1(cli_opts_t* popts, char* line, char* path, int lineno) {
static int handle_mlrrc_line_1(cli_opts_t* popts, char* line) {
// chomp
size_t len = strlen(line);
if (len >= 2 && line[len-2] == '\r' && line[len-1] == '\n') {
@ -1202,12 +1154,12 @@ static int handle_mlrrc_line_1(cli_opts_t* popts, char* line, char* path, int li
if (end < start) { // line was whitespace-only
return TRUE;
} else {
return handle_mlrrc_line_2(popts, start, path, lineno);
return handle_mlrrc_line_2(popts, start);
}
}
// Prepends initial "--" if it's not already there
static int handle_mlrrc_line_2(cli_opts_t* popts, char* line, char* path, int lineno) {
static int handle_mlrrc_line_2(cli_opts_t* popts, char* line) {
size_t len = strlen(line);
char* dashed_line = NULL;
@ -1217,14 +1169,14 @@ static int handle_mlrrc_line_2(cli_opts_t* popts, char* line, char* path, int li
dashed_line = strdup(line);
}
int rc = handle_mlrrc_line_3(popts, dashed_line, path, lineno);
int rc = handle_mlrrc_line_3(popts, dashed_line);
free(dashed_line);
return rc;
}
// Splits line into argv array
static int handle_mlrrc_line_3(cli_opts_t* popts, char* line, char* path, int lineno) {
static int handle_mlrrc_line_3(cli_opts_t* popts, char* line) {
char* argv[3];
int argc = 0;
char* split = strpbrk(line, " \t");
@ -1243,11 +1195,10 @@ static int handle_mlrrc_line_3(cli_opts_t* popts, char* line, char* path, int li
argv[2] = NULL;
argc = 2;
}
return handle_mlrrc_line_4(popts, argv, argc, path, lineno);
return handle_mlrrc_line_4(popts, argv, argc);
}
// xxx rm pass-thru of path & lineno
static int handle_mlrrc_line_4(cli_opts_t* popts, char** argv, int argc, char* path, int lineno) {
static int handle_mlrrc_line_4(cli_opts_t* popts, char** argv, int argc) {
int argi = 0;
if (cli_handle_reader_options(argv, argc, &argi, &popts->reader_opts)) {
// handled
@ -1255,7 +1206,10 @@ static int handle_mlrrc_line_4(cli_opts_t* popts, char** argv, int argc, char* p
// handled
} else if (cli_handle_reader_writer_options(argv, argc, &argi, &popts->reader_opts, &popts->writer_opts)) {
// handled
} else if (cli_handle_misc_options(argv, argc, &argi, popts)) {
// handled
} else {
// unhandled
return FALSE;
}
@ -1280,7 +1234,6 @@ void cli_reader_opts_init(cli_reader_opts_t* preader_opts) {
preader_opts->comment_handling = COMMENTS_ARE_DATA;
preader_opts->comment_string = NULL;
// xxx temp
preader_opts->generator_opts.field_name = "i";
preader_opts->generator_opts.start = 0LL;
preader_opts->generator_opts.stop = 100LL;
@ -1672,10 +1625,10 @@ int cli_handle_reader_options(char** argv, int argc, int *pargi, cli_reader_opts
preader_opts->ifile_fmt = argv[argi+1];
argi += 2;
} else if (streq(argv[argi], "--igen")) { // xxx temp
} else if (streq(argv[argi], "--igen")) {
preader_opts->ifile_fmt = "gen";
argi += 1;
} else if (streq(argv[argi], "--gen-start")) { // xxx temp
} else if (streq(argv[argi], "--gen-start")) {
preader_opts->ifile_fmt = "gen";
check_arg_count(argv, argi, argc, 2);
if (sscanf(argv[argi+1], "%lld", &preader_opts->generator_opts.start) != 1) {
@ -1683,7 +1636,7 @@ int cli_handle_reader_options(char** argv, int argc, int *pargi, cli_reader_opts
MLR_GLOBALS.bargv0, argv[argi+1]);
}
argi += 2;
} else if (streq(argv[argi], "--gen-stop")) { // xxx temp
} else if (streq(argv[argi], "--gen-stop")) {
preader_opts->ifile_fmt = "gen";
check_arg_count(argv, argi, argc, 2);
if (sscanf(argv[argi+1], "%lld", &preader_opts->generator_opts.stop) != 1) {
@ -1691,7 +1644,7 @@ int cli_handle_reader_options(char** argv, int argc, int *pargi, cli_reader_opts
MLR_GLOBALS.bargv0, argv[argi+1]);
}
argi += 2;
} else if (streq(argv[argi], "--gen-step")) { // xxx temp
} else if (streq(argv[argi], "--gen-step")) {
preader_opts->ifile_fmt = "gen";
check_arg_count(argv, argi, argc, 2);
if (sscanf(argv[argi+1], "%lld", &preader_opts->generator_opts.step) != 1) {
@ -2378,6 +2331,67 @@ int cli_handle_reader_writer_options(char** argv, int argc, int *pargi,
return argi != oargi;
}
// Returns TRUE if the current flag was handled.
static int cli_handle_misc_options(char** argv, int argc, int *pargi, cli_opts_t* popts) {
int argi = *pargi;
int oargi = argi;
if (streq(argv[argi], "-I")) {
popts->do_in_place = TRUE;
argi += 1;
} else if (streq(argv[argi], "-n")) {
popts->no_input = TRUE;
argi += 1;
} else if (streq(argv[argi], "--from")) {
check_arg_count(argv, argi, argc, 2);
slls_append(popts->filenames, argv[argi+1], NO_FREE);
argi += 2;
} else if (streq(argv[argi], "--ofmt")) {
check_arg_count(argv, argi, argc, 2);
popts->ofmt = argv[argi+1];
argi += 2;
} else if (streq(argv[argi], "--nr-progress-mod")) {
check_arg_count(argv, argi, argc, 2);
if (sscanf(argv[argi+1], "%lld", &popts->nr_progress_mod) != 1) {
fprintf(stderr,
"%s: --nr-progress-mod argument must be a positive integer; got \"%s\".\n",
MLR_GLOBALS.bargv0, argv[argi+1]);
main_usage_short(stderr, MLR_GLOBALS.bargv0);
exit(1);
}
if (popts->nr_progress_mod <= 0) {
fprintf(stderr,
"%s: --nr-progress-mod argument must be a positive integer; got \"%s\".\n",
MLR_GLOBALS.bargv0, argv[argi+1]);
main_usage_short(stderr, MLR_GLOBALS.bargv0);
exit(1);
}
argi += 2;
} else if (streq(argv[argi], "--seed")) {
check_arg_count(argv, argi, argc, 2);
if (sscanf(argv[argi+1], "0x%x", &popts->rand_seed) == 1) {
popts->have_rand_seed = TRUE;
} else if (sscanf(argv[argi+1], "%u", &popts->rand_seed) == 1) {
popts->have_rand_seed = TRUE;
} else {
fprintf(stderr,
"%s: --seed argument must be a decimal or hexadecimal integer; got \"%s\".\n",
MLR_GLOBALS.bargv0, argv[argi+1]);
main_usage_short(stderr, MLR_GLOBALS.bargv0);
exit(1);
}
argi += 2;
}
*pargi = argi;
return argi != oargi;
}
// ----------------------------------------------------------------
static char* lhmss_get_or_die(lhmss_t* pmap, char* key) {
char* value = lhmss_get(pmap, key);

View file

@ -95,6 +95,10 @@ typedef struct _cli_opts_t {
int do_in_place;
int no_input;
int have_rand_seed;
unsigned rand_seed;
} cli_opts_t;
// ----------------------------------------------------------------
@ -102,7 +106,7 @@ cli_opts_t* parse_command_line(int argc, char** argv, sllv_t** ppmapper_list);
// See stream.c. The idea is that the mapper-chain is constructed once for normal stream-over-all-files
// mode, but per-file for in-place mode.
sllv_t* cli_parse_mappers(char** argv, int* pargi, int argc, cli_opts_t* popts, int* pno_input);
sllv_t* cli_parse_mappers(char** argv, int* pargi, int argc, cli_opts_t* popts);
int cli_handle_reader_options(char** argv, int argc, int *pargi, cli_reader_opts_t* preader_opts);
int cli_handle_writer_options(char** argv, int argc, int *pargi, cli_writer_opts_t* pwriter_opts);

View file

@ -68,10 +68,10 @@ static int do_stream_chained_in_place(context_t* pctx, cli_opts_t* popts) {
// after processing in case mappers have retained pointers into argv.
int argi = popts->mapper_argb;
int unused;
char** argv_copy = copy_argv(popts->original_argv);
sllv_t* pmapper_list = cli_parse_mappers(argv_copy, &argi, popts->argc, popts, &unused);
MLR_INTERNAL_CODING_ERROR_IF(pmapper_list->length < 1); // Should not have been allowed by the CLI parser.
sllv_t* pmapper_list = cli_parse_mappers(argv_copy, &argi, popts->argc, popts);
// Should not have been allowed by the CLI parser:
MLR_INTERNAL_CODING_ERROR_IF(pmapper_list->length < 1);
char* filename = pe->value;
char* tempname = alloc_suffixed_temp_file_name(filename);