summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemi Collet <remi@remirepo.net>2023-09-11 10:21:36 +0200
committerRemi Collet <remi@php.net>2023-09-11 10:21:36 +0200
commit64504e8b8fb097d6e849953eb0e4721321c41a27 (patch)
tree6d993631f655de280efa8b6db1c664f0294ae39b
parent1662502e7dc10dcd4f17eb304486e2058cbb1d5a (diff)
add optional operator to rpmcmpver for consistency with version_compare
-rw-r--r--package.xml2
-rw-r--r--rpminfo.c50
-rw-r--r--rpminfo.stub.php2
-rw-r--r--rpminfo_arginfo.h5
-rw-r--r--tests/002-rpmvercmp.phpt44
-rw-r--r--tests/010-rpmvercmp_error7.phpt10
-rw-r--r--tests/011-rpmvercmp_error8.phpt12
7 files changed, 106 insertions, 19 deletions
diff --git a/package.xml b/package.xml
index 38dc60e..4756ce4 100644
--- a/package.xml
+++ b/package.xml
@@ -24,7 +24,7 @@ Documentation: https://www.php.net/rpminfo
</stability>
<license uri="https://www.php.net/license/3_01.txt" filesource="LICENSE">PHP-3.01</license>
<notes>
--
+- add optional operator to rpmcmpver for consistency with version_compare
</notes>
<contents>
<dir name="/">
diff --git a/rpminfo.c b/rpminfo.c
index 53b9c6c..1ba0123 100644
--- a/rpminfo.c
+++ b/rpminfo.c
@@ -37,6 +37,11 @@
#define ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, type_hint, allow_null, default_value) \
ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null)
#endif
+/* only used for rpmvercmp */
+#ifndef ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX
+#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(name, return_reference, required_num_args, type) \
+ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, IS_LONG, 0)
+#endif
#ifndef RETURN_THROWS
#define RETURN_THROWS() return
@@ -469,10 +474,11 @@ PHP_FUNCTION(rpmvercmp)
char *in_evr1, *evr1, *v1, *r1;
char *in_evr2, *evr2, *v2, *r2;
char *p, empty[] = "";
+ char *op = NULL;
long e1, e2, r;
- size_t len1, len2;
+ size_t len1, len2, oplen;
- if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &in_evr1, &len1, &in_evr2, &len2) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|s", &in_evr1, &len1, &in_evr2, &len2, &op, &oplen) == FAILURE) {
RETURN_THROWS();
}
evr1 = estrdup(in_evr1);
@@ -498,9 +504,9 @@ PHP_FUNCTION(rpmvercmp)
e2 = 0;
}
if (e1 < e2) {
- RETVAL_LONG(-1);
+ r = -1;
} else if (e1 > e2) {
- RETVAL_LONG(1);
+ r = 1;
} else {
// Version
p = strchr(v1, '-');
@@ -518,16 +524,44 @@ PHP_FUNCTION(rpmvercmp)
r2 = empty;
}
r = rpmvercmp(v1, v2);
- if (r) {
- RETVAL_LONG(r);
- } else {
+ if (!r) {
// Release
r = rpmvercmp(r1, r2);
- RETVAL_LONG(r);
}
}
efree(evr1);
efree(evr2);
+
+ if (!op) {
+ RETURN_LONG(r);
+ }
+
+ if (!strcmp(op, "<") || !strcmp(op, "lt")) {
+ RETURN_BOOL(r < 0);
+ }
+ if (!strcmp(op, "<=") || !strcmp(op, "le")) {
+ RETURN_BOOL(r <= 0);
+ }
+ if (!strcmp(op, ">") || !strcmp(op, "gt")) {
+ RETURN_BOOL(r > 0);
+ }
+ if (!strcmp(op, ">=") || !strcmp(op, "ge")) {
+ RETURN_BOOL(r >= 0);
+ }
+ if (!strcmp(op, "==") || !strcmp(op, "=") || !strcmp(op, "eq")) {
+ RETURN_BOOL(r == 0);
+ }
+ if (!strcmp(op, "!=") || !strcmp(op, "<>") || !strcmp(op, "ne")) {
+ RETURN_BOOL(r != 0);
+ }
+
+#if PHP_VERSION_ID < 80000
+ php_error_docref(NULL, E_WARNING, "%s is not a valid comparison operator", op);
+ RETURN_NULL();
+#else
+ zend_argument_value_error(3, "must be a valid comparison operator");
+ RETURN_THROWS();
+#endif
}
/* }}} */
diff --git a/rpminfo.stub.php b/rpminfo.stub.php
index 543cc5f..022ccd4 100644
--- a/rpminfo.stub.php
+++ b/rpminfo.stub.php
@@ -10,6 +10,6 @@ function rpmdbsearch(string $pattern, int $rpmtag = RPMTAG_NAME, int $rpmmire =
function rpminfo(string $path, bool $full = false, ?string &$error = null): Array|null {}
-function rpmvercmp(string $evr1, string $evr2): int {}
+function rpmvercmp(string $evr1, string $evr2, ?string $operator = null): int|bool {}
diff --git a/rpminfo_arginfo.h b/rpminfo_arginfo.h
index 20c501f..03fa650 100644
--- a/rpminfo_arginfo.h
+++ b/rpminfo_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 6b4dfeada2b5de5c5453d2b38c1a861e01bf958e */
+ * Stub hash: 8636be19a4c17d1ed16247fb265a923ee7c89104 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rpmaddtag, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, rpmtag, IS_LONG, 0)
@@ -23,9 +23,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rpminfo, 0, 1, IS_ARRAY, 1)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(1, error, IS_STRING, 1, "null")
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rpmvercmp, 0, 2, IS_LONG, 0)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_rpmvercmp, 0, 2, MAY_BE_LONG|MAY_BE_BOOL)
ZEND_ARG_TYPE_INFO(0, evr1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, evr2, IS_STRING, 0)
+ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, operator, IS_STRING, 1, "null")
ZEND_END_ARG_INFO()
diff --git a/tests/002-rpmvercmp.phpt b/tests/002-rpmvercmp.phpt
index d83cf67..c53a183 100644
--- a/tests/002-rpmvercmp.phpt
+++ b/tests/002-rpmvercmp.phpt
@@ -29,11 +29,53 @@ $ok = true;
foreach ($cases as $case) {
list($a,$b,$expected) = $case;
$result = rpmvercmp($a,$b);
- if ($result != $expected) {
+ if ($result !== $expected) {
$ok = false;
printf("rpmvercmp(%s, %s) = %d when %d expected\n", $a, $b, $result, $expected);
}
}
+
+$cases = [
+ ['1', '2', '>', false],
+ ['1', '2', 'gt', false],
+ ['1', '2', '>=', false],
+ ['1', '2', 'ge', false],
+ ['1', '1', '>=', true],
+ ['1', '1', 'ge', true],
+
+ ['1', '2', '<', true],
+ ['1', '2', 'lt', true],
+ ['1', '2', '<=', true],
+ ['1', '2', 'le', true],
+ ['1', '1', '<=', true],
+ ['1', '1', 'le', true],
+
+ ['1', '1', '=', true],
+ ['1', '1', '==', true],
+ ['1', '1', 'eq', true],
+
+ ['1', '2', '=', false],
+ ['1', '2', '==', false],
+ ['1', '2', 'eq', false],
+
+ ['1', '1', '!=', false],
+ ['1', '1', '<>', false],
+ ['1', '1', 'ne', false],
+
+ ['1', '2', '!=', true],
+ ['1', '2', '<>', true],
+ ['1', '2', 'ne', true],
+];
+foreach ($cases as $case) {
+ list($a,$b,$op,$expected) = $case;
+ $result = rpmvercmp($a,$b,$op);
+ if ($result !== $expected) {
+ $ok = false;
+ printf("rpmvercmp(%s, %s, %s) = %s when %s expected\n",
+ $a, $b, $op, $result ? "true" : "false", $expected ? "true" : "false");
+ }
+}
+
if ($ok) echo "OK\n";
?>
Done
diff --git a/tests/010-rpmvercmp_error7.phpt b/tests/010-rpmvercmp_error7.phpt
index c9b3875..2d5c220 100644
--- a/tests/010-rpmvercmp_error7.phpt
+++ b/tests/010-rpmvercmp_error7.phpt
@@ -10,16 +10,20 @@ if (PHP_VERSION_ID >= 80000) print "skip only for PHP 7";
var_dump(rpmvercmp());
var_dump(rpmvercmp("a"));
var_dump(rpmvercmp("a", "b", "c"));
+var_dump(rpmvercmp("a", "b", "c", "d"));
?>
Done
--EXPECTF--
-Warning: rpmvercmp() expects exactly 2 parameters, 0 given in %s
+Warning: rpmvercmp() expects at least 2 parameters, 0 given in %s
NULL
-Warning: rpmvercmp() expects exactly 2 parameters, 1 given in %s
+Warning: rpmvercmp() expects at least 2 parameters, 1 given in %s
NULL
-Warning: rpmvercmp() expects exactly 2 parameters, 3 given in %s
+Warning: rpmvercmp(): c is not a valid comparison operator in %s
+NULL
+
+Warning: rpmvercmp() expects at most 3 parameters, 4 given in %s
NULL
Done
diff --git a/tests/011-rpmvercmp_error8.phpt b/tests/011-rpmvercmp_error8.phpt
index 4430975..2fe6aa1 100644
--- a/tests/011-rpmvercmp_error8.phpt
+++ b/tests/011-rpmvercmp_error8.phpt
@@ -19,13 +19,19 @@ try {
}
try {
var_dump(rpmvercmp("a", "b", "c"));
+} catch (ValueError $e) {
+ echo $e->getMessage(), "\n";
+}
+try {
+ var_dump(rpmvercmp("a", "b", "c", "d"));
} catch (ArgumentCountError $e) {
echo $e->getMessage(), "\n";
}
?>
Done
--EXPECTF--
-rpmvercmp() expects exactly 2 %s, 0 given
-rpmvercmp() expects exactly 2 %s, 1 given
-rpmvercmp() expects exactly 2 %s, 3 given
+rpmvercmp() expects at least 2 %s, 0 given
+rpmvercmp() expects at least 2 %s, 1 given
+rpmvercmp(): Argument #3 ($operator) must be a valid comparison operator
+rpmvercmp() expects at most 3 %s, 4 given
Done