From b9381830ea61ec067aab6d500e359e6a80e285b6 Mon Sep 17 00:00:00 2001 From: John Peacock Date: Tue, 6 Apr 2004 17:56:19 -0400 Subject: [PATCH] Bleadperl to version 0.37 Message-ID: <40735FC3.5010305@rowman.com> p4raw-id: //depot/perl@22668 --- embed.fnc | 1 + embed.h | 2 + global.sym | 1 + lib/version.pm | 196 ++++++++++++++++++++++++++++++++++++------------------- lib/version.t | 21 +++--- pod/perlapi.pod | 75 ++++++++++++--------- proto.h | 1 + t/comp/use.t | 12 ++-- t/op/universal.t | 2 +- universal.c | 8 +-- util.c | 36 +++++++++- 11 files changed, 233 insertions(+), 122 deletions(-) diff --git a/embed.fnc b/embed.fnc index ccd0f57..5ed740e 100644 --- a/embed.fnc +++ b/embed.fnc @@ -539,6 +539,7 @@ Apd |char* |scan_version |char *vstr|SV *sv|bool qv Apd |SV* |new_version |SV *ver Apd |SV* |upg_version |SV *ver Apd |SV* |vnumify |SV *vs +Apd |SV* |vnormal |SV *vs Apd |SV* |vstringify |SV *vs Apd |int |vcmp |SV *lvs|SV *rvs p |PerlIO*|nextargv |GV* gv diff --git a/embed.h b/embed.h index dd3cc46..7d725fe 100644 --- a/embed.h +++ b/embed.h @@ -738,6 +738,7 @@ #define new_version Perl_new_version #define upg_version Perl_upg_version #define vnumify Perl_vnumify +#define vnormal Perl_vnormal #define vstringify Perl_vstringify #define vcmp Perl_vcmp #ifdef PERL_CORE @@ -3235,6 +3236,7 @@ #define new_version(a) Perl_new_version(aTHX_ a) #define upg_version(a) Perl_upg_version(aTHX_ a) #define vnumify(a) Perl_vnumify(aTHX_ a) +#define vnormal(a) Perl_vnormal(aTHX_ a) #define vstringify(a) Perl_vstringify(aTHX_ a) #define vcmp(a,b) Perl_vcmp(aTHX_ a,b) #ifdef PERL_CORE diff --git a/global.sym b/global.sym index 12b8d72..46b6458 100644 --- a/global.sym +++ b/global.sym @@ -324,6 +324,7 @@ Perl_scan_version Perl_new_version Perl_upg_version Perl_vnumify +Perl_vnormal Perl_vstringify Perl_vcmp Perl_ninstr diff --git a/lib/version.pm b/lib/version.pm index f4cf944..232e2f2 100644 --- a/lib/version.pm +++ b/lib/version.pm @@ -12,7 +12,7 @@ use vars qw(@ISA $VERSION $CLASS @EXPORT); @EXPORT = qw(qv); -$VERSION = 0.36; # stop using CVS and switch to subversion +$VERSION = 0.37; # stop using CVS and switch to subversion $CLASS = 'version'; @@ -31,22 +31,19 @@ version - Perl extension for Version Objects =head1 SYNOPSIS use version; - $version = new version "12.2.1"; # must be quoted! + $version = version->new("12.2.1"); # must be quoted for Perl < 5.8.1 print $version; # 12.2.1 print $version->numify; # 12.002001 if ( $version gt "12.2" ) # true - $vstring = new version qw(1.2); # must be quoted! - print $vstring; # 1.2 - - $alphaver = new version "1.2_3"; # must be quoted! + $alphaver = version->new("1.2_3"); # must be quoted! print $alphaver; # 1.2_3 print $alphaver->is_alpha(); # true $ver = qv(1.2); # 1.2.0 $ver = qv("1.2"); # 1.2.0 - $perlver = new version 5.005_03; # must not be quoted! + $perlver = version->new(5.005_03); # must not be quoted! print $perlver; # 5.5.30 =head1 DESCRIPTION @@ -78,27 +75,28 @@ Any initial parameter which contains more than one decimal point or contains an embedded underscore, see L. The most recent development version of Perl (5.9.x) and the next major release (5.10.0) will automatically create version objects for bare -numbers containing more than one decimal point. +numbers containing more than one decimal point in the appropriate +context. =back Both of these methods will produce similar version objects, in that -the default stringification will always be in a reduced form, i.e.: +the default stringification will yield the version L only +if required: - $v = new version 1.002003; # 1.2.3 - $v2 = new version "1.2.3"; # 1.2.3 - $v3 = new version 1.2.3; # 1.2.3 for Perl > 5.8.0 + $v = version->new(1.002); # 1.002, but compares like 1.2.0 + $v = version->new(1.002003); # 1.2.3 + $v2 = version->new( "1.2.3"); # 1.2.3 + $v3 = version->new( 1.2.3); # 1.2.3 for Perl >= 5.8.1 -Note that the default stringification will display at least three sub -terms (to ensure that appropriate round-trip processing is possible). Please see L<"Quoting"> for more details on how Perl will parse various input values. Any value passed to the new() operator will be parsed only so far as it contains a numeric, decimal, or underscore character. So, for example: - $v1 = new version "99 and 94/100 percent pure"; # $v1 == 99.0 - $v2 = new version "something"; # $v2 == "" and $v2->numify == 0 + $v1 = version->new("99 and 94/100 percent pure"); # $v1 == 99.0 + $v2 = version->new("something"); # $v2 == "" and $v2->numify == 0 However, see L for one case where non-numeric text is acceptable when initializing version objects. @@ -118,16 +116,17 @@ decimal places, or a bare number with one or more decimal places and a leading 'v' character (also bare). For example: $vs1 = 1.2.3; # encoded as \1\2\3 - $vs2 = v1.2; # encoded as \1\2 + $vs2 = v1.2; # encoded as \1\2 The first of those two syntaxes is destined to be the default way to create a version object in 5.10.0, whereas the second will issue a mandatory -deprecation warning beginning at the same time. +deprecation warning beginning at the same time. In both cases, a v-string +encoded version will always be stringified in the version L. Consequently, the use of v-strings to initialize version objects with -this module is only possible with Perl 5.8.1 (which will contain special +this module is only possible with Perl 5.8.1 or better (which contain special code to enable it). Their use is B discouraged in all -circumstances(especially the leading 'v' style), since the meaning will +circumstances (especially the leading 'v' style), since the meaning will change depending on which Perl you are running. It is better to use L<"Quoted Versions"> to ensure the proper interpretation. @@ -140,20 +139,26 @@ a floating point number. Leading zeros B significant and trailing zeros are implied so that a minimum of three places is maintained between subversions. What this means is that any subversion (digits to the right of the decimal place) that contains less than three digits -will have trailing zeros added to make up the difference. For example: +will have trailing zeros added to make up the difference, but only for +purposes of comparison with other version objects. For example: - $v = new version 1.2; # 1.200 - $v = new version 1.02; # 1.20 - $v = new version 1.002; # 1.2 - $v = new version 1.0023; # 1.2.300 - $v = new version 1.00203; # 1.2.30 - $v = new version 1.002_03; # 1.2.30 See "Quoting" - $v = new version 1.002003; # 1.2.3 + $v = version->new( 1.2); # prints 1.2, compares as 1.200.0 + $v = version->new( 1.02); # prints 1.02, compares as 1.20.0 + $v = version->new( 1.002); # prints 1.002, compares as 1.2.0 + $v = version->new( 1.0023); # 1.2.300 + $v = version->new( 1.00203); # 1.2.30 + $v = version->new( 1.002_03); # 1.2.30 See "Quoting" + $v = version->new( 1.002003); # 1.2.3 All of the preceeding examples except the second to last are true whether or not the input value is quoted. The important feature is that the input value contains only a single decimal. +IMPORTANT NOTE: If your numeric version contains more than 3 significant +digits after the decimal place, it will be split on each multiple of 3, so +1.0003 becomes 1.0.300, due to the need to remain compatible with Perl's +own 5.005_03 == 5.5.30 interpretation. + =head2 Quoted Versions These are the newest form of versions, and correspond to Perl's own @@ -164,18 +169,15 @@ method requires that the input parameter be quoted, although Perl's after of quoting. Unlike L, Quoted Versions may have more than -a single decimal point, e.g. "5.6.1" but must be quoted like this "5.6" in -order to prevent the Numeric Version interpretation. Also unlike -L, leading zeros are B significant, and trailing -zeros must be explicitely specified (i.e. will not be automatically added). -In addition, the subversions are not enforced to be three decimal places. +a single decimal point, e.g. "5.6.1" (for all versions of Perl). If a +Quoted Version has only one decimal place (and no embedded underscore), +it is interpreted exactly like a L. So, for example: - $v = new version "1.002"; # 1.2 - $v = new version "1.2.3"; # 1.2.3 - $v = new version "1.2.3"; # 1.2.3 - $v = new version "1.0003"; # 1.3 + $v = version->new( "1.002"); # 1.2 + $v = version->new( "1.2.3"); # 1.2.3 + $v = version->new("1.0003"); # 1.0.300 In addition to conventional versions, Quoted Versions can be used to create L. @@ -203,12 +205,12 @@ CVS every time the file is committed to the repository. In order to facilitate this feature, the following code can be employed: - $VERSION = new version qw$Revision: 2.7 $; + $VERSION = version->new(qw$Revision: 2.7 $); and the version object will be created as if the following code were used: - $VERSION = new version "2.7"; + $VERSION = version->new("v2.7"); In other words, the version will be automatically parsed out of the string, and it will be quoted to preserve the meaning CVS normally @@ -236,33 +238,33 @@ either will yield the same version number. For the subsequent examples, the following two objects will be used: - $ver = new version "1.2.3"; # see "Quoting" below - $alpha = new version "1.2_3"; # see "Alpha versions" below + $ver = version->new("1.2.3"); # see "Quoting" below + $alpha = version->new("1.2_3"); # see "Alpha versions" below + $nver = version->new(1.2); # see "Numeric Versions" above =over 4 -=item * Stringification +=item * Normal Form -Any time a version object is used as a string, a stringified -representation is returned in reduced form (no extraneous zeros): +For any version object which is initialized with multiple decimal +places (either quoted or if possible v-string), or initialized using +the L operator, the stringified representation is returned in +a normalized or reduced form (no extraneous zeros): - print $ver->stringify; # prints 1.2.3 - print $ver; # same thing + print $ver->normal; # prints as 1.2.3 + print $ver->stringify; # ditto + print $ver; # ditto + print $nver->normal; # prints as 1.2.0 + print $nver->stringify; # prints as 1.2, see "Stringification" In order to preserve the meaning of the processed version, the -default stringified representation will always contain at least -three sub terms. In other words, the following is guaranteed to -always be true: +normalized representation will always contain at least three sub terms. +In other words, the following is guaranteed to always be true: my $newver = version->new($ver->stringify); if ($newver eq $ver ) # always true {...} -If the string representation "looked like a number" then there is -a possibility that creating a new version object from that would use -the Numeric Version interpretation, If a version object contains only -two terms internally, it will stringify with an explicit '.0' appended. - =back =over 4 @@ -277,6 +279,7 @@ corresponds a version object, all sub versions are assumed to have three decimal places. So for example: print $ver->numify; # prints 1.002003 + print $nver->numify; # prints 1.2 Unlike the stringification operator, there is never any need to append trailing zeros to preserve the correct version value. @@ -285,6 +288,33 @@ trailing zeros to preserve the correct version value. =over 4 +=item * Stringification + +In order to mirror as much as possible the existing behavior of ordinary +$VERSION scalars, the stringification operation will display differently, +depending on whether the version was initialized as a L +or L. + +What this means in practice is that if the normal CPAN and Camel rules are +followed ($VERSION is a floating point number with no more than 3 decimal +places), the stringified output will be exactly the same as the numified +output. There will be no visible difference, although the internal +representation will be different, and the L will +function using the internal coding. + +If a version object is initialized using a L form, or if +the number of significant decimal places exceed three, then the stringified +form will be the L. The $obj->normal operation can always be +used to produce the L, even if the version was originally a +L. + + print $ver->stringify; # prints 1.2.3 + print $nver->stringify; # prints 1.2 + +=back + +=over 4 + =item * Comparison operators Both cmp and <=> operators perform the same comparison between terms @@ -308,6 +338,16 @@ It is probably best to chose either the numeric notation or the string notation and stick with it, to reduce confusion. Perl6 version objects B only support numeric comparisons. See also L<"Quoting">. +WARNING: Comparing version with unequal numbers of decimal places (whether +explicitely or implicitely initialized), may yield unexpected results at +first glance. For example, the following inequalities hold: + + version->new(0.96) > version->new(0.95); # 0.960.0 > 0.950.0 + version->new("0.96.1") < version->new(0.95); # 0.096.1 < 0.950.0 + +For this reason, it is best to use either exclusively L or +L with multiple decimal places. + =back =over 4 @@ -317,14 +357,14 @@ B only support numeric comparisons. See also L<"Quoting">. If you need to test whether a version object has been initialized, you can simply test it directly: - $vobj = new version $something; + $vobj = version->new($something); if ( $vobj ) # true only if $something was non-blank You can also test whether a version object is an L, for example to prevent the use of some feature not present in the main release: - $vobj = new version "1.2_3"; # MUST QUOTE + $vobj = version->new("1.2_3"); # MUST QUOTE ...later... if ( $vobj->is_alpha ) # True @@ -357,17 +397,17 @@ you are dependent on Perl's conversion routines to yield the version you expect. You are pretty safe by dividing by a power of 10, for example, but other operations are not likely to be what you intend. For example: - $VERSION = new version (qw$Revision: 1.4)[1]/10; + $VERSION = version->new((qw$Revision: 1.4)[1]/10); print $VERSION; # yields 0.14 - $V2 = new version 100/9; # Integer overflow in decimal number - print $V2; # yields 11_1285418553 + $V2 = version->new(100/9); # Integer overflow in decimal number + print $V2; # yields something like 11.111.111.100 Perl 5.8.1 and beyond will be able to automatically quote v-strings -(although a warning will be issued under 5.9.x and 5.10.0), but that +(although a warning may be issued under 5.9.x and 5.10.0), but that is not possible in earlier versions of Perl. In other words: - $version = new version "v2.5.4"; # legal in all versions of Perl - $newvers = new version v2.5.4; # legal only in Perl > 5.8.1 + $version = version->new("v2.5.4"); # legal in all versions of Perl + $newvers = version->new(v2.5.4); # legal only in Perl >= 5.8.1 =head2 Types of Versions Objects @@ -380,9 +420,9 @@ There are two types of Version Objects: These are the versions that normal modules will use. Can contain as many subversions as required. In particular, those using RCS/CVS can -use one of the following: +use the following: - $VERSION = new version qw$Revision: 2.7 $; + $VERSION = version->new(qw$Revision: 2.7 $); and the current RCS Revision for that file will be inserted automatically. If the file has been moved to a branch, the Revision @@ -398,7 +438,7 @@ unstable releases with an underscore in the version string, see L. Alpha releases will test as being newer than the more recent stable release, and less than the next stable release. For example: - $alphaver = new version "12.3_1"; # must quote + $alphaver = version->new("12.3_1"); # must quote obeys the relationship @@ -415,7 +455,31 @@ the non-alpha release. In addition to the version objects, this modules also replaces the core UNIVERSAL::VERSION function with one that uses version objects for its -comparisons. +comparisons. The return from this operator is always the numified form, +and the warning message generated includes both the numified and normal +forms (for clarity). + +For example: + + package Foo; + $VERSION = 1.2; + + package Bar; + $VERSION = "1.3.5"; # works with all Perl's (since it is quoted) + + package main; + use version; + + print $Foo::VERSION; # prints 1.2 + + print $Bar::VERSION; # prints 1.003005 + + eval "use CGI 10"; # some far future release + print $@; # prints "CGI version 10 (10.0.0) required..." + +IMPORTANT NOTE: This may mean that code which searches for a specific +string (to determine whether a given module is available) may need to be +changed. =head1 EXPORT diff --git a/lib/version.t b/lib/version.t index ecf9f46..dd8cb67 100644 --- a/lib/version.t +++ b/lib/version.t @@ -4,7 +4,7 @@ ######################### -use Test::More tests => 166; +use Test::More tests => 164; diag "Tests with base class" unless $ENV{PERL_CORE}; @@ -43,7 +43,7 @@ sub BaseTests { $version = $CLASS->new(5.005_03); is ( "$version" , "5.5.30" , '5.005_03 eq 5.5.30' ); $version = $CLASS->new(1.23); - is ( "$version" , "1.230.0" , '1.23 eq "1.230.0"' ); + is ( "$version" , "1.23" , '1.23 eq "1.23"' ); # Test quoted number processing diag "tests with quoted numbers" unless $ENV{PERL_CORE}; @@ -55,7 +55,7 @@ sub BaseTests { # Test stringify operator diag "tests with stringify" unless $ENV{PERL_CORE}; $version = $CLASS->new("5.005"); - is ( "$version" , "5.5.0" , '5.005 eq 5.5' ); + is ( "$version" , "5.005" , '5.005 eq "5.005"' ); $version = $CLASS->new("5.006.001"); is ( "$version" , "5.6.1" , '5.006.001 eq 5.6.1' ); $version = $CLASS->new("1.2.3_4"); @@ -72,7 +72,7 @@ sub BaseTests { "Invalid version format (underscores before decimal)"); $version = $CLASS->new("99 and 44/100 pure"); - ok ("$version" eq "99.0.0", '$version eq "99.0.0"'); + ok ("$version" eq "99", '$version eq "99.0.0"'); ok ($version->numify == 99.0, '$version->numify == 99.0'); $version = $CLASS->new("something"); @@ -223,7 +223,7 @@ sub BaseTests { # we know this file is here since we require it ourselves $version = $CLASS->new( $Test::More::VERSION ); eval "use Test::More $version"; - unlike($@, qr/Test::More version $version required/, + unlike($@, qr/Test::More version $version/, 'Replacement eval works with exact version'); $version = $CLASS->new( $Test::More::VERSION+0.01 ); # this should fail even with old UNIVERSAL::VERSION @@ -231,22 +231,22 @@ sub BaseTests { ( $]<5.6 ? $version->numify() #why is this a problem??? : $version ); eval $testeval; - like($@, qr/Test::More version $version required/, + like($@, qr/Test::More version $version/, 'Replacement eval works with incremented version'); - $version =~ s/...$//; #convert to string and remove trailing '.0' + $version =~ s/\.0$//; #convert to string and remove trailing '.0' chop($version); # shorten by 1 digit, should still succeed eval "use Test::More $version"; - unlike($@, qr/Test::More version $version required/, + unlike($@, qr/Test::More version $version/, 'Replacement eval works with single digit'); $version += 0.1; # this would fail with old UNIVERSAL::VERSION eval "use Test::More $version"; - unlike($@, qr/Test::More version $version required/, + like($@, qr/Test::More version $version/, 'Replacement eval works with incremented digit'); SKIP: { - skip 'Cannot test v-strings with Perl < 5.8.1', 5 + skip 'Cannot test v-strings with Perl < 5.8.1', 4 if $] < 5.008_001; diag "Tests with v-strings" unless $ENV{PERL_CORE}; $version = $CLASS->new(1.2.3); @@ -255,7 +255,6 @@ SKIP: { $new_version = $CLASS->new(1); ok($version == $new_version, '$version == $new_version'); ok($version eq $new_version, '$version eq $new_version'); - ok("$version" eq "$new_version", '"$version" eq "$new_version"'); $version = qv(1.2.3); ok("$version" eq "1.2.3", 'v-string initialized qv()'); } diff --git a/pod/perlapi.pod b/pod/perlapi.pod index 52051ff..91da7ae 100644 --- a/pod/perlapi.pod +++ b/pod/perlapi.pod @@ -120,7 +120,8 @@ Found in file av.c =item av_delete Deletes the element indexed by C from the array. Returns the -deleted element. C is currently ignored. +deleted element. If C equals C, the element is freed +and null is returned. SV* av_delete(AV* ar, I32 key, I32 flags) @@ -1924,6 +1925,21 @@ converted into version objects. =for hackers Found in file util.c +=item vnormal + +Accepts a version object and returns the normalized string +representation. Call like: + + sv = vnormal(rv); + +NOTE: you can pass either the object directly or the SV +contained within the RV. + + SV* vnormal(SV *vs) + +=for hackers +Found in file util.c + =item vnumify Accepts a version object and returns the normalized floating @@ -1941,13 +1957,10 @@ Found in file util.c =item vstringify -Accepts a version object and returns the normalized string -representation. Call like: - - sv = vstringify(rv); - -NOTE: you can pass either the object directly or the SV -contained within the RV. +In order to maintain maximum compatibility with earlier versions +of Perl, this function will return either the floating point +notation or the multiple dotted notation, depending on whether +the original version contained 1 or more dots, respectively SV* vstringify(SV *vs) @@ -3029,22 +3042,22 @@ which guarantees to evaluate sv only once. =for hackers Found in file sv.h -=item SvNVx +=item SvNVX -Coerces the given SV to a double and returns it. Guarantees to evaluate -sv only once. Use the more efficient C otherwise. +Returns the raw value in the SV's NV slot, without checks or conversions. +Only use when you are sure SvNOK is true. See also C. - NV SvNVx(SV* sv) + NV SvNVX(SV* sv) =for hackers Found in file sv.h -=item SvNVX +=item SvNVx -Returns the raw value in the SV's NV slot, without checks or conversions. -Only use when you are sure SvNOK is true. See also C. +Coerces the given SV to a double and returns it. Guarantees to evaluate +sv only once. Use the more efficient C otherwise. - NV SvNVX(SV* sv) + NV SvNVx(SV* sv) =for hackers Found in file sv.h @@ -3238,21 +3251,21 @@ Like C, but converts sv to utf8 first if necessary. =for hackers Found in file sv.h -=item SvPVX +=item SvPVx -Returns a pointer to the physical string in the SV. The SV must contain a -string. +A version of C which guarantees to evaluate sv only once. - char* SvPVX(SV* sv) + char* SvPVx(SV* sv, STRLEN len) =for hackers Found in file sv.h -=item SvPVx +=item SvPVX -A version of C which guarantees to evaluate sv only once. +Returns a pointer to the physical string in the SV. The SV must contain a +string. - char* SvPVx(SV* sv, STRLEN len) + char* SvPVX(SV* sv) =for hackers Found in file sv.h @@ -3500,22 +3513,22 @@ for a version which guarantees to evaluate sv only once. =for hackers Found in file sv.h -=item SvUVx +=item SvUVX -Coerces the given SV to an unsigned integer and returns it. Guarantees to -evaluate sv only once. Use the more efficient C otherwise. +Returns the raw value in the SV's UV slot, without checks or conversions. +Only use when you are sure SvIOK is true. See also C. - UV SvUVx(SV* sv) + UV SvUVX(SV* sv) =for hackers Found in file sv.h -=item SvUVX +=item SvUVx -Returns the raw value in the SV's UV slot, without checks or conversions. -Only use when you are sure SvIOK is true. See also C. +Coerces the given SV to an unsigned integer and returns it. Guarantees to +evaluate sv only once. Use the more efficient C otherwise. - UV SvUVX(SV* sv) + UV SvUVx(SV* sv) =for hackers Found in file sv.h diff --git a/proto.h b/proto.h index 8825c09..ec2cdb7 100644 --- a/proto.h +++ b/proto.h @@ -518,6 +518,7 @@ PERL_CALLCONV char* Perl_scan_version(pTHX_ char *vstr, SV *sv, bool qv); PERL_CALLCONV SV* Perl_new_version(pTHX_ SV *ver); PERL_CALLCONV SV* Perl_upg_version(pTHX_ SV *ver); PERL_CALLCONV SV* Perl_vnumify(pTHX_ SV *vs); +PERL_CALLCONV SV* Perl_vnormal(pTHX_ SV *vs); PERL_CALLCONV SV* Perl_vstringify(pTHX_ SV *vs); PERL_CALLCONV int Perl_vcmp(pTHX_ SV *lvs, SV *rvs); PERL_CALLCONV PerlIO* Perl_nextargv(pTHX_ GV* gv); diff --git a/t/comp/use.t b/t/comp/use.t index 0e3c22d..dc3265b 100755 --- a/t/comp/use.t +++ b/t/comp/use.t @@ -111,7 +111,7 @@ print "ok ",$i++,"\n"; print "ok ",$i++,"\n"; eval "use lib v100.105"; - unless ($@ =~ /lib version 100\.105\.0 required--this is only version 35\.360\.0/) { + unless ($@ =~ /lib version 100.105 \(100\.105\.0\) required--this is only version 35.36 \(35\.360\.0\)/) { print "not "; } print "ok ",$i++,"\n"; @@ -121,7 +121,7 @@ print "ok ",$i++,"\n"; print "ok ",$i++,"\n"; eval "use lib 100.105"; - unless ($@ =~ /lib version 100\.105\.0 required--this is only version 35\.360\.0/) { + unless ($@ =~ /lib version 100.105 \(100\.105\.0\) required--this is only version 35.36 \(35\.360\.0\)/) { print "not "; } print "ok ",$i++,"\n"; @@ -132,7 +132,7 @@ print "ok ",$i++,"\n"; print "ok ",$i++,"\n"; eval "use lib v100.105"; - unless ($@ =~ /lib version 100\.105\.0 required--this is only version 35\.360\.0/) { + unless ($@ =~ /lib version 100.105 \(100\.105\.0\) required--this is only version 35.36 \(35\.360\.0\)/) { print "not "; } print "ok ",$i++,"\n"; @@ -142,7 +142,7 @@ print "ok ",$i++,"\n"; print "ok ",$i++,"\n"; eval "use lib 100.105"; - unless ($@ =~ /lib version 100\.105\.0 required--this is only version 35\.360\.0/) { + unless ($@ =~ /lib version 100.105 \(100\.105\.0\) required--this is only version 35.36 \(35\.360\.0\)/) { print "not "; } print "ok ",$i++,"\n"; @@ -153,7 +153,7 @@ print "ok ",$i++,"\n"; print "ok ",$i++,"\n"; eval "use lib v100.105"; - unless ($@ =~ /lib version 100\.105\.0 required--this is only version 35\.36\.0/) { + unless ($@ =~ /lib version 100.105 \(100\.105\.0\) required--this is only version 35.036 \(35\.36\.0\)/) { print "not "; } print "ok ",$i++,"\n"; @@ -163,7 +163,7 @@ print "ok ",$i++,"\n"; print "ok ",$i++,"\n"; eval "use lib 100.105"; - unless ($@ =~ /lib version 100\.105\.0 required--this is only version 35\.36\.0/) { + unless ($@ =~ /lib version 100.105 \(100\.105\.0\) required--this is only version 35.036 \(35\.36\.0\)/) { print "not "; } print "ok ",$i++,"\n"; diff --git a/t/op/universal.t b/t/op/universal.t index 4587c3f..b7d452f 100755 --- a/t/op/universal.t +++ b/t/op/universal.t @@ -121,7 +121,7 @@ test ! $a->can("export_tags"); # a method in Exporter test (eval { $a->VERSION }) == 2.718; test ! (eval { $a->VERSION(2.719) }) && - $@ =~ /^Alice version 2\.719\.0 required--this is only version 2\.718\.0 at /; + $@ =~ /^Alice version 2.719 \(2\.719\.0\) required--this is only version 2.718 \(2\.718\.0\) at /; test (eval { $a->VERSION(2.718) }) && ! $@; diff --git a/universal.c b/universal.c index 4822d3d..bac641c 100644 --- a/universal.c +++ b/universal.c @@ -369,12 +369,12 @@ XS(XS_UNIVERSAL_VERSION) } if ( vcmp( req, sv ) > 0 ) - Perl_croak(aTHX_ - "%s version %"SVf" required--this is only version %"SVf, - HvNAME(pkg), req, sv); + Perl_croak(aTHX_ "%s version %"SVf" (%"SVf") required--" + "this is only version %"SVf" (%"SVf")", HvNAME(pkg), + vnumify(req),vnormal(req),vnumify(sv),vnormal(sv)); } - ST(0) = sv; + ST(0) = vnumify(sv); XSRETURN(1); } diff --git a/util.c b/util.c index e2783b4..56dc800 100644 --- a/util.c +++ b/util.c @@ -3769,6 +3769,11 @@ Perl_scan_version(pTHX_ char *s, SV *rv, bool qv) } } } + if ( qv ) { /* quoted versions always become full version objects */ + I32 len = av_len((AV *)sv); + for ( len = 2 - len; len != 0; len-- ) + av_push((AV *)sv, newSViv(0)); + } return s; } @@ -3890,12 +3895,12 @@ Perl_vnumify(pTHX_ SV *vs) } /* -=for apidoc vstringify +=for apidoc vnormal Accepts a version object and returns the normalized string representation. Call like: - sv = vstringify(rv); + sv = vnormal(rv); NOTE: you can pass either the object directly or the SV contained within the RV. @@ -3904,7 +3909,7 @@ contained within the RV. */ SV * -Perl_vstringify(pTHX_ SV *vs) +Perl_vnormal(pTHX_ SV *vs) { I32 i, len, digit; SV *sv = newSV(0); @@ -3936,6 +3941,31 @@ Perl_vstringify(pTHX_ SV *vs) } /* +=for apidoc vstringify + +In order to maintain maximum compatibility with earlier versions +of Perl, this function will return either the floating point +notation or the multiple dotted notation, depending on whether +the original version contained 1 or more dots, respectively + +=cut +*/ + +SV * +Perl_vstringify(pTHX_ SV *vs) +{ + I32 i, len, digit; + if ( SvROK(vs) ) + vs = SvRV(vs); + len = av_len((AV *)vs); + + if ( len < 2 ) + return vnumify(vs); + else + return vnormal(vs); +} + +/* =for apidoc vcmp Version object aware cmp. Both operands must already have been -- 2.7.4