package Netdisco::Util; =head2 sort_port( $a, $b ) Sort port names with the following formatting types: A5 5 FastEthernet0/1 FastEthernet0/1-atm 5.5 Port:3 Interface is as Perl's own C - two input args and an integer return value. Code taken from netdisco.pm. Thanks to Bradley Baetz (bbaetz) for improvements in this sub. =cut sub sort_port { my ($aval, $bval) = @_; my $numbers = qr{^(\d+)$}; my $numeric = qr{^([\d\.]+)$}; my $dotted_numeric = qr{^(\d+)\.(\d+)$}; my $letter_number = qr{^([a-zA-Z]+)(\d+)$}; my $wordcharword = qr{^([^:\/.]+)[\ :\/\.]+([^:\/.]+)(\d+)?$}; #port-channel45 my $ciscofast = qr{^ # Word Number slash (Gigabit0/) (\D+)(\d+)[\/:] # Groups of symbol float (/5.5/5.5/5.5), separated by slash or colon ([\/:\.\d]+) # Optional dash (-Bearer Channel) (-.*)? $}x; my @a = (); my @b = (); if ($aval =~ $dotted_numeric) { @a = ($1,$2); } elsif ($aval =~ $letter_number) { @a = ($1,$2); } elsif ($aval =~ $numbers) { @a = ($1); } elsif ($aval =~ $ciscofast) { @a = ($1,$2); push @a, split(/[:\/]/,$3), $4; } elsif ($aval =~ $wordcharword) { @a = ($1,$2,$3); } else { @a = ($aval); } if ($bval =~ $dotted_numeric) { @b = ($1,$2); } elsif ($bval =~ $letter_number) { @b = ($1,$2); } elsif ($bval =~ $numbers) { @b = ($1); } elsif ($bval =~ $ciscofast) { @b = ($1,$2); push @b, split(/[:\/]/,$3),$4; } elsif ($bval =~ $wordcharword) { @b = ($1,$2,$3); } else { @b = ($bval); } # Equal until proven otherwise my $val = 0; while (scalar(@a) or scalar(@b)){ # carried around from the last find. last if $val != 0; my $a1 = shift @a; my $b1 = shift @b; # A has more components - loses unless (defined $b1){ $val = 1; last; } # A has less components - wins unless (defined $a1) { $val = -1; last; } if ($a1 =~ $numeric and $b1 =~ $numeric){ $val = $a1 <=> $b1; } elsif ($a1 ne $b1) { $val = $a1 cmp $b1; } } return $val; } 1;