diff options
author | Hugo van der Sanden <hv@crypt.org> | 2020-10-02 02:59:28 +0100 |
---|---|---|
committer | Hugo van der Sanden <hv@crypt.org> | 2020-10-02 03:04:42 +0100 |
commit | 532384b8e9074501de22e945fe68e04ee4fcc778 (patch) | |
tree | acde0a4cbe792c4e8e48efbb22981541b72d99c0 /pp.c | |
parent | 8a24d4166801085d81e9b6bd0adb1a77919a7b61 (diff) | |
download | perl-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.c | 100 |
1 files changed, 53 insertions, 47 deletions
@@ -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; } } } |