Re: [perl #37897] sprintf of version objects
John Peacock [Wed, 14 Dec 2005 10:12:56 +0000 (05:12 -0500)]
Message-ID: <43A03678.2060700@rowman.com>

(with some formatting tweaks and extra test cases)

p4raw-id: //depot/perl@26365

sv.c
t/op/sprintf.t

diff --git a/sv.c b/sv.c
index b2d9d2e..5029fb2 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -7990,21 +7990,23 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
                vecsv = svargs[efix ? efix-1 : svix++];
                vecstr = (U8*)SvPV_const(vecsv,veclen);
                vec_utf8 = DO_UTF8(vecsv);
-               /* if this is a version object, we need to return the
-                * stringified representation (which the SvPVX_const has
-                * already done for us), but not vectorize the args
+
+               /* if this is a version object, we need to convert
+                * back into v-string notation and then let the
+                * vectorize happen normally
                 */
-               if ( *q == 'd' && sv_derived_from(vecsv,"version") )
-               {
-                       q++; /* skip past the rest of the %vd format */
-                       eptr = (const char *) vecstr;
-                       elen = veclen;
-                       if (elen && *eptr == 'v') {
-                           eptr++;
-                           elen--;
-                       }
-                       vectorize=FALSE;
-                       goto string;
+               if (sv_derived_from(vecsv, "version")) {
+                   char *version = savesvpv(vecsv);
+                   vecsv = sv_newmortal();
+                   /* scan_vstring is expected to be called during
+                    * tokenization, so we need to fake up the end
+                    * of the buffer for it
+                    */
+                   PL_bufend = version + veclen;
+                   scan_vstring(version, vecsv);
+                   vecstr = (U8*)SvPV_const(vecsv, veclen);
+                   vec_utf8 = DO_UTF8(vecsv);
+                   Safefree(version);
                }
            }
            else {
index fcc2d30..79953ef 100755 (executable)
@@ -243,10 +243,20 @@ __END__
 >%vd<       >"\01\02\03"< >1.2.3<
 >%vd<       >v1.2.3<      >1.2.3<
 >%vd<       >[version::qv("1.2.3")]< >1.2.3<
+>%vd<       >[version::qv("1.2")]< >1.2.0<
+>%vd<       >[version::qv("1.02")]< >1.2.0<
+>%vd<       >[version::qv("1.002")]< >1.2.0<
+>%vd<       >[version::qv("1.02_03")]< >1.23<
+>%vd<       >[version::qv("1048576.5")]< >1048576.5.0<
+>%vd<       >[version::qv("50")]< >50.0.0<
+>%vd<       >[version::qv("50_20")]< >50.200<
+>%vd<       >[version::qv("5.005_03")]< >5.53<
 >%v.3d<     >"\01\02\03"< >001.002.003<
 >%0v3d<     >"\01\02\03"< >001.002.003<
+>%v.3d<     >[version::qv("1.2.3")]< >001.002.003<
 >%-v3d<     >"\01\02\03"< >1  .2  .3  <
 >%+-v3d<    >"\01\02\03"< >+1 .2  .3  <
+>%+-v3d<    >[version::qv("1.2.3")]< >+1 .2  .3  <
 >%v4.3d<    >"\01\02\03"< > 001. 002. 003<
 >%0v4.3d<   >"\01\02\03"< >0001.0002.0003<
 >%0*v2d<    >['-', "\0\7\14"]< >00-07-12<
@@ -257,6 +267,7 @@ __END__
 >%v*.*d<    >["\01\02\03", 4, 3]< > 001. 002. 003<
 >%0v*.*d<   >["\01\02\03", 4, 3]< >0001.0002.0003<
 >%0*v*d<    >['-', "\0\7\13", 2]< >00-07-11<
+>%0*v*d<    >['-', version::qv("0.7.11"), 2]< >00-07-11<
 >%e<        >1234.875<    >1.234875e+03<
 >%e<        >0.000012345< >1.234500e-05<
 >%e<        >1234567E96<  >1.234567e+102<
@@ -391,6 +402,8 @@ __END__
 >%-010x<    >2**32-1<     >ffffffff  <
 >%0-10x<    >2**32-1<     >ffffffff  <
 >%0*x<      >[-10, ,2**32-1]< >ffffffff  <
+>%vx<       >[version::qv("1.2.3")]< >1.2.3<
+>%vx<       >[version::qv("1.20.300")]< >1.14.12c<
 >%y<        >''<          >%y INVALID<
 >%z<        >''<          >%z INVALID<
 >%2$d %1$d<    >[12, 34]<      >34 12<