Changes between Initial Version and Version 1 of VersionPathSorter


Ignore:
Timestamp:
02/09/14 09:04:49 (4 years ago)
Author:
Bluefin Tuna
Comment:

Sorting the BOINC git tags

Legend:

Unmodified
Added
Removed
Modified
  • VersionPathSorter

    v1 v1  
     1{{{
     2#!/usr/bin/perl -w
     3
     4use strict;
     5
     6# Read all lines from STDIN or file
     7
     8my @lines = <>;
     9
     10# Remove terminating newline from each line
     11
     12foreach (@lines) {
     13   chomp
     14}
     15
     16# Function to compare version numbers like "7.1.2"
     17
     18sub compare_version_numbers {
     19   my ($l,$r) = @_;
     20   my @lx = split("\\.",$l);
     21   my @rx = split("\\.",$r);
     22   my $minlen = (@lx < @rx) ? @lx : @rx;
     23   for (my $i=0; $i < $minlen; $i++) {
     24      # make numeric by multiplying with 1
     25      my $l_number = ($lx[$i] * 1);
     26      my $r_number = ($rx[$i] * 1);
     27      # compare with spaceship operator
     28      my $l_vs_r = ($l_number <=> $r_number);
     29      # return if decision is clear!
     30      if ($l_vs_r != 0) {
     31         return $l_vs_r
     32      }
     33      # otherwise, next part in array of version numbers
     34   }
     35   # if we are here, we could not decide - shortest entry wins!
     36   return @lx <=> @rx
     37}
     38
     39# Function to compare whole paths like "client_release/7.2/7.2.25"
     40# As it is called from "sort", the values are passed in via "$a" and "$b"
     41
     42sub compare_paths {
     43   my @ax = split("/",$a);
     44   my @bx = split("/",$b);
     45   my $minlen = (@ax < @bx) ? @ax : @bx;
     46   for (my $i=0; $i < $minlen; $i++) {
     47      # Check whether we have version numbers at position $i
     48      my $a_is_vnum = ($ax[$i] =~ /^[\d\.]+$/);
     49      my $b_is_vnum = ($bx[$i] =~ /^[\d\.]+$/);
     50      if ($a_is_vnum && !$b_is_vnum) {
     51         # "a" version number before "b": b wins
     52         return 1
     53      }
     54      if (!$a_is_vnum && $b_is_vnum) {
     55         # "b" is version number before "a": a wins
     56         return -1
     57      }
     58      if (!$a_is_vnum && !$b_is_vnum && $ax[$i] ne $bx[$i]) {
     59         # both are not version numbers and both are unequal: compare the strings
     60         return $ax[$i] cmp $bx[$i]
     61      }
     62      if ($a_is_vnum && $b_is_vnum && $ax[$i] ne $bx[$i]) {
     63         # both are unequal version numbers: compare the version number
     64         # print STDERR $ax[$i] . " vs " . $bx[$i];
     65         my $sn = compare_version_numbers($ax[$i],$bx[$i]);
     66         # print STDERR " = " . $sn . "\n";
     67         if ($sn != 0) {
     68            return $sn
     69         }
     70      }
     71      # otherwise, next part in array of path elements
     72   }
     73   # if we are here, we could not decide - shortest entry wins!
     74   return @ax <=> @bx
     75}
     76
     77# Sort and print
     78
     79my @sorted = sort compare_paths @lines;
     80
     81foreach (@sorted) {
     82   print "$_\n"
     83}
     84}}}