diff options
Diffstat (limited to 'share/swig/2.0.11/d/dhead.swg')
-rw-r--r-- | share/swig/2.0.11/d/dhead.swg | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/share/swig/2.0.11/d/dhead.swg b/share/swig/2.0.11/d/dhead.swg new file mode 100644 index 0000000..7a2f4fd --- /dev/null +++ b/share/swig/2.0.11/d/dhead.swg @@ -0,0 +1,344 @@ +/* ----------------------------------------------------------------------------- + * dhead.swg + * + * Support code for exceptions if the SWIG_D_NO_EXCEPTION_HELPER is not defined + * Support code for strings if the SWIG_D_NO_STRING_HELPER is not defined + * + * Support code for function pointers. ----------------------------------------------------------------------------- */ + +%insert(runtime) %{ +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +/* Contract support. */ +#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_DSetPendingException(SWIG_DException, msg); return nullreturn; } else +%} + + +/* + * Exception support code. + */ + +#if !defined(SWIG_D_NO_EXCEPTION_HELPER) +%insert(runtime) %{ +// Support for throwing D exceptions from C/C++. +typedef enum { + SWIG_DException = 0, + SWIG_DIllegalArgumentException, + SWIG_DIllegalElementException, + SWIG_DIOException, + SWIG_DNoSuchElementException, +} SWIG_DExceptionCodes; + +typedef void (* SWIG_DExceptionCallback_t)(const char *); + +typedef struct { + SWIG_DExceptionCodes code; + SWIG_DExceptionCallback_t callback; +} SWIG_DException_t; + +static SWIG_DException_t SWIG_d_exceptions[] = { + { SWIG_DException, NULL }, + { SWIG_DIllegalArgumentException, NULL }, + { SWIG_DIllegalElementException, NULL }, + { SWIG_DIOException, NULL }, + { SWIG_DNoSuchElementException, NULL } +}; + +static void SWIGUNUSED SWIG_DSetPendingException(SWIG_DExceptionCodes code, const char *msg) { + if ((size_t)code < sizeof(SWIG_d_exceptions)/sizeof(SWIG_DException_t)) { + SWIG_d_exceptions[code].callback(msg); + } else { + SWIG_d_exceptions[SWIG_DException].callback(msg); + } +} + +#ifdef __cplusplus +extern "C" +#endif +SWIGEXPORT void SWIGRegisterExceptionCallbacks_$module( + SWIG_DExceptionCallback_t exceptionCallback, + SWIG_DExceptionCallback_t illegalArgumentCallback, + SWIG_DExceptionCallback_t illegalElementCallback, + SWIG_DExceptionCallback_t ioCallback, + SWIG_DExceptionCallback_t noSuchElementCallback) { + SWIG_d_exceptions[SWIG_DException].callback = exceptionCallback; + SWIG_d_exceptions[SWIG_DIllegalArgumentException].callback = illegalArgumentCallback; + SWIG_d_exceptions[SWIG_DIllegalElementException].callback = illegalElementCallback; + SWIG_d_exceptions[SWIG_DIOException].callback = ioCallback; + SWIG_d_exceptions[SWIG_DNoSuchElementException].callback = noSuchElementCallback; +} +%} + +#if (SWIG_D_VERSION == 1) +%pragma(d) imdmoduleimports=%{ +// Exception throwing support currently requires Tango, but there is no reason +// why it could not support Phobos. +static import tango.core.Exception; +static import tango.core.Thread; +static import tango.stdc.stringz; +%} + +%pragma(d) imdmodulecode=%{ +private class SwigExceptionHelper { + static this() { + swigRegisterExceptionCallbacks$module( + &setException, + &setIllegalArgumentException, + &setIllegalElementException, + &setIOException, + &setNoSuchElementException); + } + + static void setException(char* message) { + auto exception = new object.Exception(tango.stdc.stringz.fromStringz(message).dup); + exception.next = SwigPendingException.retrieve(); + SwigPendingException.set(exception); + } + + static void setIllegalArgumentException(char* message) { + auto exception = new tango.core.Exception.IllegalArgumentException(tango.stdc.stringz.fromStringz(message).dup); + exception.next = SwigPendingException.retrieve(); + SwigPendingException.set(exception); + } + + static void setIllegalElementException(char* message) { + auto exception = new tango.core.Exception.IllegalElementException(tango.stdc.stringz.fromStringz(message).dup); + exception.next = SwigPendingException.retrieve(); + SwigPendingException.set(exception); + } + + static void setIOException(char* message) { + auto exception = new tango.core.Exception.IOException(tango.stdc.stringz.fromStringz(message).dup); + exception.next = SwigPendingException.retrieve(); + SwigPendingException.set(exception); + } + + static void setNoSuchElementException(char* message) { + auto exception = new tango.core.Exception.NoSuchElementException(tango.stdc.stringz.fromStringz(message).dup); + exception.next = SwigPendingException.retrieve(); + SwigPendingException.set(exception); + } +} + +package class SwigPendingException { +public: + static this() { + m_sPendingCount = 0; + m_sPendingException = new ThreadLocalData(null); + } + + static bool isPending() { + bool pending = false; + if (m_sPendingCount > 0) { + if (m_sPendingException.val !is null) { + pending = true; + } + } + return pending; + } + + static void set(object.Exception e) { + if (m_sPendingException.val !is null) { + throw new object.Exception("FATAL: An earlier pending exception from C/C++ code " ~ + "was missed and thus not thrown (" ~ m_sPendingException.val.classinfo.name ~ + ": " ~ m_sPendingException.val.msg ~ ")!", e); + } + + m_sPendingException.val = e; + synchronized { + ++m_sPendingCount; + } + } + + static object.Exception retrieve() { + object.Exception e = null; + if (m_sPendingCount > 0) { + if (m_sPendingException.val !is null) { + e = m_sPendingException.val; + m_sPendingException.val = null; + synchronized { + --m_sPendingCount; + } + } + } + return e; + } + +private: + // The pending exception counter is stored thread-global. + static int m_sPendingCount; + + // The reference to the pending exception (if any) is stored thread-local. + alias tango.core.Thread.ThreadLocal!(object.Exception) ThreadLocalData; + static ThreadLocalData m_sPendingException; +} +alias void function(char* message) SwigExceptionCallback; +%} +#else +%pragma(d) imdmoduleimports=%{ +static import std.conv; +%} + +%pragma(d) imdmodulecode=%{ +private class SwigExceptionHelper { + static this() { + // The D1/Tango version maps C++ exceptions to multiple exception types. + swigRegisterExceptionCallbacks$module( + &setException, + &setException, + &setException, + &setException, + &setException + ); + } + + static void setException(const char* message) { + auto exception = new object.Exception(std.conv.to!string(message).idup); + exception.next = SwigPendingException.retrieve(); + SwigPendingException.set(exception); + } +} + +package struct SwigPendingException { +public: + static this() { + m_sPendingCount = 0; + m_sPendingException = null; + } + + static bool isPending() { + bool pending = false; + if (m_sPendingCount > 0) { + if (m_sPendingException !is null) { + pending = true; + } + } + return pending; + } + + static void set(object.Exception e) { + if (m_sPendingException !is null) { + throw new object.Exception("FATAL: An earlier pending exception from C/C++ code " ~ + "was missed and thus not thrown (" ~ m_sPendingException.classinfo.name ~ + ": " ~ m_sPendingException.msg ~ ")!", e); + } + + m_sPendingException = e; + synchronized { + ++m_sPendingCount; + } + } + + static object.Exception retrieve() { + object.Exception e = null; + if (m_sPendingCount > 0) { + if (m_sPendingException !is null) { + e = m_sPendingException; + m_sPendingException = null; + synchronized { + --m_sPendingCount; + } + } + } + return e; + } + +private: + // The pending exception counter is stored thread-global. + static shared int m_sPendingCount; + + // The reference to the pending exception (if any) is stored thread-local. + static object.Exception m_sPendingException; +} +alias void function(const char* message) SwigExceptionCallback; +%} +#endif +// Callback registering function in wrapperloader.swg. +#endif // SWIG_D_NO_EXCEPTION_HELPER + + +/* + * String support code. + */ + +#if !defined(SWIG_D_NO_STRING_HELPER) +%insert(runtime) %{ +// Callback for returning strings to D without leaking memory. +typedef char * (* SWIG_DStringHelperCallback)(const char *); +static SWIG_DStringHelperCallback SWIG_d_string_callback = NULL; + +#ifdef __cplusplus +extern "C" +#endif +SWIGEXPORT void SWIGRegisterStringCallback_$module(SWIG_DStringHelperCallback callback) { + SWIG_d_string_callback = callback; +} +%} + +#if (SWIG_D_VERSION == 1) +%pragma(d) imdmoduleimports = "static import tango.stdc.stringz;"; + +%pragma(d) imdmodulecode = %{ +private class SwigStringHelper { + static this() { + swigRegisterStringCallback$module(&createString); + } + + static char* createString(char* cString) { + // We are effectively dup'ing the string here. + return tango.stdc.stringz.toStringz(tango.stdc.stringz.fromStringz(cString)); + } +} +alias char* function(char* cString) SwigStringCallback; +%} +#else +%pragma(d) imdmoduleimports = %{ +static import std.conv; +static import std.string; +%} + +%pragma(d) imdmodulecode = %{ +private class SwigStringHelper { + static this() { + swigRegisterStringCallback$module(&createString); + } + + static const(char)* createString(const(char*) cString) { + // We are effectively dup'ing the string here. + // TODO: Is this also correct for D2/Phobos? + return std.string.toStringz(std.conv.to!string(cString)); + } +} +alias const(char)* function(const(char*) cString) SwigStringCallback; +%} +#endif +// Callback registering function in wrapperloader.swg. +#endif // SWIG_D_NO_STRING_HELPER + + +/* + * Function pointer support code. + */ +#if (SWIG_D_VERSION == 1) +%pragma(d) imdmodulecode = %{ +template SwigExternC(T) { + static if (is(typeof(*(T.init)) R == return)) { + static if (is(typeof(*(T.init)) P == function)) { + alias extern(C) R function(P) SwigExternC; + } + } +} +%} +#else +%pragma(d) imdmodulecode = %{ +template SwigExternC(T) if (is(typeof(*(T.init)) P == function)) { + static if (is(typeof(*(T.init)) R == return)) { + static if (is(typeof(*(T.init)) P == function)) { + alias extern(C) R function(P) SwigExternC; + } + } +} +%} +#endif |