mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Add number or str ZPP macros
This commit is contained in:
parent
53829b7daf
commit
80e90ad7ba
6 changed files with 194 additions and 1 deletions
74
Zend/tests/number_or_str_zpp.phpt
Normal file
74
Zend/tests/number_or_str_zpp.phpt
Normal file
|
@ -0,0 +1,74 @@
|
|||
--TEST--
|
||||
Test Z_PARAM_NUMBER_OR_STR() and Z_PARAM_NUMBER_OR_STR_OR_NULL
|
||||
--EXTENSIONS--
|
||||
zend_test
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Foo {}
|
||||
class ToString {
|
||||
public function __toString() {
|
||||
return "ToString";
|
||||
}
|
||||
}
|
||||
|
||||
var_dump(zend_number_or_string("string"));
|
||||
var_dump(zend_number_or_string(1));
|
||||
var_dump(zend_number_or_string(5.5));
|
||||
var_dump(zend_number_or_string(null));
|
||||
var_dump(zend_number_or_string(false));
|
||||
var_dump(zend_number_or_string(true));
|
||||
var_dump(zend_number_or_string(new ToString()));
|
||||
|
||||
try {
|
||||
zend_string_or_object([]);
|
||||
} catch (TypeError $exception) {
|
||||
echo $exception->getMessage() . "\n";
|
||||
}
|
||||
try {
|
||||
zend_number_or_string(new Foo());
|
||||
} catch (TypeError $exception) {
|
||||
echo $exception->getMessage() . "\n";
|
||||
}
|
||||
|
||||
var_dump(zend_number_or_string_or_null("string"));
|
||||
var_dump(zend_number_or_string_or_null(1));
|
||||
var_dump(zend_number_or_string_or_null(5.5));
|
||||
var_dump(zend_number_or_string_or_null(null));
|
||||
var_dump(zend_number_or_string_or_null(false));
|
||||
var_dump(zend_number_or_string_or_null(true));
|
||||
var_dump(zend_number_or_string_or_null(new ToString()));
|
||||
|
||||
try {
|
||||
zend_number_or_string_or_null([]);
|
||||
} catch (TypeError $exception) {
|
||||
echo $exception->getMessage() . "\n";
|
||||
}
|
||||
try {
|
||||
zend_number_or_string_or_null(new Foo());
|
||||
} catch (TypeError $exception) {
|
||||
echo $exception->getMessage() . "\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
string(6) "string"
|
||||
int(1)
|
||||
float(5.5)
|
||||
|
||||
Deprecated: zend_number_or_string(): Passing null to parameter #1 ($param) of type string|int|float is deprecated in %s on line %d
|
||||
int(0)
|
||||
int(0)
|
||||
int(1)
|
||||
string(8) "ToString"
|
||||
zend_string_or_object(): Argument #1 ($param) must be of type object|string, array given
|
||||
zend_number_or_string(): Argument #1 ($param) must be of type string|int|float, Foo given
|
||||
string(6) "string"
|
||||
int(1)
|
||||
float(5.5)
|
||||
NULL
|
||||
int(0)
|
||||
int(1)
|
||||
string(8) "ToString"
|
||||
zend_number_or_string_or_null(): Argument #1 ($param) must be of type string|int|float|null, array given
|
||||
zend_number_or_string_or_null(): Argument #1 ($param) must be of type string|int|float|null, Foo given
|
|
@ -674,6 +674,36 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest, u
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval **dest, uint32_t arg_num) /* {{{ */
|
||||
{
|
||||
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
|
||||
return false;
|
||||
}
|
||||
if (Z_TYPE_P(arg) < IS_TRUE) {
|
||||
if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("string|int|float", arg_num)) {
|
||||
return false;
|
||||
}
|
||||
ZVAL_LONG(arg, 0);
|
||||
} else if (Z_TYPE_P(arg) == IS_TRUE) {
|
||||
ZVAL_LONG(arg, 1);
|
||||
} else if (UNEXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
|
||||
zend_object *zobj = Z_OBJ_P(arg);
|
||||
zval obj;
|
||||
if (zobj->handlers->cast_object(zobj, &obj, IS_STRING) == SUCCESS) {
|
||||
OBJ_RELEASE(zobj);
|
||||
ZVAL_COPY_VALUE(arg, &obj);
|
||||
*dest = arg;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
*dest = arg;
|
||||
return true;
|
||||
}
|
||||
|
||||
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num) /* {{{ */
|
||||
{
|
||||
if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) {
|
||||
|
|
|
@ -1520,6 +1520,8 @@ static zend_always_inline zval *zend_try_array_init(zval *zv)
|
|||
_(Z_EXPECTED_DOUBLE_OR_NULL, "of type ?float") \
|
||||
_(Z_EXPECTED_NUMBER, "of type int|float") \
|
||||
_(Z_EXPECTED_NUMBER_OR_NULL, "of type int|float|null") \
|
||||
_(Z_EXPECTED_NUMBER_OR_STRING, "of type string|int|float") \
|
||||
_(Z_EXPECTED_NUMBER_OR_STRING_OR_NULL, "of type string|int|float|null") \
|
||||
_(Z_EXPECTED_ARRAY_OR_STRING, "of type array|string") \
|
||||
_(Z_EXPECTED_ARRAY_OR_STRING_OR_NULL, "of type array|string|null") \
|
||||
_(Z_EXPECTED_STRING_OR_LONG, "of type string|int") \
|
||||
|
@ -1891,6 +1893,20 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char *
|
|||
#define Z_PARAM_NUMBER(dest) \
|
||||
Z_PARAM_NUMBER_EX(dest, 0)
|
||||
|
||||
#define Z_PARAM_NUMBER_OR_STR_EX(dest, check_null) \
|
||||
Z_PARAM_PROLOGUE(0, 0); \
|
||||
if (UNEXPECTED(!zend_parse_arg_number_or_str(_arg, &dest, check_null, _i))) { \
|
||||
_expected_type = check_null ? Z_EXPECTED_NUMBER_OR_STRING_OR_NULL : Z_EXPECTED_NUMBER_OR_STRING; \
|
||||
_error_code = ZPP_ERROR_WRONG_ARG; \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define Z_PARAM_NUMBER_OR_STR(dest) \
|
||||
Z_PARAM_NUMBER_OR_STR_EX(dest, false)
|
||||
|
||||
#define Z_PARAM_NUMBER_OR_STR_OR_NULL(dest) \
|
||||
Z_PARAM_NUMBER_OR_STR_EX(dest, true)
|
||||
|
||||
/* old "o" */
|
||||
#define Z_PARAM_OBJECT_EX(dest, check_null, deref) \
|
||||
Z_PARAM_PROLOGUE(deref, 0); \
|
||||
|
@ -2145,6 +2161,7 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *
|
|||
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num);
|
||||
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num);
|
||||
ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest, uint32_t arg_num);
|
||||
ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval **dest, uint32_t arg_num);
|
||||
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long, uint32_t arg_num);
|
||||
|
||||
static zend_always_inline bool zend_parse_arg_bool(const zval *arg, bool *dest, bool *is_null, bool check_null, uint32_t arg_num)
|
||||
|
@ -2209,6 +2226,18 @@ static zend_always_inline bool zend_parse_arg_number(zval *arg, zval **dest, boo
|
|||
return 1;
|
||||
}
|
||||
|
||||
static zend_always_inline bool zend_parse_arg_number_or_str(zval *arg, zval **dest, bool check_null, uint32_t arg_num)
|
||||
{
|
||||
if (EXPECTED(Z_TYPE_P(arg) == IS_LONG || Z_TYPE_P(arg) == IS_DOUBLE || Z_TYPE_P(arg) == IS_STRING)) {
|
||||
*dest = arg;
|
||||
} else if (check_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
|
||||
*dest = NULL;
|
||||
} else {
|
||||
return zend_parse_arg_number_or_str_slow(arg, dest, arg_num);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static zend_always_inline bool zend_parse_arg_str(zval *arg, zend_string **dest, bool check_null, uint32_t arg_num)
|
||||
{
|
||||
if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
|
||||
|
|
|
@ -266,6 +266,50 @@ static ZEND_FUNCTION(zend_string_or_stdclass_or_null)
|
|||
}
|
||||
}
|
||||
|
||||
/* Tests Z_PARAM_NUMBER_OR_STR */
|
||||
static ZEND_FUNCTION(zend_number_or_string)
|
||||
{
|
||||
zval *input;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_NUMBER_OR_STR(input)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
switch (Z_TYPE_P(input)) {
|
||||
case IS_LONG:
|
||||
RETURN_LONG(Z_LVAL_P(input));
|
||||
case IS_DOUBLE:
|
||||
RETURN_DOUBLE(Z_DVAL_P(input));
|
||||
case IS_STRING:
|
||||
RETURN_STR_COPY(Z_STR_P(input));
|
||||
EMPTY_SWITCH_DEFAULT_CASE();
|
||||
}
|
||||
}
|
||||
|
||||
/* Tests Z_PARAM_NUMBER_OR_STR_OR_NULL */
|
||||
static ZEND_FUNCTION(zend_number_or_string_or_null)
|
||||
{
|
||||
zval *input;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_NUMBER_OR_STR_OR_NULL(input)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (!input) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
switch (Z_TYPE_P(input)) {
|
||||
case IS_LONG:
|
||||
RETURN_LONG(Z_LVAL_P(input));
|
||||
case IS_DOUBLE:
|
||||
RETURN_DOUBLE(Z_DVAL_P(input));
|
||||
case IS_STRING:
|
||||
RETURN_STR_COPY(Z_STR_P(input));
|
||||
EMPTY_SWITCH_DEFAULT_CASE();
|
||||
}
|
||||
}
|
||||
|
||||
static ZEND_FUNCTION(zend_weakmap_attach)
|
||||
{
|
||||
zval *value;
|
||||
|
|
|
@ -162,6 +162,10 @@ namespace {
|
|||
/** @param stdClass|string|null $param */
|
||||
function zend_string_or_stdclass_or_null($param): stdClass|string|null {}
|
||||
|
||||
function zend_number_or_string(string|int|float $param): string|int|float {}
|
||||
|
||||
function zend_number_or_string_or_null(string|int|float|null $param): string|int|float|null {}
|
||||
|
||||
function zend_iterable(iterable $arg1, ?iterable $arg2 = null): void {}
|
||||
|
||||
function zend_weakmap_attach(object $object, mixed $value): bool {}
|
||||
|
|
14
ext/zend_test/test_arginfo.h
generated
14
ext/zend_test/test_arginfo.h
generated
|
@ -1,5 +1,5 @@
|
|||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 58ae12118458386ab204a2400966c25c833baeae */
|
||||
* Stub hash: c526a3e961501a511b210eab38bb961ca61bb258 */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
@ -56,6 +56,14 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_zend_string_or_stdclass_or_n
|
|||
ZEND_ARG_INFO(0, param)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_zend_number_or_string, 0, 1, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE)
|
||||
ZEND_ARG_TYPE_MASK(0, param, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE, NULL)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_zend_number_or_string_or_null, 0, 1, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_NULL)
|
||||
ZEND_ARG_TYPE_MASK(0, param, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_NULL, NULL)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_iterable, 0, 1, IS_VOID, 0)
|
||||
ZEND_ARG_OBJ_TYPE_MASK(0, arg1, Traversable, MAY_BE_ARRAY, NULL)
|
||||
ZEND_ARG_OBJ_TYPE_MASK(0, arg2, Traversable, MAY_BE_ARRAY|MAY_BE_NULL, "null")
|
||||
|
@ -209,6 +217,8 @@ static ZEND_FUNCTION(zend_string_or_object);
|
|||
static ZEND_FUNCTION(zend_string_or_object_or_null);
|
||||
static ZEND_FUNCTION(zend_string_or_stdclass);
|
||||
static ZEND_FUNCTION(zend_string_or_stdclass_or_null);
|
||||
static ZEND_FUNCTION(zend_number_or_string);
|
||||
static ZEND_FUNCTION(zend_number_or_string_or_null);
|
||||
static ZEND_FUNCTION(zend_iterable);
|
||||
static ZEND_FUNCTION(zend_weakmap_attach);
|
||||
static ZEND_FUNCTION(zend_weakmap_remove);
|
||||
|
@ -272,6 +282,8 @@ static const zend_function_entry ext_functions[] = {
|
|||
ZEND_FE(zend_string_or_object_or_null, arginfo_zend_string_or_object_or_null)
|
||||
ZEND_FE(zend_string_or_stdclass, arginfo_zend_string_or_stdclass)
|
||||
ZEND_FE(zend_string_or_stdclass_or_null, arginfo_zend_string_or_stdclass_or_null)
|
||||
ZEND_FE(zend_number_or_string, arginfo_zend_number_or_string)
|
||||
ZEND_FE(zend_number_or_string_or_null, arginfo_zend_number_or_string_or_null)
|
||||
ZEND_FE(zend_iterable, arginfo_zend_iterable)
|
||||
ZEND_FE(zend_weakmap_attach, arginfo_zend_weakmap_attach)
|
||||
ZEND_FE(zend_weakmap_remove, arginfo_zend_weakmap_remove)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue