PageRenderTime 43ms CodeModel.GetById 13ms app.highlight 26ms RepoModel.GetById 1ms app.codeStats 0ms

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