diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 8d6f94f43..db9b13433 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -181,6 +181,7 @@ CPP_TEST_CASES += \ director_detect \ director_enum \ director_exception \ + director_exception_catches \ director_extend \ director_finalizer \ director_frob \ diff --git a/Examples/test-suite/director_exception_catches.i b/Examples/test-suite/director_exception_catches.i new file mode 100644 index 000000000..ad183665f --- /dev/null +++ b/Examples/test-suite/director_exception_catches.i @@ -0,0 +1,25 @@ +%module(directors="1") director_exception_catches + +%include +%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() {} +}; +%} diff --git a/Examples/test-suite/java/director_exception_catches_runme.java b/Examples/test-suite/java/director_exception_catches_runme.java new file mode 100644 index 000000000..c6fed192d --- /dev/null +++ b/Examples/test-suite/java/director_exception_catches_runme.java @@ -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"); + } +} + diff --git a/Lib/go/director.swg b/Lib/go/director.swg new file mode 100644 index 000000000..69244ebea --- /dev/null +++ b/Lib/go/director.swg @@ -0,0 +1,15 @@ +/* ----------------------------------------------------------------------------- + * director.swg + * + * This file contains support for director classes so that Go proxy + * methods can be called from C++. + * ----------------------------------------------------------------------------- */ + +#include + +namespace Swig { + + class DirectorException : public std::exception { + }; +} + diff --git a/Lib/java/java.swg b/Lib/java/java.swg index 903387a1d..809fc40a3 100644 --- a/Lib/java/java.swg +++ b/Lib/java/java.swg @@ -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 */ diff --git a/Lib/octave/director.swg b/Lib/octave/director.swg index e80877ef6..86ac3b004 100644 --- a/Lib/octave/director.swg +++ b/Lib/octave/director.swg @@ -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()); diff --git a/Lib/perl5/perltypemaps.swg b/Lib/perl5/perltypemaps.swg index ffec5eaf1..a86d3ad54 100644 --- a/Lib/perl5/perltypemaps.swg +++ b/Lib/perl5/perltypemaps.swg @@ -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 diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index 896872d47..572985a6c 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -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.