summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/pacman.8.txt2
-rw-r--r--lib/libalpm/package.c26
-rwxr-xr-xpactest/vercmptest.sh36
3 files changed, 48 insertions, 16 deletions
diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
index 9e56a54e..0a632ea9 100644
--- a/doc/pacman.8.txt
+++ b/doc/pacman.8.txt
@@ -67,7 +67,7 @@ You can also use `pacman -Su` to upgrade all packages that are out of date. See
to determine which packages need upgrading. This behavior operates as follows:
Alphanumeric:
- 1.0 < 1.0a < 1.0alpha < 1.0b < 1.0beta < 1.0p < 1.0pre < 1.0rc
+ 1.0a < 1.0alpha < 1.0b < 1.0beta < 1.0p < 1.0pre < 1.0rc < 1.0
Numeric:
1 < 1.0 < 1.1 < 1.1.1 < 1.2 < 2.0 < 3.0.0
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index 124d89a0..13d0ae3f 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -691,17 +691,13 @@ int SYMEXPORT alpm_pkg_vercmp(const char *a, const char *b)
if(*ptr1 == '-' && *ptr2 == '-') {
/* no-op, continue comparing since we are equivalent throughout */
} else if(*ptr1 == '-') {
- /* ptr1 has hit the pkgrel and ptr2 has not.
- * version 2 is newer iff we are not at the end of ptr2;
- * if we are at end then one version had pkgrel and one did not */
- ret = *ptr2 ? -1 : 0;
- goto cleanup;
+ /* ptr1 has hit the pkgrel and ptr2 has not. continue version
+ * comparison after stripping the pkgrel from ptr1. */
+ *ptr1 = '\0';
} else if(*ptr2 == '-') {
- /* ptr2 has hit the pkgrel and ptr1 has not.
- * version 1 is newer iff we are not at the end of ptr1;
- * if we are at end then one version had pkgrel and one did not */
- ret = *ptr1 ? 1 : 0;
- goto cleanup;
+ /* ptr2 has hit the pkgrel and ptr1 has not. continue version
+ * comparison after stripping the pkgrel from ptr2. */
+ *ptr2 = '\0';
}
}
@@ -713,8 +709,14 @@ int SYMEXPORT alpm_pkg_vercmp(const char *a, const char *b)
goto cleanup;
}
- /* whichever version still has characters left over wins */
- if (!*one) {
+ /* the final showdown. we never want a remaining alpha string to
+ * beat an empty string. the logic is a bit weird, but:
+ * - if one is empty and two is not an alpha, two is newer.
+ * - if one is an alpha, two is newer.
+ * - otherwise one is newer.
+ * */
+ if ( ( !*one && !isalpha((int)*two) )
+ || isalpha((int)*one) ) {
ret = -1;
} else {
ret = 1;
diff --git a/pactest/vercmptest.sh b/pactest/vercmptest.sh
index f8d457ee..e36bf4be 100755
--- a/pactest/vercmptest.sh
+++ b/pactest/vercmptest.sh
@@ -26,8 +26,9 @@ failure=0
# args:
# pass ver1 ver2 ret expected
pass() {
- echo "test: ver1: $1 ver2: $2 ret: $3 expected: $4"
- echo " --> pass"
+ #echo "test: ver1: $1 ver2: $2 ret: $3 expected: $4"
+ #echo " --> pass"
+ echo -n
}
# args:
@@ -54,13 +55,20 @@ runtest() {
ret=$($bin $2 $1)
func='pass'
[ $ret -eq $reverse ] || func='fail'
- $func $1 $2 $ret $reverse
+ $func $2 $1 $ret $reverse
total=$(expr $total + 1)
}
# use first arg as our binary if specified
[ -n "$1" ] && bin="$1"
+if [ ! -x "$bin" ]; then
+ echo "vercmp binary ($bin) could not be located"
+ exit 1
+fi
+
+echo "Beginning vercmp tests"
+
# BEGIN TESTS
# all similar length, no pkgrel
@@ -88,6 +96,28 @@ runtest 1.1-1 1.1 0
runtest 1.0-1 1.1 -1
runtest 1.1-1 1.0 1
+# alphanumeric versions
+runtest 1.5b-1 1.5-1 -1
+runtest 1.5b 1.5 -1
+runtest 1.5b-1 1.5 -1
+runtest 1.5b 1.5.1 -1
+
+# from the manpage
+runtest 1.0a 1.0alpha -1
+runtest 1.0alpha 1.0b -1
+runtest 1.0b 1.0beta -1
+runtest 1.0beta 1.0rc -1
+runtest 1.0rc 1.0 -1
+
+# going crazy? alpha-dotted versions
+runtest 1.5.a 1.5 1
+runtest 1.5.b 1.5.a 1
+runtest 1.5.1 1.5.b 1
+
+# alpha dots and dashes
+runtest 1.5.b-1 1.5.b 0
+runtest 1.5-1 1.5.b -1
+
#END TESTS
echo