mg_length returns the number of bytes if a scalar has length magic,
but the number of characters otherwise.
sv_len_utf8 used to assume that mg_length would return bytes. The
first mistake was added in commit
b76347f2eb, which assumed that
mg_length would return characters. But it was #ifdeffed out until
commit
ffc61ed20e.
Later, commit
5636d518683 met sv_len_utf8’s assumptions by making
mg_length return the length in characters, without accounting for
sv_len, which also used mg_length.
So we ended up with a buggy sv_len that would return a character
count for scalars with get- but not length-magic, and a byte count
otherwise.
In the previous commit, I fixed sv_len not to use mg_length at all. I
plan shortly to remove any use of mg_length (the one remaining use is
in sv_len_utf8, which is currently not called on magical values).
The reason for removing all calls to mg_length is that the returned
length cannot be converted to characters without access to the PV as
well, which requires get-magic. So length magic on scalars makes no
sense since the advent of utf8.
This commit restore mg_length to its old behaviour and lists it as
deprecated. This is mostly cosmetic, as there are no CPAN users. But
it is in the API, and I don’t know whether we can easily remove it.
Apd |int |mg_free |NN SV* sv
Apd |void |mg_free_type |NN SV* sv|int how
Apd |int |mg_get |NN SV* sv
-Apd |U32 |mg_length |NN SV* sv
+ApdD |U32 |mg_length |NN SV* sv
Apd |void |mg_magical |NN SV* sv
Apd |int |mg_set |NN SV* sv
Ap |I32 |mg_size |NN SV* sv
/*
=for apidoc mg_length
-Report on the SV's length. See C<sv_magic>.
+This function is deprecated.
+
+It reports on the SV's length in bytes, calling length magic if available,
+but does not set the UTF8 flag on the sv. It will fall back to 'get'
+magic if there is no 'length' magic, but with no indication as to
+whether it called 'get' magic. It assumes the sv is a PVMG or
+higher. Use sv_len() instead.
=cut
*/
}
}
- {
- /* You can't know whether it's UTF-8 until you get the string again...
- */
- const U8 *s = (U8*)SvPV_const(sv, len);
-
- if (DO_UTF8(sv)) {
- len = utf8_length(s, s + len);
- }
- }
+ (void)SvPV_const(sv, len);
return len;
}
assert(sv)
PERL_CALLCONV U32 Perl_mg_length(pTHX_ SV* sv)
+ __attribute__deprecated__
__attribute__nonnull__(pTHX_1);
#define PERL_ARGS_ASSERT_MG_LENGTH \
assert(sv)
os2/os2/os2-rexx/rexx.pm Verbatim line length including indents exceeds 79 by 1
pod/perl.pod Verbatim line length including indents exceeds 79 by 8
pod/perlaix.pod Verbatim line length including indents exceeds 79 by 11
-pod/perlapi.pod ? Should you be using L<...> instead of 85
+pod/perlapi.pod ? Should you be using L<...> instead of 84
pod/perlapi.pod Verbatim line length including indents exceeds 79 by 6
pod/perlapi.pod unresolved internal link 3
pod/perlapio.pod Verbatim line length including indents exceeds 79 by 5