[PHP] When using %throws or %catches, SWIG-generated PHP5 wrappers

now throw PHP Exception objects instead of giving a PHP error of
type E_ERROR.

This change shouldn't cause incompatibility issues, since you can't
set an error handler for E_ERROR, so previously PHP would just exit
which also happens for unhandled exceptions.  The benefit is you can
now catch them if you want to.

Fixes SF#2545578 and SF#2955522.


git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12055 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Olly Betts 2010-05-26 07:32:20 +00:00
commit 1392a6e497
7 changed files with 112 additions and 6 deletions

View file

@ -1,6 +1,18 @@
Version 2.0.0 (in progress)
============================
2010-05-26: olly
[PHP] When using %throws or %catches, SWIG-generated PHP5 wrappers
now throw PHP Exception objects instead of giving a PHP error of
type E_ERROR.
This change shouldn't cause incompatibility issues, since you can't
set an error handler for E_ERROR, so previously PHP would just exit
which also happens for unhandled exceptions. The benefit is you can
now catch them if you want to.
Fixes SF#2545578 and SF#2955522.
2010-05-25: olly
[PHP] Add missing directorin typemap for const std::string &.
Fixes SF#3006404 reported by t-Legiaw.

View file

@ -44,6 +44,15 @@ missingtests: missingcpptests missingctests
+$(swig_and_compile_multi_cpp)
+$(run_testcase)
# Smart target
%.test:
@echo ' $(C_TEST_CASES) '|grep -F -v ' $* ' >/dev/null ||\
$(MAKE) $*.ctest
@echo ' $(CPP_TEST_CASES) '|grep -F -v ' $* ' >/dev/null ||\
$(MAKE) $*.cpptest
@echo ' $(MULTICPP_TEST_CASES) '|grep -F -v ' $* ' >/dev/null ||\
$(MAKE) $*.multicpptest
# Runs the testcase. Tries to run testcase_runme.php, and if that's not
# found, runs testcase.php, except for multicpptests.
run_testcase = \

View file

@ -0,0 +1,39 @@
<?
require "tests.php";
require "exception_order.php";
check::functions(array(a_foo,a_bar,a_foobar,a_barfoo));
check::classes(array(A,E1,E2,E3,exception_order,ET_i,ET_d));
check::globals(array(efoovar,foovar,cfoovar,a_sfoovar,a_foovar,a_efoovar));
$a = new A();
try {
$a->foo();
} catch (Exception $e) {
check::equal($e->getMessage(), 'C++ E1 exception thrown', '');
}
try {
$a->bar();
} catch (Exception $e) {
check::equal($e->getMessage(), 'C++ E2 exception thrown', '');
}
try {
$a->foobar();
} catch (Exception $e) {
check::equal($e->getMessage(), 'postcatch unknown', '');
}
try {
$a->barfoo(1);
} catch (Exception $e) {
check::equal($e->getMessage(), 'C++ E1 exception thrown', '');
}
try {
$a->barfoo(2);
} catch (Exception $e) {
check::equal($e->getMessage(), 'C++ E2 * exception thrown', '');
}
?>

View file

@ -0,0 +1,43 @@
<?php
require "tests.php";
require "threads_exception.php";
// Check functions
check::functions(array(test_simple,test_message,test_hosed,test_unknown,test_multi));
// Check classes.
check::classes(array(Exc,Test));
// Chek globals.
check::globals(array(exc_code,exc_msg));
$t = new Test();
try {
$t->unknown();
} catch (Exception $e) {
check::equal($e->getMessage(), 'C++ A * exception thrown', '');
}
try {
$t->simple();
} catch (Exception $e) {
check::equal($e->getCode(), 37, '');
}
try {
$t->message();
} catch (Exception $e) {
check::equal($e->getMessage(), 'I died.', '');
}
try {
$t->hosed();
} catch (Exception $e) {
check::equal($e->getMessage(), 'C++ Exc exception thrown', '');
}
foreach (Array(1,2,3,4) as $i) {
try {
$t->multi($i);
} catch (Exception $e) {
}
}

View file

@ -461,18 +461,19 @@
unsigned int,
unsigned long,
unsigned short {
char error_msg[256];
sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1);
SWIG_PHP_Error(E_ERROR, error_msg);
zend_throw_exception(NULL, const_cast<char*>("C++ $1_type exception thrown"), $1 TSRMLS_CC);
return;
}
%typemap(throws) SWIGTYPE, SWIGTYPE &, SWIGTYPE *, SWIGTYPE [], SWIGTYPE [ANY] %{
(void)$1;
SWIG_PHP_Error(E_ERROR, "C++ $1_type exception thrown");
zend_throw_exception(NULL, const_cast<char*>("C++ $1_type exception thrown"), 0 TSRMLS_CC);
return;
%}
%typemap(throws) char * %{
SWIG_PHP_Error(E_ERROR, (char *)$1);
zend_throw_exception(NULL, const_cast<char*>($1), 0 TSRMLS_CC);
return;
%}
/* Array reference typemaps */

View file

@ -9,6 +9,7 @@ extern "C" {
#endif
#include "zend.h"
#include "zend_API.h"
#include "zend_exceptions.h"
#include "php.h"
#include "ext/standard/php_string.h"

View file

@ -50,7 +50,8 @@ namespace std {
%}
%typemap(throws) string, const string& %{
SWIG_PHP_Error(E_ERROR, const_cast<char*>($1.c_str()));
zend_throw_exception(NULL, const_cast<char*>($1.c_str()), 0 TSRMLS_CC);
return;
%}
/* These next two handle a function which takes a non-const reference to