ssub function

This commit is contained in:
John Kerl 2018-04-28 11:21:14 -07:00
parent d25b241c01
commit 01c9d6d306
3 changed files with 57 additions and 0 deletions

View file

@ -233,6 +233,7 @@ static function_lookup_t FUNCTION_LOOKUP_TABLE[] = {
{FUNC_CLASS_STRING, "gsub", 3,0, "Example: '$name=gsub($name, \"old\", \"new\")'\n(replace all)."},
{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."},
{FUNC_CLASS_STRING, "substr", 3,0,
"substr(s,m,n) gives substring of s from 0-up position m to n \n"
"inclusive. Negative indices -len .. -1 alias to 0 .. len-1."},
@ -1228,6 +1229,8 @@ static rval_evaluator_t* fmgr_alloc_evaluator_from_ternary_func_name(char* fnnm,
return rval_evaluator_alloc_from_s_sss_func(sub_no_precomp_func, parg1, parg2, parg3);
} else if (streq(fnnm, "gsub")) {
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, "logifit")) {
return rval_evaluator_alloc_from_f_fff_func(f_fff_logifit_func, parg1, parg2, parg3);
} else if (streq(fnnm, "madd")) {

View file

@ -192,6 +192,58 @@ mv_t gsub_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb, mv_t
return mv_from_string(output, free_flags);
}
// ----------------------------------------------------------------
// String-substitution with no regexes or special characters.
// It is assumed that all inputs have already been checked to be strings.
mv_t s_sss_ssub_func(mv_t* pmvinput, mv_t* pmvold, mv_t* pmvnew) {
char* pinput = pmvinput->u.strv;
char* pold = pmvold->u.strv;
char* pnew = pmvnew->u.strv;
char* pmatch = strstr(pinput, pold);
if (pmatch == NULL) {
mv_free(pmvold);
mv_free(pmvnew);
return *pmvinput;
} else {
// Example:
// input: aaaaOOObbbbb
// old: OOO
// new: NNNNN
// Output length: strlen(aaaa) + strlen(NNNNN) + strlen(bbbbb)
// Compute lengths
int input_length = strlen(pinput);
int old_length = strlen(pold);
int new_length = strlen(pnew);
int output_length = input_length - old_length + new_length + 1;
int pre_length = pmatch - pinput; // the "aaaa" part
int post_length = input_length - pre_length - old_length; // the "bbbbb" part
// Allocate output
char* poutput = mlr_malloc_or_die(output_length);
char* p = poutput;
// Populate output
strncpy(p, pinput, pre_length);
p += pre_length;
strcpy(p, pnew);
p += new_length;
strcpy(p, &pinput[pre_length + old_length]);
p += post_length;
*p = 0;
mv_free(pmvinput);
mv_free(pmvold);
mv_free(pmvnew);
return mv_from_string(poutput, FREE_ENTRY_VALUE);
}
}
// ----------------------------------------------------------------
// https://en.wikipedia.org/wiki/Hamming_weight

View file

@ -193,6 +193,8 @@ 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, 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, string_builder_t* psb, mv_t* pval3);
// String-substitution with no regexes or special characters.
mv_t s_sss_ssub_func(mv_t* pstring, mv_t* pold, mv_t* pnew);
// ----------------------------------------------------------------
mv_t s_x_sec2gmt_func(mv_t* pval1);