From: John Peacock Date: Wed, 14 Dec 2005 10:12:56 +0000 (-0500) Subject: Re: [perl #37897] sprintf of version objects X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=96b8f7ce6100a86cc5ebd0a9974640b15b9529a1;p=p5sagit%2Fp5-mst-13.2.git Re: [perl #37897] sprintf of version objects Message-ID: <43A03678.2060700@rowman.com> (with some formatting tweaks and extra test cases) p4raw-id: //depot/perl@26365 --- diff --git a/sv.c b/sv.c index b2d9d2e..5029fb2 100644 --- 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 { diff --git a/t/op/sprintf.t b/t/op/sprintf.t index fcc2d30..79953ef 100755 --- a/t/op/sprintf.t +++ b/t/op/sprintf.t @@ -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<