mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-28 10:13:59 +00:00
multiple -f for filter/put
This commit is contained in:
parent
3aa550d1e8
commit
5200ce7b6e
6 changed files with 57 additions and 18 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 ...
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue