diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-09-22 21:36:22 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-09-22 21:36:22 -0700 |
commit | 93e3d055337822ceff671710ea0611e3bbf46ae2 (patch) | |
tree | 8f94bd8d219c29db9ba1304bb2b97e6f6643ab61 /regex.c | |
parent | 0bd7556d869f0038a5bf58fff41ccbed891d150d (diff) | |
download | txr-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.c | 62 |
1 files changed, 59 insertions, 3 deletions
@@ -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(®m, regex); + + for (i = pos; lt(i, end); i = plus(i, one)) { + last_res = regex_machine_feed(®m, c_chr(chr_str(str, i))); + if (last_res == REGM_FAIL) + break; + } + + last_res = regex_machine_feed(®m, 0); + + switch (last_res) { + case REGM_MATCH: + regex_machine_cleanup(®m); + return minus(end, pos); + case REGM_INCOMPLETE: + case REGM_FAIL: + regex_machine_cleanup(®m); + 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)); |