Deprecate mg_length; make it return bytes
authorFather Chrysostomos <sprout@cpan.org>
Wed, 26 Sep 2012 22:20:52 +0000 (15:20 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 1 Oct 2012 19:51:51 +0000 (12:51 -0700)
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.

embed.fnc
mg.c
proto.h
t/porting/known_pod_issues.dat

index aa64815..feef3d0 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -797,7 +797,7 @@ ApdR        |MAGIC* |mg_findext     |NULLOK const SV* sv|int type|NULLOK const MGVTBL *vtbl
 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
diff --git a/mg.c b/mg.c
index 1b18a73..db9b4ee 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -288,7 +288,13 @@ Perl_mg_set(pTHX_ 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
 */
@@ -314,15 +320,7 @@ Perl_mg_length(pTHX_ SV *sv)
        }
     }
 
-    {
-       /* 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;
 }
 
diff --git a/proto.h b/proto.h
index fa69fa9..f104a22 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -2372,6 +2372,7 @@ PERL_CALLCONV int Perl_mg_get(pTHX_ SV* sv)
        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)
index 6274a8d..2cbcf89 100644 (file)
@@ -210,7 +210,7 @@ os2/os2/os2-rexx/dll/dll.pm Verbatim line length including indents exceeds 79 by
 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