############################################################################### # SUB: compareNumbers # PURPOSE: compare epoch/version/release numbers arg2 with arg1 # # ARGS: arg1 - first number # arg2 - second number # # NOTES: we split the number string into an array using either # a dot '.' or an underscore '_' (I haven't seen any with # a dash '-') # RETURNS: $arg2 is: -1=older than; 0=same as; 1=newer then; 2=strange ############################################################################### sub compareNumbers { $arg1 = $_[0]; $arg2 = $_[1]; $aSize = 20; ## arbitrary maximum number of fields in the split below @ver = split /(?<=\d)(?=[a-zA-Z])|(?<=[a-zA-Z])(?=\d)|\.|_/, $arg1, $aSize; @nver = split /(?<=\d)(?=[a-zA-Z])|(?<=[a-zA-Z])(?=\d)|\.|_/, $arg2, $aSize; $n = ($#ver <= $#nver) ? $#ver : $#nver; $n = ($n < $aSize) ? $n : $aSize; ## number of elements for for-loop $ret = 2; ## default is '2=strange' ## loop over version/release numbers and compare for( $i=0; $i <= $n; $i++ ) { $p = $ver[$i]; $q = $nver[$i]; if( POSIX::isdigit($p) && POSIX::isdigit($q) ) { if( ($ret = $q <=> $p) != 0 ) { ## break out if not the same last; } } else { ## not completely numeric, so treat like strings ## According to the sources for rpm, we can treat these ## elements with alphanumeric comparisons if( ($ret = $q cmp $p) != 0 ) { ## break out if not the same last; } } } ## in case the numbers are the same so far, but one had more elements: if( $ret == 0 ) { if( $#ver != $#nver ) { $ret = ($#ver > $#nver) ? -1 : 1; } } return( $ret ); } # COMPARES name-$arg3-$arg4 to name-$arg1-$arg2 # RETURNS: -1=older than, 0=same as; 1=newer than; # 2=strange # SUMMARY: name-$arg3-$arg4 is name-$arg1-$arg2. sub compareVR { ($verone,$relone,$vertwo,$reltwo) = @_; $ret = 2; $verstat=&compareNumbers($verone,$vertwo); # if both versions are not equal, our result is the result of the # version comparison. if (($verstat == 1) or ($verstat == -1)) { $ret = $verstat; }; # if both versions are equal, our result is the result of the release # comparison if ($verstat == 0) { $ret=&compareNumbers($relone,$reltwo); }; return( $ret ); };