aboutsummaryrefslogtreecommitdiff
path: root/Lib/php
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/php')
-rw-r--r--Lib/php/argcargv.i38
-rw-r--r--Lib/php/const.i68
-rw-r--r--Lib/php/director.swg48
-rw-r--r--Lib/php/factory.i70
-rw-r--r--Lib/php/globalvar.i293
-rw-r--r--Lib/php/php.swg342
-rw-r--r--Lib/php/phpinit.swg19
-rw-r--r--Lib/php/phpinterfaces.i60
-rw-r--r--Lib/php/phpkw.swg60
-rw-r--r--Lib/php/phppointers.i48
-rw-r--r--Lib/php/phprun.swg271
-rw-r--r--Lib/php/std_auto_ptr.i41
-rw-r--r--Lib/php/std_common.i1
-rw-r--r--Lib/php/std_map.i19
-rw-r--r--Lib/php/std_string.i75
-rw-r--r--Lib/php/std_string_view.i69
-rw-r--r--Lib/php/std_unique_ptr.i41
-rw-r--r--Lib/php/std_vector.i2
-rw-r--r--Lib/php/stl.i1
-rw-r--r--Lib/php/swigmove.i24
-rw-r--r--Lib/php/typemaps.i60
-rw-r--r--Lib/php/utils.i33
22 files changed, 884 insertions, 799 deletions
diff --git a/Lib/php/argcargv.i b/Lib/php/argcargv.i
new file mode 100644
index 000000000..2a0d745de
--- /dev/null
+++ b/Lib/php/argcargv.i
@@ -0,0 +1,38 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+%typemap(in) (int ARGC, char **ARGV) {
+ int len, i;
+ zval *val;
+ zend_array *ar;
+ if (Z_TYPE($input) != IS_ARRAY) {
+ SWIG_PHP_Error(E_ERROR, "Type error in '$symname'. Expected array");
+ goto fail;
+ }
+ ar = Z_ARR($input);
+ len = zend_array_count(ar);
+ $1 = ($1_ltype) len;
+ $2 = (char **) malloc((len+1)*sizeof(char *));
+ i = 0;
+ ZEND_HASH_FOREACH_VAL(ar, val) {
+ if (Z_TYPE(*val) != IS_STRING) {
+ SWIG_PHP_Error(E_ERROR, "Array must use strings only, in '$symname'.");
+ goto fail;
+ }
+ if (i == len) {
+ SWIG_PHP_Error(E_ERROR, "Array is bigger than zend report in '$symname'.");
+ goto fail;
+ }
+ $2[i++] = Z_STRVAL(*val);
+ } ZEND_HASH_FOREACH_END();
+ $2[i] = NULL;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+ $1 = Z_TYPE($input) == IS_ARRAY;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+ free((void *)$2);
+}
diff --git a/Lib/php/const.i b/Lib/php/const.i
index 32b4b9b0b..1e1fe9cad 100644
--- a/Lib/php/const.i
+++ b/Lib/php/const.i
@@ -3,6 +3,58 @@
*
* Typemaps for constants
* ----------------------------------------------------------------------------- */
+%typemap(classconsttab) int,
+ unsigned int,
+ short,
+ unsigned short,
+ long,
+ unsigned long,
+ unsigned char,
+ signed char,
+ enum SWIGTYPE %{
+ zend_declare_class_constant_long(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, ($1_type)($value));
+%}
+
+%typemap(classconsttab) bool %{
+ zend_declare_class_constant_bool(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, ($1_type)($value));
+%}
+
+%typemap(classconsttab) float,
+ double %{
+ zend_declare_class_constant_double(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, $value);
+%}
+
+%typemap(classconsttab) char %{
+{
+ char swig_char = $value;
+ zend_declare_class_constant_stringl(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, &swig_char, 1);
+}
+%}
+
+%typemap(classconsttab) char *,
+ const char *,
+ char [],
+ const char [] %{
+ zend_declare_class_constant_string(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, $value);
+%}
+
+// This creates a zend_object to wrap the pointer, and we can't do that
+// before the Zend runtime has been initialised so we delay it until
+// RINIT. The downside is it then happens for every request.
+%typemap(classconsttab,rinit=1) SWIGTYPE *,
+ SWIGTYPE &,
+ SWIGTYPE &&,
+ SWIGTYPE [] %{
+{
+ zval z;
+ ZVAL_UNDEF(&z);
+ SWIG_SetPointerZval(&z, (void*)($value), $1_descriptor, 0);
+ zval_copy_ctor(&z);
+ zend_declare_class_constant(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, &z);
+}
+%}
+
+%typemap(classconsttab) SWIGTYPE (CLASS::*) ""
%typemap(consttab) int,
unsigned int,
@@ -13,10 +65,10 @@
unsigned char,
signed char,
enum SWIGTYPE
- "SWIG_LONG_CONSTANT($symname, ($1_type)$value);";
+ "SWIG_LONG_CONSTANT($symname, ($1_type)($value));";
%typemap(consttab) bool
- "SWIG_BOOL_CONSTANT($symname, ($1_type)$value);";
+ "SWIG_BOOL_CONSTANT($symname, ($1_type)($value));";
%typemap(consttab) float,
double
@@ -31,17 +83,21 @@
const char []
"SWIG_STRING_CONSTANT($symname, $value);";
-%typemap(consttab) SWIGTYPE *,
+// This creates a zend_object to wrap the pointer, and we can't do that
+// before the Zend runtime has been initialised so we delay it until
+// RINIT. The downside is it then happens for every request.
+%typemap(consttab,rinit=1) SWIGTYPE *,
SWIGTYPE &,
SWIGTYPE &&,
SWIGTYPE [] {
zend_constant c;
- SWIG_SetPointerZval(&c.value, (void*)$value, $1_descriptor, 0);
+ ZVAL_UNDEF(&c.value);
+ SWIG_SetPointerZval(&c.value, (void*)($value), $1_descriptor, 0);
zval_copy_ctor(&c.value);
c.name = zend_string_init("$symname", sizeof("$symname") - 1, 0);
- SWIG_ZEND_CONSTANT_SET_FLAGS(&c, CONST_CS, module_number);
+ ZEND_CONSTANT_SET_FLAGS(&c, CONST_CS, module_number);
zend_register_constant(&c);
}
/* Handled as a global variable. */
-%typemap(consttab) SWIGTYPE (CLASS::*) "";
+%typemap(consttab) SWIGTYPE (CLASS::*) ""
diff --git a/Lib/php/director.swg b/Lib/php/director.swg
index ea0eba8ac..55ffff516 100644
--- a/Lib/php/director.swg
+++ b/Lib/php/director.swg
@@ -8,6 +8,8 @@
#ifndef SWIG_DIRECTOR_PHP_HEADER_
#define SWIG_DIRECTOR_PHP_HEADER_
+#define SWIG_DIRECTOR_CAST(ARG) dynamic_cast<Swig::Director *>(ARG)
+
#include <string>
#include <exception>
#include <map>
@@ -76,31 +78,34 @@ namespace Swig {
};
class Director {
+ private:
+ /* flag indicating whether the object is owned by PHP or C++ */
+ mutable bool swig_disown_flag;
+
protected:
// "mutable" so we can get a non-const pointer to it in const methods.
mutable zval swig_self;
typedef std::map<void *, GCItem_var> swig_ownership_map;
mutable swig_ownership_map swig_owner;
+
public:
- Director(zval *self) {
+ Director(zval *self) : swig_disown_flag(false) {
ZVAL_COPY_VALUE(&swig_self, self);
}
- static bool swig_is_overridden_method(const char *cname, const char *lc_fname) {
- bool result = false;
- zend_string * cname_str = zend_string_init(cname, strlen(cname), 0);
- zend_class_entry *ce = zend_lookup_class(cname_str);
- if (ce) {
- zval * mptr = zend_hash_str_find(&ce->function_table, lc_fname, strlen(lc_fname));
- if (mptr) {
- // common.scope points to zend_class_entry for the declaring class,
- // and there's only one of those per class, so we can just use a
- // pointer compare here.
- result = Z_FUNC_P(mptr)->common.scope != ce;
- }
+ ~Director() {
+ if (swig_disown_flag) {
+ Z_DELREF(swig_self);
+ }
+ }
+
+ zend_object *swig_get_self() const { return Z_OBJ(swig_self); }
+
+ void swig_disown() const {
+ if (!swig_disown_flag) {
+ swig_disown_flag = true;
+ Z_ADDREF(swig_self);
}
- zend_string_release(cname_str);
- return result;
}
template <typename Type>
@@ -109,6 +114,12 @@ namespace Swig {
swig_owner[vptr] = new GCItem_T<Type>(vptr);
}
}
+
+ void swig_acquire_ownership_obj(void *vptr, int own) const {
+ if (vptr && own) {
+ swig_owner[vptr] = new GCItem_Object(own);
+ }
+ }
};
/* base class for director exceptions */
@@ -121,8 +132,8 @@ namespace Swig {
swig_msg += " ";
swig_msg += msg;
}
- SWIG_ErrorCode() = code;
- SWIG_ErrorMsg() = swig_msg.c_str();
+ // Don't replace an already active PHP exception.
+ if (!EG(exception)) zend_throw_exception(NULL, swig_msg.c_str(), code);
}
virtual ~DirectorException() throw() {
@@ -150,8 +161,7 @@ namespace Swig {
};
/* any php exception that occurs during a director method call */
- class DirectorMethodException : public DirectorException
- {
+ class DirectorMethodException : public DirectorException {
public:
DirectorMethodException()
: DirectorException(E_ERROR, "SWIG director method error", NULL) {
diff --git a/Lib/php/factory.i b/Lib/php/factory.i
index c4e082dd2..5f2b397ec 100644
--- a/Lib/php/factory.i
+++ b/Lib/php/factory.i
@@ -3,41 +3,41 @@
you have:
---- geometry.h --------
- struct Geometry {
- enum GeomType{
- POINT,
- CIRCLE
- };
-
- virtual ~Geometry() {}
+ struct Geometry {
+ enum GeomType{
+ POINT,
+ CIRCLE
+ };
+
+ virtual ~Geometry() {}
virtual int draw() = 0;
-
+
//
// Factory method for all the Geometry objects
//
- static Geometry *create(GeomType i);
- };
-
- struct Point : Geometry {
- int draw() { return 1; }
- double width() { return 1.0; }
- };
-
- struct Circle : Geometry {
- int draw() { return 2; }
- double radius() { return 1.5; }
- };
-
+ static Geometry *create(GeomType i);
+ };
+
+ struct Point : Geometry {
+ int draw() { return 1; }
+ double width() { return 1.0; }
+ };
+
+ struct Circle : Geometry {
+ int draw() { return 2; }
+ double radius() { return 1.5; }
+ };
+
//
// Factory method for all the Geometry objects
//
Geometry *Geometry::create(GeomType type) {
- switch (type) {
- case POINT: return new Point();
- case CIRCLE: return new Circle();
- default: return 0;
- }
- }
+ switch (type) {
+ case POINT: return new Point();
+ case CIRCLE: return new Circle();
+ default: return 0;
+ }
+ }
---- geometry.h --------
@@ -57,16 +57,16 @@
NOTES: remember to fully qualify all the type names and don't
use %factory inside a namespace declaration, ie, instead of
-
+
namespace Foo {
%factory(Geometry *Geometry::create, Point, Circle);
}
use
- %factory(Foo::Geometry *Foo::Geometry::create, Foo::Point, Foo::Circle);
+ %factory(Foo::Geometry *Foo::Geometry::create, Foo::Point, Foo::Circle);
+
-
*/
/* for loop for macro with one argument */
@@ -90,20 +90,20 @@
/* for loop for macro with two arguments */
%define %formacro_2(macro,...)%_formacro_2(macro, __VA_ARGS__, __fordone__)%enddef
-%define %_factory_dispatch(Type)
+%define %_factory_dispatch(Type)
if (!dcast) {
Type *dobj = dynamic_cast<Type *>($1);
if (dobj) {
dcast = 1;
- SWIG_SetPointerZval(return_value, SWIG_as_voidptr(dobj),$descriptor(Type *), $owner);
- }
+ SWIG_SetPointerZval(return_value, SWIG_as_voidptr(dobj), $descriptor(Type *), $owner);
+ }
}%enddef
%define %factory(Method,Types...)
-%typemap(out) Method {
+%typemap(out, phptype="?SWIGTYPE") Method {
int dcast = 0;
%formacro(%_factory_dispatch, Types)
if (!dcast) {
- SWIG_SetPointerZval(return_value, SWIG_as_voidptr($1),$descriptor, $owner);
+ SWIG_SetPointerZval(return_value, SWIG_as_voidptr($1), $descriptor, $owner);
}
}%enddef
diff --git a/Lib/php/globalvar.i b/Lib/php/globalvar.i
deleted file mode 100644
index 6b31207a6..000000000
--- a/Lib/php/globalvar.i
+++ /dev/null
@@ -1,293 +0,0 @@
-/* -----------------------------------------------------------------------------
- * globalvar.i
- *
- * Global variables - add the variable to PHP
- * ----------------------------------------------------------------------------- */
-
-%typemap(varinit) char *
-{
- zval z_var;
- if ($1) {
- ZVAL_STRING(&z_var, $1);
- } else {
- ZVAL_STR(&z_var, ZSTR_EMPTY_ALLOC());
- }
- zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) char []
-{
- zval z_var;
- ZVAL_STRING(&z_var, $1);
- zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) int,
- unsigned int,
- unsigned short,
- short,
- unsigned short,
- long,
- unsigned long,
- signed char,
- unsigned char,
- enum SWIGTYPE
-{
- zval z_var;
- ZVAL_LONG(&z_var, (long)$1);
- zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) bool
-{
- zval z_var;
- ZVAL_BOOL(&z_var, ($1)?1:0);
- zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) float, double
-{
- zval z_var;
- ZVAL_DOUBLE(&z_var, (double)$1);
- zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) char
-{
- zval z_var;
- char c = $1;
- ZVAL_STRINGL(&z_var, &c, 1);
- zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) SWIGTYPE *, SWIGTYPE []
-{
- zval z_var;
- SWIG_SetPointerZval(&z_var, (void*)$1, $1_descriptor, 0);
- zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) SWIGTYPE, SWIGTYPE &, SWIGTYPE &&
-{
- zval z_var;
- SWIG_SetPointerZval(&z_var, (void*)&$1, $&1_descriptor, 0);
- zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) char [ANY]
-{
- zval z_var;
- /* varinit char [ANY] */
- ZVAL_STRINGL(&z_var, $1, $1_dim0);
- zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit, fragment="swig_php_init_member_ptr") SWIGTYPE (CLASS::*)
-{
- zval resource;
- void * p = emalloc(sizeof($1));
- memcpy(p, &$1, sizeof($1));
- ZVAL_RES(&resource, zend_register_resource(p, swig_member_ptr));
- zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &resource);
-}
-
-%typemap(varin) int, unsigned int, short, unsigned short, long, unsigned long, signed char, unsigned char, enum SWIGTYPE
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- $1 = zval_get_long(z_var);
-}
-
-%typemap(varin) bool
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- convert_to_boolean(z_var);
- $1 = (Z_TYPE_P(z_var) == IS_TRUE);
-}
-
-%typemap(varin) double,float
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- $1 = zval_get_double(z_var);
-}
-
-%typemap(varin) char
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- convert_to_string(z_var);
- if ($1 != Z_STRVAL_P(z_var)[0]) {
- $1 = Z_STRVAL_P(z_var)[0];
- }
-}
-
-%typemap(varin) char *
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- char *s1;
- convert_to_string(z_var);
- s1 = Z_STRVAL_P(z_var);
- if ((s1 == NULL) || ($1 == NULL) || strcmp(s1, $1)) {
- if (s1)
- $1 = estrdup(s1);
- else
- $1 = NULL;
- }
-}
-
-
-%typemap(varin) SWIGTYPE []
-{
- if ($1) {
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- SWIG_SetPointerZval(z_var, (void*)$1, $1_descriptor, $owner);
- }
-}
-
-%typemap(varin) char [ANY]
-{
- zval **z_var;
- char *s1;
-
- zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1, (void**)&z_var);
- s1 = Z_STRVAL_P(z_var);
- if ((s1 == NULL) || ($1 == NULL) || strcmp(s1, $1)) {
- if (s1)
- strncpy($1, s1, $1_dim0);
- }
-}
-
-%typemap(varin) SWIGTYPE
-{
- zval *z_var;
- $&1_ltype _temp;
-
- z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- if (SWIG_ConvertPtr(z_var, (void**)&_temp, $&1_descriptor, 0) < 0) {
- SWIG_PHP_Error(E_ERROR,"Type error in value of $symname. Expected $&1_descriptor");
- }
-
- $1 = *($&1_ltype)_temp;
-}
-
-%typemap(varin) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&
-{
- zval *z_var;
- $1_ltype _temp;
-
- z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- if (SWIG_ConvertPtr(z_var, (void **)&_temp, $1_descriptor, 0) < 0) {
- SWIG_PHP_Error(E_ERROR,"Type error in value of $symname. Expected $&1_descriptor");
- }
-
- $1 = ($1_ltype)_temp;
-}
-
-%typemap(varin, fragment="swig_php_init_member_ptr") SWIGTYPE (CLASS::*)
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- void * p = (void*)zend_fetch_resource_ex(z_var, SWIG_MEMBER_PTR, swig_member_ptr);
- memcpy(&$1, p, sizeof($1));
-}
-
-%typemap(varout) int,
- unsigned int,
- unsigned short,
- short,
- long,
- unsigned long,
- signed char,
- unsigned char,
- enum SWIGTYPE
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- if ($1 != ($1_ltype)Z_LVAL_P(z_var)) {
- z_var->value.lval = (long)$1;
- }
-}
-
-//SAMFIX need to cast zval->type, what if zend-hash_find fails? etc?
-%typemap(varout) bool
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- if ($1 != ($1_ltype)Z_LVAL_P(z_var)) {
- z_var->value.lval = (long)$1;
- }
-}
-
-%typemap(varout) double, float
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- if ($1 != ($1_ltype)Z_DVAL_P(z_var)) {
- z_var->value.dval = (double)$1;
- }
-}
-
-%typemap(varout) char
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- char c = $1;
- if ($1 != Z_STRVAL_P(z_val)[0]) {
- ZVAL_STRING(z_var, &c);
- }
-}
-
-%typemap(varout) char *
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- const char *s1 = Z_STRVAL_P(z_var);
- if ((s1 == NULL) || ($1 == NULL) || strcmp(s1, $1)) {
- if (s1)
- efree(s1);
- if ($1) {
- (z_var)->value.str.val = estrdup($1);
- (z_var)->value.str.len = strlen($1) + 1;
- } else {
- (z_var)->value.str.val = 0;
- (z_var)->value.str.len = 0;
- }
- }
-}
-
-%typemap(varout) SWIGTYPE
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- SWIG_SetPointerZval(z_var, (void*)&$1, $&1_descriptor, 0);
-}
-
-%typemap(varout) SWIGTYPE []
-{
- if($1) {
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- SWIG_SetPointerZval(z_var, (void*)$1, $1_descriptor, 0);
- }
-}
-
-%typemap(varout) char [ANY]
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- const char *s1 = Z_STRVAL_P(z_var);
-deliberate error cos this code looks bogus to me
- if ((s1 == NULL) || strcmp(s1, $1)) {
- if ($1) {
- (z_var)->value.str.val = estrdup($1);
- (z_var)->value.str.len = strlen($1) + 1;
- } else {
- (z_var)->value.str.val = 0;
- (z_var)->value.str.len = 0;
- }
- }
-}
-
-%typemap(varout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&
-{
- zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
- SWIG_SetPointerZval(z_var, (void*)$1, $1_descriptor, 0);
-}
-
-%typemap(varout, fragment="swig_php_init_member_ptr") SWIGTYPE (CLASS::*)
-{
- zval resource;
- void * p = emalloc(sizeof($1));
- memcpy(p, &$1, sizeof($1));
- ZVAL_RES(&resource, zend_register_resource(p, swig_member_ptr));
- zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &resource);
-}
diff --git a/Lib/php/php.swg b/Lib/php/php.swg
index 4eba6be2a..ca8704fd8 100644
--- a/Lib/php/php.swg
+++ b/Lib/php/php.swg
@@ -4,13 +4,19 @@
* PHP configuration file
* ----------------------------------------------------------------------------- */
+%include <typemaps/fragments.swg>
+
+// 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
%include <phpinit.swg> // PHP initialization routine.
-%include <globalvar.i> // Global variables.
%include <const.i>
// use %init %{ "/*code goes here*/ " %}
@@ -35,107 +41,142 @@
%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) {
- SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $&1_descriptor");
- }
- $1 = *tmp;
+ if (SWIG_ConvertPtr(&$input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL) {
+ zend_type_error("Expected $&1_descriptor for argument $argnum of $symname");
+ return;
+ }
+ $1 = *tmp;
%}
%typemap(directorout) SWIGTYPE ($&1_ltype tmp)
%{
- /* If exit was via exception, PHP NULL is returned so skip the conversion. */
- if (!EG(exception)) {
- if (SWIG_ConvertPtr($input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL)
- SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $&1_descriptor");
- $result = *tmp;
- }
+ if (SWIG_ConvertPtr($input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL) {
+ zend_type_error("Expected $&1_descriptor for argument $argnum of $symname");
+ SWIG_fail;
+ }
+ $result = *tmp;
%}
-%typemap(in) SWIGTYPE *,
+%typemap(in, phptype="?SWIGTYPE") SWIGTYPE *,
SWIGTYPE []
%{
- if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0) {
- SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
- }
+ if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0) {
+ zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+ return;
+ }
%}
-%typemap(in) SWIGTYPE &
+%typemap(directorout) SWIGTYPE * (swig_owntype own),
+ SWIGTYPE [] (swig_owntype own)
%{
- if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) {
- SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
- }
+ if (SWIG_ConvertPtrAndOwn($input, (void **)&$result, $1_descriptor, SWIG_POINTER_DISOWN, &own) < 0) {
+ zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+ SWIG_fail;
+ }
+ swig_acquire_ownership_obj((void*)$result, own);
%}
-%typemap(in) SWIGTYPE &&
+%typemap(in, phptype="SWIGTYPE") SWIGTYPE &
%{
- if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) {
- SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
- }
+ if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) {
+ zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+ return;
+ }
+%}
+%typemap(in, fragment="<memory>") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) %{
+ res = SWIG_ConvertPtr(&$input, &argp, $descriptor, SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $1_descriptor of $symname");
+ return;
+ } else {
+ zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+ return;
+ }
+ }
+ if (!argp) {
+ zend_type_error("Invalid null reference for argument $argnum of $1_descriptor of $symname");
+ return;
+ }
+ $1 = ($1_ltype)argp;
+ rvrdeleter.reset($1);
+%}
+
+%typemap(directorout) SWIGTYPE & ($1_ltype tmp),
+ 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");
+ SWIG_fail;
+ }
+ $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) {
- SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $*1_descriptor");
- }
- $1 = ($1_ltype)&temp;
+ if (SWIG_ConvertPtr(&$input, (void **) &temp, $*1_descriptor, 0) < 0) {
+ zend_type_error("Expected $*1_descriptor for argument $argnum of $symname");
+ return;
+ }
+ $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) {
- SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
+ if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, SWIG_POINTER_DISOWN) < 0) {
+ zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+ return;
}
%}
@@ -144,19 +185,22 @@
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* */
- if (Z_ISNULL($input)) $1=0;
- else
- SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
- }
+ if (SWIG_ConvertPtr(&$input, (void **) &$1, 0, 0) < 0) {
+ /* Allow NULL from php for void* */
+ if (Z_ISNULL($input)) {
+ $1=0;
+ } else {
+ zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+ return;
+ }
+ }
%}
/* Special case when void* is passed by reference so it can be made to point
to opaque api structs */
-%typemap(in) 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*
@@ -165,7 +209,8 @@
/* So... we didn't get a ref or ptr, but we'll accept NULL by reference */
if (!(Z_ISREF($input) && Z_ISNULL_P(Z_REFVAL($input)))) {
/* wasn't a pre/ref/thing, OR anything like an int thing */
- SWIG_PHP_Error(E_ERROR, "Type error in argument $arg of $symname.");
+ zend_throw_exception(zend_ce_type_error, "Type error in argument $arg of $symname", 0);
+ goto fail;
}
}
force=0;
@@ -183,14 +228,15 @@
%typemap(argout) void **,
void *&
%{
- if (force$argnum) {
- SWIG_SetPointerZval(&$input, (void*) ptr$argnum, $*1_descriptor, 1);
+ if (force$argnum && Z_ISREF($input)) {
+ SWIG_SetPointerZval(Z_REFVAL($input), (void*) ptr$argnum, $*1_descriptor, 1);
}
%}
/* Typemap for output values */
-%typemap(out) int,
+%typemap(out, phptype="int")
+ int,
unsigned int,
short,
unsigned short,
@@ -198,39 +244,35 @@
unsigned long,
signed char,
unsigned char,
- bool,
size_t
%{
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));
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)$1);
- RETVAL_STRING(temp);
+ RETVAL_NEW_STR(zend_strpprintf(0, "%lld", (long long)$1));
}
%}
-%typemap(out) unsigned long long
+%typemap(out, phptype="int|string") unsigned long long
%{
if ($1 <= (unsigned long long)LONG_MAX) {
RETVAL_LONG((long)($1));
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)$1);
- RETVAL_STRING(temp);
+ RETVAL_NEW_STR(zend_strpprintf(0, "%llu", (unsigned long long)$1));
}
%}
-%typemap(out) const int &,
+%typemap(out, phptype="int")
+ const int &,
const unsigned int &,
const short &,
const unsigned short &,
@@ -244,34 +286,30 @@
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));
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)(*$1));
- RETVAL_STRING(temp);
+ RETVAL_NEW_STR(zend_strpprintf(0, "%lld", (long long)(*$1)));
}
%}
-%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));
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)(*$1));
- RETVAL_STRING(temp);
+ RETVAL_NEW_STR(zend_strpprintf(0, "%llu", (unsigned long long)(*$1)));
}
%}
@@ -303,12 +341,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);
%}
@@ -318,13 +356,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);
@@ -336,18 +374,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();
@@ -356,7 +398,7 @@
}
%}
-%typemap(out) char *&
+%typemap(out, phptype="?string") char *&
%{
if (!*$1) {
RETVAL_NULL();
@@ -365,17 +407,22 @@
}
%}
-%typemap(out) SWIGTYPE *,
+%typemap(out, phptype="?SWIGTYPE") SWIGTYPE *
+%{
+ SWIG_SetPointerZval($result, (void *)$1, $1_descriptor, $owner);
+%}
+
+%typemap(out, phptype="SWIGTYPE")
SWIGTYPE [],
SWIGTYPE &,
SWIGTYPE &&
%{
- SWIG_SetPointerZval(return_value, (void *)$1, $1_descriptor, $owner);
+ SWIG_SetPointerZval($result, (void *)$1, $1_descriptor, $owner);
%}
-%typemap(out) SWIGTYPE *const&
+%typemap(out, phptype="?SWIGTYPE") SWIGTYPE *const&
%{
- SWIG_SetPointerZval(return_value, (void *)*$1, $*1_descriptor, $owner);
+ SWIG_SetPointerZval($result, (void *)*$1, $*1_descriptor, $owner);
%}
%typemap(directorin) SWIGTYPE *,
@@ -383,53 +430,57 @@
SWIGTYPE &,
SWIGTYPE &&
%{
- SWIG_SetPointerZval($input, (void *)&$1, $1_descriptor, ($owner)|2);
+ ZVAL_UNDEF($input);
+ SWIG_SetPointerZval($input, (void *)&$1, $1_descriptor, $owner);
%}
-%typemap(out, fragment="swig_php_init_member_ptr") SWIGTYPE (CLASS::*)
+%typemap(out, phptype="SWIGTYPE") SWIGTYPE (CLASS::*)
{
void * p = emalloc(sizeof($1));
memcpy(p, &$1, sizeof($1));
- RETVAL_RES(zend_register_resource(p, swig_member_ptr));
+ SWIG_SetPointerZval($result, (void *)p, $&1_descriptor, 1);
}
-%typemap(in, fragment="swig_php_init_member_ptr") SWIGTYPE (CLASS::*)
+%typemap(in, phptype="SWIGTYPE") SWIGTYPE (CLASS::*)
{
- void * p = (void*)zend_fetch_resource_ex(&$input, SWIG_MEMBER_PTR, swig_member_ptr);
+ 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(return_value, (void *)$1, ty, $owner);
+ SWIG_SetPointerZval($result, (void *)$1, ty, $owner);
}
-%typemap(out) SWIGTYPE
-#ifdef __cplusplus
+%typemap(out, phptype="SWIGTYPE") SWIGTYPE &DYNAMIC
{
- $&1_ltype resultobj = new $1_ltype((const $1_ltype &) $1);
- SWIG_SetPointerZval(return_value, (void *)resultobj, $&1_descriptor, 1);
+ swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1);
+ SWIG_SetPointerZval($result, (void *)$1, ty, $owner);
}
-#else
+
+%typemap(out, phptype="SWIGTYPE") SWIGTYPE
{
- $&1_ltype resultobj = ($&1_ltype) emalloc(sizeof($1_type));
+#ifdef __cplusplus
+ $&1_ltype resultobj = new $1_ltype($1);
+#else
+ $&1_ltype resultobj = ($&1_ltype) malloc(sizeof($1_type));
memcpy(resultobj, &$1, sizeof($1_type));
- SWIG_SetPointerZval(return_value, (void *)resultobj, $&1_descriptor, 1);
-}
#endif
+ SWIG_SetPointerZval($result, (void *)resultobj, $&1_descriptor, 1);
+}
%typemap(directorin) SWIGTYPE
%{
- SWIG_SetPointerZval($input, SWIG_as_voidptr(new $1_ltype((const $1_ltype &)$1)), $&1_descriptor, 1|2);
+ ZVAL_UNDEF($input);
+ SWIG_SetPointerZval($input, (new $1_ltype(SWIG_STD_MOVE($1))), $&1_descriptor, 1);
%}
-%typemap(out) void "";
+%typemap(out, phptype="void") void ""
-%typemap(out) char [ANY]
+%typemap(out, phptype="string") char [ANY]
{
- int len = 0;
+ size_t len = 0;
while (len < $1_dim0 && $1[len]) ++len;
RETVAL_STRINGL($1, len);
}
@@ -448,24 +499,38 @@
" $1 = (Z_TYPE($input) == is1 || Z_TYPE($input) == is2);"
%enddef
-%php_typecheck(int,SWIG_TYPECHECK_INTEGER,IS_LONG)
-%php_typecheck(unsigned int,SWIG_TYPECHECK_UINT32,IS_LONG)
-%php_typecheck(short,SWIG_TYPECHECK_INT16,IS_LONG)
-%php_typecheck(unsigned short,SWIG_TYPECHECK_UINT16,IS_LONG)
-%php_typecheck(long,SWIG_TYPECHECK_INT32,IS_LONG)
-%php_typecheck(unsigned long,SWIG_TYPECHECK_UINT32,IS_LONG)
-%php_typecheck(long long,SWIG_TYPECHECK_INT64,IS_LONG)
-%php_typecheck(unsigned long long,SWIG_TYPECHECK_UINT64,IS_LONG)
-%php_typecheck(signed char,SWIG_TYPECHECK_INT8,IS_LONG)
-%php_typecheck(unsigned char,SWIG_TYPECHECK_UINT8,IS_LONG)
-%php_typecheck(size_t,SWIG_TYPECHECK_SIZE,IS_LONG)
+%define %php_typecheck_long(_type,_prec,_min,_max)
+%typemap(typecheck,precedence=_prec) _type, const _type & %{
+ $1 = (Z_TYPE($input) == IS_LONG &&
+ (_min <= ZEND_LONG_MIN || (zend_long)_min <= Z_LVAL($input)) &&
+ (_max >= ZEND_LONG_MAX || (zend_long)_max >= Z_LVAL($input)));
+%}
+%enddef
+
+%php_typecheck_long(int,SWIG_TYPECHECK_INTEGER,INT_MIN,INT_MAX)
+%php_typecheck_long(unsigned int,SWIG_TYPECHECK_UINT32,0,UINT_MAX)
+%php_typecheck_long(short,SWIG_TYPECHECK_INT16,SHRT_MIN,SHRT_MAX)
+%php_typecheck_long(unsigned short,SWIG_TYPECHECK_UINT16,0,USHRT_MAX)
+%php_typecheck_long(long,SWIG_TYPECHECK_INT32,LONG_MIN,LONG_MAX)
+%php_typecheck_long(unsigned long,SWIG_TYPECHECK_UINT32,0,ULONG_MAX)
+%php_typecheck_long(long long,SWIG_TYPECHECK_INT64,LLONG_MIN,LLONG_MAX)
+%php_typecheck_long(unsigned long long,SWIG_TYPECHECK_UINT64,0,ULLONG_MAX)
+%php_typecheck_long(signed char,SWIG_TYPECHECK_INT8,SCHAR_MIN,SCHAR_MAX)
+%php_typecheck_long(unsigned char,SWIG_TYPECHECK_UINT8,0,UCHAR_MAX)
+%php_typecheck_long(size_t,SWIG_TYPECHECK_SIZE,0,(size_t)-1)
%php_typecheck(enum SWIGTYPE,SWIG_TYPECHECK_INTEGER,IS_LONG)
%php_typecheck2(bool,SWIG_TYPECHECK_BOOL,IS_TRUE,IS_FALSE)
-%php_typecheck(float,SWIG_TYPECHECK_FLOAT,IS_DOUBLE)
+%typemap(typecheck,precedence=SWIG_TYPECHECK_FLOAT,fragment="SWIG_Float_Overflow_Check") float, const float & %{
+ $1 = (Z_TYPE($input) == IS_DOUBLE && !SWIG_Float_Overflow_Check(Z_DVAL($input)));
+%}
+/* Don't range check here since PHP stores this as C/C++ double. */
%php_typecheck(double,SWIG_TYPECHECK_DOUBLE,IS_DOUBLE)
%php_typecheck(char,SWIG_TYPECHECK_CHAR,IS_STRING)
-%typemap(typecheck,precedence=SWIG_TYPECHECK_STRING) char *, char *&, char []
+%typemap(typecheck,precedence=SWIG_TYPECHECK_STRING) char *, char *&
+ " $1 = (Z_TYPE($input) == IS_STRING || Z_TYPE($input) == IS_NULL); "
+
+%typemap(typecheck,precedence=SWIG_TYPECHECK_STRING) char []
" $1 = (Z_TYPE($input) == IS_STRING); "
%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE
@@ -512,18 +577,18 @@
unsigned long,
unsigned short %{
zend_throw_exception(NULL, "C++ $1_type exception thrown", $1);
- return;
+ goto fail;
%}
%typemap(throws) SWIGTYPE, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE *, SWIGTYPE [], SWIGTYPE [ANY] %{
(void)$1;
zend_throw_exception(NULL, "C++ $1_type exception thrown", 0);
- return;
+ goto fail;
%}
%typemap(throws) char * %{
zend_throw_exception(NULL, $1, 0);
- return;
+ goto fail;
%}
/* Array reference typemaps */
@@ -537,3 +602,6 @@
/* php keywords */
%include <phpkw.swg>
+
+/* PHP known interfaces */
+%include <phpinterfaces.i>
diff --git a/Lib/php/phpinit.swg b/Lib/php/phpinit.swg
index 1665f5dc4..ae72a10ae 100644
--- a/Lib/php/phpinit.swg
+++ b/Lib/php/phpinit.swg
@@ -7,19 +7,10 @@
%init %{
SWIG_php_minit {
+ zend_class_entry SWIGUNUSED internal_ce;
SWIG_InitializeModule((void*)&module_number);
-%}
-
-%fragment("swig_php_init_member_ptr2", "header") %{
-#define SWIG_MEMBER_PTR "CLASS::*"
-
-static void swig_member_ptr_dtor(zend_resource *res) {
- efree(res->ptr);
-}
-
-static int swig_member_ptr = 0;
-%}
-
-%fragment("swig_php_init_member_ptr", "init", fragment="swig_php_init_member_ptr2") %{
- swig_member_ptr = zend_register_list_destructors_ex(swig_member_ptr_dtor, NULL, SWIG_MEMBER_PTR, module_number);
+#if PHP_MAJOR_VERSION == 8 && PHP_MINOR_VERSION == 0
+ /* This hack is needed to avoid segfaults. */
+ EG(class_table) = CG(class_table);
+#endif
%}
diff --git a/Lib/php/phpinterfaces.i b/Lib/php/phpinterfaces.i
new file mode 100644
index 000000000..e1029b645
--- /dev/null
+++ b/Lib/php/phpinterfaces.i
@@ -0,0 +1,60 @@
+/* -----------------------------------------------------------------------------
+ * phpinterfaces.i
+ *
+ * Define "known" PHP interfaces.
+ *
+ * These can be added at MINIT time (which is when PHP loads the extension
+ * module).
+ *
+ * Any interface can be added via phpinterfaces, but looking up the
+ * zend_class_entry by name has to wait until RINIT time, which means it
+ * happens for every request.
+ * ----------------------------------------------------------------------------- */
+
+// Note: Abstract interfaces such as "Traversable" can't be used in
+// "implements" so are not relevant here.
+
+%insert(header) %{
+
+#define SWIG_PHP_INTERFACE_Iterator_CE zend_ce_iterator
+#define SWIG_PHP_INTERFACE_Iterator_HEADER "zend_interfaces.h"
+
+#define SWIG_PHP_INTERFACE_IteratorAggregate_CE zend_ce_aggregate
+#define SWIG_PHP_INTERFACE_IteratorAggregate_HEADER "zend_interfaces.h"
+
+#define SWIG_PHP_INTERFACE_ArrayAccess_CE zend_ce_arrayaccess
+#define SWIG_PHP_INTERFACE_ArrayAccess_HEADER "zend_interfaces.h"
+
+#define SWIG_PHP_INTERFACE_Serializable_CE zend_ce_serializable
+#define SWIG_PHP_INTERFACE_Serializable_HEADER "zend_interfaces.h"
+
+#define SWIG_PHP_INTERFACE_Countable_CE zend_ce_countable
+#define SWIG_PHP_INTERFACE_Countable_HEADER "zend_interfaces.h"
+
+#define SWIG_PHP_INTERFACE_OuterIterator_CE spl_ce_OuterIterator
+#define SWIG_PHP_INTERFACE_OuterIterator_HEADER "ext/spl/spl_iterators.h"
+
+#define SWIG_PHP_INTERFACE_RecursiveIterator_CE spl_ce_RecursiveIterator
+#define SWIG_PHP_INTERFACE_RecursiveIterator_HEADER "ext/spl/spl_iterators.h"
+
+#define SWIG_PHP_INTERFACE_SeekableIterator_CE spl_ce_SeekableIterator
+#define SWIG_PHP_INTERFACE_SeekableIterator_HEADER "ext/spl/spl_iterators.h"
+
+#define SWIG_PHP_INTERFACE_SplObserver_CE spl_ce_SplObserver
+#define SWIG_PHP_INTERFACE_SplObserver_HEADER "ext/spl/spl_observer.h"
+
+#define SWIG_PHP_INTERFACE_SplSubject_CE spl_ce_SplSubject
+#define SWIG_PHP_INTERFACE_SplSubject_HEADER "ext/spl/spl_observer.h"
+
+#define SWIG_PHP_INTERFACE_DateTimeInterface_CE php_date_get_interface_ce()
+#define SWIG_PHP_INTERFACE_DateTimeInterface_HEADER "ext/date/php_date.h"
+
+// The "json" extension needs to be loaded earlier that us for this to work.
+#define SWIG_PHP_INTERFACE_JsonSerializable_CE php_json_serializable_ce
+#define SWIG_PHP_INTERFACE_JsonSerializable_HEADER "ext/json/php_json.h"
+
+// New in PHP 8.0.
+#define SWIG_PHP_INTERFACE_Stringable_CE zend_ce_stringable
+#define SWIG_PHP_INTERFACE_Stringable_HEADER "zend_interfaces.h"
+
+%}
diff --git a/Lib/php/phpkw.swg b/Lib/php/phpkw.swg
index 5c5296a1f..443ac8bf8 100644
--- a/Lib/php/phpkw.swg
+++ b/Lib/php/phpkw.swg
@@ -3,10 +3,13 @@
* ----------------------------------------------------------------------------- */
/* Keyword (case insensitive) */
-#define PHPKW(x) %keywordwarn("'" `x` "' is a PHP keyword, renaming to 'c_" `x` "'",sourcefmt="%(lower)s",rename="c_%s") `x`
+#define PHPKW(x) %keywordwarn("'" `x` "' is a PHP keyword",sourcefmt="%(lower)s",rename="c_%s") `x`
+
+/* Keyword, except ok as a function */
+#define PHPKW_ok_as_function(x) %keywordwarn("'" `x` "' is a PHP keyword, renaming to 'c_" `x` "'",%$not %$isfunction,sourcefmt="%(lower)s",rename="c_%s") `x`
/* Class (case insensitive) */
-#define PHPCN(x) %keywordwarn("'" `x` "' is a PHP reserved class name, renaming to 'c_" `x` "'",%$isclass,sourcefmt="%(lower)s",rename="c_%s") `x`
+#define PHPCN(x) %keywordwarn("'" `x` "' is a PHP reserved class name",%$isclass,sourcefmt="%(lower)s",rename="c_%s") `x`
/* Constant (case insensitive) */
#define PHPBN1a(x) %namewarn(%warningmsg(SWIGWARN_PARSE_BUILTIN_NAME, "enum conflicts with a built-in constant '"`x`"' in PHP"),%$isenumitem,sourcefmt="%(lower)s") `x`
@@ -22,7 +25,7 @@
PHPBN2a(X); PHPBN2b(X)
%enddef
-#define PHPFN(x) %keywordwarn("'" `x` "' is a PHP built-in function, renaming to 'c_" `x` "'",sourcefmt="%(lower)s",%$isfunction,%$not %$ismember,rename="c_%s") `x`
+#define PHPFN(x) %keywordwarn("'" `x` "' is a PHP built-in function",sourcefmt="%(lower)s",%$isfunction,%$not %$ismember,rename="c_%s") `x`
/* From: http://php.net/manual/en/reserved.keywords.php
* "You cannot use any of the following words as constants, class names,
@@ -55,6 +58,7 @@ PHPKW(endwhile);
PHPKW(extends);
PHPKW(final);
PHPKW(finally);
+PHPKW(fn); // as of PHP 7.4
PHPKW(for);
PHPKW(foreach);
PHPKW(function);
@@ -65,6 +69,7 @@ PHPKW(implements);
PHPKW(instanceof);
PHPKW(insteadof);
PHPKW(interface);
+PHPKW(match); // as of PHP 8.0
PHPKW(namespace);
PHPKW(new);
PHPKW(or);
@@ -82,6 +87,11 @@ PHPKW(while);
PHPKW(xor);
PHPKW(yield);
+/* PHP 8.1 made `readonly` a keyword, but (unlike any other keyword it seems)
+ * it may still be used as a function name.
+ */
+PHPKW_ok_as_function(readonly);
+
// Compile-time "magic" constants
// From: http://php.net/manual/en/reserved.keywords.php
// also at: http://php.net/manual/en/language.constants.predefined.php
@@ -119,6 +129,10 @@ PHPBN2(PHP_SAPI);
PHPBN2(PHP_EOL);
PHPBN2(PHP_INT_MAX);
PHPBN2(PHP_INT_SIZE);
+PHPBN2(PHP_FLOAT_DIG); // Since 7.2.0
+PHPBN2(PHP_FLOAT_EPSILON); // Since 7.2.0
+PHPBN2(PHP_FLOAT_MIN); // Since 7.2.0
+PHPBN2(PHP_FLOAT_MAX); // Since 7.2.0
PHPBN2(DEFAULT_INCLUDE_PATH);
PHPBN2(PEAR_INSTALL_DIR);
PHPBN2(PEAR_EXTENSION_DIR);
@@ -134,6 +148,7 @@ PHPBN2(PHP_LOCALSTATEDIR);
PHPBN2(PHP_CONFIG_FILE_PATH);
PHPBN2(PHP_CONFIG_FILE_SCAN_DIR);
PHPBN2(PHP_SHLIB_SUFFIX);
+PHPBN2(PHP_FD_SETSIZE); // Since 7.1.0
PHPBN2(E_ERROR);
PHPBN2(E_WARNING);
PHPBN2(E_PARSE);
@@ -145,6 +160,7 @@ PHPBN2(E_COMPILE_WARNING);
PHPBN2(E_USER_ERROR);
PHPBN2(E_USER_WARNING);
PHPBN2(E_USER_NOTICE);
+PHPBN2(E_RECOVERABLE_ERROR);
PHPBN2(E_DEPRECATED);
PHPBN2(E_USER_DEPRECATED);
PHPBN2(E_ALL);
@@ -156,6 +172,9 @@ PHPBN2(__COMPILER_HALT_OFFSET__);
PHPBN2(PHP_OUTPUT_HANDLER_START);
PHPBN2(PHP_OUTPUT_HANDLER_CONT);
PHPBN2(PHP_OUTPUT_HANDLER_END);
+/* Since 7.4.0 (Microsoft Windows only) */
+PHPBN2(PHP_WINDOWS_EVENT_CTRL_C);
+PHPBN2(PHP_WINDOWS_EVENT_CTRL_BREAK);
/* These don't actually seem to be set (tested on Linux, I guess they're
* Windows only?) */
PHPBN2(PHP_WINDOWS_NT_DOMAIN_CONTROLLER);
@@ -402,21 +421,6 @@ PHPBN2(CURLOPT_TCP_NODELAY);
PHPBN2(CURLOPT_TIMEOUT_MS);
PHPBN2(CURLOPT_CONNECTTIMEOUT_MS);
PHPBN2(GMP_VERSION);
-PHPBN2(SWFTEXTFIELD_USEFONT);
-PHPBN2(SWFTEXTFIELD_AUTOSIZE);
-PHPBN2(SWF_SOUND_NOT_COMPRESSED);
-PHPBN2(SWF_SOUND_ADPCM_COMPRESSED);
-PHPBN2(SWF_SOUND_MP3_COMPRESSED);
-PHPBN2(SWF_SOUND_NOT_COMPRESSED_LE);
-PHPBN2(SWF_SOUND_NELLY_COMPRESSED);
-PHPBN2(SWF_SOUND_5KHZ);
-PHPBN2(SWF_SOUND_11KHZ);
-PHPBN2(SWF_SOUND_22KHZ);
-PHPBN2(SWF_SOUND_44KHZ);
-PHPBN2(SWF_SOUND_8BITS);
-PHPBN2(SWF_SOUND_16BITS);
-PHPBN2(SWF_SOUND_MONO);
-PHPBN2(SWF_SOUND_STEREO);
PHPBN2(OPENSSL_VERSION_NUMBER);
PHPBN2(SNMP_OID_OUTPUT_FULL);
PHPBN2(SNMP_OID_OUTPUT_NUMERIC);
@@ -627,27 +631,26 @@ PHPBN2(PGSQL_POLLING_OK);
PHPBN2(PGSQL_POLLING_READING);
PHPBN2(PGSQL_POLLING_WRITING);
-/* Class names reserved by PHP (case insensitive) */
+/* Class names reserved by PHP. */
+/* Check is case insensitive - these *MUST* be listed in lower case here. */
PHPCN(directory);
PHPCN(stdclass);
PHPCN(__php_incomplete_class);
-/* Added in PHP5. */
PHPCN(exception);
PHPCN(errorexception);
PHPCN(php_user_filter);
PHPCN(closure);
PHPCN(generator);
PHPCN(self);
-PHPCN(static);
PHPCN(parent);
/* http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.other.classes */
PHPCN(bool); // As of PHP 7.0
PHPCN(int); // As of PHP 7.0
PHPCN(float); // As of PHP 7.0
PHPCN(string); // As of PHP 7.0
-PHPCN(NULL); // As of PHP 7.0
-PHPCN(TRUE); // As of PHP 7.0
-PHPCN(FALSE); // As of PHP 7.0
+PHPCN(null); // As of PHP 7.0
+PHPCN(true); // As of PHP 7.0
+PHPCN(false); // As of PHP 7.0
PHPCN(resource); // As of PHP 7.0 (currently works but reserved)
PHPCN(object); // As of PHP 7.0 (currently works but reserved)
PHPCN(mixed); // As of PHP 7.0 (currently works but reserved)
@@ -655,6 +658,14 @@ PHPCN(numeric); // As of PHP 7.0 (currently works but reserved)
/* http://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.invalid-class-names */
PHPCN(iterable); // As of PHP 7.1
PHPCN(void); // As of PHP 7.1
+/* Predefined interfaces and classes, introduced in PHP 7.0.0 */
+PHPCN(arithmeticerror);
+PHPCN(assertionerror);
+PHPCN(divisionbyzeroerror);
+PHPCN(error);
+PHPCN(throwable);
+PHPCN(parseerror);
+PHPCN(typeerror);
/* From extensions (which of these are actually predefined depends which
* extensions are loaded by default). */
PHPCN(xmlwriter);
@@ -866,6 +877,7 @@ PHPFN(unset); // "Language construct"
PHPFN(usort);
#undef PHPKW
+#undef PHPKW_ok_as_function
#undef PHPBN1a
#undef PHPBN1b
#undef PHPBN1
diff --git a/Lib/php/phppointers.i b/Lib/php/phppointers.i
index d79697b5e..a4ff3c0bd 100644
--- a/Lib/php/phppointers.i
+++ b/Lib/php/phppointers.i
@@ -1,16 +1,12 @@
-%define %pass_by_ref( TYPE, CONVERT_IN, CONVERT_OUT )
-%typemap(in, byref=1) TYPE *REF ($*1_ltype tmp),
+%define %pass_by_ref( TYPE, PHP_TYPE, CONVERT_IN, CONVERT_OUT )
+%typemap(in,byref=1,phptype=PHP_TYPE) TYPE *REF ($*1_ltype tmp),
TYPE &REF ($*1_ltype tmp)
%{
- /* First Check for SWIG wrapped type */
- if (Z_ISNULL($input)) {
- $1 = 0;
- } else if (Z_ISREF($input)) {
- /* Not swig wrapped type, so we check if it's a PHP reference type */
- CONVERT_IN(tmp, $*1_ltype, $input);
- $1 = &tmp;
+ if (Z_ISREF($input)) {
+ CONVERT_IN(tmp, $*1_ltype, $input);
+ $1 = &tmp;
} else {
- SWIG_PHP_Error(E_ERROR, SWIG_PHP_Arg_Error_Msg($argnum, Expected a reference));
+ zend_type_error(SWIG_PHP_Arg_Error_Msg($argnum, Expected a reference));
}
%}
%typemap(argout) TYPE *REF,
@@ -22,25 +18,25 @@
%}
%enddef
-%pass_by_ref( size_t, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( size_t, "int", CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( signed int, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( int, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( unsigned int, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( signed int, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( int, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( unsigned int, "int", CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( signed short, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( short, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( unsigned short, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( signed short, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( short, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( unsigned short, "int", CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( signed long, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( long, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( unsigned long, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( signed long, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( long, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( unsigned long, "int", CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( signed char, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( char, CONVERT_CHAR_IN, ZVAL_STRING );
-%pass_by_ref( unsigned char, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( signed char, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( char, "string", CONVERT_CHAR_IN, ZVAL_STRING );
+%pass_by_ref( unsigned char, "int", CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( float, CONVERT_FLOAT_IN, ZVAL_DOUBLE );
-%pass_by_ref( double, CONVERT_FLOAT_IN, ZVAL_DOUBLE );
+%pass_by_ref( float, "float", CONVERT_FLOAT_IN, ZVAL_DOUBLE );
+%pass_by_ref( double, "float", CONVERT_FLOAT_IN, ZVAL_DOUBLE );
-%pass_by_ref( char *, CONVERT_CHAR_IN, ZVAL_STRING );
+%pass_by_ref( char *, "string", CONVERT_CHAR_IN, ZVAL_STRING );
diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg
index a07a1b9f8..588701f9b 100644
--- a/Lib/php/phprun.swg
+++ b/Lib/php/phprun.swg
@@ -4,24 +4,21 @@
* PHP runtime library
* ----------------------------------------------------------------------------- */
+#define swig_owntype int
+
#ifdef __cplusplus
extern "C" {
#endif
-#include "zend.h"
-#include "zend_API.h"
-#include "zend_exceptions.h"
-#include "php.h"
-#if PHP_MAJOR_VERSION != 7
-# error These bindings need PHP7 - to generate PHP5 bindings use: SWIG < 4.0.0 and swig -php5
+#if PHP_MAJOR_VERSION < 8
+# error These bindings need PHP 8 or later - to generate PHP7 bindings use SWIG < 4.1.0; to generate PHP5 bindings use: SWIG < 4.0.0 and swig -php5
#endif
-#include "ext/standard/php_string.h"
-#include <stdlib.h> /* for abort(), used in generated code. */
+#include "zend_inheritance.h"
+#include "zend_exceptions.h"
+#include "zend_inheritance.h"
-/* This indirection is to work around const correctness issues in older PHP.
- * FIXME: Remove for PHP7? Or might user code be using it? */
-#define SWIG_ZEND_NAMED_FE(ZN, N, A) ZEND_NAMED_FE(ZN, N, A)
+#include <stdlib.h> /* for abort(), used in generated code. */
#define SWIG_BOOL_CONSTANT(N, V) REGISTER_BOOL_CONSTANT(#N, V, CONST_CS | CONST_PERSISTENT)
#define SWIG_LONG_CONSTANT(N, V) REGISTER_LONG_CONSTANT(#N, V, CONST_CS | CONST_PERSISTENT)
@@ -32,13 +29,6 @@ extern "C" {
REGISTER_STRINGL_CONSTANT(#N, &swig_char, 1, CONST_CS | CONST_PERSISTENT);\
} while (0)
-/* ZEND_CONSTANT_SET_FLAGS is new in PHP 7.3. */
-#ifdef ZEND_CONSTANT_SET_FLAGS
-# define SWIG_ZEND_CONSTANT_SET_FLAGS ZEND_CONSTANT_SET_FLAGS
-#else
-# define SWIG_ZEND_CONSTANT_SET_FLAGS(C, F, N) do { (C)->flags = (F); (C)->module_number = (N); } while (0)
-#endif
-
#ifdef __cplusplus
}
#endif
@@ -50,178 +40,125 @@ static int default_error_code = E_ERROR;
#define SWIG_PHP_Arg_Error_Msg(argnum,extramsg) "Error in argument " #argnum " "#extramsg
-#define SWIG_PHP_Error(code,msg) do { SWIG_ErrorCode() = code; SWIG_ErrorMsg() = msg; SWIG_fail; } while (0)
+#define SWIG_PHP_Error(code,msg) do { zend_throw_exception(NULL, msg, code); SWIG_fail; } while (0)
#define SWIG_contract_assert(expr,msg) \
- if (!(expr) ) { zend_printf("Contract Assert Failed %s\n",msg ); } else
+ do { if (!(expr)) zend_printf("Contract Assert Failed %s\n", msg); } while (0)
/* Standard SWIG API */
#define SWIG_GetModule(clientdata) SWIG_Php_GetModule()
#define SWIG_SetModule(clientdata, pointer) SWIG_Php_SetModule(pointer, *(int*)clientdata)
+static zend_class_entry SWIG_Php_swig_wrapped_interface_ce;
+
/* used to wrap returned objects in so we know whether they are newobject
and need freeing, or not */
typedef struct {
void * ptr;
int newobject;
+ const swig_type_info * type;
+ zend_object std;
} swig_object_wrapper;
+#define SWIG_Z_FETCH_OBJ_P(zv) swig_php_fetch_object(Z_OBJ_P(zv))
+
+static inline
+swig_object_wrapper * swig_php_fetch_object(zend_object *obj) {
+ return (swig_object_wrapper *)((char *)obj - XtOffsetOf(swig_object_wrapper, std));
+}
+
#define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a))
static void
SWIG_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject) {
- /*
- * First test for Null pointers. Return those as PHP native NULL
- */
- if (!ptr ) {
+ // Return PHP NULL for a C/C++ NULL pointer.
+ if (!ptr) {
ZVAL_NULL(z);
return;
}
- if (type->clientdata) {
- swig_object_wrapper *value;
- if (! (*(int *)(type->clientdata)))
- zend_error(E_ERROR, "Type: %s failed to register with zend",type->name);
- value=(swig_object_wrapper *)emalloc(sizeof(swig_object_wrapper));
- value->ptr=ptr;
- value->newobject=(newobject & 1);
- if ((newobject & 2) == 0) {
- /* Just register the pointer as a resource. */
- ZVAL_RES(z, zend_register_resource(value, *(int *)(type->clientdata)));
- } else {
- /*
- * Wrap the resource in an object, the resource will be accessible
- * via the "_cPtr" member. This is currently only used by
- * directorin typemaps.
- */
- zval resource;
- zend_class_entry *ce = NULL;
- const char *type_name = type->name+3; /* +3 so: _p_Foo -> Foo */
- size_t type_name_len;
- const char * p;
- HashTable * ht;
-
- /* Namespace__Foo -> Foo */
- /* FIXME: ugly and goes wrong for classes with __ in their names. */
- while ((p = strstr(type_name, "__")) != NULL) {
- type_name = p + 2;
- }
- type_name_len = strlen(type_name);
-
- ZVAL_RES(&resource, zend_register_resource(value, *(int *)(type->clientdata)));
- if (SWIG_PREFIX_LEN > 0) {
- zend_string * classname = zend_string_alloc(SWIG_PREFIX_LEN + type_name_len, 0);
- memcpy(classname->val, SWIG_PREFIX, SWIG_PREFIX_LEN);
- memcpy(classname->val + SWIG_PREFIX_LEN, type_name, type_name_len);
- ce = zend_lookup_class(classname);
- zend_string_release(classname);
- } else {
- zend_string * classname = zend_string_init(type_name, type_name_len, 0);
- ce = zend_lookup_class(classname);
- zend_string_release(classname);
- }
- if (ce == NULL) {
- /* class does not exist */
- ce = zend_standard_class_def;
- }
- ALLOC_HASHTABLE(ht);
- zend_hash_init(ht, 1, NULL, NULL, 0);
- zend_hash_str_update(ht, "_cPtr", sizeof("_cPtr") - 1, &resource);
- object_and_properties_init(z, ce, ht);
- }
+ if (!type->clientdata) {
+ zend_type_error("Type: %s not registered with zend", type->name);
return;
}
- zend_error(E_ERROR, "Type: %s not registered with zend",type->name);
-}
-
-/* This pointer conversion routine takes the native pointer p (along with
- its type name) and converts it by calling appropriate casting functions
- according to ty. The resultant pointer is returned, or NULL is returned
- if the pointer can't be cast.
-
- Sadly PHP has no API to find a type name from a type id, only from an
- instance of a resource of the type id, so we have to pass type_name as well.
-
- The two functions which might call this are:
- SWIG_ConvertResourcePtr which gets the type name from the resource
- and the registered zend destructors for which we have one per type each
- with the type name hard wired in. */
-static void *
-SWIG_ConvertResourceData(void * p, const char *type_name, swig_type_info *ty) {
- swig_cast_info *tc;
- void *result = 0;
-
- if (!ty) {
- /* They don't care about the target type, so just pass on the pointer! */
- return p;
- }
-
- if (! type_name) {
- /* can't convert p to ptr type ty if we don't know what type p is */
- return NULL;
- }
-
- /* convert and cast p from type_name to ptr as ty. */
- tc = SWIG_TypeCheck(type_name, ty);
- if (tc) {
- int newmemory = 0;
- result = SWIG_TypeCast(tc, p, &newmemory);
- assert(!newmemory); /* newmemory handling not yet implemented */
- }
- return result;
-}
-/* This function returns a pointer of type ty by extracting the pointer
- and type info from the resource in z. z must be a resource.
- If it fails, NULL is returned.
- It uses SWIG_ConvertResourceData to do the real work. */
-static void *
-SWIG_ConvertResourcePtr(zval *z, swig_type_info *ty, int flags) {
- swig_object_wrapper *value;
- void *p;
- const char *type_name;
-
- if (Z_RES_TYPE_P(z) == -1) return NULL;
- value = (swig_object_wrapper *) Z_RES_VAL_P(z);
- if (flags & SWIG_POINTER_DISOWN) {
- value->newobject = 0;
+ {
+ zend_object *obj;
+ swig_object_wrapper *value;
+ if (Z_TYPE_P(z) == IS_OBJECT) {
+ /* The PHP object is already initialised - this is the case when wrapping
+ * the return value from a PHP constructor. */
+ obj = Z_OBJ_P(z);
+ } else {
+ zend_class_entry *ce = (zend_class_entry*)(type->clientdata);
+ obj = ce->create_object(ce);
+ ZVAL_OBJ(z, obj);
+ }
+ value = swig_php_fetch_object(obj);
+ value->ptr = ptr;
+ value->newobject = (newobject & 1);
+ value->type = type;
}
- p = value->ptr;
-
- type_name=zend_rsrc_list_get_rsrc_type(Z_RES_P(z));
-
- return SWIG_ConvertResourceData(p, type_name, ty);
}
-/* We allow passing of a RESOURCE pointing to the object or an OBJECT whose
- _cPtr is a resource pointing to the object */
+/* We wrap C/C++ pointers as PHP objects. */
static int
-SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) {
+SWIG_ConvertPtrAndOwn(zval *z, void **ptr, swig_type_info *ty, int flags, swig_owntype *own) {
+ if (own)
+ *own = 0;
+
if (z == NULL) {
*ptr = 0;
- return 0;
+ return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
}
switch (Z_TYPE_P(z)) {
case IS_OBJECT: {
- HashTable * ht = Z_OBJ_HT_P(z)->get_properties(z);
- if (ht) {
- zval * _cPtr = zend_hash_str_find(ht, "_cPtr", sizeof("_cPtr") - 1);
- if (_cPtr) {
- if (Z_TYPE_P(_cPtr) == IS_INDIRECT) {
- _cPtr = Z_INDIRECT_P(_cPtr);
- }
- if (Z_TYPE_P(_cPtr) == IS_RESOURCE) {
- *ptr = SWIG_ConvertResourcePtr(_cPtr, ty, flags);
- return (*ptr == NULL ? -1 : 0);
- }
+ zend_object *obj = Z_OBJ_P(z);
+ swig_object_wrapper *value;
+ if (ty && ty->clientdata == (void*)obj->ce) {
+ // Object is exactly the class asked for - this handles common cases cheaply,
+ // and in particular the PHP classes we use to wrap a pointer to a non-class.
+ } else if (!zend_class_implements_interface(obj->ce, &SWIG_Php_swig_wrapped_interface_ce)) {
+ // Not an object we've wrapped.
+ return -1;
+ }
+
+ /* convert and cast value->ptr from value->type to ptr as ty. */
+ value = swig_php_fetch_object(obj);
+ if (!ty) {
+ /* They don't care about the target type, so just pass on the pointer! */
+ *ptr = value->ptr;
+ } else {
+ swig_cast_info *tc = SWIG_TypeCheck(value->type->name, ty);
+ if (tc) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc, value->ptr, &newmemory);
+ if (newmemory == SWIG_CAST_NEW_MEMORY) {
+ assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
+ if (own)
+ *own |= SWIG_CAST_NEW_MEMORY;
+ }
+ } else {
+ *ptr = NULL;
+ }
+ }
+
+ if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !value->newobject) {
+ return SWIG_ERROR_RELEASE_NOT_OWNED;
+ } else {
+ if (*ptr == NULL)
+ return SWIG_ERROR; /* should be SWIG_NullReferenceError?? */
+ if (flags & SWIG_POINTER_DISOWN) {
+ value->newobject = 0;
+ }
+ if (flags & SWIG_POINTER_CLEAR) {
+ value->ptr = 0;
}
}
- break;
+
+ return SWIG_OK;
}
- case IS_RESOURCE:
- *ptr = SWIG_ConvertResourcePtr(z, ty, flags);
- return (*ptr == NULL ? -1 : 0);
case IS_NULL:
*ptr = 0;
return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
@@ -230,17 +167,43 @@ SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) {
return -1;
}
+static int
+SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) {
+ return SWIG_ConvertPtrAndOwn(z, ptr, ty, flags, 0);
+}
+
static const char const_name[] = "swig_runtime_data_type_pointer";
-static swig_module_info *SWIG_Php_GetModule() {
+static swig_module_info *SWIG_Php_GetModule(void) {
zval *pointer = zend_get_constant_str(const_name, sizeof(const_name) - 1);
if (pointer) {
if (Z_TYPE_P(pointer) == IS_LONG) {
return (swig_module_info *) pointer->value.lval;
}
- }
+ }
return NULL;
}
static void SWIG_Php_SetModule(swig_module_info *pointer, int module_number) {
REGISTER_LONG_CONSTANT(const_name, (long) pointer, CONST_CS | CONST_PERSISTENT);
}
+
+/* Common parts of the "create_object" object handler. */
+static zend_object *SWIG_Php_do_create_object(zend_class_entry *ce, zend_object_handlers *handlers) {
+ swig_object_wrapper *obj = (swig_object_wrapper*)zend_object_alloc(sizeof(swig_object_wrapper), ce);
+ zend_object_std_init(&obj->std, ce);
+ object_properties_init(&obj->std, ce);
+ obj->std.handlers = handlers;
+ obj->newobject = 1;
+ return &obj->std;
+}
+
+/* Common parts of the "free_obj" object handler.
+ Returns void* pointer if the C/C++ object should be destroyed. */
+static void* SWIG_Php_free_obj(zend_object *object) {
+ if (object) {
+ swig_object_wrapper *obj = swig_php_fetch_object(object);
+ zend_object_std_dtor(&obj->std);
+ if (obj->newobject) return obj->ptr;
+ }
+ return NULL;
+}
diff --git a/Lib/php/std_auto_ptr.i b/Lib/php/std_auto_ptr.i
new file mode 100644
index 000000000..284091657
--- /dev/null
+++ b/Lib/php/std_auto_ptr.i
@@ -0,0 +1,41 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr(&$input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $descriptor(TYPE *) of $symname");
+ return;
+ } else {
+ zend_type_error("Expected $descriptor(TYPE *) for argument $argnum of $symname");
+ return;
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+ SWIG_SetPointerZval($result, (void *)$1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN);
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(&$input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class auto_ptr {};
+}
diff --git a/Lib/php/std_common.i b/Lib/php/std_common.i
index 092bf012b..1b69fc779 100644
--- a/Lib/php/std_common.i
+++ b/Lib/php/std_common.i
@@ -7,4 +7,3 @@
%include <std/std_except.i>
%apply size_t { std::size_t };
-
diff --git a/Lib/php/std_map.i b/Lib/php/std_map.i
index 7c0157353..6904efc6e 100644
--- a/Lib/php/std_map.i
+++ b/Lib/php/std_map.i
@@ -35,7 +35,7 @@ namespace std {
map();
map(const map& other);
-
+
unsigned int size() const;
void clear();
%extend {
@@ -47,7 +47,11 @@ namespace std {
throw std::out_of_range("key not found");
}
void set(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+ (*self).insert_or_assign(key, x);
+%#else
(*self)[key] = x;
+%#endif
}
void del(const K& key) throw (std::out_of_range) {
std::map< K, T, C >::iterator i = self->find(key);
@@ -66,17 +70,4 @@ namespace std {
}
};
-// Legacy macros (deprecated)
-%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
-#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary"
-%enddef
-
}
diff --git a/Lib/php/std_string.i b/Lib/php/std_string.i
index b55751f07..5abbbbbef 100644
--- a/Lib/php/std_string.i
+++ b/Lib/php/std_string.i
@@ -4,19 +4,21 @@
* SWIG typemaps for std::string types
* ----------------------------------------------------------------------------- */
-// ------------------------------------------------------------------------
-// std::string is typemapped by value
-// This can prevent exporting methods which return a string
-// in order for the user to modify it.
-// However, I think I'll wait until someone asks for it...
-// ------------------------------------------------------------------------
-
-%include <exception.i>
-
%{
#include <string>
%}
+/* std::string and const std::string& are converted to/from PHP string
+ * automatically.
+ *
+ * A C++ std::string& parameter is wrapped as a pass-by-reference PHP
+ * string parameter by default, but the INPUT/INOUT/OUTPUT typemaps
+ * below provide other options (see below).
+ *
+ * std::string* is not wrapped by default, but INPUT/INOUT/OUTPUT typemaps
+ * are provided (see below).
+ */
+
namespace std {
%naturalvar string;
@@ -27,19 +29,17 @@ namespace std {
$1 = (Z_TYPE($input) == IS_STRING) ? 1 : 0;
%}
- %typemap(in) string %{
+ %typemap(in, phptype="string") string %{
convert_to_string(&$input);
$1.assign(Z_STRVAL($input), Z_STRLEN($input));
%}
%typemap(directorout) string %{
- if (!EG(exception)) {
convert_to_string($input);
$result.assign(Z_STRVAL_P($input), Z_STRLEN_P($input));
- }
%}
- %typemap(out) string %{
+ %typemap(out, phptype="string") string %{
ZVAL_STRINGL($result, $1.data(), $1.size());
%}
@@ -47,24 +47,31 @@ namespace std {
ZVAL_STRINGL($input, $1.data(), $1.size());
%}
- %typemap(out) const string & %{
+ %typemap(out, phptype="string") const string& %{
ZVAL_STRINGL($result, $1->data(), $1->size());
%}
%typemap(throws) string, const string& %{
zend_throw_exception(NULL, $1.c_str(), 0);
- return;
+ goto fail;
%}
- %typemap(in) const string & ($*1_ltype temp) %{
+ %typemap(throws) string*, const string* %{
+ zend_throw_exception(NULL, $1->c_str(), 0);
+ goto fail;
+ %}
+
+ %typemap(in, phptype="string") const string& ($*1_ltype temp) %{
convert_to_string(&$input);
temp.assign(Z_STRVAL($input), Z_STRLEN($input));
$1 = &temp;
%}
- /* These next two handle a function which takes a non-const reference to
- * a std::string and modifies the string. */
- %typemap(in,byref=1) string & ($*1_ltype temp) %{
+ /*************************************************************************/
+
+ /* These next four typemaps handle a function which takes a non-const
+ * reference to a std::string and modifies the string. */
+ %typemap(in,byref=1, phptype="string") string& ($*1_ltype temp) %{
{
zval * p = Z_ISREF($input) ? Z_REFVAL($input) : &$input;
convert_to_string(p);
@@ -73,16 +80,14 @@ namespace std {
}
%}
- %typemap(directorout) string & ($*1_ltype *temp) %{
- if (!EG(exception)) {
+ %typemap(directorout) string& ($*1_ltype *temp) %{
convert_to_string($input);
temp = new $*1_ltype(Z_STRVAL_P($input), Z_STRLEN_P($input));
swig_acquire_ownership(temp);
$result = temp;
- }
%}
- %typemap(argout) string & %{
+ %typemap(argout) string& %{
if (Z_ISREF($input)) {
ZVAL_STRINGL(Z_REFVAL($input), $1->data(), $1->size());
}
@@ -90,5 +95,27 @@ namespace std {
/* SWIG will apply the non-const typemap above to const string& without
* this more specific typemap. */
- %typemap(argout) const string & "";
+ %typemap(argout) const string& ""
+
+ /*************************************************************************/
+
+ /* Alternative ways to handle string& - you can specify how to wrap based
+ * on the parameter name, e.g. this handles parameters named `str` as
+ * INOUT:
+ *
+ * %apply (std::string& INOUT) (std::string& str);
+ */
+
+ %typemap(in) string& INPUT = const string&;
+ %typemap(in, numinputs=0) string& OUTPUT ($*1_ltype temp)
+ %{ $1 = &temp; %}
+ %typemap(argout,fragment="t_output_helper") string& OUTPUT
+ {
+ zval o;
+ ZVAL_STRINGL(&o, $1->data(), $1->size());
+ t_output_helper($result, &o);
+ }
+ %typemap(in) string& INOUT = const string&;
+ %typemap(argout) string& INOUT = string& OUTPUT;
+
}
diff --git a/Lib/php/std_string_view.i b/Lib/php/std_string_view.i
new file mode 100644
index 000000000..8fff6e100
--- /dev/null
+++ b/Lib/php/std_string_view.i
@@ -0,0 +1,69 @@
+/* -----------------------------------------------------------------------------
+ * std_string_view.i
+ *
+ * SWIG typemaps for std::string_view types
+ * ----------------------------------------------------------------------------- */
+
+%include <exception.i>
+
+%{
+#include <string_view>
+%}
+
+namespace std {
+
+ %naturalvar string_view;
+
+ class string_view;
+
+ %typemap(typecheck,precedence=SWIG_TYPECHECK_STRINGVIEW) string_view, const string_view& %{
+ $1 = (Z_TYPE($input) == IS_STRING) ? 1 : 0;
+ %}
+
+ %typemap(in, phptype="string") string_view %{
+ convert_to_string(&$input);
+ $1 = std::string_view(Z_STRVAL($input), Z_STRLEN($input));
+ %}
+
+ %typemap(in, phptype="string") const string_view& ($*1_ltype temp) %{
+ convert_to_string(&$input);
+ temp = std::string_view(Z_STRVAL($input), Z_STRLEN($input));
+ $1 = &temp;
+ %}
+
+ %typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) string_view %{
+ convert_to_string($input);
+ $result = std::string_view(Z_STRVAL_P($input), Z_STRLEN_P($input));
+ %}
+
+ %typemap(out, phptype="string") string_view %{
+ ZVAL_STRINGL($result, $1.data(), $1.size());
+ %}
+
+ %typemap(directorin) string_view, const string_view& %{
+ ZVAL_STRINGL($input, $1.data(), $1.size());
+ %}
+
+ %typemap(out, phptype="string") const string_view& %{
+ ZVAL_STRINGL($result, $1->data(), $1->size());
+ %}
+
+ %typemap(throws) string_view, const string_view& %{
+ {
+ zval swig_exception;
+ ZVAL_STRINGL(&swig_exception, $1.data(), $1.size());
+ zend_throw_exception_object(&swig_exception);
+ goto fail;
+ }
+ %}
+
+ %typemap(throws) string_view*, const string_view* %{
+ {
+ zval swig_exception;
+ ZVAL_STRINGL(&swig_exception, $1->data(), $1->size());
+ zend_throw_exception_object(&swig_exception);
+ goto fail;
+ }
+ %}
+
+}
diff --git a/Lib/php/std_unique_ptr.i b/Lib/php/std_unique_ptr.i
new file mode 100644
index 000000000..1bf31595e
--- /dev/null
+++ b/Lib/php/std_unique_ptr.i
@@ -0,0 +1,41 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr(&$input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $descriptor(TYPE *) of $symname");
+ return;
+ } else {
+ zend_type_error("Expected $descriptor(TYPE *) for argument $argnum of $symname");
+ return;
+ }
+ }
+ $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+ SWIG_SetPointerZval($result, (void *)$1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN);
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(&$input, &vptr, $descriptor(TYPE *), 0);
+ $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+ template <class T> class unique_ptr {};
+}
diff --git a/Lib/php/std_vector.i b/Lib/php/std_vector.i
index e633bc3ad..382b37ca0 100644
--- a/Lib/php/std_vector.i
+++ b/Lib/php/std_vector.i
@@ -112,5 +112,3 @@ namespace std {
%define specialize_std_vector(T)
#warning "specialize_std_vector - specialization for type T no longer needed"
%enddef
-
-
diff --git a/Lib/php/stl.i b/Lib/php/stl.i
index 04f86014f..38aba67b8 100644
--- a/Lib/php/stl.i
+++ b/Lib/php/stl.i
@@ -7,4 +7,3 @@
%include <std_vector.i>
%include <std_map.i>
%include <std_pair.i>
-
diff --git a/Lib/php/swigmove.i b/Lib/php/swigmove.i
new file mode 100644
index 000000000..b16a3c544
--- /dev/null
+++ b/Lib/php/swigmove.i
@@ -0,0 +1,24 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, noblock=1) SWIGTYPE MOVE (void *argp = 0, int res = 0) {
+ res = SWIG_ConvertPtr(&$input, &argp, $&1_descriptor, SWIG_POINTER_RELEASE);
+ if (!SWIG_IsOK(res)) {
+ if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+ zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $&1_descriptor of $symname");
+ return;
+ } else {
+ zend_type_error("Expected $&1_descriptor for argument $argnum of $symname");
+ return;
+ }
+ }
+ if (!argp) {
+ zend_type_error("Invalid null reference for argument $argnum of $&1_descriptor of $symname");
+ return;
+ }
+ SwigValueWrapper< $1_ltype >::reset($1, ($&1_type)argp);
+}
diff --git a/Lib/php/typemaps.i b/Lib/php/typemaps.i
index c248a588e..718469edc 100644
--- a/Lib/php/typemaps.i
+++ b/Lib/php/typemaps.i
@@ -25,21 +25,21 @@
* ----------------------------------------------------------------------------- */
%define BOOL_TYPEMAP(TYPE)
-%typemap(in) TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
+%typemap(in, phptype="bool") TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
%{
convert_to_boolean(&$input);
temp = (Z_TYPE($input) == IS_TRUE);
$1 = &temp;
%}
-%typemap(argout) TYPE *INPUT, TYPE &INPUT "";
-%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;";
+%typemap(argout) TYPE *INPUT, TYPE &INPUT ""
+%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;"
%typemap(argout,fragment="t_output_helper") TYPE *OUTPUT, TYPE &OUTPUT
{
zval o;
ZVAL_BOOL(&o, temp$argnum);
t_output_helper($result, &o);
}
-%typemap(in) TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
+%typemap(in, phptype="float") TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
%{
convert_to_boolean($input);
lvalue = (Z_TYPE_P($input) == IS_TRUE);
@@ -52,20 +52,20 @@
%enddef
%define DOUBLE_TYPEMAP(TYPE)
-%typemap(in) TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
+%typemap(in, phptype="float") TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
%{
temp = (TYPE) zval_get_double(&$input);
$1 = &temp;
%}
-%typemap(argout) TYPE *INPUT, TYPE &INPUT "";
-%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;";
+%typemap(argout) TYPE *INPUT, TYPE &INPUT ""
+%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;"
%typemap(argout,fragment="t_output_helper") TYPE *OUTPUT, TYPE &OUTPUT
{
zval o;
ZVAL_DOUBLE(&o, temp$argnum);
t_output_helper($result, &o);
}
-%typemap(in) TYPE *REFERENCE (TYPE dvalue), TYPE &REFERENCE (TYPE dvalue)
+%typemap(in, phptype="float") TYPE *REFERENCE (TYPE dvalue), TYPE &REFERENCE (TYPE dvalue)
%{
dvalue = (TYPE) zval_get_double(&$input);
$1 = &dvalue;
@@ -77,20 +77,20 @@
%enddef
%define INT_TYPEMAP(TYPE)
-%typemap(in) TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
+%typemap(in, phptype="int") TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
%{
temp = (TYPE) zval_get_long(&$input);
$1 = &temp;
%}
-%typemap(argout) TYPE *INPUT, TYPE &INPUT "";
-%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;";
+%typemap(argout) TYPE *INPUT, TYPE &INPUT ""
+%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;"
%typemap(argout,fragment="t_output_helper") TYPE *OUTPUT, TYPE &OUTPUT
{
zval o;
ZVAL_LONG(&o, temp$argnum);
t_output_helper($result, &o);
}
-%typemap(in) TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
+%typemap(in, phptype="int") TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
%{
lvalue = (TYPE) zval_get_long(&$input);
$1 = &lvalue;
@@ -122,13 +122,11 @@ INT_TYPEMAP(long long);
if ((long long)LONG_MIN <= temp$argnum && temp$argnum <= (long long)LONG_MAX) {
ZVAL_LONG(&o, (long)temp$argnum);
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)temp$argnum);
- ZVAL_STRING(&o, temp);
+ ZVAL_NEW_STR(&o, zend_strpprintf(0, "%lld", (long long)temp$argnum));
}
t_output_helper($result, &o);
}
-%typemap(in) TYPE *REFERENCE (long long lvalue)
+%typemap(in, phptype="int|string") TYPE *REFERENCE (long long lvalue)
%{
CONVERT_LONG_LONG_IN(lvalue, long long, $input)
$1 = &lvalue;
@@ -138,9 +136,7 @@ INT_TYPEMAP(long long);
if ((long long)LONG_MIN <= lvalue$argnum && lvalue$argnum <= (long long)LONG_MAX) {
ZVAL_LONG(&$arg, (long)temp$argnum);
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)lvalue$argnum);
- ZVAL_STRING(&$arg, temp);
+ ZVAL_NEW_STR(&$arg, zend_strpprintf(0, "%lld", (long long)lvalue$argnum));
}
%}
%typemap(argout) long long &OUTPUT
@@ -148,11 +144,10 @@ INT_TYPEMAP(long long);
if ((long long)LONG_MIN <= *arg$argnum && *arg$argnum <= (long long)LONG_MAX) {
ZVAL_LONG($result, (long)(*arg$argnum));
} else {
- char temp[256];
- sprintf(temp, "%lld", (long long)(*arg$argnum));
- ZVAL_STRING($result, temp);
+ ZVAL_NEW_STR($result, zend_strpprintf(0, "%lld", (long long)(*arg$argnum)));
}
%}
+
INT_TYPEMAP(unsigned long long);
%typemap(argout,fragment="t_output_helper") unsigned long long *OUTPUT
{
@@ -160,13 +155,11 @@ INT_TYPEMAP(unsigned long long);
if (temp$argnum <= (unsigned long long)LONG_MAX) {
ZVAL_LONG(&o, temp$argnum);
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)temp$argnum);
- ZVAL_STRING(&o, temp);
+ ZVAL_NEW_STR(&o, zend_strpprintf(0, "%llu", (unsigned long long)temp$argnum));
}
t_output_helper($result, &o);
}
-%typemap(in) TYPE *REFERENCE (unsigned long long lvalue)
+%typemap(in, phptype="int|string") TYPE *REFERENCE (unsigned long long lvalue)
%{
CONVERT_UNSIGNED_LONG_LONG_IN(lvalue, unsigned long long, $input)
$1 = &lvalue;
@@ -176,9 +169,7 @@ INT_TYPEMAP(unsigned long long);
if (lvalue$argnum <= (unsigned long long)LONG_MAX) {
ZVAL_LONG($arg, (long)(lvalue$argnum));
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)lvalue$argnum);
- ZVAL_STRING((*$arg), temp);
+ ZVAL_NEW_STR((*$arg), zend_strpprintf(0, "%llu", (unsigned long long)lvalue$argnum));
}
%}
%typemap(argout) unsigned long long &OUTPUT
@@ -186,9 +177,7 @@ INT_TYPEMAP(unsigned long long);
if (*arg$argnum <= (unsigned long long)LONG_MAX) {
ZVAL_LONG($result, (long)(*arg$argnum));
} else {
- char temp[256];
- sprintf(temp, "%llu", (unsigned long long)(*arg$argnum));
- ZVAL_STRING($result, temp);
+ ZVAL_NEW_STR($result, zend_strpprintf(0, "%llu", (unsigned long long)(*arg$argnum)));
}
%}
@@ -252,7 +241,7 @@ INT_TYPEMAP(unsigned long long);
%typemap(argout) unsigned long long &INOUT = unsigned long long *OUTPUT;
%typemap(argout) signed char &INOUT = signed char *OUTPUT;
-%typemap(in) char INPUT[ANY] ( char temp[$1_dim0] )
+%typemap(in, phptype="string") char INPUT[ANY] ( char temp[$1_dim0] )
%{
convert_to_string(&$input);
strncpy(temp, Z_STRVAL($input), $1_dim0);
@@ -267,7 +256,7 @@ INT_TYPEMAP(unsigned long long);
t_output_helper($result, &o);
}
-%typemap(in,numinputs=0) void **OUTPUT (int force),
+%typemap(in,numinputs=0,phptype="?SWIGTYPE") void **OUTPUT (int force),
void *&OUTPUT (int force)
%{
/* If they pass NULL by reference, make it into a void*
@@ -276,7 +265,8 @@ INT_TYPEMAP(unsigned long long);
/* So... we didn't get a ref or ptr, but we'll accept NULL by reference */
if (!(Z_ISREF($input) && Z_ISNULL_P(Z_REFVAL($input)))) {
/* wasn't a pre/ref/thing, OR anything like an int thing */
- SWIG_PHP_Error(E_ERROR, "Type error in argument $arg of $symname.");
+ zend_type_error("Expected reference or NULL for argument $arg of $symname");
+ return;
}
}
force=0;
diff --git a/Lib/php/utils.i b/Lib/php/utils.i
index ed6e08ff4..33db942a9 100644
--- a/Lib/php/utils.i
+++ b/Lib/php/utils.i
@@ -16,9 +16,9 @@
char * endptr;
errno = 0;
lvar = (t) strtoll(Z_STRVAL(invar), &endptr, 10);
- if (*endptr && !errno) break;
- /* FALL THRU */
+ if (*endptr == '\0' && !errno) break;
}
+ /* FALL THRU */
default:
lvar = (t) zval_get_long(&invar);
}
@@ -33,9 +33,9 @@
char * endptr;
errno = 0;
lvar = (t) strtoull(Z_STRVAL(invar), &endptr, 10);
- if (*endptr && !errno) break;
- /* FALL THRU */
+ if (*endptr == '\0' && !errno) break;
}
+ /* FALL THRU */
default:
lvar = (t) zval_get_long(&invar);
}
@@ -63,28 +63,33 @@
}
%enddef
-%define %pass_by_val( TYPE, CONVERT_IN )
-%typemap(in) TYPE
+%define %pass_by_val( TYPE, PHP_TYPE, CONVERT_IN )
+%typemap(in, phptype=PHP_TYPE) TYPE
%{
CONVERT_IN($1,$1_ltype,$input);
%}
-%typemap(in) const TYPE & ($*1_ltype temp)
+%typemap(in, phptype=PHP_TYPE) const TYPE & ($*1_ltype temp)
%{
CONVERT_IN(temp,$*1_ltype,$input);
$1 = &temp;
%}
%typemap(directorout) TYPE
%{
- if (!EG(exception)) {
- CONVERT_IN($result, $1_ltype, *$input);
- }
+ CONVERT_IN($result, $1_ltype, *$input);
+%}
+%typemap(directorout) const TYPE &
+%{
+ $*1_ltype swig_val;
+ CONVERT_IN(swig_val, $*1_ltype, *$input);
+ $1_ltype temp = new $*1_ltype(swig_val);
+ swig_acquire_ownership(temp);
+ $result = temp;
%}
-%typemap(directorout) const TYPE & ($*1_ltype temp)
+%typemap(directorfree) const TYPE &
%{
- if (!EG(exception)) {
- CONVERT_IN(temp, $*1_ltype, *$input);
+ if (director) {
+ director->swig_release_ownership(%as_voidptr($input));
}
- $result = &temp;
%}
%enddef