Changeset: b20960a8799b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/b20960a8799b
Modified Files:
monetdb5/modules/mal/pcre.c
Branch: regexp
Log Message:
Introduces empty_match_correction in single_replace for properly
dealing with empty string matching
diffs (59 lines):
diff --git a/monetdb5/modules/mal/pcre.c b/monetdb5/modules/mal/pcre.c
--- a/monetdb5/modules/mal/pcre.c
+++ b/monetdb5/modules/mal/pcre.c
@@ -593,6 +593,7 @@ single_replace(pcre *pcre_code, pcre_ext
int offset = 0;
int len_result = 0;
int addlen;
+ int empty_match_correction = 0;
char *tmp;
do {
@@ -600,7 +601,12 @@ single_replace(pcre *pcre_code, pcre_ext
exec_options, ovector, ovecsize);
if (j <= 0)
break;
- addlen = ovector[0] - offset + (nbackrefs == 0 ?
len_replacement : 0);
+
+ empty_match_correction = ovector[0] == ovector[1] ? 1 : 0;
+
+ // calculate the length of the string that will be appended to
result
+ addlen = ovector[0] - offset
+ + (nbackrefs == 0 ? len_replacement : 0) +
empty_match_correction;
if (len_result + addlen >= *max_result) {
tmp = GDKrealloc(result, len_result + addlen + 1);
if (tmp == NULL) {
@@ -610,11 +616,13 @@ single_replace(pcre *pcre_code, pcre_ext
result = tmp;
*max_result = len_result + addlen + 1;
}
+ // append to the result the parts of the original string that
are left unchanged
if (ovector[0] > offset) {
strncpy(result + len_result, origin_str + offset,
ovector[0] - offset);
len_result += ovector[0] - offset;
}
+ // append to the result the replacement of the matched string
if (nbackrefs == 0) {
strncpy(result + len_result, replacement,
len_replacement);
len_result += len_replacement;
@@ -668,8 +676,17 @@ single_replace(pcre *pcre_code, pcre_ext
}
}
// In case of an empty match just advance the offset by 1
- offset = ovector[0] == ovector[1] ? ovector[1] + 1 : ovector[1];
- } while (offset < len_origin_str && global);
+ offset = ovector[1] + empty_match_correction;
+ // and copy the character that we just advanced over
+ if (empty_match_correction) {
+ strncpy(result + len_result, origin_str + ovector[1],
1);
+ ++len_result;
+ }
+ // before we loop around check with the offset - 1 if we had an
empty match
+ // since we manually advanced the offset by one. otherwise we
gonna skip a
+ // replacement at the end of the string
+ } while ((offset - empty_match_correction) < len_origin_str && global);
+
if (offset < len_origin_str) {
addlen = len_origin_str - offset;
if (len_result + addlen >= *max_result) {
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]