Changes to use common DirectorException class

Add director.swg for Go as was completely absent.
This is just the start of a common exception handling approach to directors.
An exception thrown in a Java director method will be propogated back to
Java via a C++ DirectorException.
DirectorException throws typemap for Java is fully working, all other languages need work.
DirectorException throws typemap for Perl added just to fix compilation errors.
Add director_exception_catches test.
This commit is contained in:
William S Fulton 2017-11-17 08:00:46 +00:00
parent 077bb0b04f
commit 923091da13
8 changed files with 108 additions and 2 deletions

View File

@ -181,6 +181,7 @@ CPP_TEST_CASES += \
director_detect \
director_enum \
director_exception \
director_exception_catches \
director_extend \
director_finalizer \
director_frob \

View File

@ -0,0 +1,25 @@
%module(directors="1") director_exception_catches
%include <std_string.i>
%feature("director") BaseClass;
%{
// define dummy director exception classes to prevent spurious errors
// in target languages that do not support directors.
#ifndef SWIG_DIRECTORS
namespace Swig {
class DirectorException {};
}
#endif /* !SWIG_DIRECTORS */
%}
%catches(Swig::DirectorException) BaseClass::call_description;
%inline %{
struct BaseClass {
virtual std::string description() const = 0;
static std::string call_description(BaseClass& bc) { return bc.description(); }
virtual ~BaseClass() {}
};
%}

View File

@ -0,0 +1,35 @@
import director_exception_catches.*;
public class director_exception_catches_runme {
static {
try {
System.loadLibrary("director_exception_catches");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String argv[]) {
BaseClass b = new director_exception_catches_MyClass();
try {
String s = BaseClass.call_description(b);
throw new RuntimeException("Failed to catch exception");
} catch (NullPointerException e) {
if (!e.getMessage().startsWith("Testing exception thrown in BaseClass.description"))
throw new RuntimeException("Unexpected exception message: " + e.getMessage());
}
}
}
class director_exception_catches_MyClass extends BaseClass {
@Override
public String description() {
throw new NullPointerException("Testing exception thrown in BaseClass.description");
}
}

15
Lib/go/director.swg Normal file
View File

@ -0,0 +1,15 @@
/* -----------------------------------------------------------------------------
* director.swg
*
* This file contains support for director classes so that Go proxy
* methods can be called from C++.
* ----------------------------------------------------------------------------- */
#include <exception>
namespace Swig {
class DirectorException : public std::exception {
};
}

View File

@ -1051,6 +1051,10 @@ Swig::LocalRefGuard $1_refguard(jenv, $input); }
%{ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1);
return $null; %}
// For directors to raise/throw the original Java exception
%typemap(throws) Swig::DirectorException
%{ $1.raiseJavaException(jenv);
return $null; %}
/* Typemaps for code generation in proxy classes and Java type wrapper classes */

View File

@ -46,7 +46,22 @@ namespace Swig {
}
};
struct DirectorTypeMismatchException {
// Base class for director exceptions.
class DirectorException : public std::exception {
public:
static void raise(const char *msg) {
// ... todo
throw(DirectorException());
}
static void raise(const octave_value &ov, const char *msg) {
// ... todo
raise(msg);
}
};
class DirectorTypeMismatchException : public DirectorException {
public:
static void raise(const char *msg) {
// ... todo
throw(DirectorTypeMismatchException());
@ -58,7 +73,8 @@ namespace Swig {
}
};
struct DirectorPureVirtualException {
class DirectorPureVirtualException : public DirectorException {
public:
static void raise(const char *msg) {
// ... todo
throw(DirectorPureVirtualException());

View File

@ -71,6 +71,10 @@
/* raise exception */
%define %raise(obj, type, desc) sv_setsv(get_sv("@", GV_ADD), obj); SWIG_fail %enddef
/* For directors to raise/throw the original exception */
%typemap(throws) Swig::DirectorException
%{ sv_setsv(ERRSV, $1.getNative()); SWIG_fail; %}
/* Include the unified typemap library */
%include <typemaps/swigtypemaps.swg>

View File

@ -615,6 +615,12 @@ private:
Language::top(n);
if (directorsEnabled()) {
// Insert director runtime into the f_runtime file (make it occur before %header section)
Swig_insert_file("director_common.swg", f_c_runtime);
Swig_insert_file("director.swg", f_c_runtime);
}
Delete(go_imports);
// Write out definitions for the types not defined by SWIG.