summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorHugo van der Sanden <hv@crypt.org>2020-10-02 02:59:28 +0100
committerHugo van der Sanden <hv@crypt.org>2020-10-02 03:04:42 +0100
commit532384b8e9074501de22e945fe68e04ee4fcc778 (patch)
treeacde0a4cbe792c4e8e48efbb22981541b72d99c0 /pp.c
parent8a24d4166801085d81e9b6bd0adb1a77919a7b61 (diff)
downloadperl-532384b8e9074501de22e945fe68e04ee4fcc778.tar.gz
Revert "pp_split: RXf_NULL branch [...]"
"pp_split: RXf_NULL branch - separate out (gimme_scalar), reduce unnecessary work" was causing CPAN failures such as github #18188, which appear to be down to a change of behaviour in 'split //, $s, 2'. This reverts commit 59892837454d0ca367c3f7c83b2a646c57333b9a.
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c100
1 files changed, 53 insertions, 47 deletions
diff --git a/pp.c b/pp.c
index 06de4e688d..58181f4e35 100644
--- a/pp.c
+++ b/pp.c
@@ -6174,56 +6174,62 @@ PP(pp_split)
}
}
else if (RX_EXTFLAGS(rx) & RXf_NULL && !(s >= strend)) {
- /* This case boils down to deciding which is the smaller of:
- * limit - effectively a number of characters
- * slen - which already contains the number of characters in s
- *
- * The resulting number is the number of iters (for gimme_scalar)
- * or the number of SVs to create (!gimme_scalar). */
-
- /* setting it to -1 will trigger a panic in EXTEND() */
- const SSize_t sslen = slen > SSize_t_MAX ? -1 : (SSize_t)slen;
- /*limit is not needed later, so can clobber it here */
- limit--;
- if (sslen < limit || limit < 0) {
- iters = slen -1;
- limit = slen;
- /* Note: The same result is returned if the following block
- * is removed, because of the "keep field after final delim?"
- * adjustment, but having the following makes the "correct"
- * behaviour more apparent. */
- if (gimme_scalar) {
- s = strend;
- iters++;
+ /*
+ Pre-extend the stack, either the number of bytes or
+ characters in the string or a limited amount, triggered by:
+
+ my ($x, $y) = split //, $str;
+ or
+ split //, $str, $i;
+ */
+ if (!gimme_scalar) {
+ const IV items = limit - 1;
+ /* setting it to -1 will trigger a panic in EXTEND() */
+ const SSize_t sslen = slen > SSize_t_MAX ? -1 : (SSize_t)slen;
+ if (items >=0 && items < sslen)
+ EXTEND(SP, items);
+ else
+ EXTEND(SP, sslen);
+ }
+
+ if (do_utf8) {
+ while (--limit) {
+ /* keep track of how many bytes we skip over */
+ m = s;
+ s += UTF8SKIP(s);
+ if (gimme_scalar) {
+ iters++;
+ if (s-m == 0)
+ trailing_empty++;
+ else
+ trailing_empty = 0;
+ } else {
+ dstr = newSVpvn_flags(m, s-m, SVf_UTF8 | make_mortal);
+
+ PUSHs(dstr);
+ }
+
+ if (s >= strend)
+ break;
}
} else {
- iters = limit;
- }
+ while (--limit) {
+ if (gimme_scalar) {
+ iters++;
+ } else {
+ dstr = newSVpvn(s, 1);
- if (!gimme_scalar) {
- /*
- Pre-extend the stack, either the number of bytes or
- characters in the string or a limited amount, triggered by:
-
- my ($x, $y) = split //, $str;
- or
- split //, $str, $i;
- */
- EXTEND(SP, limit);
-
- if (do_utf8) {
- while (--limit) {
- m = s;
- s += UTF8SKIP(s);
- dstr = newSVpvn_flags(m, s-m, SVf_UTF8 | make_mortal);
- PUSHs(dstr);
- }
- } else {
- while (--limit) {
- dstr = newSVpvn_flags(s, 1, make_mortal);
- PUSHs(dstr);
- s++;
- }
+
+ if (make_mortal)
+ sv_2mortal(dstr);
+
+ PUSHs(dstr);
+ }
+
+ s++;
+
+ if (s >= strend)
+ break;
}
}
}