This commit is contained in:
John Kerl 2015-10-13 23:01:50 -04:00
parent a17d1518bd
commit 1e71fa76c4
3 changed files with 41 additions and 34 deletions

View file

@ -513,3 +513,38 @@ char* regex_sub(char* input, regex_t* pregex, string_builder_t* psb, char* repla
return sb_finish(psb);
}
}
char* regex_gsub(char* input, regex_t* pregex, string_builder_t* psb, char* replacement) {
const size_t nmatch = 1; // xxx temp: parameterize after adding capture-group support
regmatch_t pmatch[nmatch];
int match_start = 0;
char* current_input = input;
while (TRUE) {
int matched = regmatch_or_die(pregex, &current_input[match_start], nmatch, pmatch);
if (!matched) {
return current_input;
}
int so = pmatch[0].rm_so;
int eo = pmatch[0].rm_eo;
int len1 = match_start + so;
int olen2 = eo - so;
int nlen2 = strlen(replacement);
int len3 = strlen(&current_input[len1 + olen2]);
int len4 = len1 + nlen2 + len3;
char* current_output = mlr_malloc_or_die(len4 + 1);
strncpy(&current_output[0], current_input, len1);
strncpy(&current_output[len1], replacement, nlen2);
strncpy(&current_output[len1+nlen2], &current_input[len1+olen2], len3);
current_output[len4] = 0;
free(current_input);
current_input = current_output;
match_start = len1 + nlen2;
}
}

View file

@ -135,6 +135,7 @@ int regmatch_or_die(const regex_t* pregex, const char* restrict match_string,
// allocated. If not, input is returned. So in either case, the caller should
// free the return value, and it is assumed that the input has been dynamically
// allocated.
char* regex_sub(char* input, regex_t* pregex, string_builder_t* psb, char* replacement);
char* regex_sub(char* input, regex_t* pregex, string_builder_t* psb, char* replacement);
char* regex_gsub(char* input, regex_t* pregex, string_builder_t* psb, char* replacement);
#endif // MLRUTIL_H

View file

@ -203,7 +203,6 @@ mv_t sub_no_precomp_func(mv_t* pval1, mv_t* pval2, mv_t* pval3) {
// * len4 = 6 = 2+3+1
mv_t sub_precomp_func(mv_t* pval1, regex_t* pregex, string_builder_t* psb, mv_t* pval3) {
char* input = pval1->u.strv;
char* output = regex_sub(input, pregex, psb, pval3->u.strv);
@ -238,39 +237,11 @@ 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) {
const size_t nmatch = 1; // xxx temp: parameterize after adding capture-group support
regmatch_t pmatch[nmatch];
char* input = pval1->u.strv;
char* output = regex_gsub(input, pregex, psb, pval3->u.strv);
int match_start = 0;
char* current_input = pval1->u.strv;
while (TRUE) {
int matched = regmatch_or_die(pregex, &current_input[match_start], nmatch, pmatch);
if (!matched) {
free(pval3->u.strv);
return (mv_t) {.type = MT_STRING, .u.strv = current_input};
}
int so = pmatch[0].rm_so;
int eo = pmatch[0].rm_eo;
int len1 = match_start + so;
int olen2 = eo - so;
int nlen2 = strlen(pval3->u.strv);
int len3 = strlen(&current_input[len1 + olen2]);
int len4 = len1 + nlen2 + len3;
char* current_output = mlr_malloc_or_die(len4 + 1);
strncpy(&current_output[0], current_input, len1);
strncpy(&current_output[len1], pval3->u.strv, nlen2);
strncpy(&current_output[len1+nlen2], &current_input[len1+olen2], len3);
current_output[len4] = 0;
free(current_input);
current_input = current_output;
match_start = len1 + nlen2;
}
free(pval3->u.strv);
return (mv_t) {.type = MT_STRING, .u.strv = output};
}
// ----------------------------------------------------------------