File Coverage

blib/lib/Sort/Versions.pm
Criterion Covered Total %
statement 34 36 94.4
branch 19 22 86.3
condition 13 15 86.6
subroutine 6 6 100.0
pod 0 2 0.0
total 72 81 88.8


line stmt bran cond sub pod time code
1             package Sort::Versions;
2             $Sort::Versions::VERSION = '1.60';
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 1     1   1343 use 5.006;
  1         4  
  1         38  
8 1     1   5 use strict;
  1         2  
  1         27  
9 1     1   4 use warnings;
  1         5  
  1         698  
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 127     127 0 2335 my @A = ($_[0] =~ /([-.]|\d+|[^-.\d]+)/g);
18 127         710 my @B = ($_[1] =~ /([-.]|\d+|[^-.\d]+)/g);
19              
20 127         163 my ($A, $B);
21 127   66     529 while (@A and @B) {
22 394         527 $A = shift @A;
23 394         432 $B = shift @B;
24 394 100 100     3277 if ($A eq '-' and $B eq '-') {
    100 100        
    50 100        
    100          
    100          
    50          
    100          
25 24         83 next;
26             } elsif ( $A eq '-' ) {
27 28         121 return -1;
28             } elsif ( $B eq '-') {
29 0         0 return 1;
30             } elsif ($A eq '.' and $B eq '.') {
31 90         310 next;
32             } elsif ( $A eq '.' ) {
33 12         59 return -1;
34             } elsif ( $B eq '.' ) {
35 0         0 return 1;
36             } elsif ($A =~ /^\d+$/ and $B =~ /^\d+$/) {
37 204 100 66     756 if ($A =~ /^0/ || $B =~ /^0/) {
38 8 50       48 return $A cmp $B if $A cmp $B;
39             } else {
40 196 100       1035 return $A <=> $B if $A <=> $B;
41             }
42             } else {
43 36         52 $A = uc $A;
44 36         41 $B = uc $B;
45 36 100       277 return $A cmp $B if $A cmp $B;
46             }
47             }
48 27         133 @A <=> @B;
49             }
50              
51             sub versions() {
52 63     63 0 14022 my $callerpkg = (caller)[0];
53 63         156 my $caller_a = "${callerpkg}::a";
54 63         92 my $caller_b = "${callerpkg}::b";
55 1     1   5 no strict 'refs';
  1         1  
  1         74  
56 63         223 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 takes two arguments and compares them like C.
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 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, L which is part of the L distribution.
139              
140              
141             =head1 REPOSITORY
142              
143             L
144              
145             =head1 AUTHOR
146              
147             Ed Avis and Matt Johnson for
148             recent releases; the original author is Kenneth J. Albanowski
149             . 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