[PHP] Fix throwing a PHP exception through C++ from a subclassed
director method - PHP NULL gets returned by the subclassed method in this case, so the directorout typemap needs to allow that (at least if an exception is active).
This commit is contained in:
parent
fa94a29df4
commit
e12322df86
4 changed files with 80 additions and 6 deletions
|
|
@ -5,6 +5,12 @@ See the RELEASENOTES file for a summary of changes in each release.
|
|||
Version 3.0.3 (in progress)
|
||||
===========================
|
||||
|
||||
2014-09-11: olly
|
||||
[PHP] Fix throwing a PHP exception through C++ from a subclassed
|
||||
director method - PHP NULL gets returned by the subclassed method
|
||||
in this case, so the directorout typemap needs to allow that (at
|
||||
least if an exception is active).
|
||||
|
||||
2014-09-09: ianlancetaylor
|
||||
[Go] Add goargout typemap.
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ Foo *launder(Foo *f) {
|
|||
%}
|
||||
|
||||
%feature("director") Bar;
|
||||
|
||||
%feature("director") ReturnAllTypes;
|
||||
|
||||
%inline %{
|
||||
struct Exception1
|
||||
|
|
@ -132,4 +132,21 @@ Foo *launder(Foo *f) {
|
|||
virtual std::string pang() throw () { return "Bar::pang()"; }
|
||||
};
|
||||
|
||||
// Class to allow regression testing SWIG/PHP not checking if an exception
|
||||
// had been thrown in directorout typemaps.
|
||||
class ReturnAllTypes
|
||||
{
|
||||
public:
|
||||
int call_int() { return return_int(); }
|
||||
double call_double() { return return_double(); }
|
||||
const char * call_const_char_star() { return return_const_char_star(); }
|
||||
std::string call_std_string() { return return_std_string(); }
|
||||
Bar call_Bar() { return return_Bar(); }
|
||||
|
||||
virtual int return_int() { return 0; }
|
||||
virtual double return_double() { return 0.0; }
|
||||
virtual const char * return_const_char_star() { return ""; }
|
||||
virtual std::string return_std_string() { return std::string(); }
|
||||
virtual Bar return_Bar() { return Bar(); }
|
||||
};
|
||||
%}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ require "tests.php";
|
|||
require "director_exception.php";
|
||||
|
||||
// No new functions
|
||||
check::functions(array(foo_ping,foo_pong,launder,bar_ping,bar_pong,bar_pang));
|
||||
check::functions(array(foo_ping,foo_pong,launder,bar_ping,bar_pong,bar_pang,returnalltypes_return_int,returnalltypes_return_double,returnalltypes_return_const_char_star,returnalltypes_return_std_string,returnalltypes_return_bar));
|
||||
// No new classes
|
||||
check::classes(array(director_exception,Foo,Exception1,Exception2,Base,Bar));
|
||||
check::classes(array(director_exception,Foo,Exception1,Exception2,Base,Bar,ReturnAllTypes));
|
||||
// now new vars
|
||||
check::globals(array());
|
||||
|
||||
|
|
@ -74,5 +74,54 @@ try {
|
|||
} catch (Exception1 $e1) {
|
||||
}
|
||||
|
||||
// Check that we can throw exceptions from director methods (this didn't used
|
||||
// to work in all cases, as the exception gets "set" in PHP and the method
|
||||
// then returns PHP NULL, which the directorout template may fail to convert.
|
||||
|
||||
class Bad extends ReturnAllTypes {
|
||||
function return_int() { throw new Exception("bad int"); }
|
||||
function return_double() { throw new Exception("bad double"); }
|
||||
function return_const_char_star() { throw new Exception("bad const_char_star"); }
|
||||
function return_std_string() { throw new Exception("bad std_string"); }
|
||||
function return_Bar() { throw new Exception("bad Bar"); }
|
||||
}
|
||||
|
||||
$bad = new Bad();
|
||||
|
||||
try {
|
||||
$bad->call_int();
|
||||
check::fail("Exception wasn't propagated from Bad::return_int()");
|
||||
} catch (Exception $e) {
|
||||
check::equal($e->getMessage(), "bad int", "propagated exception incorrect");
|
||||
}
|
||||
|
||||
try {
|
||||
$bad->call_double();
|
||||
check::fail("Exception wasn't propagated from Bad::return_double()");
|
||||
} catch (Exception $e) {
|
||||
check::equal($e->getMessage(), "bad double", "propagated exception incorrect");
|
||||
}
|
||||
|
||||
try {
|
||||
$bad->call_const_char_star();
|
||||
check::fail("Exception wasn't propagated from Bad::return_const_char_star()");
|
||||
} catch (Exception $e) {
|
||||
check::equal($e->getMessage(), "bad const_char_star", "propagated exception incorrect");
|
||||
}
|
||||
|
||||
try {
|
||||
$bad->call_std_string();
|
||||
check::fail("Exception wasn't propagated from Bad::return_std_string()");
|
||||
} catch (Exception $e) {
|
||||
check::equal($e->getMessage(), "bad std_string", "propagated exception incorrect");
|
||||
}
|
||||
|
||||
try {
|
||||
$bad->call_Bar();
|
||||
check::fail("Exception wasn't propagated from Bad::return_Bar()");
|
||||
} catch (Exception $e) {
|
||||
check::equal($e->getMessage(), "bad Bar", "propagated exception incorrect");
|
||||
}
|
||||
|
||||
check::done();
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -93,10 +93,12 @@
|
|||
|
||||
%typemap(directorout) 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");
|
||||
/* 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;
|
||||
}
|
||||
$result = *tmp;
|
||||
}
|
||||
|
||||
%typemap(in) SWIGTYPE *,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue