Filename | /usr/share/perl5/Sort/Versions.pm |
Statements | Executed 14 statements in 665µs |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 81µs | 86µs | BEGIN@8 | Sort::Versions::
1 | 1 | 1 | 28µs | 28µs | BEGIN@7 | Sort::Versions::
1 | 1 | 1 | 10µs | 44µs | BEGIN@9 | Sort::Versions::
1 | 1 | 1 | 9µs | 27µs | BEGIN@55 | Sort::Versions::
0 | 0 | 0 | 0s | 0s | versioncmp | Sort::Versions::
0 | 0 | 0 | 0s | 0s | versions | Sort::Versions::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Sort::Versions; | ||||
2 | 1 | 300ns | $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 | 2 | 63µs | 1 | 28µs | # spent 28µs within Sort::Versions::BEGIN@7 which was called:
# once (28µs+0s) by RBM::BEGIN@19 at line 7 # spent 28µs making 1 call to Sort::Versions::BEGIN@7 |
8 | 2 | 97µs | 2 | 91µs | # spent 86µs (81+5) within Sort::Versions::BEGIN@8 which was called:
# once (81µs+5µs) by RBM::BEGIN@19 at line 8 # spent 86µs making 1 call to Sort::Versions::BEGIN@8
# spent 5µs making 1 call to strict::import |
9 | 2 | 390µs | 2 | 79µs | # spent 44µs (10+34) within Sort::Versions::BEGIN@9 which was called:
# once (10µs+34µs) by RBM::BEGIN@19 at line 9 # spent 44µs making 1 call to Sort::Versions::BEGIN@9
# spent 34µs making 1 call to warnings::import |
10 | |||||
11 | 1 | 300ns | require Exporter; | ||
12 | 1 | 6µs | our @ISA = qw(Exporter); | ||
13 | 1 | 500ns | our @EXPORT = qw(&versions &versioncmp); | ||
14 | 1 | 200ns | 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 | 2 | 102µs | 2 | 45µs | # spent 27µs (9+18) within Sort::Versions::BEGIN@55 which was called:
# once (9µs+18µs) by RBM::BEGIN@19 at line 55 # spent 27µs making 1 call to Sort::Versions::BEGIN@55
# spent 18µs making 1 call to strict::unimport |
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 | 5µs | 1; | ||
162 |