/Source/Swig/typemap.c
C | 1936 lines | 1396 code | 198 blank | 342 comment | 361 complexity | 7fabb35cd4d611b0d420b650544cf23f MD5 | raw file
Possible License(s): 0BSD, GPL-2.0, LGPL-2.1
Large files files are truncated, but you can click here to view the full file
- /* -----------------------------------------------------------------------------
- * 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.
- *
- * typemap.c
- *
- * A somewhat generalized implementation of SWIG1.1 typemaps.
- * ----------------------------------------------------------------------------- */
- char cvsroot_typemap_c[] = "$Id$";
- #include "swig.h"
- #include "cparse.h"
- #include <ctype.h>
- #if 0
- #define SWIG_DEBUG
- #endif
- static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f);
- /* -----------------------------------------------------------------------------
- * Typemaps are stored in a collection of nested hash tables. Something like
- * this:
- *
- * [ type ]
- * +-------- [ name ]
- * +-------- [ name ]
- *
- * Each hash table [ type ] or [ name ] then contains references to the
- * different typemap methods. These are referenced by names such as
- * "tmap:in", "tmap:out", "tmap:argout", and so forth.
- *
- * The object corresponding to a specific typemap method has the following attributes:
- *
- * "type" - Typemap type
- * "pname" - Parameter name
- * "code" - Typemap code
- * "typemap" - Descriptive text describing the actual map
- * "locals" - Local variables (if any)
- * "kwargs" - Typemap attributes
- *
- * Example for a typemap method named "in":
- * %typemap(in, warning="987:my warning", noblock=1) int &my_int (int tmp) "$1 = $input;"
- *
- * "type" - r.int
- * "pname" - my_int
- * "code" - $1 = $input;
- * "typemap" - typemap(in) int &my_int
- * "locals" - int tmp
- * "kwargs" - warning="987:my typemap warning", foo=123
- *
- * ----------------------------------------------------------------------------- */
- #define MAX_SCOPE 32
- static Hash *typemaps[MAX_SCOPE];
- static int tm_scope = 0;
- static Hash *get_typemap(int tm_scope, SwigType *type) {
- Hash *tm = 0;
- SwigType *dtype = 0;
- if (SwigType_istemplate(type)) {
- String *ty = Swig_symbol_template_deftype(type, 0);
- dtype = Swig_symbol_type_qualify(ty, 0);
- /* Printf(stderr,"gettm %s %s\n", type, dtype); */
- type = dtype;
- Delete(ty);
- }
- tm = Getattr(typemaps[tm_scope], type);
- if (dtype) {
- if (!tm) {
- String *t_name = SwigType_templateprefix(type);
- if (!Equal(t_name, type)) {
- tm = Getattr(typemaps[tm_scope], t_name);
- }
- Delete(t_name);
- }
- Delete(dtype);
- }
- return tm;
- }
- static void set_typemap(int tm_scope, SwigType *type, Hash *tm) {
- SwigType *dtype = 0;
- if (SwigType_istemplate(type)) {
- String *ty = Swig_symbol_template_deftype(type, 0);
- dtype = Swig_symbol_type_qualify(ty, 0);
- /* Printf(stderr,"settm %s %s\n", type, dtype); */
- type = dtype;
- Delete(ty);
- } else {
- dtype = Copy(type);
- type = dtype;
- }
- Setattr(typemaps[tm_scope], type, tm);
- Delete(dtype);
- }
- /* -----------------------------------------------------------------------------
- * Swig_typemap_init()
- *
- * Initialize the typemap system
- * ----------------------------------------------------------------------------- */
- void Swig_typemap_init() {
- int i;
- for (i = 0; i < MAX_SCOPE; i++) {
- typemaps[i] = 0;
- }
- typemaps[0] = NewHash();
- tm_scope = 0;
- }
- static String *typemap_method_name(const_String_or_char_ptr tmap_method) {
- static Hash *names = 0;
- String *s;
- /* Due to "interesting" object-identity semantics of DOH,
- we have to make sure that we only intern strings without object
- identity into the hash table.
- (typemap_attach_kwargs calls typemap_method_name several times with
- the "same" String *tmap_method (i.e., same object identity) but differing
- string values.)
- Most other callers work around this by using char* rather than
- String *.
- -- mkoeppe, Jun 17, 2003
- */
- const char *method_without_object_identity = Char(tmap_method);
- if (!names)
- names = NewHash();
- s = Getattr(names, method_without_object_identity);
- if (s)
- return s;
- s = NewStringf("tmap:%s", tmap_method);
- Setattr(names, method_without_object_identity, s);
- Delete(s);
- return s;
- }
- #if 0
- /* -----------------------------------------------------------------------------
- * Swig_typemap_new_scope()
- *
- * Create a new typemap scope
- * ----------------------------------------------------------------------------- */
- void Swig_typemap_new_scope() {
- tm_scope++;
- typemaps[tm_scope] = NewHash();
- }
- /* -----------------------------------------------------------------------------
- * Swig_typemap_pop_scope()
- *
- * Pop the last typemap scope off
- * ----------------------------------------------------------------------------- */
- Hash *Swig_typemap_pop_scope() {
- if (tm_scope > 0) {
- return typemaps[tm_scope--];
- }
- return 0;
- }
- #endif
- /* -----------------------------------------------------------------------------
- * Swig_typemap_register()
- *
- * Add a new multi-argument typemap
- * ----------------------------------------------------------------------------- */
- void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs) {
- Hash *tm;
- Hash *tm1;
- Hash *tm2;
- Parm *np;
- String *tm_method;
- SwigType *type;
- String *pname;
- if (!parms)
- return;
- tm_method = typemap_method_name(tmap_method);
- /* Register the first type in the parameter list */
- type = Getattr(parms, "type");
- pname = Getattr(parms, "name");
- /* See if this type has been seen before */
- tm = get_typemap(tm_scope, type);
- if (!tm) {
- tm = NewHash();
- set_typemap(tm_scope, type, tm);
- Delete(tm);
- }
- if (pname) {
- /* See if parameter has been seen before */
- tm1 = Getattr(tm, pname);
- if (!tm1) {
- tm1 = NewHash();
- Setattr(tm, pname, tm1);
- Delete(tm1);
- }
- tm = tm1;
- }
- /* Now see if this typemap method has been seen before */
- tm2 = Getattr(tm, tm_method);
- if (!tm2) {
- tm2 = NewHash();
- Setattr(tm, tm_method, tm2);
- Delete(tm2);
- }
- /* For a multi-argument typemap, the typemap code and information
- is really only stored in the last argument. However, to
- make this work, we perform a really neat trick using
- the typemap operator name.
- For example, consider this typemap
- %typemap(in) (int foo, int *bar, char *blah[]) {
- ...
- }
- To store it, we look at typemaps for the following:
- operator type-name
- ----------------------------------------------
- "in" int foo
- "in-int+foo:" int *bar
- "in-int+foo:-p.int+bar: char *blah[]
- Notice how the operator expands to encode information about
- previous arguments.
- */
- np = nextSibling(parms);
- if (np) {
- /* Make an entirely new operator key */
- String *newop = NewStringf("%s-%s+%s:", tmap_method, type, pname);
- /* Now reregister on the remaining arguments */
- Swig_typemap_register(newop, np, code, locals, kwargs);
- /* Setattr(tm2,newop,newop); */
- Delete(newop);
- } else {
- String *str = SwigType_str(type, pname);
- String *typemap = NewStringf("typemap(%s) %s", tmap_method, str);
- ParmList *clocals = CopyParmList(locals);
- ParmList *ckwargs = CopyParmList(kwargs);
- Setattr(tm2, "code", code);
- Setattr(tm2, "type", type);
- Setattr(tm2, "typemap", typemap);
- if (pname) {
- Setattr(tm2, "pname", pname);
- }
- Setattr(tm2, "locals", clocals);
- Setattr(tm2, "kwargs", ckwargs);
- Delete(clocals);
- Delete(ckwargs);
- Delete(str);
- Delete(typemap);
- }
- }
- /* -----------------------------------------------------------------------------
- * typemap_get()
- *
- * Retrieve typemap information from current scope.
- * ----------------------------------------------------------------------------- */
- static Hash *typemap_get(SwigType *type, const_String_or_char_ptr name, int scope) {
- Hash *tm, *tm1;
- /* See if this type has been seen before */
- if ((scope < 0) || (scope > tm_scope))
- return 0;
- tm = get_typemap(scope, type);
- if (!tm) {
- return 0;
- }
- if ((name) && Len(name)) {
- tm1 = Getattr(tm, name);
- return tm1;
- }
- return tm;
- }
- /* -----------------------------------------------------------------------------
- * Swig_typemap_copy()
- *
- * Copy a typemap
- * ----------------------------------------------------------------------------- */
- int Swig_typemap_copy(const_String_or_char_ptr tmap_method, ParmList *srcparms, ParmList *parms) {
- Hash *tm = 0;
- String *tm_method;
- Parm *p;
- String *pname;
- SwigType *ptype;
- int ts = tm_scope;
- String *tm_methods, *newop;
- if (ParmList_len(parms) != ParmList_len(srcparms))
- return -1;
- tm_method = typemap_method_name(tmap_method);
- while (ts >= 0) {
- p = srcparms;
- tm_methods = NewString(tm_method);
- while (p) {
- ptype = Getattr(p, "type");
- pname = Getattr(p, "name");
- /* Lookup the type */
- tm = typemap_get(ptype, pname, ts);
- if (!tm)
- break;
- tm = Getattr(tm, tm_methods);
- if (!tm)
- break;
- /* Got a match. Look for next typemap */
- newop = NewStringf("%s-%s+%s:", tm_methods, ptype, pname);
- Delete(tm_methods);
- tm_methods = newop;
- p = nextSibling(p);
- }
- Delete(tm_methods);
- if (!p && tm) {
- /* Got some kind of match */
- Swig_typemap_register(tmap_method, parms, Getattr(tm, "code"), Getattr(tm, "locals"), Getattr(tm, "kwargs"));
- return 0;
- }
- ts--;
- }
- /* Not found */
- return -1;
- }
- /* -----------------------------------------------------------------------------
- * Swig_typemap_clear()
- *
- * Delete a multi-argument typemap
- * ----------------------------------------------------------------------------- */
- void Swig_typemap_clear(const_String_or_char_ptr tmap_method, ParmList *parms) {
- SwigType *type;
- String *name;
- Parm *p;
- String *newop;
- Hash *tm = 0;
- /* This might not work */
- newop = NewString(tmap_method);
- p = parms;
- while (p) {
- type = Getattr(p, "type");
- name = Getattr(p, "name");
- tm = typemap_get(type, name, tm_scope);
- if (!tm)
- return;
- p = nextSibling(p);
- if (p)
- Printf(newop, "-%s+%s:", type, name);
- }
- if (tm) {
- tm = Getattr(tm, typemap_method_name(newop));
- if (tm) {
- Delattr(tm, "code");
- Delattr(tm, "locals");
- Delattr(tm, "kwargs");
- }
- }
- Delete(newop);
- }
- /* -----------------------------------------------------------------------------
- * Swig_typemap_apply()
- *
- * Multi-argument %apply directive. This is pretty horrible so I sure hope
- * it works.
- * ----------------------------------------------------------------------------- */
- static int count_args(String *s) {
- /* Count up number of arguments */
- int na = 0;
- char *c = Char(s);
- while (*c) {
- if (*c == '+')
- na++;
- c++;
- }
- return na;
- }
- int Swig_typemap_apply(ParmList *src, ParmList *dest) {
- String *ssig, *dsig;
- Parm *p, *np, *lastp, *dp, *lastdp = 0;
- int narg = 0;
- int ts = tm_scope;
- SwigType *type = 0, *name;
- Hash *tm, *sm;
- int match = 0;
- /* Printf(stdout,"apply : %s --> %s\n", ParmList_str(src), ParmList_str(dest)); */
- /* Create type signature of source */
- ssig = NewStringEmpty();
- dsig = NewStringEmpty();
- p = src;
- dp = dest;
- lastp = 0;
- while (p) {
- lastp = p;
- lastdp = dp;
- np = nextSibling(p);
- if (np) {
- Printf(ssig, "-%s+%s:", Getattr(p, "type"), Getattr(p, "name"));
- Printf(dsig, "-%s+%s:", Getattr(dp, "type"), Getattr(dp, "name"));
- narg++;
- }
- p = np;
- dp = nextSibling(dp);
- }
- /* make sure a typemap node exists for the last destination node */
- type = Getattr(lastdp, "type");
- tm = get_typemap(tm_scope, type);
- if (!tm) {
- tm = NewHash();
- set_typemap(tm_scope, type, tm);
- Delete(tm);
- }
- name = Getattr(lastdp, "name");
- if (name) {
- Hash *tm1 = Getattr(tm, name);
- if (!tm1) {
- tm1 = NewHash();
- Setattr(tm, NewString(name), tm1);
- Delete(tm1);
- }
- tm = tm1;
- }
- /* This is a little nasty. We need to go searching for all possible typemaps in the
- source and apply them to the target */
- type = Getattr(lastp, "type");
- name = Getattr(lastp, "name");
- while (ts >= 0) {
- /* See if there is a matching typemap in this scope */
- sm = typemap_get(type, name, ts);
- /* if there is not matching, look for a typemap in the
- original typedef, if any, like in:
- typedef unsigned long size_t;
- ...
- %apply(size_t) {my_size}; ==> %apply(unsigned long) {my_size};
- */
- if (!sm) {
- SwigType *ntype = SwigType_typedef_resolve(type);
- if (ntype && (Cmp(ntype, type) != 0)) {
- sm = typemap_get(ntype, name, ts);
- }
- Delete(ntype);
- }
- if (sm) {
- /* Got a typemap. Need to only merge attributes for methods that match our signature */
- Iterator ki;
- match = 1;
- for (ki = First(sm); ki.key; ki = Next(ki)) {
- /* Check for a signature match with the source signature */
- if ((count_args(ki.key) == narg) && (Strstr(ki.key, ssig))) {
- String *oldm;
- /* A typemap we have to copy */
- String *nkey = Copy(ki.key);
- Replace(nkey, ssig, dsig, DOH_REPLACE_ANY);
- /* Make sure the typemap doesn't already exist in the target map */
- oldm = Getattr(tm, nkey);
- if (!oldm || (!Getattr(tm, "code"))) {
- String *code;
- ParmList *locals;
- ParmList *kwargs;
- Hash *sm1 = ki.item;
- code = Getattr(sm1, "code");
- locals = Getattr(sm1, "locals");
- kwargs = Getattr(sm1, "kwargs");
- if (code) {
- Replace(nkey, dsig, "", DOH_REPLACE_ANY);
- Replace(nkey, "tmap:", "", DOH_REPLACE_ANY);
- Swig_typemap_register(nkey, dest, code, locals, kwargs);
- }
- }
- Delete(nkey);
- }
- }
- }
- ts--;
- }
- Delete(ssig);
- Delete(dsig);
- return match;
- }
- /* -----------------------------------------------------------------------------
- * Swig_typemap_clear_apply()
- *
- * %clear directive. Clears all typemaps for a type (in the current scope only).
- * ----------------------------------------------------------------------------- */
- /* Multi-argument %clear directive */
- void Swig_typemap_clear_apply(Parm *parms) {
- String *tsig;
- Parm *p, *np, *lastp;
- int narg = 0;
- Hash *tm;
- String *name;
- /* Create a type signature of the parameters */
- tsig = NewStringEmpty();
- p = parms;
- lastp = 0;
- while (p) {
- lastp = p;
- np = nextSibling(p);
- if (np) {
- Printf(tsig, "-%s+%s:", Getattr(p, "type"), Getattr(p, "name"));
- narg++;
- }
- p = np;
- }
- tm = get_typemap(tm_scope, Getattr(lastp, "type"));
- if (!tm) {
- Delete(tsig);
- return;
- }
- name = Getattr(lastp, "name");
- if (name) {
- tm = Getattr(tm, name);
- }
- if (tm) {
- /* Clear typemaps that match our signature */
- Iterator ki, ki2;
- char *ctsig = Char(tsig);
- for (ki = First(tm); ki.key; ki = Next(ki)) {
- char *ckey = Char(ki.key);
- if (strncmp(ckey, "tmap:", 5) == 0) {
- int na = count_args(ki.key);
- if ((na == narg) && strstr(ckey, ctsig)) {
- Hash *h = ki.item;
- for (ki2 = First(h); ki2.key; ki2 = Next(ki2)) {
- Delattr(h, ki2.key);
- }
- }
- }
- }
- }
- Delete(tsig);
- }
- /* Internal function to strip array dimensions. */
- static SwigType *strip_arrays(SwigType *type) {
- SwigType *t;
- int ndim;
- int i;
- t = Copy(type);
- ndim = SwigType_array_ndim(t);
- for (i = 0; i < ndim; i++) {
- SwigType_array_setdim(t, i, "ANY");
- }
- return t;
- }
- /* -----------------------------------------------------------------------------
- * typemap_search()
- *
- * Search for a typemap match. Tries to find the most specific typemap
- * that includes a 'code' attribute.
- * ----------------------------------------------------------------------------- */
- static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type, const_String_or_char_ptr name, SwigType **matchtype) {
- Hash *result = 0, *tm, *tm1, *tma;
- Hash *backup = 0;
- SwigType *noarrays = 0;
- SwigType *primitive = 0;
- SwigType *ctype = 0;
- int ts;
- int isarray;
- const String *cname = 0;
- SwigType *unstripped = 0;
- String *tm_method = typemap_method_name(tmap_method);
- if ((name) && Len(name))
- cname = name;
- ts = tm_scope;
- while (ts >= 0) {
- ctype = type;
- while (ctype) {
- /* Try to get an exact type-match */
- tm = get_typemap(ts, ctype);
- if (tm && cname) {
- tm1 = Getattr(tm, cname);
- if (tm1) {
- result = Getattr(tm1, tm_method); /* See if there is a type-name match */
- if (result && Getattr(result, "code"))
- goto ret_result;
- if (result)
- backup = result;
- }
- }
- if (tm) {
- result = Getattr(tm, tm_method); /* See if there is simply a type match */
- if (result && Getattr(result, "code"))
- goto ret_result;
- if (result)
- backup = result;
- }
- isarray = SwigType_isarray(ctype);
- if (isarray) {
- /* If working with arrays, strip away all of the dimensions and replace with "ANY".
- See if that generates a match */
- if (!noarrays) {
- noarrays = strip_arrays(ctype);
- }
- tma = get_typemap(ts, noarrays);
- if (tma && cname) {
- tm1 = Getattr(tma, cname);
- if (tm1) {
- result = Getattr(tm1, tm_method); /* type-name match */
- if (result && Getattr(result, "code"))
- goto ret_result;
- if (result)
- backup = result;
- }
- }
- if (tma) {
- result = Getattr(tma, tm_method); /* type match */
- if (result && Getattr(result, "code"))
- goto ret_result;
- if (result)
- backup = result;
- }
- Delete(noarrays);
- noarrays = 0;
- }
- /* No match so far. If the type is unstripped, we'll strip its
- qualifiers and check. Otherwise, we'll try to resolve a typedef */
- if (!unstripped) {
- unstripped = ctype;
- ctype = SwigType_strip_qualifiers(ctype);
- if (!Equal(ctype, unstripped))
- continue; /* Types are different */
- Delete(ctype);
- ctype = unstripped;
- unstripped = 0;
- }
- {
- String *octype;
- if (unstripped) {
- Delete(ctype);
- ctype = unstripped;
- unstripped = 0;
- }
- octype = ctype;
- ctype = SwigType_typedef_resolve(ctype);
- if (octype != type)
- Delete(octype);
- }
- }
- /* Hmmm. Well, no match seems to be found at all. See if there is some kind of default mapping */
- primitive = SwigType_default(type);
- while (primitive) {
- tm = get_typemap(ts, primitive);
- if (tm && cname) {
- tm1 = Getattr(tm, cname);
- if (tm1) {
- result = Getattr(tm1, tm_method); /* See if there is a type-name match */
- if (result)
- goto ret_result;
- }
- }
- if (tm) { /* See if there is simply a type match */
- result = Getattr(tm, tm_method);
- if (result)
- goto ret_result;
- }
- {
- SwigType *nprim = SwigType_default(primitive);
- Delete(primitive);
- primitive = nprim;
- }
- }
- if (ctype != type) {
- Delete(ctype);
- ctype = 0;
- }
- ts--; /* Hmmm. Nothing found in this scope. Guess we'll go try another scope */
- }
- result = backup;
- ret_result:
- if (noarrays)
- Delete(noarrays);
- if (primitive)
- Delete(primitive);
- if ((unstripped) && (unstripped != type))
- Delete(unstripped);
- if (matchtype) {
- *matchtype = Copy(ctype);
- }
- if (type != ctype)
- Delete(ctype);
- return result;
- }
- /* -----------------------------------------------------------------------------
- * typemap_search_multi()
- *
- * Search for a multi-argument typemap.
- * ----------------------------------------------------------------------------- */
- static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList *parms, int *nmatch) {
- SwigType *type;
- SwigType *mtype = 0;
- String *name;
- String *newop;
- Hash *tm, *tm1;
- if (!parms) {
- *nmatch = 0;
- return 0;
- }
- type = Getattr(parms, "type");
- name = Getattr(parms, "name");
- /* Try to find a match on the first type */
- tm = typemap_search(tmap_method, type, name, &mtype);
- if (tm) {
- if (mtype && SwigType_isarray(mtype)) {
- Setattr(parms, "tmap:match", mtype);
- }
- Delete(mtype);
- newop = NewStringf("%s-%s+%s:", tmap_method, type, name);
- tm1 = typemap_search_multi(newop, nextSibling(parms), nmatch);
- if (tm1)
- tm = tm1;
- if (Getattr(tm, "code")) {
- *(nmatch) = *nmatch + 1;
- } else {
- tm = 0;
- }
- Delete(newop);
- }
- return tm;
- }
- /* -----------------------------------------------------------------------------
- * typemap_replace_vars()
- *
- * Replaces typemap variables on a string. index is the $n variable.
- * type and pname are the type and parameter name.
- * ----------------------------------------------------------------------------- */
- static void replace_local_types(ParmList *p, const String *name, const String *rep) {
- SwigType *t;
- while (p) {
- t = Getattr(p, "type");
- Replace(t, name, rep, DOH_REPLACE_ANY);
- p = nextSibling(p);
- }
- }
- static int check_locals(ParmList *p, const char *s) {
- while (p) {
- char *c = GetChar(p, "type");
- if (strstr(c, s))
- return 1;
- p = nextSibling(p);
- }
- return 0;
- }
- static int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType *rtype, String *pname, String *lname, int index) {
- char var[512];
- char *varname;
- SwigType *ftype;
- int bare_substitution_count = 0;
- Replaceall(s, "$typemap", "$TYPEMAP"); /* workaround for $type substitution below */
- ftype = SwigType_typedef_resolve_all(type);
- if (!pname)
- pname = lname;
- {
- Parm *p;
- int rep = 0;
- p = locals;
- while (p) {
- if (Strchr(Getattr(p, "type"), '$'))
- rep = 1;
- p = nextSibling(p);
- }
- if (!rep)
- locals = 0;
- }
- sprintf(var, "$%d_", index);
- varname = &var[strlen(var)];
- /* If the original datatype was an array. We're going to go through and substitute
- its array dimensions */
- if (SwigType_isarray(type) || SwigType_isarray(ftype)) {
- String *size;
- int ndim;
- int i;
- if (SwigType_array_ndim(type) != SwigType_array_ndim(ftype))
- type = ftype;
- ndim = SwigType_array_ndim(type);
- size = NewStringEmpty();
- for (i = 0; i < ndim; i++) {
- String *dim = SwigType_array_getdim(type, i);
- if (index == 1) {
- char t[32];
- sprintf(t, "$dim%d", i);
- Replace(s, t, dim, DOH_REPLACE_ANY);
- replace_local_types(locals, t, dim);
- }
- sprintf(varname, "dim%d", i);
- Replace(s, var, dim, DOH_REPLACE_ANY);
- replace_local_types(locals, var, dim);
- if (Len(size))
- Putc('*', size);
- Append(size, dim);
- Delete(dim);
- }
- sprintf(varname, "size");
- Replace(s, var, size, DOH_REPLACE_ANY);
- replace_local_types(locals, var, size);
- Delete(size);
- }
- /* Parameter name substitution */
- if (index == 1) {
- Replace(s, "$parmname", pname, DOH_REPLACE_ANY);
- }
- strcpy(varname, "name");
- Replace(s, var, pname, DOH_REPLACE_ANY);
- /* Type-related stuff */
- {
- SwigType *star_type, *amp_type, *base_type, *lex_type;
- SwigType *ltype, *star_ltype, *amp_ltype;
- String *mangle, *star_mangle, *amp_mangle, *base_mangle, *base_name;
- String *descriptor, *star_descriptor, *amp_descriptor;
- String *ts;
- char *sc;
- sc = Char(s);
- if (strstr(sc, "type") || check_locals(locals, "type")) {
- /* Given type : $type */
- ts = SwigType_str(type, 0);
- if (index == 1) {
- Replace(s, "$type", ts, DOH_REPLACE_ANY);
- replace_local_types(locals, "$type", type);
- }
- strcpy(varname, "type");
- Replace(s, var, ts, DOH_REPLACE_ANY);
- replace_local_types(locals, var, type);
- Delete(ts);
- sc = Char(s);
- }
- if (strstr(sc, "ltype") || check_locals(locals, "ltype")) {
- /* Local type: $ltype */
- ltype = SwigType_ltype(type);
- ts = SwigType_str(ltype, 0);
- if (index == 1) {
- Replace(s, "$ltype", ts, DOH_REPLACE_ANY);
- replace_local_types(locals, "$ltype", ltype);
- }
- strcpy(varname, "ltype");
- Replace(s, var, ts, DOH_REPLACE_ANY);
- replace_local_types(locals, var, ltype);
- Delete(ts);
- Delete(ltype);
- sc = Char(s);
- }
- if (strstr(sc, "mangle") || strstr(sc, "descriptor")) {
- /* Mangled type */
- mangle = SwigType_manglestr(type);
- if (index == 1)
- Replace(s, "$mangle", mangle, DOH_REPLACE_ANY);
- strcpy(varname, "mangle");
- Replace(s, var, mangle, DOH_REPLACE_ANY);
- descriptor = NewStringf("SWIGTYPE%s", mangle);
- if (index == 1)
- if (Replace(s, "$descriptor", descriptor, DOH_REPLACE_ANY))
- SwigType_remember(type);
- strcpy(varname, "descriptor");
- if (Replace(s, var, descriptor, DOH_REPLACE_ANY))
- SwigType_remember(type);
- Delete(descriptor);
- Delete(mangle);
- }
- /* One pointer level removed */
- /* This creates variables of the form
- $*n_type
- $*n_ltype
- */
- if (SwigType_ispointer(ftype) || (SwigType_isarray(ftype)) || (SwigType_isreference(ftype))) {
- if (!(SwigType_isarray(type) || SwigType_ispointer(type) || SwigType_isreference(type))) {
- star_type = Copy(ftype);
- } else {
- star_type = Copy(type);
- }
- if (!SwigType_isreference(star_type)) {
- if (SwigType_isarray(star_type)) {
- SwigType_del_element(star_type);
- } else {
- SwigType_del_pointer(star_type);
- }
- ts = SwigType_str(star_type, 0);
- if (index == 1) {
- Replace(s, "$*type", ts, DOH_REPLACE_ANY);
- replace_local_types(locals, "$*type", star_type);
- }
- sprintf(varname, "$*%d_type", index);
- Replace(s, varname, ts, DOH_REPLACE_ANY);
- replace_local_types(locals, varname, star_type);
- Delete(ts);
- } else {
- SwigType_del_element(star_type);
- }
- star_ltype = SwigType_ltype(star_type);
- ts = SwigType_str(star_ltype, 0);
- if (index == 1) {
- Replace(s, "$*ltype", ts, DOH_REPLACE_ANY);
- replace_local_types(locals, "$*ltype", star_ltype);
- }
- sprintf(varname, "$*%d_ltype", index);
- Replace(s, varname, ts, DOH_REPLACE_ANY);
- replace_local_types(locals, varname, star_ltype);
- Delete(ts);
- Delete(star_ltype);
- star_mangle = SwigType_manglestr(star_type);
- if (index == 1)
- Replace(s, "$*mangle", star_mangle, DOH_REPLACE_ANY);
- sprintf(varname, "$*%d_mangle", index);
- Replace(s, varname, star_mangle, DOH_REPLACE_ANY);
- star_descriptor = NewStringf("SWIGTYPE%s", star_mangle);
- if (index == 1)
- if (Replace(s, "$*descriptor", star_descriptor, DOH_REPLACE_ANY))
- SwigType_remember(star_type);
- sprintf(varname, "$*%d_descriptor", index);
- if (Replace(s, varname, star_descriptor, DOH_REPLACE_ANY))
- SwigType_remember(star_type);
- Delete(star_descriptor);
- Delete(star_mangle);
- Delete(star_type);
- } else {
- /* TODO: Signal error if one of the $* substitutions is
- requested */
- }
- /* One pointer level added */
- amp_type = Copy(type);
- SwigType_add_pointer(amp_type);
- ts = SwigType_str(amp_type, 0);
- if (index == 1) {
- Replace(s, "$&type", ts, DOH_REPLACE_ANY);
- replace_local_types(locals, "$&type", amp_type);
- }
- sprintf(varname, "$&%d_type", index);
- Replace(s, varname, ts, DOH_REPLACE_ANY);
- replace_local_types(locals, varname, amp_type);
- Delete(ts);
- amp_ltype = SwigType_ltype(type);
- SwigType_add_pointer(amp_ltype);
- ts = SwigType_str(amp_ltype, 0);
- if (index == 1) {
- Replace(s, "$<ype", ts, DOH_REPLACE_ANY);
- replace_local_types(locals, "$<ype", amp_ltype);
- }
- sprintf(varname, "$&%d_ltype", index);
- Replace(s, varname, ts, DOH_REPLACE_ANY);
- replace_local_types(locals, varname, amp_ltype);
- Delete(ts);
- Delete(amp_ltype);
- amp_mangle = SwigType_manglestr(amp_type);
- if (index == 1)
- Replace(s, "$&mangle", amp_mangle, DOH_REPLACE_ANY);
- sprintf(varname, "$&%d_mangle", index);
- Replace(s, varname, amp_mangle, DOH_REPLACE_ANY);
- amp_descriptor = NewStringf("SWIGTYPE%s", amp_mangle);
- if (index == 1)
- if (Replace(s, "$&descriptor", amp_descriptor, DOH_REPLACE_ANY))
- SwigType_remember(amp_type);
- sprintf(varname, "$&%d_descriptor", index);
- if (Replace(s, varname, amp_descriptor, DOH_REPLACE_ANY))
- SwigType_remember(amp_type);
- Delete(amp_descriptor);
- Delete(amp_mangle);
- Delete(amp_type);
- /* Base type */
- if (SwigType_isarray(type)) {
- SwigType *bt = Copy(type);
- Delete(SwigType_pop_arrays(bt));
- base_type = SwigType_str(bt, 0);
- Delete(bt);
- } else {
- base_type = SwigType_base(type);
- }
- base_name = SwigType_namestr(base_type);
- if (index == 1) {
- Replace(s, "$basetype", base_name, DOH_REPLACE_ANY);
- replace_local_types(locals, "$basetype", base_name);
- }
- strcpy(varname, "basetype");
- Replace(s, var, base_type, DOH_REPLACE_ANY);
- replace_local_types(locals, var, base_name);
- base_mangle = SwigType_manglestr(base_type);
- if (index == 1)
- Replace(s, "$basemangle", base_mangle, DOH_REPLACE_ANY);
- strcpy(varname, "basemangle");
- Replace(s, var, base_mangle, DOH_REPLACE_ANY);
- Delete(base_mangle);
- Delete(base_type);
- Delete(base_name);
- lex_type = SwigType_base(rtype);
- if (index == 1)
- Replace(s, "$lextype", lex_type, DOH_REPLACE_ANY);
- strcpy(varname, "lextype");
- Replace(s, var, lex_type, DOH_REPLACE_ANY);
- Delete(lex_type);
- }
- /* Replace any $n. with (&n)-> */
- {
- char temp[64];
- sprintf(var, "$%d.", index);
- sprintf(temp, "(&$%d)->", index);
- Replace(s, var, temp, DOH_REPLACE_ANY);
- }
- /* Replace the bare $n variable */
- sprintf(var, "$%d", index);
- bare_substitution_count = Replace(s, var, lname, DOH_REPLACE_ANY);
- Delete(ftype);
- return bare_substitution_count;
- }
- /* ------------------------------------------------------------------------
- * static typemap_locals()
- *
- * Takes a string, a parameter list and a wrapper function argument and
- * creates the local variables.
- * ------------------------------------------------------------------------ */
- static void typemap_locals(DOHString * s, ParmList *l, Wrapper *f, int argnum) {
- Parm *p;
- char *new_name;
- p = l;
- while (p) {
- SwigType *pt = Getattr(p, "type");
- SwigType *at = SwigType_alttype(pt, 1);
- String *pn = Getattr(p, "name");
- String *value = Getattr(p, "value");
- if (at)
- pt = at;
- if (pn) {
- if (Len(pn) > 0) {
- String *str;
- int isglobal = 0;
- str = NewStringEmpty();
- if (strncmp(Char(pn), "_global_", 8) == 0) {
- isglobal = 1;
- }
- /* If the user gave us $type as the name of the local variable, we'll use
- the passed datatype instead */
- if ((argnum >= 0) && (!isglobal)) {
- Printf(str, "%s%d", pn, argnum);
- } else {
- Append(str, pn);
- }
- if (isglobal && Wrapper_check_local(f, str)) {
- p = nextSibling(p);
- Delete(str);
- if (at)
- Delete(at);
- continue;
- }
- if (value) {
- String *pstr = SwigType_str(pt, str);
- new_name = Wrapper_new_localv(f, str, pstr, "=", value, NIL);
- Delete(pstr);
- } else {
- String *pstr = SwigType_str(pt, str);
- new_name = Wrapper_new_localv(f, str, pstr, NIL);
- Delete(pstr);
- }
- if (!isglobal) {
- /* Substitute */
- Replace(s, pn, new_name, DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE);
- }
- Delete(str);
- }
- }
- p = nextSibling(p);
- if (at)
- Delete(at);
- }
- }
- /* -----------------------------------------------------------------------------
- * Swig_typemap_lookup()
- *
- * Attach one or more typemaps to a node and optionally generate the typemap contents
- * into the wrapper.
- *
- * Looks for a typemap matching the given type and name and attaches the typemap code
- * and any typemap attributes to the provided node.
- *
- * The node should contain the "type" and "name" attributes for the typemap match on.
- * input. The typemap code and typemap attribute values are attached onto the node
- * prefixed with "tmap:". For example with tmap_method="in", the typemap code can be retrieved
- * with a call to Getattr(node, "tmap:in") (this is also the string returned) and the
- * "noblock" attribute can be retrieved with a call to Getattr(node, "tmap:in:noblock").
- *
- * tmap_method - typemap method, eg "in", "out", "newfree"
- * node - the node to attach the typemap and typemap attributes to
- * lname - name of variable to substitute $1, $2 etc for
- * f - wrapper code to generate into if non null
- * actioncode - code to generate into f before the out typemap code, unless
- * the optimal attribute is set in the out typemap in which case
- * $1 in the out typemap will be replaced by the code in actioncode.
- * ----------------------------------------------------------------------------- */
- static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f, String *actioncode) {
- SwigType *type;
- SwigType *mtype = 0;
- String *pname;
- Hash *tm = 0;
- String *s = 0;
- String *sdef = 0;
- ParmList *locals;
- ParmList *kw;
- char temp[256];
- String *symname;
- String *cname = 0;
- String *clname = 0;
- char *cop = Char(tmap_method);
- int optimal_attribute = 0;
- int optimal_substitution = 0;
- int num_substitutions = 0;
- /* special case, we need to check for 'ref' call
- and set the default code 'sdef' */
- if (node && Cmp(tmap_method, "newfree") == 0) {
- sdef = Swig_ref_call(node, lname);
- }
- type = Getattr(node, "type");
- if (!type)
- return sdef;
- pname = Getattr(node, "name");
- #if 1
- if (pname && node && checkAttribute(node, "kind", "function")) {
- /*
- For functions, look qualified names first, such as
- struct Foo {
- int *foo(int bar) -> Foo::foo
- };
- */
- Symtab *st = Getattr(node, "sym:symtab");
- String *qsn = st ? Swig_symbol_string_qualify(pname, st) : 0;
- if (qsn) {
- if (Len(qsn) && !Equal(qsn, pname)) {
- tm = typemap_search(tmap_method, type, qsn, &mtype);
- if (tm && (!Getattr(tm, "pname") || strstr(Char(Getattr(tm, "type")), "SWIGTYPE"))) {
- tm = 0;
- }
- }
- Delete(qsn);
- }
- }
- if (!tm)
- #endif
- tm = typemap_search(tmap_method, type, pname, &mtype);
- if (!tm)
- return sdef;
- s = Getattr(tm, "code");
- if (!s)
- return sdef;
- /* Empty typemap. No match */
- if (Cmp(s, "pass") == 0)
- return sdef;
- s = Copy(s); /* Make a local copy of the typemap code */
- /* Attach kwargs - ie the typemap attributes */
- kw = Getattr(tm, "kwargs");
- while (kw) {
- String *value = Copy(Getattr(kw, "value"));
- String *kwtype = Getattr(kw, "type");
- char *ckwname = Char(Getattr(kw, "name"));
- if (kwtype) {
- String *mangle = Swig_string_mangle(kwtype);
- Append(value, mangle);
- Delete(mangle);
- }
- sprintf(temp, "%s:%s", cop, ckwname);
- Setattr(node, typemap_method_name(temp), value);
- if (Cmp(temp, "out:optimal") == 0)
- optimal_attribute = (Cmp(value, "0") != 0) ? 1 : 0;
- Delete(value);
- kw = nextSibling(kw);
- }
-
- if (optimal_attribute) {
- /* Note: "out" typemap is the only typemap that will have the "optimal" attribute set.
- * If f and actioncode are NULL, then the caller is just looking to attach the "out" attributes
- * ie, not use the typemap code, otherwise both f and actioncode must be non null. */
- if (actioncode) {
- clname = Copy(actioncode);
- /* check that the code in the typemap can be used in this optimal way.
- * The code should be in the form "result = ...;\n". We need to extract
- * the "..." part. This may not be possible for various reasons, eg
- * code added by %exception. This optimal code generation is bit of a
- * hack and circumvents the normal requirement for a temporary variable
- * to hold the result returned from a wrapped function call.
- */
- if (Strncmp(clname, "result = ", 9) == 0) {
- int numreplacements = Replace(clname, "result = ", "", DOH_REPLACE_ID_BEGIN);
- if (numreplacements == 1) {
- numreplacements = Replace(clname, ";\n", "", DOH_REPLACE_ID_END);
- if (numreplacements == 1) {
- if (Strchr(clname, ';') == 0) {
- lname = clname;
- actioncode = 0;
- optimal_substitution = 1;
- }
- }
- }
- }
- if (!optimal_substitution) {
- Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(node), Getline(node), "Method %s usage of the optimal attribute in the out typemap at %s:%d ignored as the following cannot be used to generate optimal code: %s\n", Swig_name_decl(node), Getfile(s), Getline(s), clname);
- Delattr(node, "tmap:out:optimal");
- }
- } else {
- assert(!f);
- }
- }
- if (actioncode) {
- assert(f);
- Append(f->code, actioncode);
- }
- /* emit local variables declared in typemap, eg emit declarations for aa and bb in:
- * %typemap(in) foo (int aa, int bb) "..." */
- locals = Getattr(tm, "locals");
- if (locals)
- locals = CopyParmList(locals);
- if (pname) {
- if (SwigType_istemplate(pname)) {
- cname = SwigType_namestr(pname);
- pname = cname;
- }
- }
- if (SwigType_istemplate((char *) lname)) {
- clname = SwigType_namestr((char *) lname);
- lname = clname;
- }
- if (mtype && SwigType_isarray(mtype)) {
- num_substitutions = typemap_replace_vars(s, locals, mtype, type, pname, (char *) lname, 1);
- } else {
- num_substitutions = typemap_replace_vars(s, locals, type, type, pname, (char *) lname, 1);
- }
- if (optimal_substitution && num_substitutions > 1)
- Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(node), Getline(node), "Multiple calls to %s might be generated due to optimal attribute usage in the out typemap at %s:%d.\n", Swig_name_decl(node), Getfile(s), Getline(s));
- if (locals && f) {
- typemap_locals(s, locals, f, -1);
- }
- {
- ParmList *parm_sublist = NewParm(type, pname);
- Setattr(parm_sublist, "lname", lname);
- replace_embedded_typemap(s, parm_sublist, f);
- Delete(parm_sublist);
- }
- Replace(s, "$name", pname, DOH_REPLACE_ANY);
- symname = Getattr(node, "sym:name");
- if (symname) {
- Replace(s, "$symname", symname, DOH_REPLACE_ANY);
- }
- Setattr(node, typemap_method_name(tmap_method), s);
- if (locals) {
- sprintf(temp, "%s:locals", cop);
- Setattr(node, typemap_method_name(temp), locals);
- Delete(locals);
- }
- if (Checkattr(tm, "type", "SWIGTYPE")) {
- sprintf(temp, "%s:SWIGTYPE", cop);
- Setattr(node, typemap_method_name(temp), "1");
- }
- /* Look for warnings */
- {
- String *w;
- sprintf(temp, "%s:warning", cop);
- w = Getattr(node, typemap_method_name(temp));
- if (w) {
- Swig_warning(0, Getfile(node), Getline(node), "%s\n", w);
- }
- }
- /* Look for code fragments */
- {
- String *fragment;
- sprintf(temp, "%s:fragment", cop);
- fragment = Getattr(node, typemap_method_name(temp));
- if (fragment) {
- String *fname = Copy(fragment);
- Setfile(fname, Getfile(node));
- Setline(fname, Getline(node));
- Swig_fragment_emit(fname);
- Delete(fname);
- }
- }
- Delete(cname);
- Delete(clname);
- Delete(mtype);
- if (sdef) { /* put 'ref' and 'newfree' codes together */
- String *p = NewStringf("%s\n%s", sdef, s);
- Delete(s);
- Delete(sdef);
- s = p;
- }
- Delete(actioncode);
- return s;
- }
- String *Swig_typemap_lookup_out(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f, String *actioncode) {
- assert(actioncode);
- assert(Cmp(tmap_method, "out") == 0);
- return Swig_typemap_lookup_impl(tmap_method, node, lname, f, actioncode);
- }
- String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *node, const_String_or_char_ptr lname, Wrapper *f) {
- return Swig_typemap_lookup_impl(tmap_method, node, lname, f, 0);
- }
- /* -----------------------------------------------------------------------------
- * typemap_attach_kwargs()
- *
- * If this hash (tm) contains a linked list of parameters under its "kwargs"
- * attribute, add keys for each of those named keyword arguments to this
- * parameter for later use.
- * For example, attach the typemap attributes to p:
- * %typemap(in, foo="xyz") ...
- * A new attribute called "tmap:in:foo" with value "xyz" is attached to p.
- * ----------------------------------------------------------------------------- */
- static void typemap_attach_kwargs(Hash *tm, const_String_or_char_ptr tmap_method, Parm *p) {
- String *temp = NewStringEmpty();
- Parm *kw = Getattr(tm, "kwargs");
- while (kw) {
- String *value = Copy(Getattr(kw, "value"));
- String *type = Getattr(kw, "type");
- if (type) {
- Hash *v = NewHash();
- Setattr(v, "type", type);
- Setattr(v, "value", value);
- Delete(value);
- value = v;
- }
- Clear(temp);
- Printf(temp, "%s:%s", tmap_method, Getattr(kw, "name"));
- Setattr(p, typemap_method_name(temp), value);
- Delete(value);
- kw = nextSibling(kw);
- }
- Clear(temp);
- Printf(temp, "%s:match_type", tmap_method);
- Setattr(p, typemap_method_name(temp), Getattr(tm, "type"));
- Delete(temp);
- }
- /* -----------------------------------------------------------------------------
- * typemap_warn()
- *
- * If any warning message is attached to this parameter's "tmap:<method>:warning"
- * attribute, print that warning message.
- * ----------------------------------------------------------------------------- */
- static void typemap_warn(const_String_or_char_ptr tmap_method, Parm *p) {
- String *temp = NewStringf("%s:warning", tmap_method);
- String *w = Getattr(p, typemap_method_name(temp));
- Delete(temp);
- if (w) {
- Swig_warning(0, Getfile(p), Getline(p), "%s\n", w);
- }
- }
- static void typemap_emit_code_fragments(const_String_or_char_ptr tmap_method, Parm *p) {
- String *temp = NewStringf("%s:fragment", tmap_method);
- String *f = Getattr(p, typemap_method_name(temp));
- if (f) {
- String *fname = Copy(f);
- Setfile(fname, Getfile(p));
- Setline(fname, Getline(p));
- Swig_fragment_emit(fname);
- Delete(fname);
- }
- Delete(temp);
- }
- static String *typemap_get_option(Hash *tm, const_String_or_char_ptr name) {
- Parm *kw = Getattr(tm, "kwargs");
- while (kw) {
- String *kname = Getattr(kw, "name");
- if (Equal(kname, name)) {
- return Getattr(kw, "value");
- }
- kw = nextSibling(kw);
- }
- return 0;
- }
- /* -----------------------------------------------------------------------------
- * Swig_typemap_attach_parms()
- *
- * Given a parameter list, this function attaches all of the typemaps and typemap
- * attributes to the parameter for each type in the parameter list.
- *
- * This function basically provides the typemap code and typemap attribute values as
- * attributes on each parameter prefixed with "tmap:". For example with tmap_method="in", the typemap
- * code can be retrieved for the first parameter with a call to Getattr(parm, "tmap:in")
- * and the "numinputs" attribute can be retrieved with a call to Getattr(parm, "tmap:in:numinputs").
- *
- * tmap_method - typemap method, eg "in", "out", "newfree"
- * parms - parameter list to attach each typemap and all typemap attributes
- * f - wrapper code to generate into if non null
- * ----------------------------------------------------------------------------- */
- void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *parms, Wrapper *f) {
- Parm *p, *firstp;
- Hash *tm;
- int nmatch = 0;
- int i;
- String *s;
- ParmList *locals;
- int argnum = 0;
- char temp[256];
- char *cop = Char(tmap_method);
- String *kwmatch = 0;
- p = parms;
- #ifdef SWIG_DEBUG
- Printf(stdout, "Swig_typemap_attach_parms: %s\n", tmap_method);
- #endif
- while (p) {
- argnum++;
- nmatch = 0;
- #ifdef SWIG_DEBUG
- Printf(stdout, "parms: %s %s %s\n", tmap_method, Getattr(p, "name"), Getattr(p, "type"));
- #endif
- tm = typemap_search_multi(tmap_method, p, &nmatch);
- #ifdef SWIG_DEBUG
- if (tm)
- Printf(stdout, "found: %s\n", tm);
- #endif
- if (!tm) {
- p = nextSibling(p);
- continue;
- }
- /*
- Check if the typemap requires to match the type of another
- typemap, for example:
- %typemap(in) SWIGTYPE * (int var) {...}
- %typemap(freearg,match="in") SWIGTYPE * {if (var$argnum) ...}
- here, the freearg typemap requires the "in" typemap to match,
- or the 'var$argnum' variable will not exist.
- */
- kwmatch = typemap_get_option(tm, "match");
- if (kwmatch) {
- String *tmname = NewStringf("tmap:%s", kwmatch);
- String *tmin = Getattr(p, tmname);
- Delete(tmname);
- #ifdef SWIG_DEBUG
- if (tm)
- Printf(stdout, "matching: %s\n", kwmatch);
- #endif
- if (tmin) {
- String *tmninp = NewStringf("tmap:%s:numinputs", kwmatch);
- String *ninp = Getattr(p, tmninp);
- Delete(tmninp);
- if (ninp && Equal(ninp, "0")) {
- p = nextSibling(p);
- continue;
- } else {
- SwigType *typetm = Getattr(tm, "type");
- String *temp = NewStringf("tmap:%s:match_type", kwmatch);
- SwigType *typein = Getattr(p, temp);
- Delete(temp);
- if (!Equal(typein, typetm)) {
- p = nextSibling(p);
- continue;
- } else {
- int nnmatch;
- Hash *tmapin = typemap_search_multi(kwmatch, p, &nnmatch);
- String *tmname = Getattr(tm, "pname");
- String *tnname = Getattr(tmapin, "pname");
- if (!(tmname && tnname && Equal(tmname, tnname)) && !(!tmname && !tnname)) {
- p = nextSibling(p);
- continue;
- }
- }
- }
- } else {
- p = nextSibling(p);
- continue;
- }
- }
- s = Getattr(tm, "code");
- if (!s) {
- p = nextSibling(p);
- continue;
- }
- #ifdef SWIG_DEBUG
- if (s)
- Printf(stdout, "code: %s\n", s);
- #endif
- /* Empty typemap. No match */
- if (Cmp(s, "pass") == 0) {
- p = nextSibling(p);
- continue;
- }
- s = Copy(s);
- locals = Getattr(tm, "locals");
- if (locals)
- locals = CopyParmList(locals);
- firstp = p;
- #ifdef SWIG_DEBUG
- Printf(stdout, "nmatch: %d\n", nmatch);
- #endif
- for (i = 0; i < nmatch; i++) {
- SwigType *type;
- String *pname;
- String *lname;
- SwigType *mtype;
- type = Getattr(p, "type");
- pname = Getattr(p, "name");
- lname = Getattr(p, "lname");
- mtype = Getattr(p, "tmap:match");
- if (mtype) {
- typemap_replace_vars(s, locals, mtype, type, pname, lname, i + 1);
- Delattr(p, "tmap:match");
- } else {
- typemap_replace_vars(s, locals, type, type, pname, lname, i + 1);
- }
- if (Checkattr(tm, "type", "SWIGTYPE")) {
- sprintf(temp, "%s:SWIGTYPE", cop);
- Setattr(p, typemap_method_name(temp), "1");
- }
- p = nextSibling(p);
- }
- if (locals && f) {
- typemap_locals(s, locals, f, argnum);
- }
- replace_embedded_typemap(s, firstp, f);
- /* Replace the argument number */
- sprintf(temp, "%d", argnum);
- Replace(s, "$argnum", temp, DOH_REPLACE_ANY);
- /* Attach attributes to object */
- #ifdef SWIG_DEBUG
- Printf(stdout, "attach: %s %s %s\n", Getattr(firstp, "name"), typemap_method_name(tmap_method), s);
- #endif
- Setattr(firstp, typemap_method_name(tmap_method), s); /* Code object */
- if (locals) {
- sprintf(temp, "%s:locals", cop);
- Setattr(firstp, typemap_method_name(temp), locals);
- Delete(locals);
- }
- /* Attach a link to the next parameter. Needed for multimaps */
- sprintf(temp, "%s:next", cop);
- Setattr(firstp, typemap_method_name(temp), p);
- /* Attach kwargs */
- typemap_attach_kwargs(tm, tmap_method, firstp);
- /* Print warnings, if any */
- typemap_warn(tmap_method, firstp);
- /* Look for code fragments */
- typemap_emit_code_fragments(tmap_method, firstp);
- /* increase argnum to consider numinputs */
- argnum += nmatch - 1;
- Delete(s);
- #ifdef SWIG_DEBUG
- Printf(stdout, "res: %s %s %s\n", Getattr(firstp, "name"), typemap_method_name(tmap_method), Getattr(firstp, typemap_method_name(tmap_method)));
- #endif
- }
- #ifdef SWIG_DEBUG
- Printf(stdout, "Swig_typemap_attach_parms: end\n");
- #endif
- }
- /* Splits the arguments of an embedded typemap */
- static List *split_embedded_typemap(String *s) {
- List *args = 0;
- char *c, *start;
- int level = 0;
- int angle_level = 0;
- int leading = 1;
- args = NewList();
- c = strchr(Char(s), '(');
- assert(c);
- c++;
- start = c;
- while (*c) {
- if (*c == '\"') {
- c++;
- while (*c) {
- if (*c == '\\') {
- c++;
- } else {
- if (*c == '\"')
- break;
- }
- c++;
- }
- }
- if ((level == 0) && angle_level == 0 && ((*c == ',') || (*c == ')'))) {
- String *tmp = NewStringWithSize(start, c - start);
- Append(args, tmp);
- Delete(tmp);
- start = c + 1;
- leading = 1;
- if (*c == ')')
- break;
- c++;
- continue;
- }
- if (*c == '(')
- level++;
- if (*c == ')')
- level--;
- if (*c == '<')
- angle_level++;
- if (*c == '>')
- angle_level--;
- if (isspace((int) *c) && leading)
- start++;
- if (!isspace((int) *c))
- leading = 0;
- c++;
- }
- return args;
- }
- /* -----------------------------------------------------------------------------
- * replace_embedded_typemap()
- *
- * This function replaces the special variable macro $typemap(...) with typemap
- * code. The general form of $typemap is as follows:
- *
- * $typemap(method, typelist, var1=value, var2=value, ...)
- *
- * where varx parameters are optional and undocumented; they were used in an earlier version of $typemap.
- * A search is made using the typemap matching rules of form:
- *
- * %typemap(method) typelist {...}
- *
- * and if found will substitute in the typemap contents, making appropriate variable replacements.
- *
- * For example:
- * $typemap(in, int) # simple usage matching %typemap(in) int { ... }
- * $typemap(in, int b) # simple usage matching %typemap(in) int b { ... } or above %typemap
- * $typemap(in, (Foo<int, bool> a, int b)) # multi-argument typemap matching %typemap(in) (Foo<int, bool> a, int b) {...}
- * --------------------------------------------------------------------…
Large files files are truncated, but you can click here to view the full file