sub/gsub capture-group iterate

This commit is contained in:
John Kerl 2015-10-13 21:29:28 -04:00
parent 5b998fba7e
commit 805ed4aa33
4 changed files with 30 additions and 15 deletions

View file

@ -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 \

View file

@ -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;

View file

@ -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(&regex, pval2->u.strv, 0), pval3);
string_builder_t sb;
sb_init(&sb, 32);
mv_t rv = sub_precomp_func(pval1, regcomp_or_die(&regex, pval2->u.strv, 0), &sb, pval3);
free(sb_finish(&sb));
regfree(&regex);
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(&regex, pval2->u.strv, 0), pval3);
string_builder_t sb;
sb_init(&sb, 32);
mv_t rv = gsub_precomp_func(pval1, regcomp_or_die(&regex, pval2->u.strv, 0), &sb, pval3);
free(sb_finish(&sb));
regfree(&regex);
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;
}

View file

@ -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);