swig/Lib/c/c.swg
Vadim Zeitlin 10d25c7327 Drop longjmp-based exception handling approach
Using longjmp was incompatible with using C++ objects in the code using the
wrappers, and using this C API from C++ to avoid ABI incompatibilities between
different C++ compilers is one of the main reasons for using this module.

Also, this required using a separate SwigObj instead of just using the real
object pointer which inevitably resulted in memory leaks whenever a non owned
object was returned from anywhere, e.g. from a member accessor or any method
returning pointer or reference.

Abandon the attempts to recreate C++ exceptions in C and just use a very
simple approach allowing to pass an error message out of band after any
function call in a global variable. An alternative could be to add a special
"out" error parameter to each and every function, but this risked being too
verbose, especially for the functions which don't really throw, and the calls
to SWIG_PendingException_get() won't need to be made explicitly when using a
C++ wrapper around the generated C API in the future.

This simplifies both the module and the generated code, in particular we don't
need any runtime code at all any more and there is no need for an extra level
of indirection for every object.

It also makes a couple more tests pass.
2016-09-15 01:27:40 +02:00

299 lines
8.8 KiB
Text

/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* c.swg
* ----------------------------------------------------------------------------- */
%insert("runtime") "clabels.swg"
%insert("cheader") "cheader.swg"
%insert("runtime") %{
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#define SWIG_contract_assert(expr, msg) if(!(expr)) { printf("%s\n", msg); SWIG_exit(0); } else
%}
%fragment("stdbool_inc", "cheader") {#include <stdbool.h>}
%define same_macro_all_primitive_types_but_void(macro_name, TM)
macro_name(TM, short);
macro_name(TM, unsigned short);
macro_name(TM, int);
macro_name(TM, unsigned int);
macro_name(TM, long);
macro_name(TM, unsigned long);
macro_name(TM, long long);
macro_name(TM, unsigned long long);
macro_name(TM, char);
macro_name(TM, signed char);
macro_name(TM, unsigned char);
macro_name(TM, float);
macro_name(TM, double);
macro_name(TM, size_t);
%enddef
// This is used to handle all primitive types as just themselves.
// Notice that const pointers are mapped to non-const ones as we need to
// declare variables of this type when it's used as a return type, and top
// level const doesn't matter anyhow in the function declarations.
%define same_type(TM, T)
%typemap(TM) T, const T "T"
%typemap(TM) T*, T&, T[ANY], T[] "T *"
%typemap(TM) const T&, const T*, const T[ANY], const T[] "const T *"
%typemap(TM) T**, T*&, T*[ANY], T[ANY][ANY] "T **"
%typemap(TM) const T**, const T*&, T *const &, const T*[ANY], const T[ANY][ANY] "const T **"
// constant pointers
%typemap(TM) T * const "T *"
%typemap(TM) T* * const "T* *"
%typemap(TM) const T* * const "const T* *"
%enddef
%define same_type_all_primitive_types_but_void(TM)
same_macro_all_primitive_types_but_void(same_type,TM);
%enddef
//Used by 'in' and 'out' typemaps
%define same_action(TM, T, ACTION)
%typemap(TM) T, const T ACTION
%typemap(TM) T*, T&, T[ANY], T[] ACTION
%typemap(TM) const T&, const T*, const T[ANY], const T[] ACTION
%typemap(TM) T**, T*&, T*[ANY], T[ANY][ANY] ACTION
%typemap(TM) const T**, const T*&, const T*[ANY], const T[ANY][ANY] ACTION
// constant pointers
%typemap(TM) T * const ACTION
%typemap(TM) T* * const ACTION
%typemap(TM) const T* * const ACTION
%enddef
%define same_action_all_primitive_types(TM, ACTION)
same_action(TM, short, ACTION);
same_action(TM, unsigned short, ACTION);
same_action(TM, int, ACTION);
same_action(TM, unsigned int, ACTION);
same_action(TM, long, ACTION);
same_action(TM, unsigned long, ACTION);
same_action(TM, long long, ACTION);
same_action(TM, unsigned long long, ACTION);
same_action(TM, char, ACTION);
same_action(TM, signed char, ACTION);
same_action(TM, unsigned char, ACTION);
//unsigned only
same_action(TM, float, ACTION);
same_action(TM, double, ACTION);
same_action(TM, size_t, ACTION);
%typemap(TM) void*, void const* ACTION
%enddef
// "ctype" is the type used with C wrapper functions.
// void
%typemap(ctype) void "void"
%typemap(ctype) void*, void& "void *"
%typemap(ctype) const void&, const void* "const void *"
%typemap(ctype) void**, void*& "void **"
%typemap(ctype) const void**, const void*& "const void **"
// constant pointers
%typemap(ctype) void* * const "void* * const"
%typemap(ctype) const void* * const "const void* * const"
same_type_all_primitive_types_but_void(ctype);
// objects
%typemap(ctype) SWIGTYPE "$&resolved_type*"
%typemap(ctype) SWIGTYPE * "$resolved_type*"
%typemap(ctype) SWIGTYPE & "$*resolved_type*"
%typemap(ctype) SWIGTYPE *& "$resolved_type**"
%typemap(ctype) SWIGTYPE [ANY] "/*SWIGTYPE [ANY]*/ $1_ltype **"
%typemap(ctype) SWIGTYPE * [ANY] "/*SWIGTYPE *[ANY] */ $1_ltype **"
%typemap(ctype) SWIGTYPE ** "/*SWIGTYPE ** */ $1_ltype **"
%typemap(ctype) enum SWIGTYPE "int"
%typemap(ctype) enum SWIGTYPE &, enum SWIGTYPE * "int *"
%typemap(ctype, fragment="stdbool_inc") bool, bool *, const bool, const bool * "$1_ltype"
%typemap(ctype, fragment="stdbool_inc") bool & "$1_ltype"
%typemap(ctype, fragment="stdbool_inc") const bool & "const $1_ltype"
// Typemaps for assigning wrapper parameters to local variables
same_action_all_primitive_types(in, "$1 = ($1_ltype) $input;")
%typemap(in) short [ANY], int [ANY], long [ANY], long long [ANY], char [ANY], float [ANY], double [ANY], unsigned char [ANY] "$1 = ($1_basetype *) $input;"
%typemap(in) short * [ANY], int * [ANY], long * [ANY], long long * [ANY], char * [ANY], float * [ANY], double * [ANY] "$1 = ($1_basetype *) $input;"
%typemap(in, fragment="stdbool_inc") bool, bool *, bool **, const bool, const bool * "$1 = ($1_ltype) $input;"
%typemap(in, fragment="stdbool_inc") bool & "$1 = ($1_basetype *) $input;"
%typemap(in, fragment="stdbool_inc") const bool &, const bool * "$1 = ($1_basetype *) $input;"
%typemap(in) enum SWIGTYPE "$1 = ($1_ltype) $input;"
%typemap(in) enum SWIGTYPE &,enum SWIGTYPE * "$1 = ($1_ltype) $input;"
%typemap(in) SWIGTYPE [] "$1 = ($1_ltype) $input;"
%typemap(in) SWIGTYPE ((&)[ANY]) "$1 = ($1_ltype) $input;"
%typemap(in) SWIGTYPE (CLASS::*) {
if ($input)
$1 = *($&1_ltype) &$input;
}
%typemap(in) SWIGTYPE {
$1 = *($1_ltype *)$input;
}
%typemap(in) SWIGTYPE * {
if ($input)
$1 = ($1_ltype) $input;
}
%typemap(in) SWIGTYPE ** {
if ($input)
$1 = ($1_ltype) $input;
}
%typemap(in) SWIGTYPE *[ANY] {
if ($input) {
$1 = ($1_ltype) malloc($1_dim0 * sizeof($1_basetype));
size_t i = 0;
for ( ; i < $1_dim0; ++i)
if ($input[i])
$1[i] = ($*1_ltype) $input[i];
else
$1[i] = ($*1_ltype) 0;
}
else
$1 = ($1_ltype) 0;
}
%typemap(in) SWIGTYPE [ANY][ANY] {
if ($input) {
$1 = ($1_ltype) malloc($1_dim0 * $1_dim1 * sizeof($1_basetype));
size_t i = 0, j = 0;
for ( ; i < $1_dim0; ++i) {
for ( ; j < $1_dim1; ++j) {
if ($input[i][j])
$1[i][j] = * ($*1_ltype) $input[i][j];
else
$1[i][j] = * ($*1_ltype) 0;
}
}
}
else
$1 = ($1_ltype) 0;
}
%typemap(freearg) SWIGTYPE * [ANY], SWIGTYPE * [ANY][ANY], SWIGTYPE **, SWIGTYPE *** {
if ($input)
free($input);
}
%typemap(in) SWIGTYPE & {
if ($input)
$1 = ($1_ltype) $input;
else
$1 = ($1_ltype) 0;
}
%typemap(in) SWIGTYPE *& {
if ($input)
$1 = ($1_ltype) $input;
else
$1 = ($1_ltype) 0;
}
// Typemaps for assigning result values to a special return variable
same_action_all_primitive_types(out, "$result = $1;")
%typemap(out) void ""
%typemap(out, fragment="stdbool_inc") bool, bool *, const bool, const bool * "$result = ($1_ltype) $1;"
%typemap(out, fragment="stdbool_inc") bool &, const bool & "$result = $1;"
%typemap(out) enum SWIGTYPE "$result = (int) $1;"
%typemap(out) enum SWIGTYPE &, enum SWIGTYPE * "$result = $1;"
%typemap(out) SWIGTYPE (CLASS::*) {
*($&1_ltype) &$result = $1;
}
%typemap(out) SWIGTYPE *&, SWIGTYPE ** {
static SwigObj* _ptr = (SwigObj*) $1;
$result = &_ptr;
}
%typemap(out) SWIGTYPE {
$result = (SwigObj*) &$1;
}
%typemap(out) SWIGTYPE *, SWIGTYPE & {
$result = (SwigObj*) $1;
}
%typemap(out) SWIGTYPE * [ANY], SWIGTYPE [ANY][ANY] {
static SwigObj **_temp = 0;
if ($1) {
size_t i = 0;
if (_temp) {
for ( ; i < $1_dim0; ++i)
delete ($1_ltype *)_temp[i];
free(_temp);
}
_temp = (SwigObj**) malloc($1_dim0 * sizeof(SwigObj*));
for (i = 0 ; i < $1_dim0; ++i) {
if ($1[i]) {
_temp[i] = $1[i];
}
else
_temp[i] = (SwigObj*) 0;
}
$result = ($1_ltype) _temp;
}
else
$result = ($1_ltype) 0;
}
// typemaps for 'cppresult'
same_type_all_primitive_types_but_void(cppouttype);
%typemap(cppouttype, retobj="1") SWIGTYPE "$1_ltype *"
%typemap(cppouttype) SWIGTYPE * "$1_ltype"
%typemap(cppouttype) const SWIGTYPE * "const $1_ltype"
%typemap(cppouttype) SWIGTYPE & "$1_ltype"
%typemap(cppouttype) SWIGTYPE *& "$1_ltype"
%typemap(cppouttype) SWIGTYPE [ANY] "$1_ltype"
%typemap(cppouttype) SWIGTYPE * [ANY] "/*SWIGTYPE *[ANY] */ $1_ltype"
%typemap(cppouttype) SWIGTYPE ** "/*SWIGTYPE ** */ $1_basetype **"
%typemap(cppouttype, retobj="1") enum SWIGTYPE "int"
%typemap(cppouttype) enum SWIGTYPE &, enum SWIGTYPE * "int *"
%typemap(cppouttype) SWIGTYPE (CLASS::*) "$1_ltype"
%typemap(cppouttype, fragment="stdbool_inc") bool, bool *, const bool, const bool * "$1_ltype"
%typemap(cppouttype, fragment="stdbool_inc") bool & "$1_basetype*"
%typemap(cppouttype, fragment="stdbool_inc") const bool & "$1_basetype const *"
#ifdef SWIG_CPPMODE
%insert("runtime") %{
typedef struct SwigObj SwigObj;
%}
%insert("cheader") %{
typedef struct SwigObj SwigObj;
%}
#ifdef SWIG_C_EXCEPT
%include "cexcept.swg"
#endif // SWIG_C_EXCEPT
#endif // SWIG_CPPMODE
%insert("runtime") %{
#ifdef __cplusplus
extern "C" {
#endif
SWIGEXPORTC int SWIG_exit(int code) { exit(code); }
#ifdef __cplusplus
}
#endif
%}