dhead.swg 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /* -----------------------------------------------------------------------------
  2. * dhead.swg
  3. *
  4. * Support code for exceptions if the SWIG_D_NO_EXCEPTION_HELPER is not defined
  5. * Support code for strings if the SWIG_D_NO_STRING_HELPER is not defined
  6. *
  7. * Support code for function pointers. ----------------------------------------------------------------------------- */
  8. %insert(runtime) %{
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <stdio.h>
  12. /* Contract support. */
  13. #define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_DSetPendingException(SWIG_DException, msg); return nullreturn; } else
  14. %}
  15. /*
  16. * Exception support code.
  17. */
  18. #if !defined(SWIG_D_NO_EXCEPTION_HELPER)
  19. %insert(runtime) %{
  20. // Support for throwing D exceptions from C/C++.
  21. typedef enum {
  22. SWIG_DException = 0,
  23. SWIG_DIllegalArgumentException,
  24. SWIG_DIllegalElementException,
  25. SWIG_DIOException,
  26. SWIG_DNoSuchElementException
  27. } SWIG_DExceptionCodes;
  28. typedef void (* SWIG_DExceptionCallback_t)(const char *);
  29. typedef struct {
  30. SWIG_DExceptionCodes code;
  31. SWIG_DExceptionCallback_t callback;
  32. } SWIG_DException_t;
  33. static SWIG_DException_t SWIG_d_exceptions[] = {
  34. { SWIG_DException, NULL },
  35. { SWIG_DIllegalArgumentException, NULL },
  36. { SWIG_DIllegalElementException, NULL },
  37. { SWIG_DIOException, NULL },
  38. { SWIG_DNoSuchElementException, NULL }
  39. };
  40. static void SWIGUNUSED SWIG_DSetPendingException(SWIG_DExceptionCodes code, const char *msg) {
  41. if ((size_t)code < sizeof(SWIG_d_exceptions)/sizeof(SWIG_DException_t)) {
  42. SWIG_d_exceptions[code].callback(msg);
  43. } else {
  44. SWIG_d_exceptions[SWIG_DException].callback(msg);
  45. }
  46. }
  47. #ifdef __cplusplus
  48. extern "C"
  49. #endif
  50. SWIGEXPORT void SWIGRegisterExceptionCallbacks_$module(
  51. SWIG_DExceptionCallback_t exceptionCallback,
  52. SWIG_DExceptionCallback_t illegalArgumentCallback,
  53. SWIG_DExceptionCallback_t illegalElementCallback,
  54. SWIG_DExceptionCallback_t ioCallback,
  55. SWIG_DExceptionCallback_t noSuchElementCallback) {
  56. SWIG_d_exceptions[SWIG_DException].callback = exceptionCallback;
  57. SWIG_d_exceptions[SWIG_DIllegalArgumentException].callback = illegalArgumentCallback;
  58. SWIG_d_exceptions[SWIG_DIllegalElementException].callback = illegalElementCallback;
  59. SWIG_d_exceptions[SWIG_DIOException].callback = ioCallback;
  60. SWIG_d_exceptions[SWIG_DNoSuchElementException].callback = noSuchElementCallback;
  61. }
  62. %}
  63. #if (SWIG_D_VERSION == 1)
  64. %pragma(d) imdmoduleimports=%{
  65. // Exception throwing support currently requires Tango, but there is no reason
  66. // why it could not support Phobos.
  67. static import tango.core.Exception;
  68. static import tango.core.Thread;
  69. static import tango.stdc.stringz;
  70. %}
  71. %pragma(d) imdmodulecode=%{
  72. private class SwigExceptionHelper {
  73. static this() {
  74. swigRegisterExceptionCallbacks$module(
  75. &setException,
  76. &setIllegalArgumentException,
  77. &setIllegalElementException,
  78. &setIOException,
  79. &setNoSuchElementException);
  80. }
  81. static void setException(char* message) {
  82. auto exception = new object.Exception(tango.stdc.stringz.fromStringz(message).dup);
  83. SwigPendingException.set(exception);
  84. }
  85. static void setIllegalArgumentException(char* message) {
  86. auto exception = new tango.core.Exception.IllegalArgumentException(tango.stdc.stringz.fromStringz(message).dup);
  87. SwigPendingException.set(exception);
  88. }
  89. static void setIllegalElementException(char* message) {
  90. auto exception = new tango.core.Exception.IllegalElementException(tango.stdc.stringz.fromStringz(message).dup);
  91. SwigPendingException.set(exception);
  92. }
  93. static void setIOException(char* message) {
  94. auto exception = new tango.core.Exception.IOException(tango.stdc.stringz.fromStringz(message).dup);
  95. SwigPendingException.set(exception);
  96. }
  97. static void setNoSuchElementException(char* message) {
  98. auto exception = new tango.core.Exception.NoSuchElementException(tango.stdc.stringz.fromStringz(message).dup);
  99. SwigPendingException.set(exception);
  100. }
  101. }
  102. package class SwigPendingException {
  103. public:
  104. static this() {
  105. m_sPendingException = new ThreadLocalData(null);
  106. }
  107. static bool isPending() {
  108. return m_sPendingException.val !is null;
  109. }
  110. static void set(object.Exception e) {
  111. auto pending = m_sPendingException.val;
  112. if (pending !is null) {
  113. e.next = pending;
  114. throw new object.Exception("FATAL: An earlier pending exception from C/C++ " ~
  115. "code was missed and thus not thrown (" ~ pending.classinfo.name ~ ": " ~
  116. pending.msg ~ ")!", e);
  117. }
  118. m_sPendingException.val = e;
  119. }
  120. static object.Exception retrieve() {
  121. auto e = m_sPendingException.val;
  122. m_sPendingException.val = null;
  123. return e;
  124. }
  125. private:
  126. // The reference to the pending exception (if any) is stored thread-local.
  127. alias tango.core.Thread.ThreadLocal!(object.Exception) ThreadLocalData;
  128. static ThreadLocalData m_sPendingException;
  129. }
  130. alias void function(char* message) SwigExceptionCallback;
  131. %}
  132. #else
  133. %pragma(d) imdmoduleimports=%{
  134. static import std.conv;
  135. %}
  136. %pragma(d) imdmodulecode=%{
  137. private class SwigExceptionHelper {
  138. static this() {
  139. // The D1/Tango version maps C++ exceptions to multiple exception types.
  140. swigRegisterExceptionCallbacks$module(
  141. &setException,
  142. &setException,
  143. &setException,
  144. &setException,
  145. &setException
  146. );
  147. }
  148. static void setException(const char* message) {
  149. auto exception = new object.Exception(std.conv.to!string(message));
  150. SwigPendingException.set(exception);
  151. }
  152. }
  153. package struct SwigPendingException {
  154. public:
  155. static this() {
  156. m_sPendingException = null;
  157. }
  158. static bool isPending() {
  159. return m_sPendingException !is null;
  160. }
  161. static void set(object.Exception e) {
  162. if (m_sPendingException !is null) {
  163. e.next = m_sPendingException;
  164. throw new object.Exception("FATAL: An earlier pending exception from C/C++ code " ~
  165. "was missed and thus not thrown (" ~ m_sPendingException.classinfo.name ~
  166. ": " ~ m_sPendingException.msg ~ ")!", e);
  167. }
  168. m_sPendingException = e;
  169. }
  170. static object.Exception retrieve() {
  171. auto e = m_sPendingException;
  172. m_sPendingException = null;
  173. return e;
  174. }
  175. private:
  176. // The reference to the pending exception (if any) is stored thread-local.
  177. static object.Exception m_sPendingException;
  178. }
  179. alias void function(const char* message) SwigExceptionCallback;
  180. %}
  181. #endif
  182. // Callback registering function in wrapperloader.swg.
  183. #endif // SWIG_D_NO_EXCEPTION_HELPER
  184. /*
  185. * String support code.
  186. */
  187. #if !defined(SWIG_D_NO_STRING_HELPER)
  188. %insert(runtime) %{
  189. // Callback for returning strings to D without leaking memory.
  190. typedef char * (* SWIG_DStringHelperCallback)(const char *);
  191. static SWIG_DStringHelperCallback SWIG_d_string_callback = NULL;
  192. #ifdef __cplusplus
  193. extern "C"
  194. #endif
  195. SWIGEXPORT void SWIGRegisterStringCallback_$module(SWIG_DStringHelperCallback callback) {
  196. SWIG_d_string_callback = callback;
  197. }
  198. %}
  199. #if (SWIG_D_VERSION == 1)
  200. %pragma(d) imdmoduleimports = "static import tango.stdc.stringz;";
  201. %pragma(d) imdmodulecode = %{
  202. private class SwigStringHelper {
  203. static this() {
  204. swigRegisterStringCallback$module(&createString);
  205. }
  206. static char* createString(char* cString) {
  207. // We are effectively dup'ing the string here.
  208. return tango.stdc.stringz.toStringz(tango.stdc.stringz.fromStringz(cString));
  209. }
  210. }
  211. alias char* function(char* cString) SwigStringCallback;
  212. %}
  213. #else
  214. %pragma(d) imdmoduleimports = %{
  215. static import std.conv;
  216. static import std.string;
  217. %}
  218. %pragma(d) imdmodulecode = %{
  219. private class SwigStringHelper {
  220. static this() {
  221. swigRegisterStringCallback$module(&createString);
  222. }
  223. static const(char)* createString(const(char*) cString) {
  224. // We are effectively dup'ing the string here.
  225. // TODO: Is this also correct for D2/Phobos?
  226. return std.string.toStringz(std.conv.to!string(cString));
  227. }
  228. }
  229. alias const(char)* function(const(char*) cString) SwigStringCallback;
  230. %}
  231. #endif
  232. // Callback registering function in wrapperloader.swg.
  233. #endif // SWIG_D_NO_STRING_HELPER
  234. /*
  235. * Function pointer support code.
  236. */
  237. #if (SWIG_D_VERSION == 1)
  238. %pragma(d) imdmodulecode = %{
  239. template SwigExternC(T) {
  240. static if (is(typeof(*(T.init)) R == return)) {
  241. static if (is(typeof(*(T.init)) P == function)) {
  242. alias extern(C) R function(P) SwigExternC;
  243. }
  244. }
  245. }
  246. %}
  247. #else
  248. %pragma(d) imdmodulecode = %{
  249. template SwigExternC(T) if (is(typeof(*(T.init)) P == function)) {
  250. static if (is(typeof(*(T.init)) R == return)) {
  251. static if (is(typeof(*(T.init)) P == function)) {
  252. alias extern(C) R function(P) SwigExternC;
  253. }
  254. }
  255. }
  256. %}
  257. #endif