#!/bin/sh
# Copyright (c) 2005 Natanael Copa
# GPL-2
# string compare
# return: 0=equal; 1=less; 2=greater than
strcmp() {
[ "$1" = "$2" ] && return 0
# use sort and check who is on the first line
echo -e "$1\n$2" | sort -c 2>/dev/null && return 1
return 2
}
# compare x.y.z style version numbers (no suffix, no revision)
# returns: 0=equal; 1=less than; 2=greater than
dotcmp() {
local i=0 j
local a="" b=""
local ra="$1"
local rb="$2"
[ "$1" = "$2" ] && return 0
while [ "$a" = "$b" ] ; do
# get field, split by '.'
# i=$(( $i + 1 ))
# a=`echo $1 | awk -F . '{print $'"$i"'}'`
# b=`echo $2 | awk -F . '{print $'"$i"'}'`
# same as above but no forks
a=${ra%%.*}
b=${rb%%.*}
ra=${ra#$a}
rb=${rb#$b}
ra=${ra#.}
rb=${rb#.}
done
# check for empty strings before comparing integers
[ -z "$a" ] && return 1 # $1 < $2
[ -z "$b" ] && return 2 # $1 > $2
# remove all non digits to differ between foo-1.0a and foo-1.0b
i=`echo "$a" | sed 's/[^0-9]//g'`
j=`echo "$b" | sed 's/[^0-9]//g'`
# if the integer part is equal, we have to str compare the nondigits
if [ "$i" = "$j" ] ; then
i=`echo "$a" | sed 's/[0-9]//g'`
j=`echo "$b" | sed 's/[0-9]//g'`
strcmp "$i" "$j"
return
fi
# if digit start with '0', string compare
if [ "$i" != "${i##0}" ] || [ "$j" != "${j##0}" ] ; then
# handle weird case: foo-1.01 < foo-1.1
strcmp "$i" "$j"
return
elif [ "$i" -lt "$j" ]; then
return 1
else
return 2
fi
}
# determine the suffix weight
# based on the gentoo ebuild policy
# http://www.gentoo.org/proj/en/devrel/handbook/handbook.xml?part=3&chap=1#doc_chap3
get_suff_weight() {
case "$1" in
alpha|alpha[0-9]*) return 1;;
beta|beta[0-9]*) return 2;;
pre|pre[0-9]*) return 3;;
rc|rc[0-9]*) return 4;;
"") return 5;;
p|p[0-9]*) return 6;;
# cvs|cvs[0-9]*) return 7;;
*) return 0;;
esac
}
suffcmp() {
local a="${1#_}"
local b="${2#_}"
local wa wb
[ "$a" = "$b" ] && return 0
# get the suffix weight
#get_suff_weight "$a" && return 10
get_suff_weight "${a}" && return 10
wa=$?
#get_suff_weight "$b" && return 10
get_suff_weight "${b}" && return 10
wb=$?
# compare the suffix weight
[ "$wa" -lt "$wb" ] && return 1
[ "$wa" -gt "$wb" ] && return 2
# the weight is equal. remove non-digits and dotcompare
#dotcmp "`echo $1|sed 's/^[^0-9]*//'`" "`echo $2|sed 's/^[^0-9]*//'`"
dotcmp "${a##*[a-z]}" "${b##*[a-z]}"
}
# compare package version numbers (no package name)
# returns:
# 0: equal
# 1: less than
# 2: greater than
ver_cmp() {
local a b va vb sa sb
# if equal, return
[ "$1" = "$2" ] && return 0
# get version part, without suffix or revision
#a=`echo "$1" | sed 's/_.*//; s/-r.*//'`
#b=`echo "$2" | sed 's/_.*//; s/-r.*//'`
a="${1%%_*}"
b="${2%%_*}"
va="${a%%-r*}"
vb="${b%%-r*}"
dotcmp "${va}" "${vb}" || return
# get the suffix(es), without revision
#a=`echo "$1" | sed 's/^[^_]*_*//; s/-r.*//'`
#b=`echo "$2" | sed 's/^[^_]*_*//; s/-r.*//'`
a="${1#${va}}"
b="${2#${va}}"
sa="${a%%-r*}"
sb="${b%%-r*}"
suffcmp "${sa}" "${sb}" || return
# get the revision
#a=`echo "$1" | sed 's/.*(-r)+//'`
#b=`echo "$2" | sed 's/.*(-r)+//'`
#dotcmp "$a" "$b"
a=${a#${sa}} # remove suffix
b=${b#${sb}} # remove suffix
a=${a##*-r} # remove -r
b=${b##*-r} # remove -r
# no revision is the same as -r0
dotcmp "${a:-0}" "${b:-0}"
}
# compare 2 package names with version
# returns:
# 0: equal
# 1: less than
# 2: greater than
# 10: invalid suffix
# 11: invalid package comparation
ver_cmp_pkgv() {
#local pa=`echo "$1" | sed 's/\(.*\)-[0-9].*/\1/'`
#local pb=`echo "$2" | sed 's/\(.*\)-[0-9].*/\1/'`
#[ "$pa" != "$pb" ] && return 11
# abort if the package name is not the same
local pa="${1%-[0-9]*}"
local pb="${2%-[0-9]*}"
[ "$pa" != "$pb" ] && return 11
#local va=`echo "$1" | sed 's/.*-\([0-9].*\)/\1/'`
#local vb=`echo "$2" | sed 's/.*-\([0-9].*\)/\1/'`
#ver_cmp $va $vb
ver_cmp "${1#${pa}-}" "${2#${pb}-}"
}
ver_cmp_operator() {
local retcode
ver_cmp_pkgv $1 $2
retcode=$?
case $retcode in
0) echo "=";;
1) echo "<";;
2) echo ">";;
*) echo "!";;
esac
return $retcode
}