From 805ed4aa33bcaa7dcf634075c65795446b89cf16 Mon Sep 17 00:00:00 2001 From: John Kerl Date: Tue, 13 Oct 2015 21:29:28 -0400 Subject: [PATCH] sub/gsub capture-group iterate --- c/Makefile.no-autoconfig | 1 + c/mapping/lrec_evaluators.c | 11 +++++++++-- c/mapping/mlr_val.c | 20 +++++++++++++------- c/mapping/mlr_val.h | 13 +++++++------ 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/c/Makefile.no-autoconfig b/c/Makefile.no-autoconfig index 3b7383a23..9aa5375e6 100644 --- a/c/Makefile.no-autoconfig +++ b/c/Makefile.no-autoconfig @@ -108,6 +108,7 @@ TEST_LREC_EVALUATORS_SRCS = \ lib/mlrutil.c \ lib/mtrand.c \ lib/mlrmath.c \ + lib/string_builder.c \ containers/mlr_dsl_ast.c \ containers/sllv.c \ containers/slls.c \ diff --git a/c/mapping/lrec_evaluators.c b/c/mapping/lrec_evaluators.c index 048de12e7..fbb5032c6 100644 --- a/c/mapping/lrec_evaluators.c +++ b/c/mapping/lrec_evaluators.c @@ -29,6 +29,7 @@ // lrec_evaluators.c to invoke functions here with mlr_vals of the correct // type(s). // ================================================================ +#define STRING_BUILDER_ALLOC_LENGTH 32 // ---------------------------------------------------------------- typedef struct _lrec_evaluator_b_b_state_t { @@ -476,6 +477,7 @@ typedef struct _lrec_evaluator_x_sr_state_t { mv_binary_arg2_regex_func_t* pfunc; lrec_evaluator_t* parg1; regex_t regex; + string_builder_t* psb; } lrec_evaluator_x_sr_state_t; mv_t lrec_evaluator_x_sr_func(lrec_t* prec, context_t* pctx, void* pvstate) { @@ -485,7 +487,7 @@ mv_t lrec_evaluator_x_sr_func(lrec_t* prec, context_t* pctx, void* pvstate) { if (val1.type != MT_STRING) return MV_ERROR; - return pstate->pfunc(&val1, &pstate->regex); + return pstate->pfunc(&val1, &pstate->regex, pstate->psb); } lrec_evaluator_t* lrec_evaluator_alloc_from_x_sr_func(mv_binary_arg2_regex_func_t* pfunc, @@ -497,6 +499,8 @@ lrec_evaluator_t* lrec_evaluator_alloc_from_x_sr_func(mv_binary_arg2_regex_func_ int cflags = ignore_case ? REG_ICASE : 0; regcomp_or_die(&pstate->regex, regex_string, cflags); + pstate->psb = mlr_malloc_or_die(sizeof(string_builder_t)); + sb_init(pstate->psb, STRING_BUILDER_ALLOC_LENGTH); lrec_evaluator_t* pevaluator = mlr_malloc_or_die(sizeof(lrec_evaluator_t)); pevaluator->pvstate = pstate; @@ -589,6 +593,7 @@ typedef struct _lrec_evaluator_x_srs_state_t { lrec_evaluator_t* parg1; regex_t regex; lrec_evaluator_t* parg3; + string_builder_t* psb; } lrec_evaluator_x_srs_state_t; mv_t lrec_evaluator_x_srs_func(lrec_t* prec, context_t* pctx, void* pvstate) { @@ -604,7 +609,7 @@ mv_t lrec_evaluator_x_srs_func(lrec_t* prec, context_t* pctx, void* pvstate) { if (val3.type != MT_STRING) return MV_ERROR; - return pstate->pfunc(&val1, &pstate->regex, &val3); + return pstate->pfunc(&val1, &pstate->regex, pstate->psb, &val3); } lrec_evaluator_t* lrec_evaluator_alloc_from_x_srs_func(mv_ternary_arg2_regex_func_t* pfunc, @@ -617,6 +622,8 @@ lrec_evaluator_t* lrec_evaluator_alloc_from_x_srs_func(mv_ternary_arg2_regex_fun int cflags = ignore_case ? REG_ICASE : 0; regcomp_or_die(&pstate->regex, regex_string, cflags); + pstate->psb = mlr_malloc_or_die(sizeof(string_builder_t)); + sb_init(pstate->psb, STRING_BUILDER_ALLOC_LENGTH); pstate->parg3 = parg3; diff --git a/c/mapping/mlr_val.c b/c/mapping/mlr_val.c index afc45df71..453ac14ca 100644 --- a/c/mapping/mlr_val.c +++ b/c/mapping/mlr_val.c @@ -183,7 +183,10 @@ mv_t s_ss_dot_func(mv_t* pval1, mv_t* pval2) { // ---------------------------------------------------------------- mv_t sub_no_precomp_func(mv_t* pval1, mv_t* pval2, mv_t* pval3) { regex_t regex; - mv_t rv = sub_precomp_func(pval1, regcomp_or_die(®ex, pval2->u.strv, 0), pval3); + string_builder_t sb; + sb_init(&sb, 32); + mv_t rv = sub_precomp_func(pval1, regcomp_or_die(®ex, pval2->u.strv, 0), &sb, pval3); + free(sb_finish(&sb)); regfree(®ex); return rv; } @@ -200,7 +203,7 @@ mv_t sub_no_precomp_func(mv_t* pval1, mv_t* pval2, mv_t* pval3) { // * len3 = 1 = length of "o" // * len4 = 6 = 2+3+1 -mv_t sub_precomp_func(mv_t* pval1, regex_t* pregex, mv_t* pval3) { +mv_t sub_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb, mv_t* pval3) { const size_t nmatch = 1; // xxx temp: parameterize after adding capture-group support regmatch_t pmatch[nmatch]; int eflags = 0; @@ -248,12 +251,15 @@ mv_t sub_precomp_func(mv_t* pval1, regex_t* pregex, mv_t* pval3) { mv_t gsub_no_precomp_func(mv_t* pval1, mv_t* pval2, mv_t* pval3) { regex_t regex; - mv_t rv = gsub_precomp_func(pval1, regcomp_or_die(®ex, pval2->u.strv, 0), pval3); + string_builder_t sb; + sb_init(&sb, 32); + mv_t rv = gsub_precomp_func(pval1, regcomp_or_die(®ex, pval2->u.strv, 0), &sb, pval3); + free(sb_finish(&sb)); regfree(®ex); return rv; } -mv_t gsub_precomp_func(mv_t* pval1, regex_t* pregex, mv_t* pval3) { +mv_t gsub_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb, mv_t* pval3) { const size_t nmatch = 1; // xxx temp: parameterize after adding capture-group support regmatch_t pmatch[nmatch]; int eflags = 0; @@ -958,7 +964,7 @@ mv_t does_not_match_no_precomp_func(mv_t* pval1, mv_t* pval2) { // ---------------------------------------------------------------- // arg2 is a string, compiled to regex only once at alloc time -mv_t matches_precomp_func(mv_t* pval1, regex_t* pregex) { +mv_t matches_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb) { regmatch_t pmatch[1]; int eflags = 0; @@ -969,8 +975,8 @@ mv_t matches_precomp_func(mv_t* pval1, regex_t* pregex) { } } -mv_t does_not_match_precomp_func(mv_t* pval1, regex_t* pregex) { - mv_t rv = matches_precomp_func(pval1, pregex); +mv_t does_not_match_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb) { + mv_t rv = matches_precomp_func(pval1, pregex, psb); rv.u.boolv = !rv.u.boolv; return rv; } diff --git a/c/mapping/mlr_val.h b/c/mapping/mlr_val.h index 2efd53919..0b711d8b5 100644 --- a/c/mapping/mlr_val.h +++ b/c/mapping/mlr_val.h @@ -8,6 +8,7 @@ #include "lib/mlrmath.h" #include "lib/mlrutil.h" #include "lib/mtrand.h" +#include "lib/string_builder.h" // ================================================================ // MT for Miller type -- highly abbreviated here since these are @@ -68,9 +69,9 @@ void mt_get_double_nullable(mv_t* pval); typedef mv_t mv_zary_func_t(); typedef mv_t mv_unary_func_t(mv_t* pval1); typedef mv_t mv_binary_func_t(mv_t* pval1, mv_t* pval2); -typedef mv_t mv_binary_arg2_regex_func_t(mv_t* pval1, regex_t* pregex); +typedef mv_t mv_binary_arg2_regex_func_t(mv_t* pval1, regex_t* pregex, string_builder_t* psb); typedef mv_t mv_ternary_func_t(mv_t* pval1, mv_t* pval2, mv_t* pval3); -typedef mv_t mv_ternary_arg2_regex_func_t(mv_t* pval1, regex_t* pregex, mv_t* pval3); +typedef mv_t mv_ternary_arg2_regex_func_t(mv_t* pval1, regex_t* pregex, string_builder_t* psb, mv_t* pval3); // ---------------------------------------------------------------- static inline mv_t b_b_not_func(mv_t* pval1) { @@ -204,9 +205,9 @@ mv_t s_s_toupper_func(mv_t* pval1); mv_t s_ss_dot_func(mv_t* pval1, mv_t* pval2); mv_t sub_no_precomp_func(mv_t* pval1, mv_t* pval2, mv_t* pval3); -mv_t sub_precomp_func(mv_t* pval1, regex_t* pregex, mv_t* pval3); +mv_t sub_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb, mv_t* pval3); mv_t gsub_no_precomp_func(mv_t* pval1, mv_t* pval2, mv_t* pval3); -mv_t gsub_precomp_func(mv_t* pval1, regex_t* pregex, mv_t* pval3); +mv_t gsub_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb, mv_t* pval3); // ---------------------------------------------------------------- mv_t s_f_sec2gmt_func(mv_t* pval1); @@ -228,8 +229,8 @@ mv_t i_s_strlen_func(mv_t* pval1); mv_t matches_no_precomp_func(mv_t* pval1, mv_t* pval2); mv_t does_not_match_no_precomp_func(mv_t* pval1, mv_t* pval2); // arg2 is a string, compiled to regex only once at alloc time -mv_t matches_precomp_func(mv_t* pval1, regex_t* pregex); -mv_t does_not_match_precomp_func(mv_t* pval1, regex_t* pregex); +mv_t matches_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb); +mv_t does_not_match_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb); mv_t eq_op_func(mv_t* pval1, mv_t* pval2); mv_t ne_op_func(mv_t* pval1, mv_t* pval2);