summaryrefslogtreecommitdiffstats
path: root/regex.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-09-22 21:36:22 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-09-22 21:36:22 -0700
commit93e3d055337822ceff671710ea0611e3bbf46ae2 (patch)
tree8f94bd8d219c29db9ba1304bb2b97e6f6643ab61 /regex.c
parent0bd7556d869f0038a5bf58fff41ccbed891d150d (diff)
downloadtxr-93e3d055337822ceff671710ea0611e3bbf46ae2.tar.gz
txr-93e3d055337822ceff671710ea0611e3bbf46ae2.tar.bz2
txr-93e3d055337822ceff671710ea0611e3bbf46ae2.zip
Semantics change in match-regex-right.
The way the end-position argument works in match-regex-right and match-regst-right is poorly considered. It basically enforces a constraint that there is a match which ends at that position and does not go beyond. This patch changes it work right: the functions test that the regex matches up to that position, as if the string ended there. * regex.c (match_regex_right_old): New static function, identical to the previous match_regex_right. Since we won't ever be using this inside TXR from any other module, we don't make it external. (match_regex_right): Rewritten to new semantics. (match_regst_right_old): New static function; provides the semantics of the old match_regst_right based on match_regex_right_old. (regex_init): Register match-regex-right and match-regst-right intrinsics to the match_regex_right_old and match_regst_right_old functions if compatibility <= 150 is requested. Otherwise they go to the rewritten new functions. * txr.1: Documentation updated, and compat notes added.
Diffstat (limited to 'regex.c')
-rw-r--r--regex.c62
1 files changed, 59 insertions, 3 deletions
diff --git a/regex.c b/regex.c
index 8368a8b8..090bcbdd 100644
--- a/regex.c
+++ b/regex.c
@@ -2506,7 +2506,7 @@ val match_regex_len(val str, val regex, val pos)
}
}
-val match_regex_right(val str, val regex, val end)
+static val match_regex_right_old(val str, val regex, val end)
{
val pos = zero;
val slen = length(str);
@@ -2531,6 +2531,52 @@ val match_regex_right(val str, val regex, val end)
return nil;
}
+val match_regex_right(val str, val regex, val end)
+{
+ val pos = zero;
+ val len = length(str);
+
+ if (null_or_missing_p(end)) {
+ end = len;
+ } else if (minusp(end)) {
+ end = plus(end, len);
+ if (lt(end, zero))
+ return nil;
+ } else if (gt(end, len)) {
+ return nil;
+ }
+
+ while (lt(pos, end)) {
+ regex_machine_t regm;
+ val i ;
+ regm_result_t last_res = REGM_INCOMPLETE;
+
+ regex_machine_init(&regm, regex);
+
+ for (i = pos; lt(i, end); i = plus(i, one)) {
+ last_res = regex_machine_feed(&regm, c_chr(chr_str(str, i)));
+ if (last_res == REGM_FAIL)
+ break;
+ }
+
+ last_res = regex_machine_feed(&regm, 0);
+
+ switch (last_res) {
+ case REGM_MATCH:
+ regex_machine_cleanup(&regm);
+ return minus(end, pos);
+ case REGM_INCOMPLETE:
+ case REGM_FAIL:
+ regex_machine_cleanup(&regm);
+ break;
+ }
+
+ pos = succ(pos);
+ }
+
+ return nil;
+}
+
val regsub(val regex, val repl, val str)
{
val isfunc = functionp(repl);
@@ -2594,6 +2640,14 @@ val match_regst(val str, val regex, val pos_in)
return if2(new_pos, sub_str(str, pos, new_pos));
}
+static val match_regst_right_old(val str, val regex, val end)
+{
+ val len = match_regex_right_old(str, regex, end);
+ return if2(len, if3(null_or_missing_p(end),
+ sub_str(str, neg(len), t),
+ sub_str(str, minus(end, len), end)));
+}
+
val match_regst_right(val str, val regex, val end)
{
val len = match_regex_right(str, regex, end);
@@ -2766,9 +2820,11 @@ void regex_init(void)
match_regex : match_regex_len, 2));
reg_fun(intern(lit("match-regst"), user_package), func_n3o(match_regst, 2));
reg_fun(intern(lit("match-regex-right"), user_package),
- func_n3o(match_regex_right, 2));
+ func_n3o((opt_compat && opt_compat <= 150) ?
+ match_regex_right_old : match_regex_right, 2));
reg_fun(intern(lit("match-regst-right"), user_package),
- func_n3o(match_regst_right, 2));
+ func_n3o((opt_compat && opt_compat <= 150) ?
+ match_regst_right_old : match_regst_right, 2));
reg_fun(intern(lit("regsub"), user_package), func_n3(regsub));
reg_fun(intern(lit("regex-parse"), user_package), func_n2o(regex_parse, 1));