multiple -f for filter/put

This commit is contained in:
John Kerl 2016-09-10 18:10:58 -04:00
parent 3aa550d1e8
commit 5200ce7b6e
6 changed files with 57 additions and 18 deletions

View file

@ -9,6 +9,7 @@ typedef enum _ap_flag_t {
AP_LONG_LONG_FLAG,
AP_DOUBLE_FLAG,
AP_STRING_FLAG,
AP_STRING_BUILD_LIST_FLAG,
AP_STRING_LIST_FLAG,
AP_STRING_ARRAY_FLAG
} ap_flag_t;
@ -99,6 +100,10 @@ void ap_define_string_flag(ap_state_t* pstate, char* flag_name, char** pstring)
sllv_append(pstate->pflag_defs, ap_flag_def_alloc(flag_name, AP_STRING_FLAG, 0, pstring, 2));
}
void ap_define_string_build_list_flag(ap_state_t* pstate, char* flag_name, slls_t** pplist) {
sllv_append(pstate->pflag_defs, ap_flag_def_alloc(flag_name, AP_STRING_BUILD_LIST_FLAG, 0, pplist, 2));
}
void ap_define_string_list_flag(ap_state_t* pstate, char* flag_name, slls_t** pplist) {
sllv_append(pstate->pflag_defs, ap_flag_def_alloc(flag_name, AP_STRING_LIST_FLAG, 0, pplist, 2));
}
@ -165,22 +170,34 @@ int ap_parse_aux(ap_state_t* pstate, char* verb, int* pargi, int argc, char** ar
argv[0], verb, argv[argi+1], argv[argi]);
fprintf(stderr, "\n");
}
} else if (pdef->type == AP_STRING_FLAG) {
char** pstring = pdef->pval;
*pstring = argv[argi+1];
pdef->pval = pstring;
} else if (pdef->type == AP_STRING_BUILD_LIST_FLAG) {
slls_t** pplist = pdef->pval;
if (*pplist == NULL) {
*pplist = slls_alloc();
}
slls_append_no_free(*pplist, argv[argi+1]);
pdef->pval = pplist;
} else if (pdef->type == AP_STRING_LIST_FLAG) {
slls_t** pplist = pdef->pval;
if (*pplist != NULL)
slls_free(*pplist);
*pplist = slls_from_line(argv[argi+1], ',', FALSE);
pdef->pval = pplist;
} else if (pdef->type == AP_STRING_ARRAY_FLAG) {
string_array_t** pparray = pdef->pval;
if (*pparray != NULL)
string_array_free(*pparray);
*pparray = string_array_from_line(argv[argi+1], ',');
pdef->pval = pparray;
} else {
ok = FALSE;
fprintf(stderr, "argparse.c: internal coding error: flag-def type %x not recognized.\n", pdef->type);

View file

@ -20,8 +20,9 @@ void ap_define_false_flag(ap_state_t* pstate, char* flag_name, int* pintv
void ap_define_int_value_flag(ap_state_t* pstate, char* flag_name, int value, int* pintval);
void ap_define_int_flag(ap_state_t* pstate, char* flag_name, int* pintval);
void ap_define_long_long_flag(ap_state_t* pstate, char* flag_name, long long* pintval);
void ap_define_float_flag(ap_state_t* pstate, char* flag_name, double* pdoubleval);
void ap_define_float_flag(ap_state_t* pstate, char* flag_name, double* pdoubleval);
void ap_define_string_flag(ap_state_t* pstate, char* flag_name, char** pstring);
void ap_define_string_build_list_flag(ap_state_t* pstate, char* flag_name, slls_t** pplist);
void ap_define_string_list_flag(ap_state_t* pstate, char* flag_name, slls_t** pplist);
void ap_define_string_array_flag(ap_state_t* pstate, char* flag_name, string_array_t** pparray);

View file

@ -17,7 +17,7 @@ string_builder_t* sb_alloc(int alloc_length) {
}
// ----------------------------------------------------------------
void sb_free(string_builder_t* psb) {
void sb_free(string_builder_t* psb) {
if (psb == NULL)
return;
free(psb->buffer);

View file

@ -1,5 +1,6 @@
#include "lib/mlr_globals.h"
#include "lib/mlrutil.h"
#include "lib/string_builder.h"
#include "containers/lrec.h"
#include "containers/sllv.h"
#include "mapping/context_flags.h"
@ -54,7 +55,8 @@ static void mapper_filter_usage(FILE* o, char* argv0, char* verb) {
fprintf(o, "-x: Prints records for which {expression} evaluates to false.\n");
fprintf(o, "-f {filename}: the DSL expression is taken from the specified file rather\n");
fprintf(o, " than from the command line. Outer single quotes wrapping the expression\n");
fprintf(o, " should not be placed in the file.\n");
fprintf(o, " should not be placed in the file. If -f is specified more than once,\n");
fprintf(o, " all input files specified using -f are concatenated to produce the expression.\n");
fprintf(o, "\n");
fprintf(o, "Please use a dollar sign for field names and double-quotes for string\n");
fprintf(o, "literals. If field names have special characters such as \".\" then you might\n");
@ -89,19 +91,19 @@ static mapper_t* mapper_filter_parse_cli(int* pargi, int argc, char** argv,
char* verb = argv[(*pargi)++];
char* mlr_dsl_expression = NULL;
char* comment_stripped_mlr_dsl_expression = NULL;
char* expression_filename = NULL;
slls_t* expression_filenames = NULL;
int print_ast = FALSE;
int trace_parse = FALSE;
int type_inferencing = TYPE_INFER_STRING_FLOAT_INT;
int do_exclude = FALSE;
ap_state_t* pstate = ap_alloc();
ap_define_string_flag(pstate, "-f", &expression_filename);
ap_define_true_flag(pstate, "-v", &print_ast);
ap_define_true_flag(pstate, "-t", &trace_parse);
ap_define_int_value_flag(pstate, "-S", TYPE_INFER_STRING_ONLY, &type_inferencing);
ap_define_int_value_flag(pstate, "-F", TYPE_INFER_STRING_FLOAT, &type_inferencing);
ap_define_true_flag(pstate, "-x", &do_exclude);
ap_define_string_build_list_flag(pstate, "-f", &expression_filenames);
ap_define_true_flag(pstate, "-v", &print_ast);
ap_define_true_flag(pstate, "-t", &trace_parse);
ap_define_int_value_flag(pstate, "-S", TYPE_INFER_STRING_ONLY, &type_inferencing);
ap_define_int_value_flag(pstate, "-F", TYPE_INFER_STRING_FLOAT, &type_inferencing);
ap_define_true_flag(pstate, "-x", &do_exclude);
// Pass error_on_unrecognized == FALSE to ap_parse so expressions starting
// with a minus sign aren't treated as errors. Example: "mlr filter '-$x ==
@ -111,14 +113,21 @@ static mapper_t* mapper_filter_parse_cli(int* pargi, int argc, char** argv,
return NULL;
}
if (expression_filename == NULL) {
if (expression_filenames == NULL) {
if ((argc - *pargi) < 1) {
mapper_filter_usage(stderr, argv[0], verb);
return NULL;
}
mlr_dsl_expression = mlr_strdup_or_die(argv[(*pargi)++]);
} else {
mlr_dsl_expression = read_file_into_memory(expression_filename, NULL);
string_builder_t *psb = sb_alloc(1024);
for (sllse_t* pe = expression_filenames->phead; pe != NULL; pe = pe->pnext) {
char* expression_filename = pe->value;
char* mlr_dsl_expression_piece = read_file_into_memory(expression_filename, NULL);
sb_append_string(psb, mlr_dsl_expression_piece);
}
mlr_dsl_expression = sb_finish(psb);
sb_free(psb);
}
comment_stripped_mlr_dsl_expression = alloc_comment_strip(mlr_dsl_expression);

View file

@ -1,5 +1,6 @@
#include "lib/mlr_globals.h"
#include "lib/mlrutil.h"
#include "lib/string_builder.h"
#include "cli/mlrcli.h"
#include "containers/lrec.h"
#include "containers/sllv.h"
@ -73,7 +74,10 @@ static void mapper_put_usage(FILE* o, char* argv0, char* verb) {
fprintf(o, " to output records for emit. Default \"%s\".\n", DEFAULT_OOSVAR_FLATTEN_SEPARATOR);
fprintf(o, "-f {filename}: the DSL expression is taken from the specified file rather\n");
fprintf(o, " than from the command line. Outer single quotes wrapping the expression\n");
fprintf(o, " should not be placed in the file.\n");
fprintf(o, " should not be placed in the file. If -f is specified more than once,\n");
fprintf(o, " all input files specified using -f are concatenated to produce the expression.\n");
fprintf(o, " (For example, you can define functions in one file and call them from another.)\n");
fprintf(o, "\n");
fprintf(o, "--no-fflush: for emit, tee, print, and dump, don't call fflush() after every\n");
fprintf(o, " record.\n");
fprintf(o, "Any of the output-format command-line flags (see %s -h). Example: using\n",
@ -126,7 +130,7 @@ static mapper_t* mapper_put_parse_cli(int* pargi, int argc, char** argv,
{
char* mlr_dsl_expression = NULL;
char* comment_stripped_mlr_dsl_expression = NULL;
char* expression_filename = NULL;
slls_t* expression_filenames = slls_alloc();
int outer_filter = TRUE;
int type_inferencing = TYPE_INFER_STRING_FLOAT_INT;
int print_ast = FALSE;
@ -158,7 +162,7 @@ static mapper_t* mapper_put_parse_cli(int* pargi, int argc, char** argv,
mapper_put_usage(stderr, argv[0], verb);
return NULL;
}
expression_filename = argv[argi+1];
slls_append_no_free(expression_filenames, argv[argi+1]);
argi += 2;
} else if (streq(argv[argi], "-v")) {
print_ast = TRUE;
@ -192,14 +196,21 @@ static mapper_t* mapper_put_parse_cli(int* pargi, int argc, char** argv,
}
}
if (expression_filename == NULL) {
if (expression_filenames->length == 0) {
if ((argc - argi) < 1) {
mapper_put_usage(stderr, argv[0], verb);
return NULL;
}
mlr_dsl_expression = mlr_strdup_or_die(argv[argi++]);
} else {
mlr_dsl_expression = read_file_into_memory(expression_filename, NULL);
string_builder_t *psb = sb_alloc(1024);
for (sllse_t* pe = expression_filenames->phead; pe != NULL; pe = pe->pnext) {
char* expression_filename = pe->value;
char* mlr_dsl_expression_piece = read_file_into_memory(expression_filename, NULL);
sb_append_string(psb, mlr_dsl_expression_piece);
}
mlr_dsl_expression = sb_finish(psb);
sb_free(psb);
}
comment_stripped_mlr_dsl_expression = alloc_comment_strip(mlr_dsl_expression);

View file

@ -9,7 +9,6 @@ TOP OF LIST:
* 10min vers:
- sql-schema example
- publish
- to 4.n.0 release notes as well
UDFs:
* multiple put -f
@ -22,6 +21,8 @@ UDFs:
! try to get seqgen to force eof sooner. in particular, try to get 'mlr seqgen' w/o -n. if so, fix cookbook etc.
* some help for keyword clashes? e.g. 'func E(x) { ... }' ?
* NR PI E etc. to keyword help ...
* indent by two more for jvstack
? rework comma placement for jvstack?
* --c2p, --c2j etc ...