1package CPAN::Version; 2 3use strict; 4use vars qw($VERSION); 5$VERSION = "5.5003"; 6 7# CPAN::Version::vcmp courtesy Jost Krieger 8sub vcmp { 9 my($self,$l,$r) = @_; 10 local($^W) = 0; 11 CPAN->debug("l[$l] r[$r]") if $CPAN::DEBUG; 12 13 # treat undef as zero 14 $l = 0 if $l eq 'undef'; 15 $r = 0 if $r eq 'undef'; 16 17 return 0 if $l eq $r; # short circuit for quicker success 18 19 for ($l,$r) { 20 s/_//g; 21 } 22 CPAN->debug("l[$l] r[$r]") if $CPAN::DEBUG; 23 for ($l,$r) { 24 next unless tr/.// > 1 || /^v/; 25 s/^v?/v/; 26 1 while s/\.0+(\d)/.$1/; # remove leading zeroes per group 27 } 28 CPAN->debug("l[$l] r[$r]") if $CPAN::DEBUG; 29 if ($l=~/^v/ <=> $r=~/^v/) { 30 for ($l,$r) { 31 next if /^v/; 32 $_ = $self->float2vv($_); 33 } 34 } 35 CPAN->debug("l[$l] r[$r]") if $CPAN::DEBUG; 36 my $lvstring = "v0"; 37 my $rvstring = "v0"; 38 if ($] >= 5.006 39 && $l =~ /^v/ 40 && $r =~ /^v/) { 41 $lvstring = $self->vstring($l); 42 $rvstring = $self->vstring($r); 43 CPAN->debug(sprintf "lv[%vd] rv[%vd]", $lvstring, $rvstring) if $CPAN::DEBUG; 44 } 45 46 return ( 47 ($l ne "undef") <=> ($r ne "undef") 48 || 49 $lvstring cmp $rvstring 50 || 51 $l <=> $r 52 || 53 $l cmp $r 54 ); 55} 56 57sub vgt { 58 my($self,$l,$r) = @_; 59 $self->vcmp($l,$r) > 0; 60} 61 62sub vlt { 63 my($self,$l,$r) = @_; 64 $self->vcmp($l,$r) < 0; 65} 66 67sub vge { 68 my($self,$l,$r) = @_; 69 $self->vcmp($l,$r) >= 0; 70} 71 72sub vle { 73 my($self,$l,$r) = @_; 74 $self->vcmp($l,$r) <= 0; 75} 76 77sub vstring { 78 my($self,$n) = @_; 79 $n =~ s/^v// or die "CPAN::Version::vstring() called with invalid arg [$n]"; 80 pack "U*", split /\./, $n; 81} 82 83# vv => visible vstring 84sub float2vv { 85 my($self,$n) = @_; 86 my($rev) = int($n); 87 $rev ||= 0; 88 my($mantissa) = $n =~ /\.(\d{1,12})/; # limit to 12 digits to limit 89 # architecture influence 90 $mantissa ||= 0; 91 $mantissa .= "0" while length($mantissa)%3; 92 my $ret = "v" . $rev; 93 while ($mantissa) { 94 $mantissa =~ s/(\d{1,3})// or 95 die "Panic: length>0 but not a digit? mantissa[$mantissa]"; 96 $ret .= ".".int($1); 97 } 98 # warn "n[$n]ret[$ret]"; 99 $ret =~ s/(\.0)+/.0/; # v1.0.0 => v1.0 100 $ret; 101} 102 103sub readable { 104 my($self,$n) = @_; 105 $n =~ /^([\w\-\+\.]+)/; 106 107 return $1 if defined $1 && length($1)>0; 108 # if the first user reaches version v43, he will be treated as "+". 109 # We'll have to decide about a new rule here then, depending on what 110 # will be the prevailing versioning behavior then. 111 112 if ($] < 5.006) { # or whenever v-strings were introduced 113 # we get them wrong anyway, whatever we do, because 5.005 will 114 # have already interpreted 0.2.4 to be "0.24". So even if he 115 # indexer sends us something like "v0.2.4" we compare wrongly. 116 117 # And if they say v1.2, then the old perl takes it as "v12" 118 119 if (defined $CPAN::Frontend) { 120 $CPAN::Frontend->mywarn("Suspicious version string seen [$n]\n"); 121 } else { 122 warn("Suspicious version string seen [$n]\n"); 123 } 124 return $n; 125 } 126 my $better = sprintf "v%vd", $n; 127 CPAN->debug("n[$n] better[$better]") if $CPAN::DEBUG; 128 return $better; 129} 130 1311; 132 133__END__ 134 135=head1 NAME 136 137CPAN::Version - utility functions to compare CPAN versions 138 139=head1 SYNOPSIS 140 141 use CPAN::Version; 142 143 CPAN::Version->vgt("1.1","1.1.1"); # 1 bc. 1.1 > 1.001001 144 145 CPAN::Version->vlt("1.1","1.1"); # 0 bc. 1.1 not < 1.1 146 147 CPAN::Version->vcmp("1.1","1.1.1"); # 1 bc. first is larger 148 149 CPAN::Version->vcmp("1.1.1","1.1"); # -1 bc. first is smaller 150 151 CPAN::Version->readable(v1.2.3); # "v1.2.3" 152 153 CPAN::Version->vstring("v1.2.3"); # v1.2.3 154 155 CPAN::Version->float2vv(1.002003); # "v1.2.3" 156 157=head1 DESCRIPTION 158 159This module mediates between some version that perl sees in a package 160and the version that is published by the CPAN indexer. 161 162It's only written as a helper module for both CPAN.pm and CPANPLUS.pm. 163 164As it stands it predates version.pm but has the same goal: make 165version strings visible and comparable. 166 167=head1 LICENSE 168 169This program is free software; you can redistribute it and/or 170modify it under the same terms as Perl itself. 171 172=cut 173 174# Local Variables: 175# mode: cperl 176# cperl-indent-level: 4 177# End: 178