sbotools2

Maintenance fork of the original sbotools version 2
git clone git://git.server.ky/slackcoder/sbotools2
Log | Files | Refs | README

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