summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2008-01-12 22:20:39 +0000
committerNicholas Clark <nick@ccl4.org>2008-01-12 22:20:39 +0000
commit9f621bb00a11fa3741b155ff668ae147fed95cf0 (patch)
tree7b5b39f40f93859c7938b76462590a705d7a4147 /pp.c
parentd06445298904613950b0410a2f3b1125ab58c7b5 (diff)
downloadperl-9f621bb00a11fa3741b155ff668ae147fed95cf0.tar.gz
For 5.12: saner behaviour for `length`
(Make C<length undef> return undef). Patch mostly by Rafael, with some fine tuning by me. p4raw-id: //depot/perl@32969
Diffstat (limited to 'pp.c')
-rw-r--r--pp.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/pp.c b/pp.c
index 374f3550e2..6110b4c988 100644
--- a/pp.c
+++ b/pp.c
@@ -3018,25 +3018,35 @@ PP(pp_length)
dVAR; dSP; dTARGET;
SV * const sv = TOPs;
- if (SvAMAGIC(sv)) {
- /* For an overloaded scalar, we can't know in advance if it's going to
- be UTF-8 or not. Also, we can't call sv_len_utf8 as it likes to
- cache the length. Maybe that should be a documented feature of it.
+ if (!SvOK(sv) && !SvGMAGICAL(sv)) {
+ /* FIXME - this doesn't allow GMAGIC to return undef for consistency.
+ */
+ SETs(&PL_sv_undef);
+ } else if (SvGAMAGIC(sv)) {
+ /* For an overloaded or magic scalar, we can't know in advance if
+ it's going to be UTF-8 or not. Also, we can't call sv_len_utf8 as
+ it likes to cache the length. Maybe that should be a documented
+ feature of it.
*/
STRLEN len;
- const char *const p = SvPV_const(sv, len);
+ const char *const p
+ = sv_2pv_flags(sv, &len,
+ SV_UNDEF_RETURNS_NULL|SV_CONST_RETURN|SV_GMAGIC);
- if (DO_UTF8(sv)) {
+ if (!p)
+ SETs(&PL_sv_undef);
+ else if (DO_UTF8(sv)) {
SETi(utf8_length((U8*)p, (U8*)p + len));
}
else
SETi(len);
-
+ } else {
+ /* Neither magic nor overloaded. */
+ if (DO_UTF8(sv))
+ SETi(sv_len_utf8(sv));
+ else
+ SETi(sv_len(sv));
}
- else if (DO_UTF8(sv))
- SETi(sv_len_utf8(sv));
- else
- SETi(sv_len(sv));
RETURN;
}