home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / perl / Versions.pm < prev    next >
Encoding:
Perl POD Document  |  2003-08-24  |  4.2 KB  |  152 lines

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