summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Gnatenko <i.gnatenko.brain@gmail.com>2016-09-10 11:39:23 +0200
committerIgor Gnatenko <ignatenko@redhat.com>2016-09-12 16:15:34 +0200
commit6210269ee960e39a4320e3b9a4fdc2adb9827d0d (patch)
tree612e7a1f17414308975faa509343dbe447c451c5
parent19dbaff8dd051688c0acf1b6605bf13a7fe019bd (diff)
downloadrpm-plus.tar.gz
Add support for sorting caret ('^') higher than base versionplus
1.1^20160101 means 1.1 version (base) and patches which were applied at that date on top of it. * 1.1^201601 > 1.1 * 1.1^201601 < 1.1.1 Second case might be fulfilled with tilde separator, but it's not obvious and doesn't fulfil first case. Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
-rw-r--r--build/pack.c10
-rw-r--r--lib/rpmds.c3
-rw-r--r--lib/rpmvercmp.c18
-rw-r--r--tests/rpmvercmp.at26
4 files changed, 52 insertions, 5 deletions
diff --git a/build/pack.c b/build/pack.c
index 82c12624e..80a1c90d7 100644
--- a/build/pack.c
+++ b/build/pack.c
@@ -280,12 +280,12 @@ exit:
return rc;
}
-static int haveTildeDep(Package pkg)
+static int haveCharInDep(Package pkg, char c)
{
for (int i = 0; i < PACKAGE_NUM_DEPS; i++) {
rpmds ds = rpmdsInit(pkg->dependencies[i]);
while (rpmdsNext(ds) >= 0) {
- if (strchr(rpmdsEVR(ds), '~'))
+ if (strchr(rpmdsEVR(ds), c))
return 1;
}
}
@@ -392,9 +392,13 @@ static rpmRC writeRPM(Package pkg, unsigned char ** pkgidp,
}
/* check if the package has a dependency with a '~' */
- if (haveTildeDep(pkg))
+ if (haveCharInDep(pkg, '~'))
(void) rpmlibNeedsFeature(pkg, "TildeInVersions", "4.10.0-1");
+ /* check if the package has a dependency with a '^' */
+ if (haveCharInDep(pkg, '^'))
+ (void) rpmlibNeedsFeature(pkg, "CaretInVersions", "4.14.0-1");
+
/* check if the package has a rich dependency */
if (haveRichDep(pkg))
(void) rpmlibNeedsFeature(pkg, "RichDependencies", "4.12.0-1");
diff --git a/lib/rpmds.c b/lib/rpmds.c
index 04be01266..abbc6ef6f 100644
--- a/lib/rpmds.c
+++ b/lib/rpmds.c
@@ -1272,6 +1272,9 @@ static const struct rpmlibProvides_s rpmlibProvides[] = {
{ "rpmlib(TildeInVersions)", "4.10.0-1",
( RPMSENSE_EQUAL),
N_("dependency comparison supports versions with tilde.") },
+ { "rpmlib(CaretInVersions)", "4.14.0-1",
+ ( RPMSENSE_EQUAL),
+ N_("dependency comparison supports versions with caret.") },
{ "rpmlib(LargeFiles)", "4.12.0-1",
( RPMSENSE_EQUAL),
N_("support files larger than 4GB") },
diff --git a/lib/rpmvercmp.c b/lib/rpmvercmp.c
index b3d08faa4..db51cadf1 100644
--- a/lib/rpmvercmp.c
+++ b/lib/rpmvercmp.c
@@ -33,8 +33,8 @@ int rpmvercmp(const char * a, const char * b)
/* loop through each version segment of str1 and str2 and compare them */
while (*one || *two) {
- while (*one && !risalnum(*one) && *one != '~') one++;
- while (*two && !risalnum(*two) && *two != '~') two++;
+ while (*one && !risalnum(*one) && *one != '~' && *one != '^') one++;
+ while (*two && !risalnum(*two) && *two != '~' && *two != '^') two++;
/* handle the tilde separator, it sorts before everything else */
if (*one == '~' || *two == '~') {
@@ -45,6 +45,20 @@ int rpmvercmp(const char * a, const char * b)
continue;
}
+ /*
+ * Handle caret separator. Concept is same as tilde, except if one of
+ * strings ends (base version), another considered as higher version.
+ */
+ if (*one == '^' || *two == '^') {
+ if (!*one) return -1;
+ if (!*two) return 1;
+ if (*one != '^') return 1;
+ if (*two != '^') return -1;
+ one++;
+ two++;
+ continue;
+ }
+
/* If we ran to the end of either, we are finished with the loop */
if (!(*one && *two)) break;
diff --git a/tests/rpmvercmp.at b/tests/rpmvercmp.at
index 2a25bdd9b..a5b63ba83 100644
--- a/tests/rpmvercmp.at
+++ b/tests/rpmvercmp.at
@@ -100,6 +100,32 @@ RPMVERCMP(1.0~rc1~git123, 1.0~rc1~git123, 0)
RPMVERCMP(1.0~rc1~git123, 1.0~rc1, -1)
RPMVERCMP(1.0~rc1, 1.0~rc1~git123, 1)
+dnl Basic testcases for caret sorting
+RPMVERCMP(1.0^, 1.0^, 0)
+RPMVERCMP(1.0^, 1.0, 1)
+RPMVERCMP(1.0, 1.0^, -1)
+RPMVERCMP(1.0^git1, 1.0^git1, 0)
+RPMVERCMP(1.0^git1, 1.0, 1)
+RPMVERCMP(1.0, 1.0^git1, -1)
+RPMVERCMP(1.0^git1, 1.0^git2, -1)
+RPMVERCMP(1.0^git2, 1.0^git1, 1)
+RPMVERCMP(1.0^git1, 1.01, -1)
+RPMVERCMP(1.01, 1.0^git1, 1)
+RPMVERCMP(1.0^20160101, 1.0^20160101, 0)
+RPMVERCMP(1.0^20160101, 1.0.1, -1)
+RPMVERCMP(1.0.1, 1.0^20160101, 1)
+RPMVERCMP(1.0^20160101^git1, 1.0^20160101^git1, 0)
+RPMVERCMP(1.0^20160102, 1.0^20160101^git1, 1)
+RPMVERCMP(1.0^20160101^git1, 1.0^20160102, -1)
+
+dnl Basic testcases for tilde and caret sorting
+RPMVERCMP(1.0~rc1^git1, 1.0~rc1^git1, 0)
+RPMVERCMP(1.0~rc1^git1, 1.0~rc1, 1)
+RPMVERCMP(1.0~rc1, 1.0~rc1^git1, -1)
+RPMVERCMP(1.0^git1~pre, 1.0^git1~pre, 0)
+RPMVERCMP(1.0^git1, 1.0^git1~pre, 1)
+RPMVERCMP(1.0^git1~pre, 1.0^git1, -1)
+
dnl These are included here to document current, arguably buggy behaviors
dnl for reference purposes and for easy checking against unintended
dnl behavior changes.