diff options
author | Nicholas Clark <nick@ccl4.org> | 2010-07-12 11:38:31 +0100 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2010-07-12 13:43:19 +0100 |
commit | 79d2d448469df7917fb728ca8a674f771610599c (patch) | |
tree | 418d33433cb78146539ed32a8568c09681e1d4ac /sv.c | |
parent | ec49a12ce17d116f4e9bda1c3d385aad560ec655 (diff) | |
download | perl-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.c | 21 |
1 files changed, 15 insertions, 6 deletions
@@ -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; } |