diff options
| -rw-r--r-- | package.xml | 2 | ||||
| -rw-r--r-- | rpminfo.c | 50 | ||||
| -rw-r--r-- | rpminfo.stub.php | 2 | ||||
| -rw-r--r-- | rpminfo_arginfo.h | 5 | ||||
| -rw-r--r-- | tests/002-rpmvercmp.phpt | 44 | ||||
| -rw-r--r-- | tests/010-rpmvercmp_error7.phpt | 10 | ||||
| -rw-r--r-- | tests/011-rpmvercmp_error8.phpt | 12 | 
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="/"> @@ -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 | 
