From 5b4b47fb26b07c12dc440acdbc8004081cb52b75 Mon Sep 17 00:00:00 2001
From: Xavier Chantry <shiningxc@gmail.com>
Date: Thu, 17 Jul 2008 13:26:44 +0200
Subject: [PATCH] versioncmp : fix handling of alphanumeric versions.

Commit 84283672853350a84d2a71b72dc06e180cad1587 introduced another regression
related to alphanumeric versions.
Before we had 1.5b < 1.5, 1.5rc < 1.5, etc.. but this is no longer the case.
This patch reintroduce the old behavior.

Ref: http://archlinux.org/pipermail/pacman-dev/2008-June/012126.html

Signed-off-by: Xavier Chantry <shiningxc@gmail.com>
---
 doc/pacman.8.txt      |    2 +-
 lib/libalpm/package.c |   29 +++++++++++++++++++----------
 pactest/vercmptest.sh |    6 ++++++
 3 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt
index 9e56a54..0a632ea 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 124d89a..9153f05 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -692,15 +692,22 @@ int SYMEXPORT alpm_pkg_vercmp(const char *a, const char *b)
 			/* 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 not at the end of ptr2, then version 2 is older
+			 * if ptr2 starts with a letter, and newer otherwise;
 			 * if we are at end then one version had pkgrel and one did not */
-			ret = *ptr2 ? -1 : 0;
+			if(*ptr2) {
+				ret = isalpha(*ptr2) ? 1 : -1;
+			} else {
+				ret = 0;
+			}
 			goto cleanup;
 		} 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;
+			/* exact symmetric of the above casse */
+			if(*ptr1) {
+				ret = isalpha(*ptr1) ? -1 : 1;
+			} else {
+				ret = 0;
+			}
 			goto cleanup;
 		}
 	}
@@ -713,11 +720,13 @@ int SYMEXPORT alpm_pkg_vercmp(const char *a, const char *b)
 		goto cleanup;
 	}
 
-	/* whichever version still has characters left over wins */
-	if (!*one) {
-		ret = -1;
+	/* libalpm modified code. only one of the versions has some characters left,
+	 * but we want to handle differently numbers and letters. For example,
+	 * we want 1.0rc < 1.0 but 1.0r2 > 1.0r */
+	if (*one) {
+		ret = isalpha(*one) ? -1 : 1;
 	} else {
-		ret = 1;
+		ret = isalpha(*two) ? 1 : -1;
 	}
 
 cleanup:
diff --git a/pactest/vercmptest.sh b/pactest/vercmptest.sh
index f8d457e..43ea767 100755
--- a/pactest/vercmptest.sh
+++ b/pactest/vercmptest.sh
@@ -88,6 +88,12 @@ 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
+
 #END TESTS
 
 echo
-- 
1.5.6

