| Filename | /usr/share/perl5/Sort/Versions.pm |
| Statements | Executed 14 statements in 602µs |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 26µs | 26µs | Sort::Versions::BEGIN@7 |
| 1 | 1 | 1 | 9µs | 26µs | Sort::Versions::BEGIN@55 |
| 1 | 1 | 1 | 8µs | 13µs | Sort::Versions::BEGIN@8 |
| 1 | 1 | 1 | 8µs | 40µs | Sort::Versions::BEGIN@9 |
| 0 | 0 | 0 | 0s | 0s | Sort::Versions::versioncmp |
| 0 | 0 | 0 | 0s | 0s | Sort::Versions::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 | 53µs | 1 | 26µs | # spent 26µs within Sort::Versions::BEGIN@7 which was called:
# once (26µs+0s) by RBM::BEGIN@19 at line 7 # spent 26µs making 1 call to Sort::Versions::BEGIN@7 |
| 8 | 2 | 19µs | 2 | 17µs | # spent 13µs (8+4) within Sort::Versions::BEGIN@8 which was called:
# once (8µs+4µs) by RBM::BEGIN@19 at line 8 # spent 13µs making 1 call to Sort::Versions::BEGIN@8
# spent 4µs making 1 call to strict::import |
| 9 | 2 | 421µs | 2 | 72µs | # spent 40µs (8+32) within Sort::Versions::BEGIN@9 which was called:
# once (8µs+32µs) by RBM::BEGIN@19 at line 9 # spent 40µs making 1 call to Sort::Versions::BEGIN@9
# spent 32µs making 1 call to warnings::import |
| 10 | |||||
| 11 | 1 | 500ns | require Exporter; | ||
| 12 | 1 | 5µ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 | 99µs | 2 | 44µs | # spent 26µs (9+18) within Sort::Versions::BEGIN@55 which was called:
# once (9µs+18µs) by RBM::BEGIN@19 at line 55 # spent 26µ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 | 4µs | 1; | ||
| 162 |