regextract_or_else iterate

This commit is contained in:
John Kerl 2018-08-26 14:42:30 -04:00
parent 28e1f9db0e
commit 66cfec5850
4 changed files with 67 additions and 1 deletions

View file

@ -232,6 +232,7 @@ static function_lookup_t FUNCTION_LOOKUP_TABLE[] = {
{FUNC_CLASS_STRING, ".", 2,0, "String concatenation."},
{FUNC_CLASS_STRING, "gsub", 3,0, "Example: '$name=gsub($name, \"old\", \"new\")'\n(replace all)."},
{FUNC_CLASS_STRING, "regextract", 2,0, "Example: '$name=regextract($name, \"[A-Z]{3}[0-9]{2}\")'\n."},
{FUNC_CLASS_STRING, "regextract_or_else", 2,0, "Example: '$name=regextract_or_else($name, \"[A-Z]{3}[0-9]{2}\", \"default\")'\n."},
{FUNC_CLASS_STRING, "strlen", 1,0, "String length."},
{FUNC_CLASS_STRING, "sub", 3,0, "Example: '$name=sub($name, \"old\", \"new\")'\n(replace once)."},
{FUNC_CLASS_STRING, "ssub", 3,0, "Like sub but does no regexing. No characters are special."},
@ -989,7 +990,8 @@ static rval_evaluator_t* construct_builtin_function_callsite_evaluator(
int is_regexy =
streq(function_name, "sub") ||
streq(function_name, "gsub");
streq(function_name, "gsub") ||
streq(function_name, "regextract_or_else");
if (is_regexy && type2 == MD_AST_NODE_TYPE_STRING_LITERAL) {
// sub/gsub-regex special case:
@ -1275,6 +1277,8 @@ static rval_evaluator_t* fmgr_alloc_evaluator_from_ternary_func_name(char* fnnm,
return rval_evaluator_alloc_from_s_sss_func(gsub_no_precomp_func, parg1, parg2, parg3);
} else if (streq(fnnm, "ssub")) {
return rval_evaluator_alloc_from_s_sss_func(s_sss_ssub_func, parg1, parg2, parg3);
} else if (streq(fnnm, "regextract_or_else")) {
return rval_evaluator_alloc_from_s_sss_func(regextract_or_else_no_precomp_func, parg1, parg2, parg3);
} else if (streq(fnnm, "logifit")) {
return rval_evaluator_alloc_from_f_fff_func(f_fff_logifit_func, parg1, parg2, parg3);
} else if (streq(fnnm, "madd")) {
@ -1299,6 +1303,8 @@ static rval_evaluator_t* fmgr_alloc_evaluator_from_ternary_regex_arg2_func_name(
return rval_evaluator_alloc_from_x_srs_func(sub_precomp_func, parg1, regex_string, ignore_case, parg3);
} else if (streq(fnnm, "gsub")) {
return rval_evaluator_alloc_from_x_srs_func(gsub_precomp_func, parg1, regex_string, ignore_case, parg3);
} else if (streq(fnnm, "regextract_or_else")) {
return rval_evaluator_alloc_from_x_ses_func(regextract_or_else_precomp_func, parg1, regex_string, ignore_case, parg3);
} else { return NULL; }
}

View file

@ -177,6 +177,9 @@ rval_evaluator_t* rval_evaluator_alloc_from_s_sss_func(mv_ternary_func_t* pfunc,
rval_evaluator_t* rval_evaluator_alloc_from_x_srs_func(mv_ternary_arg2_regex_func_t* pfunc,
rval_evaluator_t* parg1, char* regex_string, int ignore_case, rval_evaluator_t* parg3);
rval_evaluator_t* rval_evaluator_alloc_from_x_ses_func(mv_ternary_arg2_regextract_func_t* pfunc,
rval_evaluator_t* parg1, char* regex_string, int ignore_case, rval_evaluator_t* parg3);
// ================================================================
// rval_list_evaluators.c
// ================================================================

View file

@ -1359,3 +1359,59 @@ rval_evaluator_t* rval_evaluator_alloc_from_x_srs_func(mv_ternary_arg2_regex_fun
return pevaluator;
}
// ----------------------------------------------------------------
typedef struct _rval_evaluator_x_ses_state_t {
mv_ternary_arg2_regextract_func_t* pfunc;
rval_evaluator_t* parg1;
regex_t regex;
rval_evaluator_t* parg3;
} rval_evaluator_x_ses_state_t;
static mv_t rval_evaluator_x_ses_func(void* pvstate, variables_t* pvars) {
rval_evaluator_x_ses_state_t* pstate = pvstate;
mv_t val1 = pstate->parg1->pprocess_func(pstate->parg1->pvstate, pvars);
NULL_OR_ERROR_OUT_FOR_STRINGS(val1);
if (!mv_is_string_or_empty(&val1))
return mv_error();
mv_t val3 = pstate->parg3->pprocess_func(pstate->parg3->pvstate, pvars);
NULL_OR_ERROR_OUT_FOR_STRINGS(val3);
if (!mv_is_string_or_empty(&val3)) {
mv_free(&val3);
return mv_error();
}
return pstate->pfunc(&val1, &pstate->regex, &val3);
}
static void rval_evaluator_x_ses_free(rval_evaluator_t* pevaluator) {
rval_evaluator_x_ses_state_t* pstate = pevaluator->pvstate;
pstate->parg1->pfree_func(pstate->parg1);
regfree(&pstate->regex);
pstate->parg3->pfree_func(pstate->parg3);
free(pstate);
free(pevaluator);
}
rval_evaluator_t* rval_evaluator_alloc_from_x_ses_func(mv_ternary_arg2_regextract_func_t* pfunc,
rval_evaluator_t* parg1, char* regex_string, int ignore_case, rval_evaluator_t* parg3)
{
rval_evaluator_x_ses_state_t* pstate = mlr_malloc_or_die(sizeof(rval_evaluator_x_ses_state_t));
pstate->pfunc = pfunc;
pstate->parg1 = parg1;
int cflags = ignore_case ? REG_ICASE : 0;
regcomp_or_die(&pstate->regex, regex_string, cflags);
pstate->parg3 = parg3;
rval_evaluator_t* pevaluator = mlr_malloc_or_die(sizeof(rval_evaluator_t));
pevaluator->pvstate = pstate;
pevaluator->pprocess_func = rval_evaluator_x_ses_func;
pevaluator->pfree_func = rval_evaluator_x_ses_free;
return pevaluator;
}

View file

@ -49,6 +49,7 @@ typedef mv_t mv_binary_arg2_regex_func_t(mv_t* pval1, regex_t* pregex, string_bu
typedef mv_t mv_binary_arg2_regextract_func_t(mv_t* pval1, regex_t* pregex);
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, string_builder_t* psb, mv_t* pval3);
typedef mv_t mv_ternary_arg2_regextract_func_t(mv_t* pval1, regex_t* pregex, mv_t* pval3);
// ----------------------------------------------------------------
static inline mv_t b_b_not_func(mv_t* pval1) {