/trunk/Lib/d/dhead.swg

# · Unknown · 344 lines · 300 code · 44 blank · 0 comment · 0 complexity · b3d4fe5beeca8c8d74cf2192afc25dfd MD5 · raw file

  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(const char* message) {
  82. auto exception = new object.Exception(tango.stdc.stringz.fromStringz(message).dup);
  83. exception.next = SwigPendingException.retrieve();
  84. SwigPendingException.set(exception);
  85. }
  86. static void setIllegalArgumentException(const char* message) {
  87. auto exception = new tango.core.Exception.IllegalArgumentException(tango.stdc.stringz.fromStringz(message).dup);
  88. exception.next = SwigPendingException.retrieve();
  89. SwigPendingException.set(exception);
  90. }
  91. static void setIllegalElementException(const char* message) {
  92. auto exception = new tango.core.Exception.IllegalElementException(tango.stdc.stringz.fromStringz(message).dup);
  93. exception.next = SwigPendingException.retrieve();
  94. SwigPendingException.set(exception);
  95. }
  96. static void setIOException(const char* message) {
  97. auto exception = new tango.core.Exception.IOException(tango.stdc.stringz.fromStringz(message).dup);
  98. exception.next = SwigPendingException.retrieve();
  99. SwigPendingException.set(exception);
  100. }
  101. static void setNoSuchElementException(const char* message) {
  102. auto exception = new tango.core.Exception.NoSuchElementException(tango.stdc.stringz.fromStringz(message).dup);
  103. exception.next = SwigPendingException.retrieve();
  104. SwigPendingException.set(exception);
  105. }
  106. }
  107. package class SwigPendingException {
  108. public:
  109. static this() {
  110. m_sPendingCount = 0;
  111. m_sPendingException = new ThreadLocalData(null);
  112. }
  113. static bool isPending() {
  114. bool pending = false;
  115. if (m_sPendingCount > 0) {
  116. if (m_sPendingException.val !is null) {
  117. pending = true;
  118. }
  119. }
  120. return pending;
  121. }
  122. static void set(object.Exception e) {
  123. if (m_sPendingException.val !is null) {
  124. throw new object.Exception("FATAL: An earlier pending exception from C/C++ code " ~
  125. "was missed and thus not thrown (" ~ m_sPendingException.val.classinfo.name ~
  126. ": " ~ m_sPendingException.val.msg ~ ")!", e);
  127. }
  128. m_sPendingException.val = e;
  129. synchronized {
  130. ++m_sPendingCount;
  131. }
  132. }
  133. static object.Exception retrieve() {
  134. object.Exception e = null;
  135. if (m_sPendingCount > 0) {
  136. if (m_sPendingException.val !is null) {
  137. e = m_sPendingException.val;
  138. m_sPendingException.val = null;
  139. synchronized {
  140. --m_sPendingCount;
  141. }
  142. }
  143. }
  144. return e;
  145. }
  146. private:
  147. // The pending exception counter is stored thread-global.
  148. static int m_sPendingCount;
  149. // The reference to the pending exception (if any) is stored thread-local.
  150. alias tango.core.Thread.ThreadLocal!(object.Exception) ThreadLocalData;
  151. static ThreadLocalData m_sPendingException;
  152. }
  153. alias void function(const char* message) SwigExceptionCallback;
  154. %}
  155. #else
  156. %pragma(d) imdmoduleimports=%{
  157. static import std.conv;
  158. %}
  159. %pragma(d) imdmodulecode=%{
  160. private class SwigExceptionHelper {
  161. static this() {
  162. // The D1/Tango version maps C++ exceptions to multiple exception types.
  163. swigRegisterExceptionCallbacks$module(
  164. &setException,
  165. &setException,
  166. &setException,
  167. &setException,
  168. &setException
  169. );
  170. }
  171. static void setException(const char* message) {
  172. auto exception = new object.Exception(std.conv.to!string(message).idup);
  173. exception.next = SwigPendingException.retrieve();
  174. SwigPendingException.set(exception);
  175. }
  176. }
  177. package struct SwigPendingException {
  178. public:
  179. static this() {
  180. m_sPendingCount = 0;
  181. m_sPendingException = null;
  182. }
  183. static bool isPending() {
  184. bool pending = false;
  185. if (m_sPendingCount > 0) {
  186. if (m_sPendingException !is null) {
  187. pending = true;
  188. }
  189. }
  190. return pending;
  191. }
  192. static void set(object.Exception e) {
  193. if (m_sPendingException !is null) {
  194. throw new object.Exception("FATAL: An earlier pending exception from C/C++ code " ~
  195. "was missed and thus not thrown (" ~ m_sPendingException.classinfo.name ~
  196. ": " ~ m_sPendingException.msg ~ ")!", e);
  197. }
  198. m_sPendingException = e;
  199. synchronized {
  200. ++m_sPendingCount;
  201. }
  202. }
  203. static object.Exception retrieve() {
  204. object.Exception e = null;
  205. if (m_sPendingCount > 0) {
  206. if (m_sPendingException !is null) {
  207. e = m_sPendingException;
  208. m_sPendingException = null;
  209. synchronized {
  210. --m_sPendingCount;
  211. }
  212. }
  213. }
  214. return e;
  215. }
  216. private:
  217. // The pending exception counter is stored thread-global.
  218. static shared int m_sPendingCount;
  219. // The reference to the pending exception (if any) is stored thread-local.
  220. static object.Exception m_sPendingException;
  221. }
  222. alias void function(const char* message) SwigExceptionCallback;
  223. %}
  224. #endif
  225. // Callback registering function in wrapperloader.swg.
  226. #endif // SWIG_D_NO_EXCEPTION_HELPER
  227. /*
  228. * String support code.
  229. */
  230. #if !defined(SWIG_D_NO_STRING_HELPER)
  231. %insert(runtime) %{
  232. // Callback for returning strings to D without leaking memory.
  233. typedef char * (* SWIG_DStringHelperCallback)(const char *);
  234. static SWIG_DStringHelperCallback SWIG_d_string_callback = NULL;
  235. #ifdef __cplusplus
  236. extern "C"
  237. #endif
  238. SWIGEXPORT void SWIGRegisterStringCallback_$module(SWIG_DStringHelperCallback callback) {
  239. SWIG_d_string_callback = callback;
  240. }
  241. %}
  242. #if (SWIG_D_VERSION == 1)
  243. %pragma(d) imdmoduleimports = "static import tango.stdc.stringz;";
  244. %pragma(d) imdmodulecode = %{
  245. private class SwigStringHelper {
  246. static this() {
  247. swigRegisterStringCallback$module(&createString);
  248. }
  249. static char* createString(char* cString) {
  250. // We are effectively dup'ing the string here.
  251. return tango.stdc.stringz.toStringz(tango.stdc.stringz.fromStringz(cString));
  252. }
  253. }
  254. alias char* function(char* cString) SwigStringCallback;
  255. %}
  256. #else
  257. %pragma(d) imdmoduleimports = %{
  258. static import std.conv;
  259. static import std.string;
  260. %}
  261. %pragma(d) imdmodulecode = %{
  262. private class SwigStringHelper {
  263. static this() {
  264. swigRegisterStringCallback$module(&createString);
  265. }
  266. static const(char)* createString(const(char*) cString) {
  267. // We are effectively dup'ing the string here.
  268. // TODO: Is this also correct for D2/Phobos?
  269. return std.string.toStringz(std.conv.to!string(cString));
  270. }
  271. }
  272. alias const(char)* function(const(char*) cString) SwigStringCallback;
  273. %}
  274. #endif
  275. // Callback registering function in wrapperloader.swg.
  276. #endif // SWIG_D_NO_STRING_HELPER
  277. /*
  278. * Function pointer support code.
  279. */
  280. #if (SWIG_D_VERSION == 1)
  281. %pragma(d) imdmodulecode = %{
  282. template SwigExternC(T) {
  283. static if (is(typeof(*(T.init)) R == return)) {
  284. static if (is(typeof(*(T.init)) P == function)) {
  285. alias extern(C) R function(P) SwigExternC;
  286. }
  287. }
  288. }
  289. %}
  290. #else
  291. %pragma(d) imdmodulecode = %{
  292. template SwigExternC(T) if (is(typeof(*(T.init)) P == function)) {
  293. static if (is(typeof(*(T.init)) R == return)) {
  294. static if (is(typeof(*(T.init)) P == function)) {
  295. alias extern(C) R function(P) SwigExternC;
  296. }
  297. }
  298. }
  299. %}
  300. #endif