Since perl 5.6.0 came out, some modules have started using a similar
style of version number with several parts separated by dots.  There
are other reasons why a version number might not be a simple number,
eg '5.42a'.  These versions cause MakeMaker to grumble with

  Argument "0.4.1" isn't numeric in numeric lt (<)
  at /usr/lib/perl5/5.6.1/ExtUtils/MakeMaker.pm line 359.

and I suspect the dependency checking is not correct.  The following
patch copies the comparison code from Sort::Versions, which should do
the right thing in most cases.

diff -ru ExtUtils-MakeMaker-6.21/lib/ExtUtils/MakeMaker.pm 
ExtUtils-MakeMaker-6.21-new/lib/ExtUtils/MakeMaker.pm
--- ExtUtils-MakeMaker-6.21/lib/ExtUtils/MakeMaker.pm   2003-11-11 08:07:36.000000000 
+0000
+++ ExtUtils-MakeMaker-6.21-new/lib/ExtUtils/MakeMaker.pm       2004-01-04 
11:02:28.159551064 +0000
@@ -345,6 +345,48 @@
 END
 }
 
+# Code to compare version numbers, copied from Sort::Versions.
+sub versioncmp( $$ ) {
+    my @A = ($_[0] =~ /([-.]|\d+|[^-.\d]+)/g);
+    my @B = ($_[1] =~ /([-.]|\d+|[^-.\d]+)/g);
+
+    my ($A, $B);
+    while (@A and @B) {
+       $A = shift @A;
+       $B = shift @B;
+       if ($A eq '-' and $B eq '-') {
+           next;
+       } elsif ( $A eq '-' ) {
+           return -1;
+       } elsif ( $B eq '-') {
+           return 1;
+       } elsif ($A eq '.' and $B eq '.') {
+           next;
+       } elsif ( $A eq '.' ) {
+           return -1;
+       } elsif ( $B eq '.' ) {
+           return 1;
+       } elsif ($A =~ /^\d+$/ and $B =~ /^\d+$/) {
+           if ($A =~ /^0/ || $B =~ /^0/) {
+               return $A cmp $B if $A cmp $B;
+           } else {
+               return $A <=> $B if $A <=> $B;
+           }
+       } else {
+           $A = uc $A;
+           $B = uc $B;
+           return $A cmp $B if $A cmp $B;
+       }       
+    }
+    @A <=> @B;
+}
+
+# $a < $b in version number terms.
+sub version_lt( $$ ) {
+    my ($a, $b) = @_;
+    return(versioncmp($a, $b) < 0);
+}
+
 sub new {
     my($class,$self) = @_;
     my($key);
@@ -397,7 +439,7 @@
               $prereq, $self->{PREREQ_PM}{$prereq} 
                    unless $self->{PREREQ_FATAL};
             $unsatisfied{$prereq} = 'not installed';
-        } elsif ($pr_version < $self->{PREREQ_PM}->{$prereq} ){
+        } elsif (version_lt($pr_version, $self->{PREREQ_PM}->{$prereq})){
             warn sprintf "Warning: prerequisite %s %s not found. We have %s.\n",
               $prereq, $self->{PREREQ_PM}{$prereq}, 
                 ($pr_version || 'unknown version') 


This change doesn't have any weird platform dependencies so the
question of whether to apply it is the question of whether MakeMaker
should understand these newfangled 'numbers'.  I think it should.

Please have a look at Sort::Versions and its test suite if you wonder
exactly how it does the comparison; in almost all cases the result for
two decimal numbers will be the same as <, the exception being that
'1.20' < '1.123'.  (But '1.200' > '1.123' and '1.02' < '1.1'.)

I hope you can apply the patch, or at least a weaker version that does
the fancy comparison only if one of the versions cannot be a plain
number.

-- 
Ed Avis <[EMAIL PROTECTED]>


Reply via email to