diff --git a/c/mapping/mapper_filter.c b/c/mapping/mapper_filter.c index 08ffeafa7..b42d62e41 100644 --- a/c/mapping/mapper_filter.c +++ b/c/mapping/mapper_filter.c @@ -8,11 +8,12 @@ typedef struct _mapper_filter_state_t { lrec_evaluator_t* pevaluator; + int do_exclude; } mapper_filter_state_t; static sllv_t* mapper_filter_process(lrec_t* pinrec, context_t* pctx, void* pvstate); static void mapper_filter_free(void* pvstate); -static mapper_t* mapper_filter_alloc(mlr_dsl_ast_node_t* past); +static mapper_t* mapper_filter_alloc(mlr_dsl_ast_node_t* past, int do_exclude); static void mapper_filter_usage(FILE* o, char* argv0, char* verb); static mapper_t* mapper_filter_parse_cli(int* pargi, int argc, char** argv); @@ -25,8 +26,9 @@ mapper_setup_t mapper_filter_setup = { // ---------------------------------------------------------------- static void mapper_filter_usage(FILE* o, char* argv0, char* verb) { - fprintf(o, "Usage: %s %s [-v] {expression}\n", argv0, verb); + fprintf(o, "Usage: %s %s [-v] [-x] {expression}\n", argv0, verb); fprintf(o, "Prints records for which {expression} evaluates to true.\n"); + fprintf(o, "With -x, prints records for which {expression} evaluates to false.\n"); fprintf(o, "With -v, first prints the AST (abstract syntax tree) for the expression, which\n"); fprintf(o, "gives full transparency on the precedence and associativity rules of Miller's.\n"); fprintf(o, "grammar. Please use a dollar sign for field names and double-quotes for string\n"); @@ -47,9 +49,11 @@ static mapper_t* mapper_filter_parse_cli(int* pargi, int argc, char** argv) { char* verb = argv[(*pargi)++]; char* mlr_dsl_expression = NULL; int print_asts = FALSE; + int do_exclude = FALSE; ap_state_t* pstate = ap_alloc(); ap_define_true_flag(pstate, "-v", &print_asts); + ap_define_true_flag(pstate, "-x", &do_exclude); if (!ap_parse(pstate, verb, pargi, argc, argv)) { mapper_filter_usage(stderr, argv[0], verb); @@ -74,14 +78,15 @@ static mapper_t* mapper_filter_parse_cli(int* pargi, int argc, char** argv) { mlr_dsl_ast_node_print(past->proot); } - return mapper_filter_alloc(past->proot); + return mapper_filter_alloc(past->proot, do_exclude); } // ---------------------------------------------------------------- -static mapper_t* mapper_filter_alloc(mlr_dsl_ast_node_t* past) { +static mapper_t* mapper_filter_alloc(mlr_dsl_ast_node_t* past, int do_exclude) { mapper_filter_state_t* pstate = mlr_malloc_or_die(sizeof(mapper_filter_state_t)); pstate->pevaluator = lrec_evaluator_alloc_from_ast(past); + pstate->do_exclude = do_exclude; mapper_t* pmapper = mlr_malloc_or_die(sizeof(mapper_t)); @@ -109,7 +114,7 @@ static sllv_t* mapper_filter_process(lrec_t* pinrec, context_t* pctx, void* pvst return NULL; } else { mt_get_boolean_strict(&val); - if (val.u.boolv) { + if (val.u.boolv ^ pstate->do_exclude) { return sllv_single(pinrec); } else { lrec_free(pinrec); diff --git a/c/reg_test/expected/out b/c/reg_test/expected/out index 573608710..f7ceff81f 100644 --- a/c/reg_test/expected/out +++ b/c/reg_test/expected/out @@ -3544,6 +3544,30 @@ a=wye,b=pan,i=5,x=0.5732889198020006,y=0.8636244699032729 a=zee,b=pan,i=6,x=0.5271261600918548,y=0.49322128674835697 a=eks,b=zee,i=7,x=0.6117840605678454,y=0.1878849191181694 +mlr filter -x $x>.3 ./reg_test/input/abixy +a=wye,b=wye,i=3,x=0.20460330576630303,y=0.33831852551664776 +a=hat,b=wye,i=9,x=0.03144187646093577,y=0.7495507603507059 + +mlr filter -x $x>0.3 ./reg_test/input/abixy +a=wye,b=wye,i=3,x=0.20460330576630303,y=0.33831852551664776 +a=hat,b=wye,i=9,x=0.03144187646093577,y=0.7495507603507059 + +mlr filter -x $x>0.3 && $y>0.3 ./reg_test/input/abixy +a=wye,b=wye,i=3,x=0.20460330576630303,y=0.33831852551664776 +a=eks,b=wye,i=4,x=0.38139939387114097,y=0.13418874328430463 +a=eks,b=zee,i=7,x=0.6117840605678454,y=0.1878849191181694 +a=hat,b=wye,i=9,x=0.03144187646093577,y=0.7495507603507059 + +mlr filter -x $x>0.3 || $y>0.3 ./reg_test/input/abixy + +mlr filter -x NR>=4 && NR <= 7 ./reg_test/input/abixy +a=pan,b=pan,i=1,x=0.3467901443380824,y=0.7268028627434533 +a=eks,b=pan,i=2,x=0.7586799647899636,y=0.5221511083334797 +a=wye,b=wye,i=3,x=0.20460330576630303,y=0.33831852551664776 +a=zee,b=wye,i=8,x=0.5985540091064224,y=0.976181385699006 +a=hat,b=wye,i=9,x=0.03144187646093577,y=0.7495507603507059 +a=pan,b=wye,i=10,x=0.5026260055412137,y=0.9526183602969864 + mlr filter $nosuchfield>.3 ./reg_test/input/abixy mlr put $x2 = $x**2 ./reg_test/input/abixy diff --git a/c/reg_test/run b/c/reg_test/run index be1640d2d..f22436ab7 100755 --- a/c/reg_test/run +++ b/c/reg_test/run @@ -280,7 +280,12 @@ run_mlr filter '$x>0.3' $indir/abixy run_mlr filter '$x>0.3 && $y>0.3' $indir/abixy run_mlr filter '$x>0.3 || $y>0.3' $indir/abixy run_mlr filter 'NR>=4 && NR <= 7' $indir/abixy -# xxx more ... + +run_mlr filter -x '$x>.3' $indir/abixy +run_mlr filter -x '$x>0.3' $indir/abixy +run_mlr filter -x '$x>0.3 && $y>0.3' $indir/abixy +run_mlr filter -x '$x>0.3 || $y>0.3' $indir/abixy +run_mlr filter -x 'NR>=4 && NR <= 7' $indir/abixy run_mlr filter '$nosuchfield>.3' $indir/abixy