Re: [PATCH] Version object combined patch
John Peacock [Thu, 10 Oct 2002 21:23:01 +0000 (17:23 -0400)]
Message-ID: <3DA627F5.5050907@rowman.com>

p4raw-id: //depot/perl@18026

lib/version.pm
lib/version.t
pod/perldiag.pod
util.c

index 63d25ac..0647648 100644 (file)
@@ -9,7 +9,7 @@ use vars qw(@ISA $VERSION $CLASS);
 
 @ISA = qw(DynaLoader);
 
-$VERSION = (qw$Revision: 2.1 $)[1]/10;
+$VERSION = (qw$Revision: 2.2 $)[1]/10;
 
 $CLASS = 'version';
 
@@ -55,6 +55,22 @@ single underscore.  This corresponds to what Perl itself uses for a
 version, as well as extending the "version as number" that is discussed
 in the various editions of the Camel book.
 
+However, in order to be compatible with earlier Perl version styles,
+any use of versions of the form 5.006001 will be translated as 5.6.1,
+In other words a version with a single decimal place will be parsed
+as implicitely having three places between subversion.
+
+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
+
+NOTE: it is strongly recommended that version objects only be created
+with numeric values based on the different types of versions in this
+documentation, see L<"Types of Versions Objects">.  That way, there is
+no confusion about what constitutes the version.
+
 =head2 Object Methods
 
 Overloading has been used with version objects to provide a natural
@@ -160,11 +176,6 @@ have only two.  This allows you to automatically increment
 your module version by using the Revision number from the primary
 file in a distribution, see L<ExtUtils::MakeMaker/"VERSION_FROM">.
 
-In order to be compatible with earlier Perl version styles, any use
-of versions of the form 5.006001 will be translated as 5.6.1,  In 
-other words a version with a single decimal place will be parsed
-as implicitely having three places between subversion.
-
 =item * Beta versions - For module authors using CPAN, the 
 convention has been to note unstable releases with an underscore
 in the version string, see L<CPAN>.  Beta releases will test as being
index 4d4a791..8823f23 100644 (file)
@@ -1,10 +1,10 @@
 # Before `make install' is performed this script should be runnable with
 # `make test'. After `make install' it should work as `perl test.pl'
-# $Revision: 2.0 $
+# $Revision: 2.1 $
 
 #########################
 
-use Test::More tests => 60;
+use Test::More tests => 64;
 use_ok(version); # If we made it this far, we are ok.
 
 my ($version, $new_version);
@@ -34,6 +34,14 @@ eval {my $version = new version "1.2_3.4";};
 like($@, qr/underscores before decimal/,
     "Invalid version format (underscores before decimal)");
 
+$version = new version "99 and 44/100 pure";
+ok ("$version" eq "99.0", '$version eq "99.0"');
+ok ($version->numify == 99.0, '$version->numify == 99.0');
+
+$version = new version "something";
+ok ("$version" eq "", '$version eq ""');
+ok ($version->numify == 0, '$version->numify == 99.0');
+
 # Test boolean operator
 ok ($version, 'boolean');
 
index 4e7ff06..1504fc9 100644 (file)
@@ -1816,6 +1816,15 @@ transparently promotes all numbers to a floating point representation
 internally--subject to loss of precision errors in subsequent
 operations.
 
+=item Integer overflow in version
+
+(F) Some portion of a version initialization is too large for the
+size of integers for your architecture.  This is not a warning
+because there is no rational reason for a version to try and use a
+element larger than typically 2**32.  This is usually caused by
+trying to use some odd mathematical operation as a version, like
+100/9.
+
 =item Internal disaster in regex; marked by <-- HERE in m/%s/
 
 (P) Something went badly wrong in the regular expression parser.
@@ -1892,6 +1901,17 @@ L<perlfunc/unpack>.
 (W unpack) The given character is not a valid unpack type but used to be
 silently ignored.
 
+=item Invalid version format (multiple underscores)
+
+(F) Versions may contain at most a single underscore, which signals
+that the version is a beta release.  See L<version> for the allowed
+version formats.
+
+=item Invalid version format (underscores before decimal)
+
+(F) Versions may not contain decimals after the optional underscore.
+See L<version> for the allowed version formats.
+
 =item ioctl is not implemented
 
 (F) Your machine apparently doesn't implement ioctl(), which is pretty
diff --git a/util.c b/util.c
index 90a0e91..0fc7db5 100644 (file)
--- a/util.c
+++ b/util.c
@@ -4004,7 +4004,7 @@ Perl_scan_version(pTHX_ char *s, SV *rv)
            if ( saw_under )
                Perl_croak(aTHX_ "Invalid version format (underscores before decimal)");
            saw_period++ ;
-           }
+       }
        else if ( *pos == '_' )
        {
            if ( saw_under )
@@ -4017,7 +4017,7 @@ Perl_scan_version(pTHX_ char *s, SV *rv)
 
     if (*pos == 'v') pos++;  /* get past 'v' */
     while (isDIGIT(*pos))
-    pos++;
+       pos++;
     if (!isALPHA(*pos)) {
        I32 rev;
 
@@ -4036,7 +4036,6 @@ Perl_scan_version(pTHX_ char *s, SV *rv)
                        mult = -1;      /* beta version */
                }
                while (--end >= s) {
-
                    I32 orev;
                    orev = rev;
                    rev += (*end - '0') * mult;
@@ -4057,7 +4056,7 @@ Perl_scan_version(pTHX_ char *s, SV *rv)
                break;
            }
            while ( isDIGIT(*pos) ) {
-               if ( saw_period == 1 && pos-s == 3 )
+               if ( !saw_under && saw_period == 1 && pos-s == 3 )
                    break;
                pos++;
            }
@@ -4144,6 +4143,11 @@ Perl_vnumify(pTHX_ SV *vs)
     if ( SvROK(vs) )
        vs = SvRV(vs);
     len = av_len((AV *)vs);
+    if ( len == -1 )
+    {
+       Perl_sv_catpv(aTHX_ sv,"0");
+       return sv;
+    }
     digit = SvIVX(*av_fetch((AV *)vs, 0, 0));
     Perl_sv_setpvf(aTHX_ sv,"%d.",abs(digit));
     for ( i = 1 ; i <= len ; i++ )
@@ -4178,10 +4182,15 @@ Perl_vstringify(pTHX_ SV *vs)
     if ( SvROK(vs) )
        vs = SvRV(vs);
     len = av_len((AV *)vs);
+    if ( len == -1 )
+    {
+       Perl_sv_catpv(aTHX_ sv,"");
+       return sv;
+    }
     digit = SvIVX(*av_fetch((AV *)vs, 0, 0));
     Perl_sv_setpvf(aTHX_ sv,"%d",digit);
     for ( i = 1 ; i <= len ; i++ )
-{
+    {
        digit = SvIVX(*av_fetch((AV *)vs, i, 0));
        if ( digit < 0 )
            Perl_sv_catpvf(aTHX_ sv,"_%d",-digit);