In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/f6166f76b7f5b59becd71ea9d8f959a789ee70f8?hp=d5fbd9dd00e27f435423fd4898ed0e5804de0fd6>

- Log -----------------------------------------------------------------
commit f6166f76b7f5b59becd71ea9d8f959a789ee70f8
Author: Chip Salzenberg <c...@pobox.com>
Date:   Fri Dec 17 10:55:20 2010 -0800

    document new printf size modifiers

M       pod/perldelta.pod

commit 673c2ba8988082a3225a61fc6a54304514e378e7
Author: Chip Salzenberg <c...@pobox.com>
Date:   Fri Dec 17 10:46:56 2010 -0800

    smoke tests for %hhd %zd %td

M       t/op/sprintf.t

commit 07208e09d4435b4e72743076e0bc290ef4b34911
Author: Chip Salzenberg <c...@pobox.com>
Date:   Fri Dec 17 10:13:43 2010 -0800

    add %jd to printf where C99 exists; tweak %zd and %td

M       sv.c
-----------------------------------------------------------------------

Summary of changes:
 pod/perldelta.pod |    9 ++++++++
 sv.c              |   57 +++++++++++++++++++++++++++++++++++++++++++++++-----
 t/op/sprintf.t    |    7 ++++-
 3 files changed, 65 insertions(+), 8 deletions(-)

diff --git a/pod/perldelta.pod b/pod/perldelta.pod
index 835d706..630ccc0 100644
--- a/pod/perldelta.pod
+++ b/pod/perldelta.pod
@@ -109,6 +109,15 @@ This double setting arrangement is a stopgap until the 
reason for unwinding can
 be made properly introspectable.  C<$@> has never been a reliable indicator of
 this.
 
+=head2 printf-like functions understand size modifiers "hh", "z", "t", and 
sometimes "j"
+
+Perl's printf and sprintf operators, and Perl's internal printf replacement
+function, now understand the C90 size modifiers "hh" (C<char>), "z"
+(C<size_t>), and "t" (C<ptrdiff_t>).  Also, when compiled with a C99
+compiler, Perl now understands the size modifier "j" (C<intmax_t>).
+
+So, for example, on any modern machine, C<sprintf('%hhd', 257)> returns '1'.
+
 =head2 DTrace probes now include package name
 
 The DTrace probes now include an additional argument (C<arg3>) which contains
diff --git a/sv.c b/sv.c
index 4371375..99433b0 100644
--- a/sv.c
+++ b/sv.c
@@ -32,6 +32,15 @@
 #include "perl.h"
 #include "regcomp.h"
 
+#ifndef HAS_C99
+# if __STDC_VERSION__ >= 199901L
+#  define HAS_C99 1
+# endif
+#endif
+#if HAS_C99
+# include <stdint.h>
+#endif
+
 #define FCALL *f
 
 #ifdef __Lynx__
@@ -10270,16 +10279,28 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char 
*const pat, const STRLEN patlen,
 #endif
        case 'l':
 #if defined(HAS_QUAD) || defined(HAS_LONG_DOUBLE)
-           if (*(q + 1) == 'l') {      /* lld, llf */
+           if (*++q == 'l') {  /* lld, llf */
                intsize = 'q';
-               q += 2;
-               break;
-            }
+               ++q;
+           }
+           else
 #endif
-           /*FALLTHROUGH*/
+               intsize = 'l';
+           break;
        case 'h':
-           /*FALLTHROUGH*/
+           if (*++q == 'h') {  /* hhd, hhu */
+               intsize = 'c';
+               ++q;
+           }
+           else
+               intsize = 'h';
+           break;
        case 'V':
+       case 'z':
+       case 't':
+#if HAS_C99
+        case 'j':
+#endif
            intsize = *q++;
            break;
        }
@@ -10405,10 +10426,16 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char 
*const pat, const STRLEN patlen,
            }
            else if (args) {
                switch (intsize) {
+               case 'c':       iv = (char)va_arg(*args, int); break;
                case 'h':       iv = (short)va_arg(*args, int); break;
                case 'l':       iv = va_arg(*args, long); break;
                case 'V':       iv = va_arg(*args, IV); break;
+               case 'z':       iv = va_arg(*args, SSize_t); break;
+               case 't':       iv = va_arg(*args, ptrdiff_t); break;
                default:        iv = va_arg(*args, int); break;
+#if HAS_C99
+               case 'j':       iv = va_arg(*args, intmax_t); break;
+#endif
                case 'q':
 #ifdef HAS_QUAD
                                iv = va_arg(*args, Quad_t); break;
@@ -10420,6 +10447,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const 
pat, const STRLEN patlen,
            else {
                IV tiv = SvIV(argsv); /* work around GCC bug #13488 */
                switch (intsize) {
+               case 'c':       iv = (char)tiv; break;
                case 'h':       iv = (short)tiv; break;
                case 'l':       iv = (long)tiv; break;
                case 'V':
@@ -10496,9 +10524,15 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const 
pat, const STRLEN patlen,
            }
            else if (args) {
                switch (intsize) {
+               case 'c':  uv = (unsigned char)va_arg(*args, unsigned); break;
                case 'h':  uv = (unsigned short)va_arg(*args, unsigned); break;
                case 'l':  uv = va_arg(*args, unsigned long); break;
                case 'V':  uv = va_arg(*args, UV); break;
+               case 'z':  uv = va_arg(*args, Size_t); break;
+               case 't':  uv = va_arg(*args, ptrdiff_t); break; /* will sign 
extend, but there is no uptrdiff_t, so oh well */
+#if HAS_C99
+               case 'j':  uv = va_arg(*args, uintmax_t); break;
+#endif
                default:   uv = va_arg(*args, unsigned); break;
                case 'q':
 #ifdef HAS_QUAD
@@ -10511,6 +10545,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const 
pat, const STRLEN patlen,
            else {
                UV tuv = SvUV(argsv); /* work around GCC bug #13488 */
                switch (intsize) {
+               case 'c':       uv = (unsigned char)tuv; break;
                case 'h':       uv = (unsigned short)tuv; break;
                case 'l':       uv = (unsigned long)tuv; break;
                case 'V':
@@ -10621,7 +10656,11 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const 
pat, const STRLEN patlen,
 #else
                /*FALLTHROUGH*/
 #endif
+           case 'c':
            case 'h':
+           case 'z':
+           case 't':
+           case 'j':
                goto unknown;
            }
 
@@ -10801,10 +10840,16 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char 
*const pat, const STRLEN patlen,
            i = SvCUR(sv) - origlen;
            if (args) {
                switch (intsize) {
+               case 'c':       *(va_arg(*args, char*)) = i; break;
                case 'h':       *(va_arg(*args, short*)) = i; break;
                default:        *(va_arg(*args, int*)) = i; break;
                case 'l':       *(va_arg(*args, long*)) = i; break;
                case 'V':       *(va_arg(*args, IV*)) = i; break;
+               case 'z':       *(va_arg(*args, SSize_t*)) = i; break;
+               case 't':       *(va_arg(*args, ptrdiff_t*)) = i; break;
+#if HAS_C99
+               case 'j':       *(va_arg(*args, intmax_t*)) = i; break;
+#endif
                case 'q':
 #ifdef HAS_QUAD
                                *(va_arg(*args, Quad_t*)) = i; break;
diff --git a/t/op/sprintf.t b/t/op/sprintf.t
index 14f0395..54f3c2b 100644
--- a/t/op/sprintf.t
+++ b/t/op/sprintf.t
@@ -301,8 +301,11 @@ __END__
 >% 3d<      >-1<          > -1<
 >%03d<      >-1<          >-01<
 >%hd<       >1<           >1<              >More extensive testing of<
->%ld<       >1<           >1<              >length modifiers would be<
->%Vd<       >1<           >1<              >platform-specific<
+>%hhd<      >1<           >1<              >length modifiers would be<
+>%ld<       >1<           >1<              >platform-specific<
+>%Vd<       >1<           >1<
+>%zd<       >1<           >1<
+>%td<       >1<           >1<
 >%vd<       >chr(1)<      >1<
 >%+vd<      >chr(1)<      >+1<
 >%#vd<      >chr(1)<      >1<

--
Perl5 Master Repository

Reply via email to