summaryrefslogtreecommitdiff
path: root/sv.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2010-07-12 11:38:31 +0100
committerNicholas Clark <nick@ccl4.org>2010-07-12 13:43:19 +0100
commit79d2d448469df7917fb728ca8a674f771610599c (patch)
tree418d33433cb78146539ed32a8568c09681e1d4ac /sv.c
parentec49a12ce17d116f4e9bda1c3d385aad560ec655 (diff)
downloadperl-79d2d448469df7917fb728ca8a674f771610599c.tar.gz
S_sv_pos_u2b_cached now updates the UTF-8 length cache if at the end of string.
Pass in a boolean to S_sv_pos_u2b_forwards, which sets it to true if it discovers that the UTF-8 offset is at (or after) the end of the string. This can only happen if we don't already know the SV's length (in Unicode characters), because if we know it, we always call S_sv_pos_u2b_midway().
Diffstat (limited to 'sv.c')
-rw-r--r--sv.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/sv.c b/sv.c
index a3bc6e18a2..ce16db6288 100644
--- a/sv.c
+++ b/sv.c
@@ -6077,7 +6077,7 @@ Perl_sv_len_utf8(pTHX_ register SV *const sv)
offset. */
static STRLEN
S_sv_pos_u2b_forwards(const U8 *const start, const U8 *const send,
- STRLEN *const uoffset_p)
+ STRLEN *const uoffset_p, bool *const at_end)
{
const U8 *s = start;
STRLEN uoffset = *uoffset_p;
@@ -6088,7 +6088,11 @@ S_sv_pos_u2b_forwards(const U8 *const start, const U8 *const send,
--uoffset;
s += UTF8SKIP(s);
}
- if (s > send) {
+ if (s == send) {
+ *at_end = TRUE;
+ }
+ else if (s > send) {
+ *at_end = TRUE;
/* This is the existing behaviour. Possibly it should be a croak, as
it's actually a bounds error */
s = send;
@@ -6145,6 +6149,7 @@ S_sv_pos_u2b_cached(pTHX_ SV *const sv, MAGIC **const mgp, const U8 *const start
{
STRLEN boffset = 0; /* Actually always set, but let's keep gcc happy. */
bool found = FALSE;
+ bool at_end = FALSE;
PERL_ARGS_ASSERT_SV_POS_U2B_CACHED;
@@ -6185,7 +6190,7 @@ S_sv_pos_u2b_cached(pTHX_ SV *const sv, MAGIC **const mgp, const U8 *const start
uoffset -= uoffset0;
boffset = boffset0
+ sv_pos_u2b_forwards(start + boffset0,
- send, &uoffset);
+ send, &uoffset, &at_end);
uoffset += uoffset0;
}
}
@@ -6227,7 +6232,7 @@ S_sv_pos_u2b_cached(pTHX_ SV *const sv, MAGIC **const mgp, const U8 *const start
STRLEN real_boffset;
uoffset -= uoffset0;
real_boffset = boffset0 + sv_pos_u2b_forwards(start + boffset0,
- send, &uoffset);
+ send, &uoffset, &at_end);
uoffset += uoffset0;
if (found && PL_utf8cache < 0) {
@@ -6244,8 +6249,12 @@ S_sv_pos_u2b_cached(pTHX_ SV *const sv, MAGIC **const mgp, const U8 *const start
boffset = real_boffset;
}
- if (PL_utf8cache)
- utf8_mg_pos_cache_update(sv, mgp, boffset, uoffset, send - start);
+ if (PL_utf8cache) {
+ if (at_end)
+ utf8_mg_len_cache_update(sv, mgp, uoffset);
+ else
+ utf8_mg_pos_cache_update(sv, mgp, boffset, uoffset, send - start);
+ }
return boffset;
}