#!/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
# dash doesnt support -e option so we have to split the line
# ugly, but the only way I know that is compatible.
[ "`echo \"$1
$2\" | sort | head -n 1`" = "$1" ] && 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=""
[ "$1" = "$2" ] && return 0
while [ "$a" = "$b" ] ; do
i=$(( $i + 1 ))
a=`echo $1 | cut -d . -f $i`
b=`echo $2 | cut -d . -f $i`
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 's/[0-9]//g'`
j=`echo "$b" | sed -s 's/[0-9]//g'`
strcmp "$i" "$j"
return
fi
# the digits are not equal, do normal integer compare
if [ "$i" -eq "$j" ] ; 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="" b="" i=0
[ "$1" = "$2" ] && return 0
# find first non equal suffix
while [ "$a" = "$b" ] ; do
i=$(( $i + 1 ))
a=`echo $1 | cut -d '_' -f $i`
b=`echo $2 | cut -d '_' -f $i`
# [ $i -ge 6 ] && return 13
done
# get the suffix weight
get_suff_weight "$a" && return 10
a=$?
get_suff_weight "$b" && return 10
b=$?
# compare the suffix weight
[ "$a" -lt "$b" ] && return 1
[ "$a" -gt "$b" ] && return 2
# the weight is equal. remove non-digits and dotcompare
dotcmp "`echo $1|sed 's/^[^0-9]*//'`" "`echo $2|sed 's/^[^0-9]*//'`"
}
# compare package version numbers (no package name)
# returns:
# 0: equal
# 1: less than
# 2: greater than
ver_cmp() {
local a b
# 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.*//'`
dotcmp "$a" "$b" || return
# get the suffix(es), without revision
a=`echo "$1" | sed 's/^[^_]*_*//; s/-r.*//'`
b=`echo "$2" | sed 's/^[^_]*_*//; s/-r.*//'`
suffcmp "$a" "$b" || return
# get the revision
a=`echo "$1" | sed 's/.*(-r)+//'`
b=`echo "$2" | sed 's/.*(-r)+//'`
dotcmp "$a" "$b"
}
# 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
local va=`echo "$1" | sed 's/.*-\([0-9].*\)/\1/'`
local vb=`echo "$2" | sed 's/.*-\([0-9].*\)/\1/'`
ver_cmp $va $vb
}
ver_cmp_operator() {
local retcode
ver_cmp_pkgv $1 $2
retcode=$?
case $retcode in
0) echo "=";;
1) echo "<";;
2) echo ">";;
*) echo "!";;
esac
return $retcode
}