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