Versions.pm (4481B)
1 package Sort::Versions; 2 $Sort::Versions::VERSION = '1.62'; 3 # Copyright (c) 1996, Kenneth J. Albanowski. All rights reserved. This 4 # program is free software; you can redistribute it and/or modify it under 5 # the same terms as Perl itself. 6 7 use 5.006; 8 use strict; 9 use warnings; 10 11 require Exporter; 12 our @ISA = qw(Exporter); 13 our @EXPORT = qw(&versions &versioncmp); 14 our @EXPORT_OK = qw(); 15 16 sub versioncmp ($$) { 17 my @A = ($_[0] =~ /([-.]|\d+|[^-.\d]+)/g); 18 my @B = ($_[1] =~ /([-.]|\d+|[^-.\d]+)/g); 19 20 my ($A, $B); 21 while (@A and @B) { 22 $A = shift @A; 23 $B = shift @B; 24 if ($A eq '-' and $B eq '-') { 25 next; 26 } elsif ( $A eq '-' ) { 27 return -1; 28 } elsif ( $B eq '-') { 29 return 1; 30 } elsif ($A eq '.' and $B eq '.') { 31 next; 32 } elsif ( $A eq '.' ) { 33 return -1; 34 } elsif ( $B eq '.' ) { 35 return 1; 36 } elsif ($A =~ /^\d+$/ and $B =~ /^\d+$/) { 37 if ($A =~ /^0/ || $B =~ /^0/) { 38 return $A cmp $B if $A cmp $B; 39 } else { 40 return $A <=> $B if $A <=> $B; 41 } 42 } else { 43 $A = uc $A; 44 $B = uc $B; 45 return $A cmp $B if $A cmp $B; 46 } 47 } 48 @A <=> @B; 49 } 50 51 sub versions () { 52 my $callerpkg = (caller)[0]; 53 my $caller_a = "${callerpkg}::a"; 54 my $caller_b = "${callerpkg}::b"; 55 no strict 'refs'; 56 return versioncmp($$caller_a, $$caller_b); 57 } 58 59 =encoding utf-8 60 61 =head1 NAME 62 63 Sort::Versions - a perl 5 module for sorting of revision-like numbers 64 65 =head1 SYNOPSIS 66 67 use Sort::Versions; 68 @l = sort { versioncmp($a, $b) } qw( 1.2 1.2.0 1.2a.0 1.2.a 1.a 02.a ); 69 70 ... 71 72 use Sort::Versions; 73 print 'lower' if versioncmp('1.2', '1.2a') == -1; 74 75 ... 76 77 use Sort::Versions; 78 %h = (1 => 'd', 2 => 'c', 3 => 'b', 4 => 'a'); 79 @h = sort { versioncmp($h{$a}, $h{$b}) } keys %h; 80 81 =head1 DESCRIPTION 82 83 Sort::Versions allows easy sorting of mixed non-numeric and numeric strings, 84 like the 'version numbers' that many shared library systems and revision 85 control packages use. This is quite useful if you are trying to deal with 86 shared libraries. It can also be applied to applications that intersperse 87 variable-width numeric fields within text. Other applications can 88 undoubtedly be found. 89 90 For an explanation of the algorithm, it's simplest to look at these examples: 91 92 1.1 < 1.2 93 1.1a < 1.2 94 1.1 < 1.1.1 95 1.1 < 1.1a 96 1.1.a < 1.1a 97 1 < a 98 a < b 99 1 < 2 100 1.1-3 < 1.1-4 101 1.1-5 < 1.1.6 102 103 More precisely (but less comprehensibly), the two strings are treated 104 as subunits delimited by periods or hyphens. Each subunit can contain 105 any number of groups of digits or non-digits. If digit groups are 106 being compared on both sides, a numeric comparison is used, otherwise 107 a ASCII ordering is used. A group or subgroup with more units will win 108 if all comparisons are equal. A period binds digit groups together 109 more tightly than a hyphen. 110 111 Some packages use a different style of version numbering: a simple 112 real number written as a decimal. Sort::Versions has limited support 113 for this style: when comparing two subunits which are both digit 114 groups, if either subunit has a leading zero, then both are treated 115 like digits after a decimal point. So for example: 116 117 0002 < 1 118 1.06 < 1.5 119 120 This wonE<39>t always work, because there wonE<39>t always be a leading zero 121 in real-number style version numbers. There is no way for 122 Sort::Versions to know which style was intended. But a lot of the time 123 it will do the right thing. If you are making up version numbers, the 124 style with (possibly) more than one dot is the style to use. 125 126 =head1 USAGE 127 128 The function C<versioncmp()> takes two arguments and compares them like C<cmp>. 129 With perl 5.6 or later, you can also use this function directly in sorting: 130 131 @l = sort versioncmp qw(1.1 1.2 1.0.3); 132 133 The function C<versions()> can be used directly as a sort function even on 134 perl 5.005 and earlier, but its use is deprecated. 135 136 =head1 SEE ALSO 137 138 L<version>, L<CPAN::Version> which is part of the L<CPAN> distribution. 139 140 141 =head1 REPOSITORY 142 143 L<https://github.com/neilb/Sort-Versions> 144 145 =head1 AUTHOR 146 147 Ed Avis <ed@membled.com> and Matt Johnson <mwj99@doc.ic.ac.uk> for 148 recent releases; the original author is Kenneth J. Albanowski 149 <kjahds@kjahds.com>. Thanks to Hack Kampbjørn and Slaven Rezic for 150 patches and bug reports. 151 152 =head1 COPYRIGHT AND LICENSE 153 154 This software is copyright (c) 1996 by Kenneth J. Albanowski. 155 156 This is free software; you can redistribute it and/or modify it under 157 the same terms as the Perl 5 programming language system itself. 158 159 =cut 160 161 1; 162