|  | 1 | {{{ | 
                          |  | 2 | #!/usr/bin/perl -w | 
                          |  | 3 |  | 
                          |  | 4 | use strict; | 
                          |  | 5 |  | 
                          |  | 6 | # Read all lines from STDIN or file | 
                          |  | 7 |  | 
                          |  | 8 | my @lines = <>; | 
                          |  | 9 |  | 
                          |  | 10 | # Remove terminating newline from each line | 
                          |  | 11 |  | 
                          |  | 12 | foreach (@lines) { | 
                          |  | 13 | chomp | 
                          |  | 14 | } | 
                          |  | 15 |  | 
                          |  | 16 | # Function to compare version numbers like "7.1.2" | 
                          |  | 17 |  | 
                          |  | 18 | sub 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 |  | 
                          |  | 42 | sub 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 |  | 
                          |  | 79 | my @sorted = sort compare_paths @lines; | 
                          |  | 80 |  | 
                          |  | 81 | foreach (@sorted) { | 
                          |  | 82 | print "$_\n" | 
                          |  | 83 | } | 
                          |  | 84 | }}} |