diff options
author | Nicholas Clark <nick@ccl4.org> | 2008-01-12 22:20:39 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2008-01-12 22:20:39 +0000 |
commit | 9f621bb00a11fa3741b155ff668ae147fed95cf0 (patch) | |
tree | 7b5b39f40f93859c7938b76462590a705d7a4147 /pp.c | |
parent | d06445298904613950b0410a2f3b1125ab58c7b5 (diff) | |
download | perl-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.c | 32 |
1 files changed, 21 insertions, 11 deletions
@@ -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; } |