summaryrefslogtreecommitdiff
path: root/Source/Swig/stype.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Swig/stype.c')
-rw-r--r--Source/Swig/stype.c1105
1 files changed, 1105 insertions, 0 deletions
diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c
new file mode 100644
index 0000000..68696ec
--- /dev/null
+++ b/Source/Swig/stype.c
@@ -0,0 +1,1105 @@
+/* -----------------------------------------------------------------------------
+ * 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.
+ *
+ * stype.c
+ *
+ * This file provides general support for datatypes that are encoded in
+ * the form of simple strings.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_stype_c[] = "$Id: stype.c 11080 2009-01-24 13:15:51Z bhy $";
+
+#include "swig.h"
+#include "cparse.h"
+#include <ctype.h>
+
+/* -----------------------------------------------------------------------------
+ * Synopsis
+ *
+ * The purpose of this module is to provide a general purpose type representation
+ * based on simple text strings.
+ *
+ * General idea:
+ *
+ * Types are represented by a base type (e.g., "int") and a collection of
+ * type operators applied to the base (e.g., pointers, arrays, etc...).
+ *
+ * Encoding:
+ *
+ * Types are encoded as strings of type constructors such as follows:
+ *
+ * String Encoding C Example
+ * --------------- ---------
+ * p.p.int int **
+ * a(300).a(400).int int [300][400]
+ * p.q(const).char char const *
+ *
+ * All type constructors are denoted by a trailing '.':
+ *
+ * 'p.' = Pointer (*)
+ * 'r.' = Reference (&)
+ * 'a(n).' = Array of size n [n]
+ * 'f(..,..).' = Function with arguments (args)
+ * 'q(str).' = Qualifier (such as const or volatile) (const, volatile)
+ * 'm(qual).' = Pointer to member (qual::*)
+ *
+ * The encoding follows the order that you might describe a type in words.
+ * For example "p.a(200).int" is "A pointer to array of int's" and
+ * "p.q(const).char" is "a pointer to a const char".
+ *
+ * This representation of types is fairly convenient because ordinary string
+ * operations can be used for type manipulation. For example, a type could be
+ * formed by combining two strings such as the following:
+ *
+ * "p.p." + "a(400).int" = "p.p.a(400).int"
+ *
+ * Similarly, one could strip a 'const' declaration from a type doing something
+ * like this:
+ *
+ * Replace(t,"q(const).","",DOH_REPLACE_ANY)
+ *
+ * For the most part, this module tries to minimize the use of special
+ * characters (*, [, <, etc...) in its type encoding. One reason for this
+ * is that SWIG might be extended to encode data in formats such as XML
+ * where you might want to do this:
+ *
+ * <function>
+ * <type>p.p.int</type>
+ * ...
+ * </function>
+ *
+ * Or alternatively,
+ *
+ * <function type="p.p.int" ...>blah</function>
+ *
+ * In either case, it's probably best to avoid characters such as '&', '*', or '<'.
+ *
+ * Why not use C syntax? Well, C syntax is fairly complicated to parse
+ * and not particularly easy to manipulate---especially for adding, deleting and
+ * composing type constructors. The string representation presented here makes
+ * this pretty easy.
+ *
+ * Why not use a bunch of nested data structures? Are you kidding? How
+ * would that be easier to use than a few simple string operations?
+ * ----------------------------------------------------------------------------- */
+
+
+SwigType *NewSwigType(int t) {
+ switch (t) {
+ case T_BOOL:
+ return NewString("bool");
+ break;
+ case T_INT:
+ return NewString("int");
+ break;
+ case T_UINT:
+ return NewString("unsigned int");
+ break;
+ case T_SHORT:
+ return NewString("short");
+ break;
+ case T_USHORT:
+ return NewString("unsigned short");
+ break;
+ case T_LONG:
+ return NewString("long");
+ break;
+ case T_ULONG:
+ return NewString("unsigned long");
+ break;
+ case T_FLOAT:
+ return NewString("float");
+ break;
+ case T_DOUBLE:
+ return NewString("double");
+ break;
+ case T_COMPLEX:
+ return NewString("complex");
+ break;
+ case T_CHAR:
+ return NewString("char");
+ break;
+ case T_SCHAR:
+ return NewString("signed char");
+ break;
+ case T_UCHAR:
+ return NewString("unsigned char");
+ break;
+ case T_STRING:{
+ SwigType *t = NewString("char");
+ SwigType_add_pointer(t);
+ return t;
+ break;
+ }
+ case T_LONGLONG:
+ return NewString("long long");
+ break;
+ case T_ULONGLONG:
+ return NewString("unsigned long long");
+ break;
+ case T_VOID:
+ return NewString("void");
+ break;
+ default:
+ break;
+ }
+ return NewStringEmpty();
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_push()
+ *
+ * Push a type constructor onto the type
+ * ----------------------------------------------------------------------------- */
+
+void SwigType_push(SwigType *t, String *cons) {
+ if (!cons)
+ return;
+ if (!Len(cons))
+ return;
+
+ if (Len(t)) {
+ char *c = Char(cons);
+ if (c[strlen(c) - 1] != '.')
+ Insert(t, 0, ".");
+ }
+ Insert(t, 0, cons);
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_ispointer_return()
+ *
+ * Testing functions for querying a raw datatype
+ * ----------------------------------------------------------------------------- */
+
+int SwigType_ispointer_return(SwigType *t) {
+ char *c;
+ int idx;
+ if (!t)
+ return 0;
+ c = Char(t);
+ idx = strlen(c) - 4;
+ if (idx >= 0) {
+ return (strcmp(c + idx, ").p.") == 0);
+ }
+ return 0;
+}
+
+int SwigType_isreference_return(SwigType *t) {
+ char *c;
+ int idx;
+ if (!t)
+ return 0;
+ c = Char(t);
+ idx = strlen(c) - 4;
+ if (idx >= 0) {
+ return (strcmp(c + idx, ").r.") == 0);
+ }
+ return 0;
+}
+
+int SwigType_isconst(SwigType *t) {
+ char *c;
+ if (!t)
+ return 0;
+ c = Char(t);
+ if (strncmp(c, "q(", 2) == 0) {
+ String *q = SwigType_parm(t);
+ if (strstr(Char(q), "const")) {
+ Delete(q);
+ return 1;
+ }
+ Delete(q);
+ }
+ /* Hmmm. Might be const through a typedef */
+ if (SwigType_issimple(t)) {
+ int ret;
+ SwigType *td = SwigType_typedef_resolve(t);
+ if (td) {
+ ret = SwigType_isconst(td);
+ Delete(td);
+ return ret;
+ }
+ }
+ return 0;
+}
+
+int SwigType_ismutable(SwigType *t) {
+ int r;
+ SwigType *qt = SwigType_typedef_resolve_all(t);
+ if (SwigType_isreference(qt) || SwigType_isarray(qt)) {
+ Delete(SwigType_pop(qt));
+ }
+ r = SwigType_isconst(qt);
+ Delete(qt);
+ return r ? 0 : 1;
+}
+
+int SwigType_isenum(SwigType *t) {
+ char *c = Char(t);
+ if (!t)
+ return 0;
+ if (strncmp(c, "enum ", 5) == 0) {
+ return 1;
+ }
+ return 0;
+}
+
+int SwigType_issimple(SwigType *t) {
+ char *c = Char(t);
+ if (!t)
+ return 0;
+ while (*c) {
+ if (*c == '<') {
+ int nest = 1;
+ c++;
+ while (*c && nest) {
+ if (*c == '<')
+ nest++;
+ if (*c == '>')
+ nest--;
+ c++;
+ }
+ c--;
+ }
+ if (*c == '.')
+ return 0;
+ c++;
+ }
+ return 1;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_default()
+ *
+ * Create the default string for this datatype. This takes a type and strips it
+ * down to its most primitive form--resolving all typedefs and removing operators.
+ *
+ * Rules:
+ * Pointers: p.SWIGTYPE
+ * References: r.SWIGTYPE
+ * Arrays: a().SWIGTYPE
+ * Types: SWIGTYPE
+ * MemberPointer: m(CLASS).SWIGTYPE
+ * Enums: enum SWIGTYPE
+ *
+ * Note: if this function is applied to a primitive type, it returns NULL. This
+ * allows recursive application for special types like arrays.
+ * ----------------------------------------------------------------------------- */
+
+#ifdef SWIG_DEFAULT_CACHE
+static Hash *default_cache = 0;
+#endif
+
+#define SWIG_NEW_TYPE_DEFAULT
+/* The new default type resolution method:
+
+1.- It preserves the original mixed types, then it goes 'backward'
+ first deleting the qualifier, then the inner types
+
+ typedef A *Aptr;
+ const Aptr&;
+ r.q(const).Aptr -> r.q(const).p.SWIGTYPE
+ r.q(const).p.SWIGTYPE -> r.p.SWIGTYPE
+ r.p.SWIGTYPE -> r.SWIGTYPE
+ r.SWIGTYPE -> SWIGTYPE
+
+
+ enum Hello {};
+ const Hello& hi;
+ r.q(const).Hello -> r.q(const).enum SWIGTYPE
+ r.q(const).enum SWIGTYPE -> r.enum SWIGTYPE
+ r.enum SWIGTYPE -> r.SWIGTYPE
+ r.SWIGTYPE -> SWIGTYPE
+
+ int a[2][4];
+ a(2).a(4).int -> a(ANY).a(ANY).SWIGTYPE
+ a(ANY).a(ANY).SWIGTYPE -> a(ANY).a().SWIGTYPE
+ a(ANY).a().SWIGTYPE -> a(ANY).p.SWIGTYPE
+ a(ANY).p.SWIGTYPE -> a(ANY).SWIGTYPE
+ a(ANY).SWIGTYPE -> a().SWIGTYPE
+ a().SWIGTYPE -> p.SWIGTYPE
+ p.SWIGTYPE -> SWIGTYPE
+*/
+
+static
+void SwigType_add_default(String *def, SwigType *nr) {
+ if (Strcmp(nr, "SWIGTYPE") == 0) {
+ Append(def, "SWIGTYPE");
+ } else {
+ String *q = SwigType_isqualifier(nr) ? SwigType_pop(nr) : 0;
+ if (q && strstr(Char(nr), "SWIGTYPE")) {
+ Append(def, nr);
+ } else {
+ String *nd = SwigType_default(nr);
+ if (nd) {
+ String *bdef = nd;
+ if (q) {
+ bdef = NewStringf("%s%s", q, nd);
+ if ((Strcmp(nr, bdef) == 0)) {
+ Delete(bdef);
+ bdef = nd;
+ } else {
+ Delete(nd);
+ }
+ }
+ Append(def, bdef);
+ Delete(bdef);
+ } else {
+ Append(def, nr);
+ }
+ }
+ Delete(q);
+ }
+}
+
+
+SwigType *SwigType_default(SwigType *t) {
+ String *r1, *def;
+ String *r = 0;
+ char *cr;
+
+#ifdef SWIG_DEFAULT_CACHE
+ if (!default_cache)
+ default_cache = NewHash();
+
+ r = Getattr(default_cache, t);
+ if (r) {
+ return Copy(r);
+ }
+#endif
+
+ if (SwigType_isvarargs(t)) {
+ return 0;
+ }
+
+ r = t;
+ while ((r1 = SwigType_typedef_resolve(r))) {
+ if (r != t)
+ Delete(r);
+ r = r1;
+ }
+ if (SwigType_isqualifier(r)) {
+ String *q;
+ if (r == t)
+ r = Copy(t);
+ q = SwigType_pop(r);
+ if (strstr(Char(r), "SWIGTYPE")) {
+ Delete(q);
+ def = r;
+ return def;
+ }
+ Delete(q);
+ }
+ cr = Char(r);
+ if (strcmp(cr, "p.SWIGTYPE") == 0) {
+ def = NewString("SWIGTYPE");
+ } else if (SwigType_ispointer(r)) {
+#ifdef SWIG_NEW_TYPE_DEFAULT
+ SwigType *nr = Copy(r);
+ SwigType_del_pointer(nr);
+ def = SwigType_isfunction(nr) ? NewStringEmpty() : NewString("p.");
+ SwigType_add_default(def, nr);
+ Delete(nr);
+#else
+ def = NewString("p.SWIGTYPE");
+#endif
+ } else if (strcmp(cr, "r.SWIGTYPE") == 0) {
+ def = NewString("SWIGTYPE");
+ } else if (SwigType_isreference(r)) {
+#ifdef SWIG_NEW_TYPE_DEFAULT
+ SwigType *nr = Copy(r);
+ SwigType_del_reference(nr);
+ def = NewString("r.");
+ SwigType_add_default(def, nr);
+ Delete(nr);
+#else
+ def = NewString("r.SWIGTYPE");
+#endif
+ } else if (SwigType_isarray(r)) {
+ if (strcmp(cr, "a().SWIGTYPE") == 0) {
+ def = NewString("p.SWIGTYPE");
+ } else if (strcmp(cr, "a(ANY).SWIGTYPE") == 0) {
+ def = NewString("a().SWIGTYPE");
+ } else {
+ int i, empty = 0;
+ int ndim = SwigType_array_ndim(r);
+ SwigType *nr = Copy(r);
+ for (i = 0; i < ndim; i++) {
+ String *dim = SwigType_array_getdim(r, i);
+ if (!Len(dim)) {
+ char *c = Char(nr);
+ empty = strstr(c, "a(ANY).") != c;
+ }
+ Delete(dim);
+ }
+ if (empty) {
+ def = NewString("a().");
+ } else {
+ def = NewString("a(ANY).");
+ }
+#ifdef SWIG_NEW_TYPE_DEFAULT
+ SwigType_del_array(nr);
+ SwigType_add_default(def, nr);
+#else
+ Append(def, "SWIGTYPE");
+#endif
+ Delete(nr);
+ }
+ } else if (SwigType_ismemberpointer(r)) {
+ if (strcmp(cr, "m(CLASS).SWIGTYPE") == 0) {
+ def = NewString("p.SWIGTYPE");
+ } else {
+ def = NewString("m(CLASS).SWIGTYPE");
+ }
+ } else if (SwigType_isenum(r)) {
+ if (strcmp(cr, "enum SWIGTYPE") == 0) {
+ def = NewString("SWIGTYPE");
+ } else {
+ def = NewString("enum SWIGTYPE");
+ }
+ } else if (SwigType_isfunction(r)) {
+ if (strcmp(cr, "f(ANY).SWIGTYPE") == 0) {
+ def = NewString("p.SWIGTYPE");
+ } else {
+ def = NewString("p.f(ANY).SWIGTYPE");
+ }
+ } else {
+ def = NewString("SWIGTYPE");
+ }
+ if (r != t)
+ Delete(r);
+ if (Equal(def, t)) {
+ Delete(def);
+ def = 0;
+ }
+#ifdef SWIG_DEFAULT_CACHE
+ /* The cache produces strange results, see enum_template.i case */
+ if (def) {
+ String *cdef = Copy(def);
+ Setattr(default_cache, t, cdef);
+ Delete(cdef);
+ }
+#endif
+
+ /* Printf(stderr,"type : def %s : %s\n", t, def); */
+
+ return def;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_namestr()
+ *
+ * Returns a string of the base type. Takes care of template expansions
+ * ----------------------------------------------------------------------------- */
+
+String *SwigType_namestr(const SwigType *t) {
+ String *r;
+ String *suffix;
+ List *p;
+ int i, sz;
+ char *d = Char(t);
+ char *c = strstr(d, "<(");
+
+ if (!c || !strstr(c + 2, ")>"))
+ return NewString(t);
+
+ r = NewStringWithSize(d, c - d);
+ if (*(c - 1) == '<')
+ Putc(' ', r);
+ Putc('<', r);
+
+ p = SwigType_parmlist(c + 1);
+ sz = Len(p);
+ for (i = 0; i < sz; i++) {
+ String *str = SwigType_str(Getitem(p, i), 0);
+ /* Avoid creating a <: token, which is the same as [ in C++ - put a space after '<'. */
+ if (i == 0 && Len(str))
+ Putc(' ', r);
+ Append(r, str);
+ if ((i + 1) < sz)
+ Putc(',', r);
+ Delete(str);
+ }
+ Putc(' ', r);
+ Putc('>', r);
+ suffix = SwigType_templatesuffix(t);
+ Append(r, suffix);
+ Delete(suffix);
+ Delete(p);
+ return r;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_str()
+ *
+ * Create a C string representation of a datatype.
+ * ----------------------------------------------------------------------------- */
+
+String *SwigType_str(SwigType *s, const_String_or_char_ptr id) {
+ String *result;
+ String *element = 0, *nextelement;
+ List *elements;
+ int nelements, i;
+
+ if (id) {
+ result = NewString(id);
+ } else {
+ result = NewStringEmpty();
+ }
+
+ elements = SwigType_split(s);
+ nelements = Len(elements);
+
+ if (nelements > 0) {
+ element = Getitem(elements, 0);
+ }
+ /* Now, walk the type list and start emitting */
+ for (i = 0; i < nelements; i++) {
+ if (i < (nelements - 1)) {
+ nextelement = Getitem(elements, i + 1);
+ } else {
+ nextelement = 0;
+ }
+ if (SwigType_isqualifier(element)) {
+ DOH *q = 0;
+ q = SwigType_parm(element);
+ Insert(result, 0, " ");
+ Insert(result, 0, q);
+ Delete(q);
+ } else if (SwigType_ispointer(element)) {
+ Insert(result, 0, "*");
+ if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
+ Insert(result, 0, "(");
+ Append(result, ")");
+ }
+ } else if (SwigType_ismemberpointer(element)) {
+ String *q;
+ q = SwigType_parm(element);
+ Insert(result, 0, "::*");
+ Insert(result, 0, q);
+ if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
+ Insert(result, 0, "(");
+ Append(result, ")");
+ }
+ Delete(q);
+ } else if (SwigType_isreference(element)) {
+ Insert(result, 0, "&");
+ if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
+ Insert(result, 0, "(");
+ Append(result, ")");
+ }
+ } else if (SwigType_isarray(element)) {
+ DOH *size;
+ Append(result, "[");
+ size = SwigType_parm(element);
+ Append(result, size);
+ Append(result, "]");
+ Delete(size);
+ } else if (SwigType_isfunction(element)) {
+ DOH *parms, *p;
+ int j, plen;
+ Append(result, "(");
+ parms = SwigType_parmlist(element);
+ plen = Len(parms);
+ for (j = 0; j < plen; j++) {
+ p = SwigType_str(Getitem(parms, j), 0);
+ Append(result, p);
+ if (j < (plen - 1))
+ Append(result, ",");
+ }
+ Append(result, ")");
+ Delete(parms);
+ } else {
+ if (strcmp(Char(element), "v(...)") == 0) {
+ Insert(result, 0, "...");
+ } else {
+ String *bs = SwigType_namestr(element);
+ Insert(result, 0, " ");
+ Insert(result, 0, bs);
+ Delete(bs);
+ }
+ }
+ element = nextelement;
+ }
+ Delete(elements);
+ Chop(result);
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_ltype(SwigType *ty)
+ *
+ * Create a locally assignable type
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_ltype(SwigType *s) {
+ String *result;
+ String *element;
+ SwigType *td, *tc = 0;
+ List *elements;
+ int nelements, i;
+ int firstarray = 1;
+ int notypeconv = 0;
+
+ result = NewStringEmpty();
+ tc = Copy(s);
+ /* Nuke all leading qualifiers */
+ while (SwigType_isqualifier(tc)) {
+ Delete(SwigType_pop(tc));
+ }
+ if (SwigType_issimple(tc)) {
+ /* Resolve any typedef definitions */
+ SwigType *tt = Copy(tc);
+ td = 0;
+ while ((td = SwigType_typedef_resolve(tt))) {
+ if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) {
+ /* We need to use the typedef type */
+ Delete(tt);
+ tt = td;
+ break;
+ } else if (td) {
+ Delete(tt);
+ tt = td;
+ }
+ }
+ if (td) {
+ Delete(tc);
+ tc = td;
+ }
+ }
+ elements = SwigType_split(tc);
+ nelements = Len(elements);
+
+ /* Now, walk the type list and start emitting */
+ for (i = 0; i < nelements; i++) {
+ element = Getitem(elements, i);
+ /* when we see a function, we need to preserve the following types */
+ if (SwigType_isfunction(element)) {
+ notypeconv = 1;
+ }
+ if (SwigType_isqualifier(element)) {
+ /* Do nothing. Ignore */
+ } else if (SwigType_ispointer(element)) {
+ Append(result, element);
+ firstarray = 0;
+ } else if (SwigType_ismemberpointer(element)) {
+ Append(result, element);
+ firstarray = 0;
+ } else if (SwigType_isreference(element)) {
+ if (notypeconv) {
+ Append(result, element);
+ } else {
+ Append(result, "p.");
+ }
+ firstarray = 0;
+ } else if (SwigType_isarray(element) && firstarray) {
+ if (notypeconv) {
+ Append(result, element);
+ } else {
+ Append(result, "p.");
+ }
+ firstarray = 0;
+ } else if (SwigType_isenum(element)) {
+ int anonymous_enum = (Cmp(element, "enum ") == 0);
+ if (notypeconv || !anonymous_enum) {
+ Append(result, element);
+ } else {
+ Append(result, "int");
+ }
+ } else {
+ Append(result, element);
+ }
+ }
+ Delete(elements);
+ Delete(tc);
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_lstr(DOH *s, DOH *id)
+ *
+ * Produces a type-string that is suitable as a lvalue in an expression.
+ * That is, a type that can be freely assigned a value without violating
+ * any C assignment rules.
+ *
+ * - Qualifiers such as 'const' and 'volatile' are stripped.
+ * - Arrays are converted into a *single* pointer (i.e.,
+ * double [][] becomes double *).
+ * - References are converted into a pointer.
+ * - Typedef names that refer to read-only types will be replaced
+ * with an equivalent assignable version.
+ * -------------------------------------------------------------------- */
+
+String *SwigType_lstr(SwigType *s, const_String_or_char_ptr id) {
+ String *result;
+ SwigType *tc;
+
+ tc = SwigType_ltype(s);
+ result = SwigType_str(tc, id);
+ Delete(tc);
+ return result;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_rcaststr()
+ *
+ * Produces a casting string that maps the type returned by lstr() to the real
+ * datatype printed by str().
+ * ----------------------------------------------------------------------------- */
+
+String *SwigType_rcaststr(SwigType *s, const_String_or_char_ptr name) {
+ String *result, *cast;
+ String *element = 0, *nextelement;
+ SwigType *td, *rs, *tc = 0;
+ List *elements;
+ int nelements, i;
+ int clear = 1;
+ int firstarray = 1;
+ int isreference = 0;
+ int isarray = 0;
+
+ result = NewStringEmpty();
+
+ if (SwigType_isconst(s)) {
+ tc = Copy(s);
+ Delete(SwigType_pop(tc));
+ rs = tc;
+ } else {
+ rs = s;
+ }
+
+ if ((SwigType_isconst(rs) || SwigType_isarray(rs) || SwigType_isreference(rs))) {
+ td = 0;
+ } else {
+ td = SwigType_typedef_resolve(rs);
+ }
+
+ if (td) {
+ if ((SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) {
+ elements = SwigType_split(td);
+ } else {
+ elements = SwigType_split(rs);
+ }
+ Delete(td);
+ } else {
+ elements = SwigType_split(rs);
+ }
+ nelements = Len(elements);
+ if (nelements > 0) {
+ element = Getitem(elements, 0);
+ }
+ /* Now, walk the type list and start emitting */
+ for (i = 0; i < nelements; i++) {
+ if (i < (nelements - 1)) {
+ nextelement = Getitem(elements, i + 1);
+ } else {
+ nextelement = 0;
+ }
+ if (SwigType_isqualifier(element)) {
+ DOH *q = 0;
+ q = SwigType_parm(element);
+ Insert(result, 0, " ");
+ Insert(result, 0, q);
+ Delete(q);
+ clear = 0;
+ } else if (SwigType_ispointer(element)) {
+ Insert(result, 0, "*");
+ if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
+ Insert(result, 0, "(");
+ Append(result, ")");
+ }
+ firstarray = 0;
+ } else if (SwigType_ismemberpointer(element)) {
+ String *q;
+ Insert(result, 0, "::*");
+ q = SwigType_parm(element);
+ Insert(result, 0, q);
+ Delete(q);
+ if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
+ Insert(result, 0, "(");
+ Append(result, ")");
+ }
+ firstarray = 0;
+ } else if (SwigType_isreference(element)) {
+ Insert(result, 0, "&");
+ if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) {
+ Insert(result, 0, "(");
+ Append(result, ")");
+ }
+ isreference = 1;
+ } else if (SwigType_isarray(element)) {
+ DOH *size;
+ if (firstarray && !isreference) {
+ Append(result, "(*)");
+ firstarray = 0;
+ } else {
+ Append(result, "[");
+ size = SwigType_parm(element);
+ Append(result, size);
+ Append(result, "]");
+ Delete(size);
+ clear = 0;
+ }
+ isarray = 1;
+ } else if (SwigType_isfunction(element)) {
+ DOH *parms, *p;
+ int j, plen;
+ Append(result, "(");
+ parms = SwigType_parmlist(element);
+ plen = Len(parms);
+ for (j = 0; j < plen; j++) {
+ p = SwigType_str(Getitem(parms, j), 0);
+ Append(result, p);
+ Delete(p);
+ if (j < (plen - 1))
+ Append(result, ",");
+ }
+ Append(result, ")");
+ Delete(parms);
+ } else {
+ String *bs = SwigType_namestr(element);
+ Insert(result, 0, " ");
+ Insert(result, 0, bs);
+ Delete(bs);
+ }
+ element = nextelement;
+ }
+ Delete(elements);
+ if (clear) {
+ cast = NewStringEmpty();
+ } else {
+ cast = NewStringf("(%s)", result);
+ }
+ if (name) {
+ if (isreference) {
+ if (isarray)
+ Clear(cast);
+ Append(cast, "*");
+ }
+ Append(cast, name);
+ }
+ Delete(result);
+ Delete(tc);
+ return cast;
+}
+
+
+/* -----------------------------------------------------------------------------
+ * SwigType_lcaststr()
+ *
+ * Casts a variable from the real type to the local datatype.
+ * ----------------------------------------------------------------------------- */
+
+String *SwigType_lcaststr(SwigType *s, const_String_or_char_ptr name) {
+ String *result;
+
+ result = NewStringEmpty();
+
+ if (SwigType_isarray(s)) {
+ String *lstr = SwigType_lstr(s, 0);
+ Printf(result, "(%s)%s", lstr, name);
+ Delete(lstr);
+ } else if (SwigType_isreference(s)) {
+ String *str = SwigType_str(s, 0);
+ Printf(result, "(%s)", str);
+ Delete(str);
+ if (name)
+ Append(result, name);
+ } else if (SwigType_isqualifier(s)) {
+ String *lstr = SwigType_lstr(s, 0);
+ Printf(result, "(%s)%s", lstr, name);
+ Delete(lstr);
+ } else {
+ if (name)
+ Append(result, name);
+ }
+ return result;
+}
+
+
+/* keep old mangling since Java codes need it */
+String *SwigType_manglestr_default(SwigType *s) {
+ char *c;
+ String *result = 0;
+ String *base = 0;
+ SwigType *lt;
+ SwigType *sr = SwigType_typedef_qualified(s);
+ SwigType *ss = SwigType_typedef_resolve_all(sr);
+
+ s = ss;
+
+ if (SwigType_istemplate(ss)) {
+ SwigType *ty = Swig_symbol_template_deftype(ss, 0);
+ Delete(ss);
+ ss = ty;
+ s = ss;
+ }
+ Delete(sr);
+
+ lt = SwigType_ltype(s);
+ result = SwigType_prefix(lt);
+ base = SwigType_base(lt);
+
+ c = Char(result);
+ while (*c) {
+ if (!isalnum((int) *c))
+ *c = '_';
+ c++;
+ }
+ if (SwigType_istemplate(base)) {
+ String *b = SwigType_namestr(base);
+ Delete(base);
+ base = b;
+ }
+
+ Replace(base, "struct ", "", DOH_REPLACE_ANY); /* This might be problematic */
+ Replace(base, "class ", "", DOH_REPLACE_ANY);
+ Replace(base, "union ", "", DOH_REPLACE_ANY);
+ Replace(base, "enum ", "", DOH_REPLACE_ANY);
+
+ c = Char(base);
+ while (*c) {
+ if (*c == '<')
+ *c = 'T';
+ else if (*c == '>')
+ *c = 't';
+ else if (*c == '*')
+ *c = 'p';
+ else if (*c == '[')
+ *c = 'a';
+ else if (*c == ']')
+ *c = 'A';
+ else if (*c == '&')
+ *c = 'R';
+ else if (*c == '(')
+ *c = 'f';
+ else if (*c == ')')
+ *c = 'F';
+ else if (!isalnum((int) *c))
+ *c = '_';
+ c++;
+ }
+ Append(result, base);
+ Insert(result, 0, "_");
+ Delete(lt);
+ Delete(base);
+ if (ss)
+ Delete(ss);
+ return result;
+}
+
+String *SwigType_manglestr(SwigType *s) {
+ return SwigType_manglestr_default(s);
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_typename_replace()
+ *
+ * Replaces a typename in a type with something else. Needed for templates.
+ * ----------------------------------------------------------------------------- */
+
+void SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
+ String *nt;
+ int i, ilen;
+ List *elem;
+
+ if (!Strstr(t, pat))
+ return;
+
+ if (Equal(t, pat)) {
+ Replace(t, pat, rep, DOH_REPLACE_ANY);
+ return;
+ }
+ nt = NewStringEmpty();
+ elem = SwigType_split(t);
+ ilen = Len(elem);
+ for (i = 0; i < ilen; i++) {
+ String *e = Getitem(elem, i);
+ if (SwigType_issimple(e)) {
+ if (Equal(e, pat)) {
+ /* Replaces a type of the form 'pat' with 'rep<args>' */
+ Replace(e, pat, rep, DOH_REPLACE_ANY);
+ } else if (SwigType_istemplate(e)) {
+ /* Replaces a type of the form 'pat<args>' with 'rep' */
+ if (Equal(e, pat)) {
+ String *repbase = SwigType_templateprefix(rep);
+ Replace(e, pat, repbase, DOH_REPLACE_ID | DOH_REPLACE_FIRST);
+ Delete(repbase);
+ }
+ {
+ String *tsuffix;
+ List *tparms = SwigType_parmlist(e);
+ int j, jlen;
+ String *nt = SwigType_templateprefix(e);
+ Append(nt, "<(");
+ jlen = Len(tparms);
+ for (j = 0; j < jlen; j++) {
+ SwigType_typename_replace(Getitem(tparms, j), pat, rep);
+ Append(nt, Getitem(tparms, j));
+ if (j < (jlen - 1))
+ Putc(',', nt);
+ }
+ tsuffix = SwigType_templatesuffix(e);
+ Printf(nt, ")>%s", tsuffix);
+ Delete(tsuffix);
+ Clear(e);
+ Append(e, nt);
+ Delete(nt);
+ Delete(tparms);
+ }
+ } else if (Swig_scopename_check(e)) {
+ String *first, *rest;
+ first = Swig_scopename_first(e);
+ rest = Swig_scopename_suffix(e);
+ SwigType_typename_replace(rest, pat, rep);
+ SwigType_typename_replace(first, pat, rep);
+ Clear(e);
+ Printv(e, first, "::", rest, NIL);
+ Delete(first);
+ Delete(rest);
+ }
+ } else if (SwigType_isfunction(e)) {
+ int j, jlen;
+ List *fparms = SwigType_parmlist(e);
+ Clear(e);
+ Append(e, "f(");
+ jlen = Len(fparms);
+ for (j = 0; j < jlen; j++) {
+ SwigType_typename_replace(Getitem(fparms, j), pat, rep);
+ Append(e, Getitem(fparms, j));
+ if (j < (jlen - 1))
+ Putc(',', e);
+ }
+ Append(e, ").");
+ Delete(fparms);
+ } else if (SwigType_isarray(e)) {
+ Replace(e, pat, rep, DOH_REPLACE_ID);
+ }
+ Append(nt, e);
+ }
+ Clear(t);
+ Append(t, nt);
+ Delete(nt);
+ Delete(elem);
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_check_decl()
+ *
+ * Checks type declarators for a match
+ * ----------------------------------------------------------------------------- */
+
+int SwigType_check_decl(SwigType *ty, const SwigType *decl) {
+ SwigType *t, *t1, *t2;
+ int r;
+ t = SwigType_typedef_resolve_all(ty);
+ t1 = SwigType_strip_qualifiers(t);
+ t2 = SwigType_prefix(t1);
+ r = Equal(t2, decl);
+ Delete(t);
+ Delete(t1);
+ Delete(t2);
+ return r == 1;
+}