sR |I32 |expect_number |NN char **const pattern
#
sn |STRLEN |sv_pos_u2b_forwards|NN const U8 *const start \
- |NN const U8 *const send|NN STRLEN *const uoffset
+ |NN const U8 *const send|NN STRLEN *const uoffset \
+ |NN bool *const at_end
sn |STRLEN |sv_pos_u2b_midway|NN const U8 *const start \
|NN const U8 *send|STRLEN uoffset|const STRLEN uend
s |STRLEN |sv_pos_u2b_cached|NN SV *const sv|NN MAGIC **const mgp \
assert(pattern)
#
-STATIC STRLEN S_sv_pos_u2b_forwards(const U8 *const start, const U8 *const send, STRLEN *const uoffset)
+STATIC STRLEN S_sv_pos_u2b_forwards(const U8 *const start, const U8 *const send, STRLEN *const uoffset, bool *const at_end)
__attribute__nonnull__(1)
__attribute__nonnull__(2)
- __attribute__nonnull__(3);
+ __attribute__nonnull__(3)
+ __attribute__nonnull__(4);
#define PERL_ARGS_ASSERT_SV_POS_U2B_FORWARDS \
- assert(start); assert(send); assert(uoffset)
+ assert(start); assert(send); assert(uoffset); assert(at_end)
STATIC STRLEN S_sv_pos_u2b_midway(const U8 *const start, const U8 *send, STRLEN uoffset, const STRLEN uend)
__attribute__nonnull__(1)
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;
--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;
{
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;
uoffset -= uoffset0;
boffset = boffset0
+ sv_pos_u2b_forwards(start + boffset0,
- send, &uoffset);
+ send, &uoffset, &at_end);
uoffset += uoffset0;
}
}
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) {
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;
}