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