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