1/* -----------------------------------------------------------------------------
2 * See the LICENSE file for information on copyright, usage and redistribution
3 * of SWIG, and the README file for authors - http://www.swig.org/release.html.
4 *
5 * cwrap.c
6 *
7 * This file defines a variety of wrapping rules for C/C++ handling including
8 * the naming of local variables, calling conventions, and so forth.
9 * ----------------------------------------------------------------------------- */
10
11char cvsroot_cwrap_c[] = "$Id: cwrap.c 11312 2009-06-24 17:20:17Z wsfulton $";
12
13#include "swig.h"
14
15extern int cparse_cplusplus;
16
17static Parm *nonvoid_parms(Parm *p) {
18  if (p) {
19    SwigType *t = Getattr(p, "type");
20    if (SwigType_type(t) == T_VOID)
21      return 0;
22  }
23  return p;
24}
25
26/* -----------------------------------------------------------------------------
27 * Swig_parm_name()
28 *
29 * Generates a name for the ith argument in an argument list
30 * ----------------------------------------------------------------------------- */
31
32String *Swig_cparm_name(Parm *p, int i) {
33  String *name = NewStringf("arg%d", i + 1);
34  if (p) {
35    Setattr(p, "lname", name);
36  }
37
38  return name;
39}
40
41/* -----------------------------------------------------------------------------
42 * Swig_clocal()
43 *
44 * Creates a string that declares a C local variable type.  Converts references
45 * and user defined types to pointers.
46 * ----------------------------------------------------------------------------- */
47
48static String *Swig_clocal(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr value) {
49  String *decl;
50
51  decl = NewStringEmpty();
52
53  switch (SwigType_type(t)) {
54  case T_REFERENCE:
55    if (value) {
56      String *lstrname = SwigType_lstr(t, name);
57      String *lstr = SwigType_lstr(t, 0);
58      Printf(decl, "%s = (%s) &%s_defvalue", lstrname, lstr, name);
59      Delete(lstrname);
60      Delete(lstr);
61    } else {
62      String *lstrname = SwigType_lstr(t, name);
63      Printf(decl, "%s = 0", lstrname);
64      Delete(lstrname);
65    }
66    break;
67  case T_VOID:
68    break;
69  case T_VARARGS:
70    Printf(decl, "void *%s = 0", name);
71    break;
72
73  default:
74    if (value) {
75      String *lcaststr = SwigType_lcaststr(t, value);
76      String *lstr = SwigType_lstr(t, 0);
77      String *lstrn = SwigType_lstr(t, name);
78      Printf(decl, "%s = (%s) %s", lstrn, lstr, lcaststr);
79      Delete(lcaststr);
80      Delete(lstr);
81      Delete(lstrn);
82    } else {
83      String *lstrname = SwigType_lstr(t, name);
84      Append(decl, lstrname);
85      Delete(lstrname);
86    }
87  }
88  return decl;
89}
90
91/* -----------------------------------------------------------------------------
92 * Swig_wrapped_var_convert()
93 *
94 * Converts a member variable for use in the get and set wrapper methods.
95 * This function only converts user defined types to pointers.
96 * ----------------------------------------------------------------------------- */
97
98String *Swig_wrapped_var_type(SwigType *t, int varcref) {
99  SwigType *ty;
100
101  if (!Strstr(t, "enum $unnamed")) {
102    ty = Copy(t);
103  } else {
104    /* Change the type for unnamed enum instance variables */
105    ty = NewString("int");
106  }
107
108  if (SwigType_isclass(t)) {
109    if (varcref) {
110      if (cparse_cplusplus) {
111	if (!SwigType_isconst(ty))
112	  SwigType_add_qualifier(ty, "const");
113	SwigType_add_reference(ty);
114      } else {
115	return Copy(ty);
116      }
117    } else {
118      SwigType_add_pointer(ty);
119    }
120  }
121  return ty;
122}
123
124String *Swig_wrapped_member_var_type(SwigType *t, int varcref) {
125  SwigType *ty;
126
127  if (!Strstr(t, "enum $unnamed")) {
128    ty = Copy(t);
129  } else {
130    /* Change the type for unnamed enum instance variables */
131    ty = NewString("int");
132  }
133  if (SwigType_isclass(t)) {
134    if (varcref) {
135      if (cparse_cplusplus) {
136	if (!SwigType_isconst(ty))
137	  SwigType_add_qualifier(ty, "const");
138	SwigType_add_reference(ty);
139      } else {
140	return Copy(ty);
141      }
142    } else {
143      SwigType_add_pointer(ty);
144    }
145  }
146  return ty;
147}
148
149
150static String *Swig_wrapped_var_deref(SwigType *t, const_String_or_char_ptr name, int varcref) {
151  if (SwigType_isclass(t)) {
152    if (varcref) {
153      if (cparse_cplusplus) {
154	return NewStringf("*%s", name);
155      } else {
156	return NewStringf("%s", name);
157      }
158    } else {
159      return NewStringf("*%s", name);
160    }
161  } else {
162    return SwigType_rcaststr(t, name);
163  }
164}
165
166static String *Swig_wrapped_var_assign(SwigType *t, const_String_or_char_ptr name, int varcref) {
167  if (SwigType_isclass(t)) {
168    if (varcref) {
169      return NewStringf("%s", name);
170    } else {
171      return NewStringf("&%s", name);
172    }
173  } else {
174    return SwigType_lcaststr(t, name);
175  }
176}
177
178/* -----------------------------------------------------------------------------
179 * Swig_cargs()
180 *
181 * Emit all of the local variables for a list of parameters.  Returns the
182 * number of parameters.
183 * Default values for the local variables are only emitted if the compact default
184 * argument behaviour is required.
185 * ----------------------------------------------------------------------------- */
186int Swig_cargs(Wrapper *w, ParmList *p) {
187  int i = 0;
188  int compactdefargs = ParmList_is_compactdefargs(p);
189
190  while (p != 0) {
191    String *lname = Swig_cparm_name(p, i);
192    SwigType *pt = Getattr(p, "type");
193    if ((SwigType_type(pt) != T_VOID)) {
194      String *local = 0;
195      String *type = Getattr(p, "type");
196      /* default values only emitted if in compact default args mode */
197      String *pvalue = (compactdefargs) ? Getattr(p, "value") : 0;
198
199      /* When using compactdefaultargs, the code generated initialises a variable via a constructor call that accepts the
200       * default value as a parameter. The default constructor is not called and therefore SwigValueWrapper is not needed. */
201      SwigType *altty = pvalue ? 0 : SwigType_alttype(type, 0);
202
203      int tycode = SwigType_type(type);
204      if (tycode == T_REFERENCE) {
205	if (pvalue) {
206	  SwigType *tvalue;
207	  String *defname, *defvalue, *rvalue, *qvalue;
208	  rvalue = SwigType_typedef_resolve_all(pvalue);
209	  qvalue = SwigType_typedef_qualified(rvalue);
210	  defname = NewStringf("%s_defvalue", lname);
211	  tvalue = Copy(type);
212	  SwigType_del_reference(tvalue);
213	  tycode = SwigType_type(tvalue);
214	  if (tycode != T_USER) {
215	    /* plain primitive type, we copy the the def value */
216	    String *lstr = SwigType_lstr(tvalue, defname);
217	    defvalue = NewStringf("%s = %s", lstr, qvalue);
218	    Delete(lstr);
219	  } else {
220	    /* user type, we copy the reference value */
221	    String *str = SwigType_str(type, defname);
222	    defvalue = NewStringf("%s = %s", str, qvalue);
223	    Delete(str);
224	  }
225	  Wrapper_add_localv(w, defname, defvalue, NIL);
226	  Delete(tvalue);
227	  Delete(rvalue);
228	  Delete(qvalue);
229	  Delete(defname);
230	  Delete(defvalue);
231	}
232      } else if (!pvalue && ((tycode == T_POINTER) || (tycode == T_STRING))) {
233	pvalue = (String *) "0";
234      }
235      if (!altty) {
236	local = Swig_clocal(pt, lname, pvalue);
237      } else {
238	local = Swig_clocal(altty, lname, pvalue);
239	Delete(altty);
240      }
241      Wrapper_add_localv(w, lname, local, NIL);
242      Delete(local);
243      i++;
244    }
245    Delete(lname);
246    p = nextSibling(p);
247  }
248  return (i);
249}
250
251/* -----------------------------------------------------------------------------
252 * Swig_cresult()
253 *
254 * This function generates the C code needed to set the result of a C
255 * function call.
256 * ----------------------------------------------------------------------------- */
257
258String *Swig_cresult(SwigType *t, const_String_or_char_ptr name, const_String_or_char_ptr decl) {
259  String *fcall;
260
261  fcall = NewStringEmpty();
262  switch (SwigType_type(t)) {
263  case T_VOID:
264    break;
265  case T_REFERENCE:
266    {
267      String *lstr = SwigType_lstr(t, 0);
268      Printf(fcall, "%s = (%s) &", name, lstr);
269      Delete(lstr);
270    }
271    break;
272  case T_USER:
273    Printf(fcall, "%s = ", name);
274    break;
275
276  default:
277    /* Normal return value */
278    {
279      String *lstr = SwigType_lstr(t, 0);
280      Printf(fcall, "%s = (%s)", name, lstr);
281      Delete(lstr);
282    }
283    break;
284  }
285
286  /* Now print out function call */
287  Append(fcall, decl);
288
289  /* A sick hack */
290  {
291    char *c = Char(decl) + Len(decl) - 1;
292    if (!((*c == ';') || (*c == '}')))
293      Append(fcall, ";");
294  }
295
296  return fcall;
297}
298
299/* -----------------------------------------------------------------------------
300 * Swig_cfunction_call()
301 *
302 * Creates a string that calls a C function using the local variable rules
303 * defined above.
304 *
305 *    name(arg0, arg1, arg2, ... argn)
306 *
307 * ----------------------------------------------------------------------------- */
308
309String *Swig_cfunction_call(const_String_or_char_ptr name, ParmList *parms) {
310  String *func;
311  int i = 0;
312  int comma = 0;
313  Parm *p = parms;
314  String *nname;
315
316  func = NewStringEmpty();
317  nname = SwigType_namestr(name);
318
319  /*
320     SWIGTEMPLATEDISAMBIGUATOR is compiler dependent (swiglabels.swg),
321     - SUN Studio 9 requires 'template',
322     - gcc-3.4 forbids the use of 'template'.
323     the rest seems not caring very much,
324   */
325  if (SwigType_istemplate(name)) {
326    String *prefix = Swig_scopename_prefix(nname);
327    if (!prefix || Len(prefix) == 0) {
328      Printf(func, "%s(", nname);
329    } else {
330      String *last = Swig_scopename_last(nname);
331      Printf(func, "%s::SWIGTEMPLATEDISAMBIGUATOR %s(", prefix, last);
332      Delete(last);
333    }
334    Delete(prefix);
335  } else {
336    Printf(func, "%s(", nname);
337  }
338  Delete(nname);
339
340  while (p) {
341    SwigType *pt = Getattr(p, "type");
342    if ((SwigType_type(pt) != T_VOID)) {
343      SwigType *rpt = SwigType_typedef_resolve_all(pt);
344      String *pname = Swig_cparm_name(p, i);
345      String *rcaststr = SwigType_rcaststr(rpt, pname);
346
347      if (comma) {
348	Printv(func, ",", rcaststr, NIL);
349      } else {
350	Append(func, rcaststr);
351      }
352      Delete(rpt);
353      Delete(pname);
354      Delete(rcaststr);
355      comma = 1;
356      i++;
357    }
358    p = nextSibling(p);
359  }
360  Append(func, ")");
361  return func;
362}
363
364/* -----------------------------------------------------------------------------
365 * Swig_cmethod_call()
366 *
367 * Generates a string that calls a C++ method from a list of parameters.
368 *
369 *    arg0->name(arg1, arg2, arg3, ..., argn)
370 *
371 * self is an argument that defines how to handle the first argument. Normally,
372 * it should be set to "this->".  With C++ proxy classes enabled, it could be
373 * set to "(*this)->" or some similar sequence.
374 * ----------------------------------------------------------------------------- */
375
376static String *Swig_cmethod_call(const_String_or_char_ptr name, ParmList *parms, const_String_or_char_ptr self, String *explicit_qualifier, SwigType *director_type) {
377  String *func, *nname;
378  int i = 0;
379  Parm *p = parms;
380  SwigType *pt;
381  int comma = 0;
382
383  func = NewStringEmpty();
384  if (!p)
385    return func;
386
387  if (!self)
388    self = (char *) "(this)->";
389  Append(func, self);
390
391  if (SwigType_istemplate(name) && (strncmp(Char(name), "operator ", 9) == 0)) {
392    /* fix for template + operators and compilers like gcc 3.3.5 */
393    String *tprefix = SwigType_templateprefix(name);
394    nname = tprefix;
395  } else {
396    nname = SwigType_namestr(name);
397  }
398
399  if (director_type) {
400    const char *pname = "darg";
401    String *rcaststr = SwigType_rcaststr(director_type, pname);
402    Replaceall(func, "this", rcaststr);
403    Delete(rcaststr);
404  } else {
405    pt = Getattr(p, "type");
406
407    /* If the method is invoked through a dereferenced pointer, we don't add any casts
408       (needed for smart pointers).  Otherwise, we cast to the appropriate type */
409
410    if (Strstr(func, "*this")) {
411      String *pname = Swig_cparm_name(p, 0);
412      Replaceall(func, "this", pname);
413      Delete(pname);
414    } else {
415      String *pname = Swig_cparm_name(p, 0);
416      String *rcaststr = SwigType_rcaststr(pt, pname);
417      Replaceall(func, "this", rcaststr);
418      Delete(rcaststr);
419      Delete(pname);
420    }
421
422    /*
423       SWIGTEMPLATEDESIMBUAGATOR is compiler dependent (swiglabels.swg),
424       - SUN Studio 9 requires 'template',
425       - gcc-3.4 forbids the use of 'template' (correctly implementing the ISO C++ standard)
426       the others don't seem to care,
427     */
428    if (SwigType_istemplate(name))
429      Printf(func, "SWIGTEMPLATEDISAMBIGUATOR ");
430
431    if (explicit_qualifier) {
432      Printv(func, explicit_qualifier, "::", NIL);
433    }
434  }
435
436  Printf(func, "%s(", nname);
437
438  i++;
439  p = nextSibling(p);
440  while (p) {
441    pt = Getattr(p, "type");
442    if ((SwigType_type(pt) != T_VOID)) {
443      String *pname = Swig_cparm_name(p, i);
444      String *rcaststr = SwigType_rcaststr(pt, pname);
445      if (comma)
446	Append(func, ",");
447      Append(func, rcaststr);
448      Delete(rcaststr);
449      Delete(pname);
450      comma = 1;
451      i++;
452    }
453    p = nextSibling(p);
454  }
455  Append(func, ")");
456  Delete(nname);
457  return func;
458}
459
460/* -----------------------------------------------------------------------------
461 * Swig_cconstructor_call()
462 *
463 * Creates a string that calls a C constructor function.
464 *
465 *      calloc(1,sizeof(name));
466 * ----------------------------------------------------------------------------- */
467
468String *Swig_cconstructor_call(const_String_or_char_ptr name) {
469  DOH *func;
470
471  func = NewStringEmpty();
472  Printf(func, "calloc(1, sizeof(%s))", name);
473  return func;
474}
475
476
477/* -----------------------------------------------------------------------------
478 * Swig_cppconstructor_call()
479 *
480 * Creates a string that calls a C function using the local variable rules
481 * defined above.
482 *
483 *    name(arg0, arg1, arg2, ... argn)
484 *
485 * ----------------------------------------------------------------------------- */
486
487String *Swig_cppconstructor_base_call(const_String_or_char_ptr name, ParmList *parms, int skip_self) {
488  String *func;
489  String *nname;
490  int i = 0;
491  int comma = 0;
492  Parm *p = parms;
493  SwigType *pt;
494  if (skip_self) {
495    if (p)
496      p = nextSibling(p);
497    i++;
498  }
499  nname = SwigType_namestr(name);
500  func = NewStringEmpty();
501  Printf(func, "new %s(", nname);
502  while (p) {
503    pt = Getattr(p, "type");
504    if ((SwigType_type(pt) != T_VOID)) {
505      String *rcaststr = 0;
506      String *pname = 0;
507      if (comma)
508	Append(func, ",");
509      if (!Getattr(p, "arg:byname")) {
510	pname = Swig_cparm_name(p, i);
511	i++;
512      } else {
513        pname = Getattr(p, "value");
514	if (pname)
515	  pname = Copy(pname);
516	else
517	  pname = Copy(Getattr(p, "name"));
518      }
519      rcaststr = SwigType_rcaststr(pt, pname);
520      Append(func, rcaststr);
521      Delete(rcaststr);
522      comma = 1;
523      Delete(pname);
524    }
525    p = nextSibling(p);
526  }
527  Append(func, ")");
528  Delete(nname);
529  return func;
530}
531
532String *Swig_cppconstructor_call(const_String_or_char_ptr name, ParmList *parms) {
533  return Swig_cppconstructor_base_call(name, parms, 0);
534}
535
536String *Swig_cppconstructor_nodirector_call(const_String_or_char_ptr name, ParmList *parms) {
537  return Swig_cppconstructor_base_call(name, parms, 1);
538}
539
540String *Swig_cppconstructor_director_call(const_String_or_char_ptr name, ParmList *parms) {
541  return Swig_cppconstructor_base_call(name, parms, 0);
542}
543
544/* -----------------------------------------------------------------------------
545 * Swig_rflag_search()
546 *
547 * This function searches for the class attribute 'attr' in the class
548 * 'n' or recursively in its bases.
549 *
550 * If you define SWIG_FAST_REC_SEARCH, the method will set the found
551 * 'attr' in the target class 'n'. If not, the method will set the
552 * 'noattr' one. This prevents of having to navigate the entire
553 * hierarchy tree everytime, so, it is an O(1) method...  or something
554 * like that. However, it populates all the parsed classes with the
555 * 'attr' and/or 'noattr' attributes.
556 *
557 * If you undefine the SWIG_FAST_REC_SEARCH no attribute will be set
558 * while searching. This could be slower for large projects with very
559 * large hierarchy trees... or maybe not. But it will be cleaner.
560 *
561 * Maybe later a swig option can be added to switch at runtime.
562 *
563 * ----------------------------------------------------------------------------- */
564
565/* #define SWIG_FAST_REC_SEARCH 1 */
566String *Swig_rflag_search(Node *n, const String *attr, const String *noattr) {
567  String *f = 0;
568  n = Swig_methodclass(n);
569  if (GetFlag(n, noattr)) {
570    return 0;
571  }
572  f = GetFlagAttr(n, attr);
573  if (f) {
574    return f;
575  } else {
576    List *bl = Getattr(n, "bases");
577    if (bl) {
578      Iterator bi;
579      for (bi = First(bl); bi.item; bi = Next(bi)) {
580	f = Swig_rflag_search(bi.item, attr, noattr);
581	if (f) {
582#ifdef SWIG_FAST_REC_SEARCH
583	  SetFlagAttr(n, attr, f);
584#endif
585	  return f;
586	}
587      }
588    }
589  }
590#ifdef SWIG_FAST_REC_SEARCH
591  SetFlag(n, noattr);
592#endif
593  return 0;
594}
595
596/* -----------------------------------------------------------------------------
597 * Swig_unref_call()
598 *
599 * find the unref call, if any.
600 * ----------------------------------------------------------------------------- */
601
602String *Swig_unref_call(Node *n) {
603  Node *cn = Swig_methodclass(n);
604  String *unref = Swig_rflag_search(cn, "feature:unref", "feature:nounref");
605  if (unref) {
606    String *pname = Swig_cparm_name(0, 0);
607    unref = NewString(unref);
608    Replaceall(unref, "$this", pname);
609    Replaceall(unref, "$self", pname);
610    Delete(pname);
611  }
612  return unref;
613}
614
615/* -----------------------------------------------------------------------------
616 * Swig_ref_call()
617 *
618 * find the ref call, if any.
619 * ----------------------------------------------------------------------------- */
620
621String *Swig_ref_call(Node *n, const String *lname) {
622  Node *cn = Swig_methodclass(n);
623  String *ref = Swig_rflag_search(cn, "feature:ref", "feature:noref");
624  if (ref) {
625    ref = NewString(ref);
626    Replaceall(ref, "$this", lname);
627    Replaceall(ref, "$self", lname);
628  }
629  return ref;
630}
631
632/* -----------------------------------------------------------------------------
633 * Swig_cdestructor_call()
634 *
635 * Creates a string that calls a C destructor function.
636 *
637 *      free((char *) arg0);
638 * ----------------------------------------------------------------------------- */
639
640String *Swig_cdestructor_call(Node *n) {
641  String *unref = Swig_unref_call(n);
642
643  if (unref) {
644    return unref;
645  } else {
646    String *pname = Swig_cparm_name(0, 0);
647    String *call = NewStringf("free((char *) %s);", pname);
648    Delete(pname);
649    return call;
650  }
651}
652
653
654/* -----------------------------------------------------------------------------
655 * Swig_cppdestructor_call()
656 *
657 * Creates a string that calls a C destructor function.
658 *
659 *      delete arg1;
660 * ----------------------------------------------------------------------------- */
661
662String *Swig_cppdestructor_call(Node *n) {
663  String *unref = Swig_unref_call(n);
664  if (unref) {
665    return unref;
666  } else {
667    String *pname = Swig_cparm_name(0, 0);
668    String *call = NewStringf("delete %s;", pname);
669    Delete(pname);
670    return call;
671  }
672}
673
674/* -----------------------------------------------------------------------------
675 * Swig_cmemberset_call()
676 *
677 * Generates a string that sets the name of a member in a C++ class or C struct.
678 *
679 *        arg0->name = arg1
680 *
681 * ----------------------------------------------------------------------------- */
682
683String *Swig_cmemberset_call(const_String_or_char_ptr name, SwigType *type, String *self, int varcref) {
684  String *func;
685  String *pname0 = Swig_cparm_name(0, 0);
686  String *pname1 = Swig_cparm_name(0, 1);
687  func = NewStringEmpty();
688  if (!self)
689    self = NewString("(this)->");
690  else
691    self = NewString(self);
692  Replaceall(self, "this", pname0);
693  if (SwigType_type(type) != T_ARRAY) {
694    if (!Strstr(type, "enum $unnamed")) {
695      String *dref = Swig_wrapped_var_deref(type, pname1, varcref);
696      Printf(func, "if (%s) %s%s = %s", pname0, self, name, dref);
697      Delete(dref);
698    } else {
699      Printf(func, "if (%s && sizeof(int) == sizeof(%s%s)) *(int*)(void*)&(%s%s) = %s", pname0, self, name, self, name, pname1);
700    }
701  }
702  Delete(self);
703  Delete(pname0);
704  Delete(pname1);
705  return (func);
706}
707
708
709/* -----------------------------------------------------------------------------
710 * Swig_cmemberget_call()
711 *
712 * Generates a string that sets the name of a member in a C++ class or C struct.
713 *
714 *        arg0->name
715 *
716 * ----------------------------------------------------------------------------- */
717
718String *Swig_cmemberget_call(const_String_or_char_ptr name, SwigType *t, String *self, int varcref) {
719  String *func;
720  String *call;
721  String *pname0 = Swig_cparm_name(0, 0);
722  if (!self)
723    self = NewString("(this)->");
724  else
725    self = NewString(self);
726  Replaceall(self, "this", pname0);
727  func = NewStringEmpty();
728  call = Swig_wrapped_var_assign(t, "", varcref);
729  Printf(func, "%s (%s%s)", call, self, name);
730  Delete(self);
731  Delete(call);
732  Delete(pname0);
733  return func;
734}
735
736/* -----------------------------------------------------------------------------
737 * extension_code()
738 *
739 * Generates an extension function (a function defined in %extend)
740 *
741 *        return_type function_name(parms) code
742 *
743 * ----------------------------------------------------------------------------- */
744static String *extension_code(const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) {
745  String *parms_str = cplusplus ? ParmList_str_defaultargs(parms) : ParmList_str(parms);
746  String *sig = NewStringf("%s(%s)", function_name, parms_str);
747  String *rt_sig = SwigType_str(return_type, sig);
748  String *body = NewStringf("SWIGINTERN %s", rt_sig);
749  Printv(body, code, "\n", NIL);
750  if (self)
751    Replaceall(body, "$self", self);
752  Delete(parms_str);
753  Delete(sig);
754  Delete(rt_sig);
755  return body;
756}
757
758/* -----------------------------------------------------------------------------
759 * Swig_add_extension_code()
760 *
761 * Generates an extension function (a function defined in %extend) and
762 * adds it to the "wrap:code" attribute of a node
763 *
764 * See also extension_code()
765 *
766 * ----------------------------------------------------------------------------- */
767int Swig_add_extension_code(Node *n, const String *function_name, ParmList *parms, SwigType *return_type, const String *code, int cplusplus, const String *self) {
768  String *body = extension_code(function_name, parms, return_type, code, cplusplus, self);
769  Setattr(n, "wrap:code", body);
770  Delete(body);
771  return SWIG_OK;
772}
773
774
775/* -----------------------------------------------------------------------------
776 * Swig_MethodToFunction(Node *n)
777 *
778 * Converts a C++ method node to a function accessor function.
779 * ----------------------------------------------------------------------------- */
780
781int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *director_type, int is_director) {
782  String *name, *qualifier;
783  ParmList *parms;
784  SwigType *type;
785  Parm *p;
786  String *self = 0;
787
788  /* If smart pointer, change self dereferencing */
789  if (flags & CWRAP_SMART_POINTER) {
790    self = NewString("(*this)->");
791  }
792
793  /* If node is a member template expansion, we don't allow added code */
794  if (Getattr(n, "templatetype"))
795    flags &= ~(CWRAP_EXTEND);
796
797  name = Getattr(n, "name");
798  qualifier = Getattr(n, "qualifier");
799  parms = CopyParmList(nonvoid_parms(Getattr(n, "parms")));
800
801  type = NewString(classname);
802  if (qualifier) {
803    SwigType_push(type, qualifier);
804  }
805  SwigType_add_pointer(type);
806  p = NewParm(type, "self");
807  Setattr(p, "self", "1");
808  Setattr(p, "hidden","1");
809  /*
810     Disable the 'this' ownership in 'self' to manage inplace
811     operations like:
812
813     A& A::operator+=(int i) { ...; return *this;}
814
815     Here the 'self' parameter ownership needs to be disabled since
816     there could be two objects sharing the same 'this' pointer: the
817     input and the result one. And worse, the pointer could be deleted
818     in one of the objects (input), leaving the other (output) with
819     just a seg. fault to happen.
820
821     To avoid the previous problem, use
822
823     %feature("self:disown") *::operator+=;
824     %feature("new") *::operator+=;
825
826     These two lines just transfer the ownership of the 'this' pointer
827     from the input to the output wrapping object.
828
829     This happens in python, but may also happens in other target
830     languages.
831   */
832  if (GetFlag(n, "feature:self:disown")) {
833    Setattr(p, "wrap:disown", "1");
834  }
835  set_nextSibling(p, parms);
836  Delete(type);
837
838  /* Generate action code for the access */
839  if (!(flags & CWRAP_EXTEND)) {
840    String *explicit_qualifier = 0;
841    String *call = 0;
842    String *cres = 0;
843    String *explicitcall_name = 0;
844    int pure_virtual = !(Cmp(Getattr(n, "storage"), "virtual")) && !(Cmp(Getattr(n, "value"), "0"));
845
846    /* Call the explicit method rather than allow for a polymorphic call */
847    if ((flags & CWRAP_DIRECTOR_TWO_CALLS) || (flags & CWRAP_DIRECTOR_ONE_CALL)) {
848      String *access = Getattr(n, "access");
849      if (access && (Cmp(access, "protected") == 0)) {
850	/* If protected access (can only be if a director method) then call the extra public accessor method (language module must provide this) */
851	String *explicit_qualifier_tmp = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname"));
852	explicitcall_name = NewStringf("%sSwigPublic", name);
853	explicit_qualifier = NewStringf("SwigDirector_%s", explicit_qualifier_tmp);
854	Delete(explicit_qualifier_tmp);
855      } else {
856	explicit_qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname"));
857      }
858    }
859
860    call = Swig_cmethod_call(explicitcall_name ? explicitcall_name : name, p, self, explicit_qualifier, director_type);
861    cres = Swig_cresult(Getattr(n, "type"), "result", call);
862
863    if (pure_virtual && is_director && (flags & CWRAP_DIRECTOR_TWO_CALLS)) {
864      String *qualifier = SwigType_namestr(Getattr(Getattr(parentNode(n), "typescope"), "qname"));
865      Delete(cres);
866      cres = NewStringf("Swig::DirectorPureVirtualException::raise(\"%s::%s\");", qualifier, name);
867      Delete(qualifier);
868    }
869
870    if (flags & CWRAP_DIRECTOR_TWO_CALLS) {
871      /* Create two method calls, one to call the explicit method, the other a normal polymorphic function call */
872      String *cres_both_calls = NewStringf("");
873      String *call_extra = Swig_cmethod_call(name, p, self, 0, director_type);
874      String *cres_extra = Swig_cresult(Getattr(n, "type"), "result", call_extra);
875      Printv(cres_both_calls, "if (upcall) {\n", cres, "\n", "} else {", cres_extra, "\n}", NIL);
876      Setattr(n, "wrap:action", cres_both_calls);
877      Delete(cres_extra);
878      Delete(call_extra);
879      Delete(cres_both_calls);
880    } else {
881      Setattr(n, "wrap:action", cres);
882    }
883
884    Delete(explicitcall_name);
885    Delete(call);
886    Delete(cres);
887    Delete(explicit_qualifier);
888  } else {
889    /* Methods with default arguments are wrapped with additional methods for each default argument,
890     * however, only one extra %extend method is generated. */
891
892    String *defaultargs = Getattr(n, "defaultargs");
893    String *code = Getattr(n, "code");
894    String *cname = Getattr(n, "classname") ? Getattr(n, "classname") : classname;
895    String *membername = Swig_name_member(cname, name);
896    String *mangled = Swig_name_mangle(membername);
897    int is_smart_pointer = flags & CWRAP_SMART_POINTER;
898
899    type = Getattr(n, "type");
900
901    /* Check if the method is overloaded.   If so, and it has code attached, we append an extra suffix
902       to avoid a name-clash in the generated wrappers.  This allows overloaded methods to be defined
903       in C. */
904    if (Getattr(n, "sym:overloaded") && code) {
905      Append(mangled, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
906    }
907
908    /* See if there is any code that we need to emit */
909    if (!defaultargs && code && !is_smart_pointer) {
910      Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus, "self");
911    }
912    if (is_smart_pointer) {
913      int i = 0;
914      Parm *pp = p;
915      String *func = NewStringf("%s(", mangled);
916      String *cres;
917
918      if (Cmp(Getattr(n, "storage"), "static") != 0) {
919	String *pname = Swig_cparm_name(pp, i);
920        String *ctname = SwigType_namestr(cname);
921	String *fadd = NewStringf("(%s*)(%s)->operator ->()", ctname, pname);
922	Append(func, fadd);
923        Delete(ctname);
924	Delete(fadd);
925	Delete(pname);
926	pp = nextSibling(pp);
927	if (pp)
928	  Append(func, ",");
929      } else {
930	pp = nextSibling(pp);
931      }
932      ++i;
933      while (pp) {
934	SwigType *pt = Getattr(pp, "type");
935	if ((SwigType_type(pt) != T_VOID)) {
936	  String *pname = Swig_cparm_name(pp, i++);
937	  String *rcaststr = SwigType_rcaststr(pt, pname);
938	  Append(func, rcaststr);
939	  Delete(rcaststr);
940	  Delete(pname);
941	  pp = nextSibling(pp);
942	  if (pp)
943	    Append(func, ",");
944	}
945      }
946      Append(func, ")");
947      cres = Swig_cresult(Getattr(n, "type"), "result", func);
948      Setattr(n, "wrap:action", cres);
949      Delete(cres);
950    } else {
951      String *call = Swig_cfunction_call(mangled, p);
952      String *cres = Swig_cresult(Getattr(n, "type"), "result", call);
953      Setattr(n, "wrap:action", cres);
954      Delete(call);
955      Delete(cres);
956    }
957
958    Delete(membername);
959    Delete(mangled);
960  }
961  Setattr(n, "parms", p);
962  Delete(p);
963  Delete(self);
964  Delete(parms);
965  return SWIG_OK;
966}
967
968/* -----------------------------------------------------------------------------
969 * Swig_methodclass()
970 *
971 * This function returns the class node for a given method or class.
972 * ----------------------------------------------------------------------------- */
973
974Node *Swig_methodclass(Node *n) {
975  Node *nodetype = nodeType(n);
976  if (Cmp(nodetype, "class") == 0)
977    return n;
978  return GetFlag(n, "feature:extend") ? parentNode(parentNode(n)) : parentNode(n);
979}
980
981int Swig_directorclass(Node *n) {
982  Node *classNode = Swig_methodclass(n);
983  assert(classNode != 0);
984  return (Getattr(classNode, "vtable") != 0);
985}
986
987Node *Swig_directormap(Node *module, String *type) {
988  int is_void = !Cmp(type, "void");
989  if (!is_void && module) {
990    /* ?? follow the inheritance hierarchy? */
991
992    String *base = SwigType_base(type);
993
994    Node *directormap = Getattr(module, "wrap:directormap");
995    if (directormap)
996      return Getattr(directormap, base);
997  }
998  return 0;
999}
1000
1001
1002/* -----------------------------------------------------------------------------
1003 * Swig_ConstructorToFunction()
1004 *
1005 * This function creates a C wrapper for a C constructor function.
1006 * ----------------------------------------------------------------------------- */
1007
1008int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags) {
1009  ParmList *parms;
1010  Parm *prefix_args;
1011  Parm *p;
1012  ParmList *directorparms;
1013  SwigType *type;
1014  Node *classNode;
1015  int use_director;
1016
1017  classNode = Swig_methodclass(n);
1018  use_director = Swig_directorclass(n);
1019
1020  parms = CopyParmList(nonvoid_parms(Getattr(n, "parms")));
1021
1022  /* Prepend the list of prefix_args (if any) */
1023  prefix_args = Getattr(n, "director:prefix_args");
1024  if (prefix_args != NIL) {
1025    Parm *p2, *p3;
1026
1027    directorparms = CopyParmList(prefix_args);
1028    for (p = directorparms; nextSibling(p); p = nextSibling(p));
1029    for (p2 = parms; p2; p2 = nextSibling(p2)) {
1030      p3 = CopyParm(p2);
1031      set_nextSibling(p, p3);
1032      Delete(p3);
1033      p = p3;
1034    }
1035  } else
1036    directorparms = parms;
1037
1038  type = NewString(classname);
1039  SwigType_add_pointer(type);
1040
1041  if (flags & CWRAP_EXTEND) {
1042    /* Constructors with default arguments are wrapped with additional constructor methods for each default argument,
1043     * however, only one extra %extend method is generated. */
1044    String *call;
1045    String *cres;
1046    String *defaultargs = Getattr(n, "defaultargs");
1047    String *code = Getattr(n, "code");
1048    String *membername = Swig_name_construct(classname);
1049    String *mangled = Swig_name_mangle(membername);
1050
1051    /* Check if the constructor is overloaded.   If so, and it has code attached, we append an extra suffix
1052       to avoid a name-clash in the generated wrappers.  This allows overloaded constructors to be defined
1053       in C. */
1054    if (Getattr(n, "sym:overloaded") && code) {
1055      Append(mangled, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
1056    }
1057
1058    /* See if there is any code that we need to emit */
1059    if (!defaultargs && code) {
1060      Swig_add_extension_code(n, mangled, parms, type, code, cparse_cplusplus, "self");
1061    }
1062
1063    call = Swig_cfunction_call(mangled, parms);
1064    cres = Swig_cresult(type, "result", call);
1065    Setattr(n, "wrap:action", cres);
1066    Delete(cres);
1067    Delete(call);
1068    Delete(membername);
1069    Delete(mangled);
1070  } else {
1071    if (cplus) {
1072      /* if a C++ director class exists, create it rather than the original class */
1073      if (use_director) {
1074	Node *parent = Swig_methodclass(n);
1075	int abstract = Getattr(parent, "abstract") != 0;
1076	String *name = Getattr(parent, "sym:name");
1077	String *directorname = NewStringf("SwigDirector_%s", name);
1078	String *action = NewStringEmpty();
1079	String *tmp_none_comparison = Copy(none_comparison);
1080	String *director_call;
1081	String *nodirector_call;
1082
1083	Replaceall(tmp_none_comparison, "$arg", "arg1");
1084
1085	director_call = Swig_cppconstructor_director_call(directorname, directorparms);
1086	nodirector_call = Swig_cppconstructor_nodirector_call(classname, parms);
1087
1088	if (abstract) {
1089	  /* whether or not the abstract class has been subclassed in python,
1090	   * create a director instance (there's no way to create a normal
1091	   * instance).  if any of the pure virtual methods haven't been
1092	   * implemented in the target language, calls to those methods will
1093	   * generate Swig::DirectorPureVirtualException exceptions.
1094	   */
1095	  String *cres = Swig_cresult(type, "result", director_call);
1096	  Append(action, cres);
1097	  Delete(cres);
1098	} else {
1099	  /* (scottm): The code for creating a new director is now a string
1100	     template that gets passed in via the director_ctor argument.
1101
1102	     $comparison : an 'if' comparison from none_comparison
1103	     $director_new: Call new for director class
1104	     $nondirector_new: Call new for non-director class
1105	   */
1106	  String *cres;
1107	  Append(action, director_ctor);
1108	  Replaceall(action, "$comparison", tmp_none_comparison);
1109
1110	  cres = Swig_cresult(type, "result", director_call);
1111	  Replaceall(action, "$director_new", cres);
1112	  Delete(cres);
1113
1114	  cres = Swig_cresult(type, "result", nodirector_call);
1115	  Replaceall(action, "$nondirector_new", cres);
1116	  Delete(cres);
1117	}
1118	Setattr(n, "wrap:action", action);
1119	Delete(tmp_none_comparison);
1120	Delete(action);
1121	Delete(directorname);
1122      } else {
1123	String *call = Swig_cppconstructor_call(classname, parms);
1124	String *cres = Swig_cresult(type, "result", call);
1125	Setattr(n, "wrap:action", cres);
1126	Delete(cres);
1127	Delete(call);
1128      }
1129    } else {
1130      String *call = Swig_cconstructor_call(classname);
1131      String *cres = Swig_cresult(type, "result", call);
1132      Setattr(n, "wrap:action", cres);
1133      Delete(cres);
1134      Delete(call);
1135    }
1136  }
1137  Setattr(n, "type", type);
1138  Setattr(n, "parms", parms);
1139  Delete(type);
1140  if (directorparms != parms)
1141    Delete(directorparms);
1142  Delete(parms);
1143  return SWIG_OK;
1144}
1145
1146/* -----------------------------------------------------------------------------
1147 * Swig_DestructorToFunction()
1148 *
1149 * This function creates a C wrapper for a destructor function.
1150 * ----------------------------------------------------------------------------- */
1151
1152int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags) {
1153  SwigType *type;
1154  Parm *p;
1155
1156  type = NewString(classname);
1157  SwigType_add_pointer(type);
1158  p = NewParm(type, "self");
1159  Setattr(p, "self", "1");
1160  Setattr(p, "hidden", "1");
1161  Setattr(p, "wrap:disown", "1");
1162  Delete(type);
1163  type = NewString("void");
1164
1165  if (flags & CWRAP_EXTEND) {
1166    String *cres;
1167    String *call;
1168    String *membername, *mangled, *code;
1169    membername = Swig_name_destroy(classname);
1170    mangled = Swig_name_mangle(membername);
1171    code = Getattr(n, "code");
1172    if (code) {
1173      Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus, "self");
1174    }
1175    call = Swig_cfunction_call(mangled, p);
1176    cres = NewStringf("%s;", call);
1177    Setattr(n, "wrap:action", cres);
1178    Delete(membername);
1179    Delete(mangled);
1180    Delete(call);
1181    Delete(cres);
1182  } else {
1183    if (cplus) {
1184      String *call = Swig_cppdestructor_call(n);
1185      String *cres = NewStringf("%s", call);
1186      Setattr(n, "wrap:action", cres);
1187      Delete(call);
1188      Delete(cres);
1189    } else {
1190      String *call = Swig_cdestructor_call(n);
1191      String *cres = NewStringf("%s", call);
1192      Setattr(n, "wrap:action", cres);
1193      Delete(call);
1194      Delete(cres);
1195    }
1196  }
1197  Setattr(n, "type", type);
1198  Setattr(n, "parms", p);
1199  Delete(type);
1200  Delete(p);
1201  return SWIG_OK;
1202}
1203
1204/* -----------------------------------------------------------------------------
1205 * Swig_MembersetToFunction()
1206 *
1207 * This function creates a C wrapper for setting a structure member.
1208 * ----------------------------------------------------------------------------- */
1209
1210int Swig_MembersetToFunction(Node *n, String *classname, int flags, String **call) {
1211  String *name;
1212  ParmList *parms;
1213  Parm *p;
1214  SwigType *t;
1215  SwigType *ty;
1216  SwigType *type;
1217  SwigType *void_type = NewString("void");
1218  String *membername;
1219  String *mangled;
1220  String *self = 0;
1221  String *sname;
1222
1223  int varcref = flags & CWRAP_NATURAL_VAR;
1224
1225  if (flags & CWRAP_SMART_POINTER) {
1226    self = NewString("(*this)->");
1227  }
1228  if (flags & CWRAP_ALL_PROTECTED_ACCESS) {
1229    self = NewStringf("darg->");
1230  }
1231
1232  name = Getattr(n, "name");
1233  type = Getattr(n, "type");
1234
1235  sname = Swig_name_set(name);
1236  membername = Swig_name_member(classname, sname);
1237  mangled = Swig_name_mangle(membername);
1238
1239  t = NewString(classname);
1240  SwigType_add_pointer(t);
1241  parms = NewParm(t, "self");
1242  Setattr(parms, "self", "1");
1243  Setattr(parms, "hidden","1");
1244  Delete(t);
1245
1246  ty = Swig_wrapped_member_var_type(type, varcref);
1247  p = NewParm(ty, name);
1248  Setattr(parms, "hidden", "1");
1249  set_nextSibling(parms, p);
1250
1251  /* If the type is a pointer or reference.  We mark it with a special wrap:disown attribute */
1252  if (SwigType_check_decl(type, "p.")) {
1253    Setattr(p, "wrap:disown", "1");
1254  }
1255  Delete(p);
1256
1257  if (flags & CWRAP_EXTEND) {
1258    String *cres;
1259    String *code = Getattr(n, "code");
1260    if (code) {
1261      /* I don't think this ever gets run - WSF */
1262      Swig_add_extension_code(n, mangled, parms, void_type, code, cparse_cplusplus, "self");
1263    }
1264    *call = Swig_cfunction_call(mangled, parms);
1265    cres = NewStringf("%s;", *call);
1266    Setattr(n, "wrap:action", cres);
1267    Delete(cres);
1268  } else {
1269    String *cres;
1270    *call = Swig_cmemberset_call(name, type, self, varcref);
1271    cres = NewStringf("%s;", *call);
1272    Setattr(n, "wrap:action", cres);
1273    Delete(cres);
1274  }
1275  Setattr(n, "type", void_type);
1276  Setattr(n, "parms", parms);
1277  Delete(parms);
1278  Delete(ty);
1279  Delete(void_type);
1280  Delete(membername);
1281  Delete(sname);
1282  Delete(mangled);
1283  Delete(self);
1284  return SWIG_OK;
1285}
1286
1287/* -----------------------------------------------------------------------------
1288 * Swig_MembergetToFunction()
1289 *
1290 * This function creates a C wrapper for getting a structure member.
1291 * ----------------------------------------------------------------------------- */
1292
1293int Swig_MembergetToFunction(Node *n, String *classname, int flags) {
1294  String *name;
1295  ParmList *parms;
1296  SwigType *t;
1297  SwigType *ty;
1298  SwigType *type;
1299  String *membername;
1300  String *mangled;
1301  String *self = 0;
1302  String *gname;
1303
1304  int varcref = flags & CWRAP_NATURAL_VAR;
1305
1306  if (flags & CWRAP_SMART_POINTER) {
1307    if (checkAttribute(n, "storage", "static")) {
1308      Node *sn = Getattr(n, "cplus:staticbase");
1309      String *base = Getattr(sn, "name");
1310      self = NewStringf("%s::", base);
1311    } else {
1312      self = NewString("(*this)->");
1313    }
1314  }
1315  if (flags & CWRAP_ALL_PROTECTED_ACCESS) {
1316    self = NewStringf("darg->");
1317  }
1318
1319  name = Getattr(n, "name");
1320  type = Getattr(n, "type");
1321
1322  gname = Swig_name_get(name);
1323  membername = Swig_name_member(classname, gname);
1324  mangled = Swig_name_mangle(membername);
1325
1326  t = NewString(classname);
1327  SwigType_add_pointer(t);
1328  parms = NewParm(t, "self");
1329  Setattr(parms, "self", "1");
1330  Setattr(parms, "hidden","1");
1331  Delete(t);
1332
1333  ty = Swig_wrapped_member_var_type(type, varcref);
1334  if (flags & CWRAP_EXTEND) {
1335    String *call;
1336    String *cres;
1337
1338    String *code = Getattr(n, "code");
1339    if (code) {
1340      /* I don't think this ever gets run - WSF */
1341      Swig_add_extension_code(n, mangled, parms, ty, code, cparse_cplusplus, "self");
1342    }
1343    call = Swig_cfunction_call(mangled, parms);
1344    cres = Swig_cresult(ty, "result", call);
1345    Setattr(n, "wrap:action", cres);
1346    Delete(cres);
1347    Delete(call);
1348  } else {
1349    String *call = Swig_cmemberget_call(name, type, self, varcref);
1350    String *cres = Swig_cresult(ty, "result", call);
1351    Setattr(n, "wrap:action", cres);
1352    Delete(call);
1353    Delete(cres);
1354  }
1355  Setattr(n, "type", ty);
1356  Setattr(n, "parms", parms);
1357  Delete(parms);
1358  Delete(ty);
1359  Delete(membername);
1360  Delete(gname);
1361  Delete(mangled);
1362
1363  return SWIG_OK;
1364}
1365
1366/* -----------------------------------------------------------------------------
1367 * Swig_VarsetToFunction()
1368 *
1369 * This function creates a C wrapper for setting a global variable or static member
1370 * variable.
1371 * ----------------------------------------------------------------------------- */
1372
1373int Swig_VarsetToFunction(Node *n, int flags) {
1374  String *name, *nname;
1375  ParmList *parms;
1376  SwigType *type, *ty;
1377
1378  int varcref = flags & CWRAP_NATURAL_VAR;
1379
1380  name = Getattr(n, "name");
1381  type = Getattr(n, "type");
1382  nname = SwigType_namestr(name);
1383  ty = Swig_wrapped_var_type(type, varcref);
1384  parms = NewParm(ty, name);
1385
1386  if (flags & CWRAP_EXTEND) {
1387    String *sname = Swig_name_set(name);
1388    String *mangled = Swig_name_mangle(sname);
1389    String *call = Swig_cfunction_call(mangled, parms);
1390    String *cres = NewStringf("%s;", call);
1391    Setattr(n, "wrap:action", cres);
1392    Delete(cres);
1393    Delete(call);
1394    Delete(mangled);
1395    Delete(sname);
1396  } else {
1397    if (!Strstr(type, "enum $unnamed")) {
1398      String *pname = Swig_cparm_name(0, 0);
1399      String *dref = Swig_wrapped_var_deref(type, pname, varcref);
1400      String *call = NewStringf("%s = %s;", nname, dref);
1401      Setattr(n, "wrap:action", call);
1402      Delete(call);
1403      Delete(dref);
1404      Delete(pname);
1405    } else {
1406      String *pname = Swig_cparm_name(0, 0);
1407      String *call = NewStringf("if (sizeof(int) == sizeof(%s)) *(int*)(void*)&(%s) = %s;", nname, nname, pname);
1408      Setattr(n, "wrap:action", call);
1409      Delete(pname);
1410      Delete(call);
1411    }
1412  }
1413  Setattr(n, "type", "void");
1414  Setattr(n, "parms", parms);
1415  Delete(parms);
1416  Delete(ty);
1417  Delete(nname);
1418  return SWIG_OK;
1419}
1420
1421/* -----------------------------------------------------------------------------
1422 * Swig_VargetToFunction()
1423 *
1424 * This function creates a C wrapper for getting a global variable or static member
1425 * variable.
1426 * ----------------------------------------------------------------------------- */
1427
1428int Swig_VargetToFunction(Node *n, int flags) {
1429  String *cres, *call;
1430  String *name;
1431  SwigType *type;
1432  SwigType *ty = 0;
1433
1434  int varcref = flags & CWRAP_NATURAL_VAR;
1435
1436  name = Getattr(n, "name");
1437  type = Getattr(n, "type");
1438  ty = Swig_wrapped_var_type(type, varcref);
1439
1440  if (flags & CWRAP_EXTEND) {
1441    String *sname = Swig_name_get(name);
1442    String *mangled = Swig_name_mangle(sname);
1443    call = Swig_cfunction_call(mangled, 0);
1444    cres = Swig_cresult(ty, "result", call);
1445    Setattr(n, "wrap:action", cres);
1446    Delete(mangled);
1447    Delete(sname);
1448  } else {
1449    String *nname = SwigType_namestr(name);
1450    call = Swig_wrapped_var_assign(type, nname, varcref);
1451    cres = Swig_cresult(ty, "result", call);
1452    Setattr(n, "wrap:action", cres);
1453    Delete(nname);
1454  }
1455
1456  Setattr(n, "type", ty);
1457  Delattr(n, "parms");
1458  Delete(cres);
1459  Delete(call);
1460  Delete(ty);
1461  return SWIG_OK;
1462}
1463