summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlly Betts <olly@survex.com>2022-10-18 10:28:17 +1300
committerOlly Betts <olly@survex.com>2022-10-18 10:28:17 +1300
commit747a6a264f56711c7b725cf883ef623e01b65922 (patch)
tree91ab34ec9f7e5cc9e07015ae6fc3158833357b38
parentd8a028601247e96c15bbaac08100cce0401f186e (diff)
downloadswig-747a6a264f56711c7b725cf883ef623e01b65922.tar.gz
[php] Fix handling of multi-module cases
Look up unknown base classes using SWIG_MangledTypeQueryModule(). Revert to using SWIG_TypeCheck() instead of SWIG_TypeCheckStruct() as the latter doesn't seem to work for this case (at least for PHP right now). Add mod_runme.php as a regression test for this. Adjust the PHP test harness not to set up reflection for the module unless it's actually needed for a testcase. Currently the approach to find the module name doesn't work for multi-module testcases. See #2126
-rw-r--r--Examples/Makefile.in3
-rw-r--r--Examples/test-suite/php/Makefile.in23
-rw-r--r--Examples/test-suite/php/mod_runme.php9
-rw-r--r--Examples/test-suite/php/tests.php33
-rw-r--r--Lib/php/phprun.swg2
-rw-r--r--Source/Modules/php.cxx9
6 files changed, 56 insertions, 23 deletions
diff --git a/Examples/Makefile.in b/Examples/Makefile.in
index e28e48149..46193348d 100644
--- a/Examples/Makefile.in
+++ b/Examples/Makefile.in
@@ -1215,6 +1215,9 @@ php_cpp: $(SRCDIR_SRCS)
php_run:
$(RUNTOOL) $(PHP) -n -d extension_dir=. -d extension=$(PHP_EXTENSION) -d display_errors=stderr -r 'set_error_handler(function($$n,$$s,$$f,$$l){if($$f!==Null){print$$f;if($$l!==Null)print":$$l";print": ";}print"$$s\n";exit(1);});if(strlen($$argv[1]))include($$argv[1]);' '$(PHP_SCRIPT)' $(RUNPIPE)
+php_run_multi:
+ $(RUNTOOL) $(PHP) -n -d extension_dir=. `while read e ; do echo ' -d extension=$(TARGETPREFIX)'"$$e"'@PHP_SO@' ; done < $(PHP_EXTENSION_LIST)` -d display_errors=stderr -r 'set_error_handler(function($$n,$$s,$$f,$$l){if($$f!==Null){print$$f;if($$l!==Null)print":$$l";print": ";}print"$$s\n";exit(1);});if(strlen($$argv[1]))include($$argv[1]);' '$(PHP_SCRIPT)' $(RUNPIPE)
+
# -----------------------------------------------------------------
# Version display
# -----------------------------------------------------------------
diff --git a/Examples/test-suite/php/Makefile.in b/Examples/test-suite/php/Makefile.in
index c918581bf..3811bd024 100644
--- a/Examples/test-suite/php/Makefile.in
+++ b/Examples/test-suite/php/Makefile.in
@@ -57,10 +57,18 @@ missingtests: missingcpptests missingctests
+$(swig_and_compile_c)
+$(run_testcase)
+# Trying to load the modules for imports.multicpptest fails with:
+#
+# Warning: Function registration failed - duplicate name - global_test in Unknown on line 0
+# Segmentation fault
+#
+# This was previously hidden because we didn't even try to load the modules for
+# .multicpptest testcases, so for now just do the parts of the test we did
+# before. FIXME: Fix this!
%.multicpptest:
$(setup)
+$(swig_and_compile_multi_cpp)
- +$(run_testcase)
+ +[ "$*" = "imports" ] || $(run_multi_testcase)
# Smart target
%.test:
@@ -72,14 +80,23 @@ missingtests: missingcpptests missingctests
$(MAKE) $*.multicpptest
# Runs the testcase. Tries to run testcase_runme.php, and if that's not found,
-# at least test that the module loads without errors, except for multicpptests.
+# at least test that the module loads without errors.
run_testcase = \
if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION=$(TARGETPREFIX)$*@PHP_SO@ PHP_SCRIPT=$(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) RUNTOOL='$(RUNTOOL)' php_run; \
- elif [ ! -f $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list ]; then \
+ else \
$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION=$(TARGETPREFIX)$*@PHP_SO@ PHP_SCRIPT= RUNTOOL='$(RUNTOOL)' php_run; \
fi
+# Runs a multicpptest testcase. Tries to run testcase_runme.php, and if that's
+# not found, at least test that the modules load without errors.
+run_multi_testcase = \
+ if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
+ $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION_LIST=$(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list PHP_SCRIPT=$(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) RUNTOOL='$(RUNTOOL)' php_run_multi; \
+ else \
+ $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION_LIST=$(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list PHP_SCRIPT= RUNTOOL='$(RUNTOOL)' php_run_multi; \
+ fi
+
# Clean: remove the generated PHP-specific files
%.clean:
@rm -f php_$*.h
diff --git a/Examples/test-suite/php/mod_runme.php b/Examples/test-suite/php/mod_runme.php
new file mode 100644
index 000000000..6e485ce80
--- /dev/null
+++ b/Examples/test-suite/php/mod_runme.php
@@ -0,0 +1,9 @@
+<?php
+
+require "tests.php";
+
+$c = new C();
+$d = new D();
+$d->DoSomething($c);
+
+check::done();
diff --git a/Examples/test-suite/php/tests.php b/Examples/test-suite/php/tests.php
index 0ff20e377..7213d7094 100644
--- a/Examples/test-suite/php/tests.php
+++ b/Examples/test-suite/php/tests.php
@@ -9,18 +9,19 @@ class check {
private static $_werror = false;
- // This is called automatically at the end of this file.
- static function init() {
- foreach(get_included_files() as $f) {
- $module_name = preg_filter('/.*\/([^\/]+)_runme\.php$/', '\1', $f);
- if ($module_name !== null) break;
- }
- if ($module_name === null) {
- print("Failed to determine module name from get_included_files()\n");
- exit(1);
+ static function get_extension() {
+ if (self::$_extension === null) {
+ foreach(get_included_files() as $f) {
+ $module_name = preg_filter('/.*\/([^\/]+)_runme\.php$/', '\1', $f);
+ if ($module_name !== null) break;
+ }
+ if ($module_name === null) {
+ print("Failed to determine module name from get_included_files()\n");
+ exit(1);
+ }
+ self::$_extension = new ReflectionExtension($module_name);
}
-
- self::$_extension = new ReflectionExtension($module_name);
+ return self::$_extension;
}
static function werror($v) {
@@ -92,7 +93,7 @@ class check {
if (! is_array($classes)) $classes=array($classes);
$message=array();
$missing=array();
- $extra = array_flip(array_filter(self::$_extension->getClassNames(),
+ $extra = array_flip(array_filter(self::get_extension()->getClassNames(),
function ($e) { return !preg_match('/^SWIG\\\\/', $e); }));
foreach($classes as $class) {
if (! class_exists($class)) $missing[]=$class;
@@ -109,7 +110,7 @@ class check {
if (! is_array($functions)) $functions=array($functions);
$message=array();
$missing=array();
- $extra = self::$_extension->getFunctions();
+ $extra = self::get_extension()->getFunctions();
foreach ($functions as $func) {
if (! function_exists($func)) $missing[]=$func;
else unset($extra[$func]);
@@ -127,7 +128,7 @@ class check {
if (! is_array($globals)) $globals=array($globals);
$message=array();
$missing=array();
- $extra = self::$_extension->getFunctions();
+ $extra = self::get_extension()->getFunctions();
foreach ($globals as $glob) {
if (! function_exists($glob . "_get") && ! function_exists($glob . "_set")) $missing[]=$glob;
else {
@@ -149,7 +150,7 @@ class check {
if (! is_array($constants)) $constants=array($constants);
$message=array();
$missing=array();
- $extra = self::$_extension->getConstants();
+ $extra = self::get_extension()->getConstants();
unset($extra['swig_runtime_data_type_pointer']);
foreach($constants as $constant) {
if (! defined($constant)) $missing[]=$constant;
@@ -213,5 +214,3 @@ class check {
# print $_SERVER[argv][0]." ok\n";
}
}
-
-check::init();
diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg
index 538b7e165..d3ad0d26a 100644
--- a/Lib/php/phprun.swg
+++ b/Lib/php/phprun.swg
@@ -193,7 +193,7 @@ SWIG_ConvertPtrAndOwn(zval *z, void **ptr, swig_type_info *ty, int flags, swig_o
/* They don't care about the target type, so just pass on the pointer! */
*ptr = value->ptr;
} else {
- swig_cast_info *tc = SWIG_TypeCheckStruct(value->type, ty);
+ swig_cast_info *tc = SWIG_TypeCheck(value->type->name, ty);
if (tc) {
int newmemory = 0;
*ptr = SWIG_TypeCast(tc, value->ptr, &newmemory);
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index a2e741215..fd53d41f7 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -1836,13 +1836,18 @@ public:
base_class = NewString("Exception");
}
- if (Equal(base_class, "Exception")) {
+ if (!base_class) {
+ Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", class_name);
+ } else if (Equal(base_class, "Exception")) {
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, zend_ce_exception);\n", class_name);
} else if (is_class_wrapped(base_class)) {
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, SWIG_Php_ce_%s);\n", class_name, base_class);
Setattr(php_parent_class, class_name, base_class);
} else {
- Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", class_name);
+ Printf(s_oinit, " {\n");
+ Printf(s_oinit, " swig_type_info *type_info = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, \"_p_%s\");\n", base_class);
+ Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, (zend_class_entry*)(type_info ? type_info->clientdata : NULL));\n", class_name);
+ Printf(s_oinit, " }\n");
}
if (Getattr(n, "abstracts") && !GetFlag(n, "feature:notabstract")) {