[php] Generate PHP type declarations

We now automatically generate PHP type declarations for PHP >= 8.0.

The generated code still compiles with PHP 7.x but without type declarations.
This commit is contained in:
Olly Betts 2022-01-20 10:07:44 +13:00 committed by GitHub
commit 1f1349741f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 536 additions and 196 deletions

View file

@ -4,6 +4,11 @@
* PHP configuration file
* ----------------------------------------------------------------------------- */
// Default to generating PHP type declarations (for PHP >= 8) except for
// cases which are liable to cause compatibility issues with existing
// bindings.
%feature("php:type", "compat");
%runtime "swigrun.swg" // Common C API type-checking code
%runtime "swigerrors.swg" // SWIG errors
%runtime "phprun.swg" // PHP runtime functions
@ -34,56 +39,56 @@
%include <utils.i>
%pass_by_val(bool,CONVERT_BOOL_IN);
%pass_by_val(bool, "bool", CONVERT_BOOL_IN);
%pass_by_val(size_t, CONVERT_INT_IN);
%pass_by_val(size_t, "int", CONVERT_INT_IN);
%pass_by_val(enum SWIGTYPE, CONVERT_INT_IN);
%pass_by_val(enum SWIGTYPE, "int", CONVERT_INT_IN);
%pass_by_val(signed int, CONVERT_INT_IN);
%pass_by_val(int,CONVERT_INT_IN);
%pass_by_val(unsigned int,CONVERT_INT_IN);
%pass_by_val(signed int, "int", CONVERT_INT_IN);
%pass_by_val(int,"int", CONVERT_INT_IN);
%pass_by_val(unsigned int,"int", CONVERT_INT_IN);
%pass_by_val(signed short, CONVERT_INT_IN);
%pass_by_val(short,CONVERT_INT_IN);
%pass_by_val(unsigned short, CONVERT_INT_IN);
%pass_by_val(signed short, "int", CONVERT_INT_IN);
%pass_by_val(short,"int", CONVERT_INT_IN);
%pass_by_val(unsigned short, "int", CONVERT_INT_IN);
%pass_by_val(signed long, CONVERT_INT_IN);
%pass_by_val(long, CONVERT_INT_IN);
%pass_by_val(unsigned long, CONVERT_INT_IN);
%pass_by_val(signed long, "int", CONVERT_INT_IN);
%pass_by_val(long, "int", CONVERT_INT_IN);
%pass_by_val(unsigned long, "int", CONVERT_INT_IN);
%pass_by_val(signed long long, CONVERT_LONG_LONG_IN);
%pass_by_val(long long, CONVERT_LONG_LONG_IN);
%pass_by_val(unsigned long long, CONVERT_UNSIGNED_LONG_LONG_IN);
%pass_by_val(signed long long, "int|string", CONVERT_LONG_LONG_IN);
%pass_by_val(long long, "int|string", CONVERT_LONG_LONG_IN);
%pass_by_val(unsigned long long, "int|string", CONVERT_UNSIGNED_LONG_LONG_IN);
%pass_by_val(signed char, CONVERT_INT_IN);
%pass_by_val(char, CONVERT_CHAR_IN);
%pass_by_val(unsigned char, CONVERT_INT_IN);
%pass_by_val(signed char, "int", CONVERT_INT_IN);
%pass_by_val(char, "string", CONVERT_CHAR_IN);
%pass_by_val(unsigned char, "int", CONVERT_INT_IN);
%pass_by_val(float, CONVERT_FLOAT_IN);
%pass_by_val(float, "float", CONVERT_FLOAT_IN);
%pass_by_val(double, CONVERT_FLOAT_IN);
%pass_by_val(double, "float", CONVERT_FLOAT_IN);
%pass_by_val(char *, CONVERT_STRING_IN);
%pass_by_val(char *, "string", CONVERT_STRING_IN);
%typemap(in) char *& = const char *&;
%typemap(directorout) char *& = const char *&;
// char array can be in/out, though the passed string may not be big enough...
// so we have to size it
%typemap(in) char[ANY]
%typemap(in, phptype="string") char[ANY]
%{
convert_to_string(&$input);
$1 = ($1_ltype) Z_STRVAL($input);
%}
%typemap(in) (char *STRING, int LENGTH), (char *STRING, size_t LENGTH) %{
%typemap(in, phptype="string") (char *STRING, int LENGTH), (char *STRING, size_t LENGTH) %{
convert_to_string(&$input);
$1 = ($1_ltype) Z_STRVAL($input);
$2 = ($2_ltype) Z_STRLEN($input);
%}
/* Object passed by value. Convert to a pointer */
%typemap(in) SWIGTYPE ($&1_ltype tmp)
%typemap(in, phptype="SWIGTYPE") SWIGTYPE ($&1_ltype tmp)
%{
if (SWIG_ConvertPtr(&$input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL) {
zend_type_error("Expected $&1_descriptor for argument $argnum of $symname");
@ -101,7 +106,7 @@
$result = *tmp;
%}
%typemap(in) SWIGTYPE *,
%typemap(in, phptype="?SWIGTYPE") SWIGTYPE *,
SWIGTYPE []
%{
if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0) {
@ -120,7 +125,7 @@
swig_acquire_ownership_obj((void*)$result, own);
%}
%typemap(in) SWIGTYPE &,
%typemap(in, phptype="SWIGTYPE") SWIGTYPE &,
SWIGTYPE &&
%{
if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) {
@ -139,7 +144,7 @@
$result = tmp;
%}
%typemap(in) SWIGTYPE *const& ($*ltype temp)
%typemap(in, phptype="?SWIGTYPE") SWIGTYPE *const& ($*ltype temp)
%{
if (SWIG_ConvertPtr(&$input, (void **) &temp, $*1_descriptor, 0) < 0) {
zend_type_error("Expected $*1_descriptor for argument $argnum of $symname");
@ -148,7 +153,7 @@
$1 = ($1_ltype)&temp;
%}
%typemap(in) SWIGTYPE *DISOWN
%typemap(in, phptype="?SWIGTYPE") SWIGTYPE *DISOWN
%{
if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, SWIG_POINTER_DISOWN) < 0) {
zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
@ -161,7 +166,7 @@
SWIGTYPE &,
SWIGTYPE &&;
%typemap(in) void *
%typemap(in, phptype="?SWIGTYPE") void *
%{
if (SWIG_ConvertPtr(&$input, (void **) &$1, 0, 0) < 0) {
/* Allow NULL from php for void* */
@ -176,7 +181,7 @@
/* Special case when void* is passed by reference so it can be made to point
to opaque api structs */
%typemap(in, byref=1) void ** ($*1_ltype ptr, int force),
%typemap(in, phptype="?SWIG\\_p_void", byref=1) void ** ($*1_ltype ptr, int force),
void *& ($*1_ltype ptr, int force)
{
/* If they pass NULL by reference, make it into a void*
@ -211,7 +216,8 @@
/* Typemap for output values */
%typemap(out) int,
%typemap(out, phptype="int")
int,
unsigned int,
short,
unsigned short,
@ -224,12 +230,12 @@
RETVAL_LONG($1);
%}
%typemap(out) enum SWIGTYPE
%typemap(out, phptype="int") enum SWIGTYPE
%{
RETVAL_LONG((long)$1);
%}
%typemap(out) long long
%typemap(out, phptype="int|string") long long
%{
if ((long long)LONG_MIN <= $1 && $1 <= (long long)LONG_MAX) {
RETVAL_LONG((long)($1));
@ -239,7 +245,7 @@
RETVAL_STRING(temp);
}
%}
%typemap(out) unsigned long long
%typemap(out, phptype="int|string") unsigned long long
%{
if ($1 <= (unsigned long long)LONG_MAX) {
RETVAL_LONG((long)($1));
@ -250,7 +256,8 @@
}
%}
%typemap(out) const int &,
%typemap(out, phptype="int")
const int &,
const unsigned int &,
const short &,
const unsigned short &,
@ -264,17 +271,17 @@
RETVAL_LONG(*$1);
%}
%typemap(out) const enum SWIGTYPE &
%typemap(out, phptype="int") const enum SWIGTYPE &
%{
RETVAL_LONG((long)*$1);
%}
%typemap(out) const enum SWIGTYPE &&
%typemap(out, phptype="int") const enum SWIGTYPE &&
%{
RETVAL_LONG((long)*$1);
%}
%typemap(out) const long long &
%typemap(out, phptype="int|string") const long long &
%{
if ((long long)LONG_MIN <= *$1 && *$1 <= (long long)LONG_MAX) {
RETVAL_LONG((long)(*$1));
@ -284,7 +291,7 @@
RETVAL_STRING(temp);
}
%}
%typemap(out) const unsigned long long &
%typemap(out, phptype="int|string") const unsigned long long &
%{
if (*$1 <= (unsigned long long)LONG_MAX) {
RETVAL_LONG((long)(*$1));
@ -323,12 +330,12 @@
}
%}
%typemap(out) bool
%typemap(out, phptype="bool") bool
%{
RETVAL_BOOL(($1) ? 1 : 0);
%}
%typemap(out) const bool &
%typemap(out, phptype="bool") const bool &
%{
RETVAL_BOOL((*$1) ? 1 : 0);
%}
@ -338,13 +345,13 @@
ZVAL_BOOL($input, ($1) ? 1 : 0);
%}
%typemap(out) float,
%typemap(out, phptype="float") float,
double
%{
RETVAL_DOUBLE($1);
%}
%typemap(out) const float &,
%typemap(out, phptype="float") const float &,
const double &
%{
RETVAL_DOUBLE(*$1);
@ -356,18 +363,22 @@
ZVAL_DOUBLE($input, $1);
%}
%typemap(out) char
%typemap(out, phptype="string") char
%{
RETVAL_STRINGL(&$1, 1);
%}
%typemap(out) const char &
%typemap(out, phptype="string") const char &
%{
RETVAL_STRINGL(&*$1, 1);
%}
%typemap(out) char *,
char []
%typemap(out, phptype="string") char []
%{
RETVAL_STRING((const char *)$1);
%}
%typemap(out, phptype="?string") char *
%{
if (!$1) {
RETVAL_NULL();
@ -376,7 +387,7 @@
}
%}
%typemap(out) char *&
%typemap(out, phptype="?string") char *&
%{
if (!*$1) {
RETVAL_NULL();
@ -385,7 +396,12 @@
}
%}
%typemap(out) SWIGTYPE *,
%typemap(out, phptype="?SWIGTYPE") SWIGTYPE *
%{
SWIG_SetPointerZval($result, (void *)$1, $1_descriptor, $owner);
%}
%typemap(out, phptype="SWIGTYPE")
SWIGTYPE [],
SWIGTYPE &,
SWIGTYPE &&
@ -393,7 +409,7 @@
SWIG_SetPointerZval($result, (void *)$1, $1_descriptor, $owner);
%}
%typemap(out) SWIGTYPE *const&
%typemap(out, phptype="?SWIGTYPE") SWIGTYPE *const&
%{
SWIG_SetPointerZval($result, (void *)*$1, $*1_descriptor, $owner);
%}
@ -406,27 +422,32 @@
SWIG_SetPointerZval($input, (void *)&$1, $1_descriptor, $owner);
%}
%typemap(out) SWIGTYPE (CLASS::*)
%typemap(out, phptype="SWIGTYPE") SWIGTYPE (CLASS::*)
{
void * p = emalloc(sizeof($1));
memcpy(p, &$1, sizeof($1));
SWIG_SetPointerZval($result, (void *)p, $&1_descriptor, 1);
}
%typemap(in) SWIGTYPE (CLASS::*)
%typemap(in, phptype="SWIGTYPE") SWIGTYPE (CLASS::*)
{
void * p = SWIG_Z_FETCH_OBJ_P(&$input)->ptr;
memcpy(&$1, p, sizeof($1));
}
%typemap(out) SWIGTYPE *DYNAMIC,
SWIGTYPE &DYNAMIC
%typemap(out, phptype="?SWIGTYPE") SWIGTYPE *DYNAMIC
{
swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1);
SWIG_SetPointerZval($result, (void *)$1, ty, $owner);
}
%typemap(out) SWIGTYPE
%typemap(out, phptype="SWIGTYPE") SWIGTYPE &DYNAMIC
{
swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1);
SWIG_SetPointerZval($result, (void *)$1, ty, $owner);
}
%typemap(out, phptype="SWIGTYPE") SWIGTYPE
{
#ifdef __cplusplus
$&1_ltype resultobj = new $1_ltype((const $1_ltype &) $1);
@ -442,9 +463,9 @@
SWIG_SetPointerZval($input, SWIG_as_voidptr(new $1_ltype((const $1_ltype &)$1)), $&1_descriptor, 1);
%}
%typemap(out) void "";
%typemap(out, phptype="void") void "";
%typemap(out) char [ANY]
%typemap(out, phptype="string") char [ANY]
{
size_t len = 0;
while (len < $1_dim0 && $1[len]) ++len;