import source from 1.3.40
[external/swig.git] / Source / Swig / cwrap.c
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
11 char cvsroot_cwrap_c[] = "$Id: cwrap.c 11312 2009-06-24 17:20:17Z wsfulton $";
12
13 #include "swig.h"
14
15 extern int cparse_cplusplus;
16
17 static 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
32 String *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
48 static 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
98 String *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
124 String *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
150 static 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
166 static 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  * ----------------------------------------------------------------------------- */
186 int 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
258 String *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
309 String *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
376 static 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
468 String *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
487 String *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
532 String *Swig_cppconstructor_call(const_String_or_char_ptr name, ParmList *parms) {
533   return Swig_cppconstructor_base_call(name, parms, 0);
534 }
535
536 String *Swig_cppconstructor_nodirector_call(const_String_or_char_ptr name, ParmList *parms) {
537   return Swig_cppconstructor_base_call(name, parms, 1);
538 }
539
540 String *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 */
566 String *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
602 String *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
621 String *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
640 String *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
662 String *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
683 String *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
718 String *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  * ----------------------------------------------------------------------------- */
744 static 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  * ----------------------------------------------------------------------------- */
767 int 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
781 int 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
974 Node *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
981 int Swig_directorclass(Node *n) {
982   Node *classNode = Swig_methodclass(n);
983   assert(classNode != 0);
984   return (Getattr(classNode, "vtable") != 0);
985 }
986
987 Node *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
1008 int 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
1152 int 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
1210 int 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
1293 int 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
1373 int 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
1428 int 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 }