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 * naming.c 6 * 7 * Functions for generating various kinds of names during code generation. 8 * ----------------------------------------------------------------------------- */ 9 10char cvsroot_naming_c[] = "$Id: naming.c 11454 2009-07-26 21:21:26Z wsfulton $"; 11 12#include "swig.h" 13#include "cparse.h" 14#include <ctype.h> 15 16/* Hash table containing naming data */ 17 18static Hash *naming_hash = 0; 19 20#if 0 21#define SWIG_DEBUG 22#endif 23 24/* ----------------------------------------------------------------------------- 25 * Swig_name_register() 26 * 27 * Register a new naming format. 28 * ----------------------------------------------------------------------------- */ 29 30void Swig_name_register(const_String_or_char_ptr method, const_String_or_char_ptr format) { 31 if (!naming_hash) 32 naming_hash = NewHash(); 33 Setattr(naming_hash, method, format); 34} 35 36void Swig_name_unregister(const_String_or_char_ptr method) { 37 if (naming_hash) { 38 Delattr(naming_hash, method); 39 } 40} 41 42static int name_mangle(String *r) { 43 char *c; 44 int special; 45 special = 0; 46 Replaceall(r, "::", "_"); 47 c = Char(r); 48 while (*c) { 49 if (!isalnum((int) *c) && (*c != '_')) { 50 special = 1; 51 switch (*c) { 52 case '+': 53 *c = 'a'; 54 break; 55 case '-': 56 *c = 's'; 57 break; 58 case '*': 59 *c = 'm'; 60 break; 61 case '/': 62 *c = 'd'; 63 break; 64 case '<': 65 *c = 'l'; 66 break; 67 case '>': 68 *c = 'g'; 69 break; 70 case '=': 71 *c = 'e'; 72 break; 73 case ',': 74 *c = 'c'; 75 break; 76 case '(': 77 *c = 'p'; 78 break; 79 case ')': 80 *c = 'P'; 81 break; 82 case '[': 83 *c = 'b'; 84 break; 85 case ']': 86 *c = 'B'; 87 break; 88 case '^': 89 *c = 'x'; 90 break; 91 case '&': 92 *c = 'A'; 93 break; 94 case '|': 95 *c = 'o'; 96 break; 97 case '~': 98 *c = 'n'; 99 break; 100 case '!': 101 *c = 'N'; 102 break; 103 case '%': 104 *c = 'M'; 105 break; 106 case '.': 107 *c = 'f'; 108 break; 109 case '?': 110 *c = 'q'; 111 break; 112 default: 113 *c = '_'; 114 break; 115 } 116 } 117 c++; 118 } 119 if (special) 120 Append(r, "___"); 121 return special; 122} 123 124/* ----------------------------------------------------------------------------- 125 * Swig_name_mangle() 126 * 127 * Converts all of the non-identifier characters of a string to underscores. 128 * ----------------------------------------------------------------------------- */ 129 130String *Swig_name_mangle(const_String_or_char_ptr s) { 131#if 0 132 String *r = NewString(s); 133 name_mangle(r); 134 return r; 135#else 136 return Swig_string_mangle(s); 137#endif 138} 139 140/* ----------------------------------------------------------------------------- 141 * Swig_name_wrapper() 142 * 143 * Returns the name of a wrapper function. 144 * ----------------------------------------------------------------------------- */ 145 146String *Swig_name_wrapper(const_String_or_char_ptr fname) { 147 String *r; 148 String *f; 149 150 r = NewStringEmpty(); 151 if (!naming_hash) 152 naming_hash = NewHash(); 153 f = Getattr(naming_hash, "wrapper"); 154 if (!f) { 155 Append(r, "_wrap_%f"); 156 } else { 157 Append(r, f); 158 } 159 Replace(r, "%f", fname, DOH_REPLACE_ANY); 160 name_mangle(r); 161 return r; 162} 163 164 165/* ----------------------------------------------------------------------------- 166 * Swig_name_member() 167 * 168 * Returns the name of a class method. 169 * ----------------------------------------------------------------------------- */ 170 171String *Swig_name_member(const_String_or_char_ptr classname, const_String_or_char_ptr mname) { 172 String *r; 173 String *f; 174 String *rclassname; 175 char *cname; 176 177 rclassname = SwigType_namestr(classname); 178 r = NewStringEmpty(); 179 if (!naming_hash) 180 naming_hash = NewHash(); 181 f = Getattr(naming_hash, "member"); 182 if (!f) { 183 Append(r, "%c_%m"); 184 } else { 185 Append(r, f); 186 } 187 cname = Char(rclassname); 188 if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { 189 cname = strchr(cname, ' ') + 1; 190 } 191 Replace(r, "%c", cname, DOH_REPLACE_ANY); 192 Replace(r, "%m", mname, DOH_REPLACE_ANY); 193 /* name_mangle(r); */ 194 Delete(rclassname); 195 return r; 196} 197 198/* ----------------------------------------------------------------------------- 199 * Swig_name_get() 200 * 201 * Returns the name of the accessor function used to get a variable. 202 * ----------------------------------------------------------------------------- */ 203 204String *Swig_name_get(const_String_or_char_ptr vname) { 205 String *r; 206 String *f; 207 208#ifdef SWIG_DEBUG 209 Printf(stdout, "Swig_name_get: '%s'\n", vname); 210#endif 211 212 r = NewStringEmpty(); 213 if (!naming_hash) 214 naming_hash = NewHash(); 215 f = Getattr(naming_hash, "get"); 216 if (!f) { 217 Append(r, "%v_get"); 218 } else { 219 Append(r, f); 220 } 221 Replace(r, "%v", vname, DOH_REPLACE_ANY); 222 /* name_mangle(r); */ 223 return r; 224} 225 226/* ----------------------------------------------------------------------------- 227 * Swig_name_set() 228 * 229 * Returns the name of the accessor function used to set a variable. 230 * ----------------------------------------------------------------------------- */ 231 232String *Swig_name_set(const_String_or_char_ptr vname) { 233 String *r; 234 String *f; 235 236 r = NewStringEmpty(); 237 if (!naming_hash) 238 naming_hash = NewHash(); 239 f = Getattr(naming_hash, "set"); 240 if (!f) { 241 Append(r, "%v_set"); 242 } else { 243 Append(r, f); 244 } 245 Replace(r, "%v", vname, DOH_REPLACE_ANY); 246 /* name_mangle(r); */ 247 return r; 248} 249 250/* ----------------------------------------------------------------------------- 251 * Swig_name_construct() 252 * 253 * Returns the name of the accessor function used to create an object. 254 * ----------------------------------------------------------------------------- */ 255 256String *Swig_name_construct(const_String_or_char_ptr classname) { 257 String *r; 258 String *f; 259 String *rclassname; 260 char *cname; 261 262 rclassname = SwigType_namestr(classname); 263 r = NewStringEmpty(); 264 if (!naming_hash) 265 naming_hash = NewHash(); 266 f = Getattr(naming_hash, "construct"); 267 if (!f) { 268 Append(r, "new_%c"); 269 } else { 270 Append(r, f); 271 } 272 273 cname = Char(rclassname); 274 if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { 275 cname = strchr(cname, ' ') + 1; 276 } 277 Replace(r, "%c", cname, DOH_REPLACE_ANY); 278 Delete(rclassname); 279 return r; 280} 281 282 283/* ----------------------------------------------------------------------------- 284 * Swig_name_copyconstructor() 285 * 286 * Returns the name of the accessor function used to copy an object. 287 * ----------------------------------------------------------------------------- */ 288 289String *Swig_name_copyconstructor(const_String_or_char_ptr classname) { 290 String *r; 291 String *f; 292 String *rclassname; 293 char *cname; 294 295 rclassname = SwigType_namestr(classname); 296 r = NewStringEmpty(); 297 if (!naming_hash) 298 naming_hash = NewHash(); 299 f = Getattr(naming_hash, "copy"); 300 if (!f) { 301 Append(r, "copy_%c"); 302 } else { 303 Append(r, f); 304 } 305 306 cname = Char(rclassname); 307 if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { 308 cname = strchr(cname, ' ') + 1; 309 } 310 311 Replace(r, "%c", cname, DOH_REPLACE_ANY); 312 Delete(rclassname); 313 return r; 314} 315 316/* ----------------------------------------------------------------------------- 317 * Swig_name_destroy() 318 * 319 * Returns the name of the accessor function used to destroy an object. 320 * ----------------------------------------------------------------------------- */ 321 322String *Swig_name_destroy(const_String_or_char_ptr classname) { 323 String *r; 324 String *f; 325 String *rclassname; 326 char *cname; 327 rclassname = SwigType_namestr(classname); 328 r = NewStringEmpty(); 329 if (!naming_hash) 330 naming_hash = NewHash(); 331 f = Getattr(naming_hash, "destroy"); 332 if (!f) { 333 Append(r, "delete_%c"); 334 } else { 335 Append(r, f); 336 } 337 338 cname = Char(rclassname); 339 if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { 340 cname = strchr(cname, ' ') + 1; 341 } 342 Replace(r, "%c", cname, DOH_REPLACE_ANY); 343 Delete(rclassname); 344 return r; 345} 346 347 348/* ----------------------------------------------------------------------------- 349 * Swig_name_disown() 350 * 351 * Returns the name of the accessor function used to disown an object. 352 * ----------------------------------------------------------------------------- */ 353 354String *Swig_name_disown(const_String_or_char_ptr classname) { 355 String *r; 356 String *f; 357 String *rclassname; 358 char *cname; 359 rclassname = SwigType_namestr(classname); 360 r = NewStringEmpty(); 361 if (!naming_hash) 362 naming_hash = NewHash(); 363 f = Getattr(naming_hash, "disown"); 364 if (!f) { 365 Append(r, "disown_%c"); 366 } else { 367 Append(r, f); 368 } 369 370 cname = Char(rclassname); 371 if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) { 372 cname = strchr(cname, ' ') + 1; 373 } 374 Replace(r, "%c", cname, DOH_REPLACE_ANY); 375 Delete(rclassname); 376 return r; 377} 378 379 380/* ----------------------------------------------------------------------------- 381 * Swig_name_object_set() 382 * 383 * Sets an object associated with a name and optional declarators. 384 * ----------------------------------------------------------------------------- */ 385 386void Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object) { 387 DOH *n; 388 389#ifdef SWIG_DEBUG 390 Printf(stdout, "Swig_name_object_set: '%s', '%s'\n", name, decl); 391#endif 392 n = Getattr(namehash, name); 393 if (!n) { 394 n = NewHash(); 395 Setattr(namehash, name, n); 396 Delete(n); 397 } 398 /* Add an object based on the declarator value */ 399 if (!decl) { 400 Setattr(n, "start", object); 401 } else { 402 SwigType *cd = Copy(decl); 403 Setattr(n, cd, object); 404 Delete(cd); 405 } 406} 407 408 409/* ----------------------------------------------------------------------------- 410 * Swig_name_object_get() 411 * 412 * Return an object associated with an optional class prefix, name, and 413 * declarator. This function operates according to name matching rules 414 * described for the %rename directive in the SWIG manual. 415 * ----------------------------------------------------------------------------- */ 416 417static DOH *get_object(Hash *n, String *decl) { 418 DOH *rn = 0; 419 if (!n) 420 return 0; 421 if (decl) { 422 rn = Getattr(n, decl); 423 } else { 424 rn = Getattr(n, "start"); 425 } 426 return rn; 427} 428 429static 430DOH *name_object_get(Hash *namehash, String *tname, SwigType *decl, SwigType *ncdecl) { 431 DOH *rn = 0; 432 Hash *n = Getattr(namehash, tname); 433 if (n) { 434 rn = get_object(n, decl); 435 if ((!rn) && ncdecl) 436 rn = get_object(n, ncdecl); 437 if (!rn) 438 rn = get_object(n, 0); 439 } 440 return rn; 441} 442 443DOH *Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl) { 444 String *tname = NewStringEmpty(); 445 DOH *rn = 0; 446 char *ncdecl = 0; 447 448 if (!namehash) 449 return 0; 450 451 /* DB: This removed to more tightly control feature/name matching */ 452 /* if ((decl) && (SwigType_isqualifier(decl))) { 453 ncdecl = strchr(Char(decl),'.'); 454 ncdecl++; 455 } 456 */ 457#ifdef SWIG_DEBUG 458 Printf(stdout, "Swig_name_object_get: '%s' '%s', '%s'\n", prefix, name, decl); 459#endif 460 461 462 /* Perform a class-based lookup (if class prefix supplied) */ 463 if (prefix) { 464 if (Len(prefix)) { 465 Printf(tname, "%s::%s", prefix, name); 466 rn = name_object_get(namehash, tname, decl, ncdecl); 467 if (!rn) { 468 String *cls = Swig_scopename_last(prefix); 469 if (!Equal(cls, prefix)) { 470 Clear(tname); 471 Printf(tname, "*::%s::%s", cls, name); 472 rn = name_object_get(namehash, tname, decl, ncdecl); 473 } 474 Delete(cls); 475 } 476 /* A template-based class lookup, check name first */ 477 if (!rn && SwigType_istemplate(name)) { 478 String *t_name = SwigType_templateprefix(name); 479 if (!Equal(t_name, name)) { 480 rn = Swig_name_object_get(namehash, prefix, t_name, decl); 481 } 482 Delete(t_name); 483 } 484 /* A template-based class lookup */ 485 /* 486 if (!rn && SwigType_istemplate(prefix)) { 487 String *t_prefix = SwigType_templateprefix(prefix); 488 if (Strcmp(t_prefix, prefix) != 0) { 489 String *t_name = SwigType_templateprefix(name); 490 rn = Swig_name_object_get(namehash, t_prefix, t_name, decl); 491 Delete(t_name); 492 } 493 Delete(t_prefix); 494 } 495 */ 496 } 497 /* A wildcard-based class lookup */ 498 if (!rn) { 499 Clear(tname); 500 Printf(tname, "*::%s", name); 501 rn = name_object_get(namehash, tname, decl, ncdecl); 502 } 503 } else { 504 /* Lookup in the global namespace only */ 505 Clear(tname); 506 Printf(tname, "::%s", name); 507 rn = name_object_get(namehash, tname, decl, ncdecl); 508 } 509 /* Catch-all */ 510 if (!rn) { 511 rn = name_object_get(namehash, name, decl, ncdecl); 512 } 513 if (!rn && Swig_scopename_check(name)) { 514 String *nprefix = NewStringEmpty(); 515 String *nlast = NewStringEmpty(); 516 Swig_scopename_split(name, &nprefix, &nlast); 517 rn = name_object_get(namehash, nlast, decl, ncdecl); 518 Delete(nlast); 519 Delete(nprefix); 520 } 521 522 Delete(tname); 523 524#ifdef SWIG_DEBUG 525 Printf(stdout, "Swig_name_object_get: found %d\n", rn ? 1 : 0); 526#endif 527 528 return rn; 529} 530 531/* ----------------------------------------------------------------------------- 532 * Swig_name_object_inherit() 533 * 534 * Implements name-based inheritance scheme. 535 * ----------------------------------------------------------------------------- */ 536 537void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) { 538 Iterator ki; 539 String *bprefix; 540 String *dprefix; 541 char *cbprefix; 542 int plen; 543 544 if (!namehash) 545 return; 546 547 bprefix = NewStringf("%s::", base); 548 dprefix = NewStringf("%s::", derived); 549 cbprefix = Char(bprefix); 550 plen = strlen(cbprefix); 551 for (ki = First(namehash); ki.key; ki = Next(ki)) { 552 char *k = Char(ki.key); 553 if (strncmp(k, cbprefix, plen) == 0) { 554 Iterator oi; 555 String *nkey = NewStringf("%s%s", dprefix, k + plen); 556 Hash *n = ki.item; 557 Hash *newh = Getattr(namehash, nkey); 558 if (!newh) { 559 newh = NewHash(); 560 Setattr(namehash, nkey, newh); 561 Delete(newh); 562 } 563 for (oi = First(n); oi.key; oi = Next(oi)) { 564 if (!Getattr(newh, oi.key)) { 565 String *ci = Copy(oi.item); 566 Setattr(newh, oi.key, ci); 567 Delete(ci); 568 } 569 } 570 Delete(nkey); 571 } 572 } 573 Delete(bprefix); 574 Delete(dprefix); 575} 576 577/* ----------------------------------------------------------------------------- 578 * merge_features() 579 * 580 * Given a hash, this function merges the features in the hash into the node. 581 * ----------------------------------------------------------------------------- */ 582 583static void merge_features(Hash *features, Node *n) { 584 Iterator ki; 585 586 if (!features) 587 return; 588 for (ki = First(features); ki.key; ki = Next(ki)) { 589 String *ci = Copy(ki.item); 590 Setattr(n, ki.key, ci); 591 Delete(ci); 592 } 593} 594 595/* ----------------------------------------------------------------------------- 596 * Swig_features_get() 597 * 598 * Attaches any features in the features hash to the node that matches 599 * the declaration, decl. 600 * ----------------------------------------------------------------------------- */ 601 602static 603void features_get(Hash *features, const String *tname, SwigType *decl, SwigType *ncdecl, Node *node) { 604 Node *n = Getattr(features, tname); 605#ifdef SWIG_DEBUG 606 Printf(stdout, " features_get: %s\n", tname); 607#endif 608 if (n) { 609 merge_features(get_object(n, 0), node); 610 if (ncdecl) 611 merge_features(get_object(n, ncdecl), node); 612 merge_features(get_object(n, decl), node); 613 } 614} 615 616void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *node) { 617 char *ncdecl = 0; 618 String *rdecl = 0; 619 String *rname = 0; 620 if (!features) 621 return; 622 623 /* MM: This removed to more tightly control feature/name matching */ 624 /* 625 if ((decl) && (SwigType_isqualifier(decl))) { 626 ncdecl = strchr(Char(decl),'.'); 627 ncdecl++; 628 } 629 */ 630 631 /* very specific hack for template constructors/destructors */ 632 if (name && SwigType_istemplate(name)) { 633 String *nodetype = nodeType(node); 634 if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) { 635 String *nprefix = NewStringEmpty(); 636 String *nlast = NewStringEmpty(); 637 String *tprefix; 638 Swig_scopename_split(name, &nprefix, &nlast); 639 tprefix = SwigType_templateprefix(nlast); 640 Delete(nlast); 641 if (Len(nprefix)) { 642 Append(nprefix, "::"); 643 Append(nprefix, tprefix); 644 Delete(tprefix); 645 rname = nprefix; 646 } else { 647 rname = tprefix; 648 Delete(nprefix); 649 } 650 rdecl = Copy(decl); 651 Replaceall(rdecl, name, rname); 652 decl = rdecl; 653 name = rname; 654 } 655 } 656 657#ifdef SWIG_DEBUG 658 Printf(stdout, "Swig_features_get: '%s' '%s' '%s'\n", prefix, name, decl); 659#endif 660 661 /* Global features */ 662 features_get(features, "", 0, 0, node); 663 if (name) { 664 String *tname = NewStringEmpty(); 665 /* add features for 'root' template */ 666 if (SwigType_istemplate(name)) { 667 String *dname = SwigType_templateprefix(name); 668 features_get(features, dname, decl, ncdecl, node); 669 Delete(dname); 670 } 671 /* Catch-all */ 672 features_get(features, name, decl, ncdecl, node); 673 /* Perform a class-based lookup (if class prefix supplied) */ 674 if (prefix) { 675 /* A class-generic feature */ 676 if (Len(prefix)) { 677 Printf(tname, "%s::", prefix); 678 features_get(features, tname, decl, ncdecl, node); 679 } 680 /* A wildcard-based class lookup */ 681 Clear(tname); 682 Printf(tname, "*::%s", name); 683 features_get(features, tname, decl, ncdecl, node); 684 /* A specific class lookup */ 685 if (Len(prefix)) { 686 /* A template-based class lookup */ 687 if (SwigType_istemplate(prefix)) { 688 String *tprefix = SwigType_templateprefix(prefix); 689 Clear(tname); 690 Printf(tname, "%s::%s", tprefix, name); 691 features_get(features, tname, decl, ncdecl, node); 692 Delete(tprefix); 693 } 694 Clear(tname); 695 Printf(tname, "%s::%s", prefix, name); 696 features_get(features, tname, decl, ncdecl, node); 697 } 698 } else { 699 /* Lookup in the global namespace only */ 700 Clear(tname); 701 Printf(tname, "::%s", name); 702 features_get(features, tname, decl, ncdecl, node); 703 } 704 Delete(tname); 705 } 706 if (name && SwigType_istemplate(name)) { 707 /* add features for complete template type */ 708 String *dname = Swig_symbol_template_deftype(name, 0); 709 if (!Equal(dname, name)) { 710 Swig_features_get(features, prefix, dname, decl, node); 711 } 712 Delete(dname); 713 } 714 715 if (rname) 716 Delete(rname); 717 if (rdecl) 718 Delete(rdecl); 719} 720 721 722/* ----------------------------------------------------------------------------- 723 * Swig_feature_set() 724 * 725 * Sets a feature name and value. Also sets optional feature attributes as 726 * passed in by featureattribs. Optional feature attributes are given a full name 727 * concatenating the feature name plus ':' plus the attribute name. 728 * ----------------------------------------------------------------------------- */ 729 730void Swig_feature_set(Hash *features, const_String_or_char_ptr name, SwigType *decl, const_String_or_char_ptr featurename, String *value, Hash *featureattribs) { 731 Hash *n; 732 Hash *fhash; 733 734#ifdef SWIG_DEBUG 735 Printf(stdout, "Swig_feature_set: '%s' '%s' '%s' '%s'\n", name, decl, featurename, value); 736#endif 737 738 n = Getattr(features, name); 739 if (!n) { 740 n = NewHash(); 741 Setattr(features, name, n); 742 Delete(n); 743 } 744 if (!decl) { 745 fhash = Getattr(n, "start"); 746 if (!fhash) { 747 fhash = NewHash(); 748 Setattr(n, "start", fhash); 749 Delete(fhash); 750 } 751 } else { 752 fhash = Getattr(n, decl); 753 if (!fhash) { 754 String *cdecl_ = Copy(decl); 755 fhash = NewHash(); 756 Setattr(n, cdecl_, fhash); 757 Delete(cdecl_); 758 Delete(fhash); 759 } 760 } 761 if (value) { 762 Setattr(fhash, featurename, value); 763 } else { 764 Delattr(fhash, featurename); 765 } 766 767 { 768 /* Add in the optional feature attributes */ 769 Hash *attribs = featureattribs; 770 while (attribs) { 771 String *attribname = Getattr(attribs, "name"); 772 String *featureattribname = NewStringf("%s:%s", featurename, attribname); 773 if (value) { 774 String *attribvalue = Getattr(attribs, "value"); 775 Setattr(fhash, featureattribname, attribvalue); 776 } else { 777 Delattr(fhash, featureattribname); 778 } 779 attribs = nextSibling(attribs); 780 Delete(featureattribname); 781 } 782 } 783 784 if (name && SwigType_istemplate(name)) { 785 String *dname = Swig_symbol_template_deftype(name, 0); 786 if (Strcmp(dname, name)) { 787 Swig_feature_set(features, dname, decl, featurename, value, featureattribs); 788 } 789 Delete(dname); 790 } 791} 792 793/* ----------------------------------------------------------------------------- 794 * The rename/namewarn engine 795 * 796 * Code below was in parser.y for a while 797 * ----------------------------------------------------------------------------- */ 798 799static Hash *namewarn_hash = 0; 800Hash *Swig_name_namewarn_hash() { 801 if (!namewarn_hash) 802 namewarn_hash = NewHash(); 803 return namewarn_hash; 804} 805 806static Hash *rename_hash = 0; 807Hash *Swig_name_rename_hash() { 808 if (!rename_hash) 809 rename_hash = NewHash(); 810 return rename_hash; 811} 812 813static List *namewarn_list = 0; 814List *Swig_name_namewarn_list() { 815 if (!namewarn_list) 816 namewarn_list = NewList(); 817 return namewarn_list; 818} 819 820static List *rename_list = 0; 821List *Swig_name_rename_list() { 822 if (!rename_list) 823 rename_list = NewList(); 824 return rename_list; 825} 826 827/* ----------------------------------------------------------------------------- 828 * int Swig_need_name_warning(Node *n) 829 * 830 * Detects if a node needs name warnings 831 * 832 * ----------------------------------------------------------------------------- */ 833 834int Swig_need_name_warning(Node *n) { 835 int need = 1; 836 /* 837 we don't use name warnings for: 838 - class forwards, no symbol is generated at the target language. 839 - template declarations, only for real instances using %template(name). 840 - typedefs, they have no effect at the target language. 841 */ 842 if (checkAttribute(n, "nodeType", "classforward")) { 843 need = 0; 844 } else if (checkAttribute(n, "storage", "typedef")) { 845 need = 0; 846 } else if (Getattr(n, "hidden")) { 847 need = 0; 848 } else if (Getattr(n, "ignore")) { 849 need = 0; 850 } else if (Getattr(n, "templatetype")) { 851 need = 0; 852 } 853 return need; 854} 855 856/* ----------------------------------------------------------------------------- 857 * int Swig_need_redefined_warn() 858 * 859 * Detects when a redefined object needs a warning 860 * 861 * ----------------------------------------------------------------------------- */ 862 863static int nodes_are_equivalent(Node *a, Node *b, int a_inclass) { 864 /* they must have the same type */ 865 String *ta = nodeType(a); 866 String *tb = nodeType(b); 867 if (Cmp(ta, tb) != 0) 868 return 0; 869 870 /* cdecl case */ 871 if (Cmp(ta, "cdecl") == 0) { 872 /* typedef */ 873 String *a_storage = Getattr(a, "storage"); 874 String *b_storage = Getattr(b, "storage"); 875 876 if ((Cmp(a_storage, "typedef") == 0) 877 || (Cmp(b_storage, "typedef") == 0)) { 878 if (Cmp(a_storage, b_storage) == 0) { 879 String *a_type = (Getattr(a, "type")); 880 String *b_type = (Getattr(b, "type")); 881 if (Cmp(a_type, b_type) == 0) 882 return 1; 883 } 884 return 0; 885 } 886 887 /* static functions */ 888 if ((Cmp(a_storage, "static") == 0) 889 || (Cmp(b_storage, "static") == 0)) { 890 if (Cmp(a_storage, b_storage) != 0) 891 return 0; 892 } 893 894 /* friend methods */ 895 896 if (!a_inclass || (Cmp(a_storage, "friend") == 0)) { 897 /* check declaration */ 898 899 String *a_decl = (Getattr(a, "decl")); 900 String *b_decl = (Getattr(b, "decl")); 901 if (Cmp(a_decl, b_decl) == 0) { 902 /* check return type */ 903 String *a_type = (Getattr(a, "type")); 904 String *b_type = (Getattr(b, "type")); 905 if (Cmp(a_type, b_type) == 0) { 906 /* check parameters */ 907 Parm *ap = (Getattr(a, "parms")); 908 Parm *bp = (Getattr(b, "parms")); 909 while (ap && bp) { 910 SwigType *at = Getattr(ap, "type"); 911 SwigType *bt = Getattr(bp, "type"); 912 if (Cmp(at, bt) != 0) 913 return 0; 914 ap = nextSibling(ap); 915 bp = nextSibling(bp); 916 } 917 if (ap || bp) { 918 return 0; 919 } else { 920 Node *a_template = Getattr(a, "template"); 921 Node *b_template = Getattr(b, "template"); 922 /* Not equivalent if one is a template instantiation (via %template) and the other is a non-templated function */ 923 if ((a_template && !b_template) || (!a_template && b_template)) 924 return 0; 925 } 926 return 1; 927 } 928 } 929 } 930 } else { 931 /* %constant case */ 932 String *a_storage = Getattr(a, "storage"); 933 String *b_storage = Getattr(b, "storage"); 934 if ((Cmp(a_storage, "%constant") == 0) 935 || (Cmp(b_storage, "%constant") == 0)) { 936 if (Cmp(a_storage, b_storage) == 0) { 937 String *a_type = (Getattr(a, "type")); 938 String *b_type = (Getattr(b, "type")); 939 if ((Cmp(a_type, b_type) == 0) 940 && (Cmp(Getattr(a, "value"), Getattr(b, "value")) == 0)) 941 return 1; 942 } 943 return 0; 944 } 945 } 946 return 0; 947} 948 949int Swig_need_redefined_warn(Node *a, Node *b, int InClass) { 950 String *a_name = Getattr(a, "name"); 951 String *b_name = Getattr(b, "name"); 952 String *a_symname = Getattr(a, "sym:name"); 953 String *b_symname = Getattr(b, "sym:name"); 954 /* always send a warning if a 'rename' is involved */ 955 if ((a_symname && !Equal(a_symname, a_name)) 956 || (b_symname && !Equal(b_symname, b_name))) { 957 if (!Equal(a_name, b_name)) { 958 return 1; 959 } 960 } 961 962 963 return !nodes_are_equivalent(a, b, InClass); 964} 965 966 967/* ----------------------------------------------------------------------------- 968 * int Swig_need_protected(Node* n) 969 * 970 * Detects when we need to fully register the protected member. 971 * This is basically any protected members when the allprotected mode is set. 972 * Otherwise we take just the protected virtual methods and non-static methods 973 * (potentially virtual methods) as well as constructors/destructors. 974 * 975 * ----------------------------------------------------------------------------- */ 976 977int Swig_need_protected(Node *n) { 978 String *nodetype = nodeType(n); 979 if (checkAttribute(n, "access", "protected")) { 980 if ((Equal(nodetype, "cdecl"))) { 981 if (Swig_director_mode() && Swig_director_protected_mode() && Swig_all_protected_mode()) { 982 return 1; 983 } 984 if (SwigType_isfunction(Getattr(n, "decl"))) { 985 String *storage = Getattr(n, "storage"); 986 /* The function is declared virtual, or it has no storage. This eliminates typedef, static etc. */ 987 return !storage || Equal(storage, "virtual"); 988 } 989 } else if (Equal(nodetype, "constructor") || Equal(nodetype, "destructor")) { 990 return 1; 991 } 992 } 993 return 0; 994} 995 996/* ----------------------------------------------------------------------------- 997 * void Swig_name_nameobj_add() 998 * 999 * Add nameobj (rename/namewarn) 1000 * 1001 * ----------------------------------------------------------------------------- */ 1002 1003static List *Swig_make_attrlist(const char *ckey) { 1004 List *list = NewList(); 1005 const char *cattr = strchr(ckey, '$'); 1006 if (cattr) { 1007 String *nattr; 1008 const char *rattr = strchr(++cattr, '$'); 1009 while (rattr) { 1010 nattr = NewStringWithSize(cattr, rattr - cattr); 1011 Append(list, nattr); 1012 Delete(nattr); 1013 cattr = rattr + 1; 1014 rattr = strchr(cattr, '$'); 1015 } 1016 nattr = NewString(cattr); 1017 Append(list, nattr); 1018 Delete(nattr); 1019 } else { 1020 Append(list, "nodeType"); 1021 } 1022 return list; 1023} 1024 1025static void Swig_name_object_attach_keys(const char *keys[], Hash *nameobj) { 1026 Node *kw = nextSibling(nameobj); 1027 List *matchlist = 0; 1028 while (kw) { 1029 Node *next = nextSibling(kw); 1030 String *kname = Getattr(kw, "name"); 1031 char *ckey = kname ? Char(kname) : 0; 1032 if (ckey) { 1033 const char **rkey; 1034 int isnotmatch = 0; 1035 int isrxsmatch = 0; 1036 if ((strncmp(ckey, "match", 5) == 0) 1037 || (isnotmatch = (strncmp(ckey, "notmatch", 8) == 0)) 1038 || (isrxsmatch = (strncmp(ckey, "rxsmatch", 8) == 0)) 1039 || (isnotmatch = isrxsmatch = (strncmp(ckey, "notrxsmatch", 11) == 0))) { 1040 Hash *mi = NewHash(); 1041 List *attrlist = Swig_make_attrlist(ckey); 1042 if (!matchlist) 1043 matchlist = NewList(); 1044 Setattr(mi, "value", Getattr(kw, "value")); 1045 Setattr(mi, "attrlist", attrlist); 1046#ifdef SWIG_DEBUG 1047 if (isrxsmatch) 1048 Printf(stdout, "rxsmatch to use: %s %s %s\n", ckey, Getattr(kw, "value"), attrlist); 1049#endif 1050 if (isnotmatch) 1051 SetFlag(mi, "notmatch"); 1052 if (isrxsmatch) 1053 SetFlag(mi, "rxsmatch"); 1054 Delete(attrlist); 1055 Append(matchlist, mi); 1056 Delete(mi); 1057 removeNode(kw); 1058 } else { 1059 for (rkey = keys; *rkey != 0; ++rkey) { 1060 if (strcmp(ckey, *rkey) == 0) { 1061 Setattr(nameobj, *rkey, Getattr(kw, "value")); 1062 removeNode(kw); 1063 } 1064 } 1065 } 1066 } 1067 kw = next; 1068 } 1069 if (matchlist) { 1070 Setattr(nameobj, "matchlist", matchlist); 1071 Delete(matchlist); 1072 } 1073} 1074 1075void Swig_name_nameobj_add(Hash *name_hash, List *name_list, String *prefix, String *name, SwigType *decl, Hash *nameobj) { 1076 String *nname = 0; 1077 if (name && Len(name)) { 1078 String *target_fmt = Getattr(nameobj, "targetfmt"); 1079 nname = prefix ? NewStringf("%s::%s", prefix, name) : NewString(name); 1080 if (target_fmt) { 1081 String *tmp = NewStringf(target_fmt, nname); 1082 Delete(nname); 1083 nname = tmp; 1084 } 1085 } 1086 1087 if (!nname || !Len(nname) || Getattr(nameobj, "fullname") || /* any of these options trigger a 'list' nameobj */ 1088 Getattr(nameobj, "sourcefmt") || Getattr(nameobj, "matchlist")) { 1089 if (decl) 1090 Setattr(nameobj, "decl", decl); 1091 if (nname && Len(nname)) 1092 Setattr(nameobj, "targetname", nname); 1093 /* put the new nameobj at the beginnig of the list, such that the 1094 last inserted rule take precedence */ 1095 Insert(name_list, 0, nameobj); 1096 } else { 1097 /* here we add an old 'hash' nameobj, simple and fast */ 1098 Swig_name_object_set(name_hash, nname, decl, nameobj); 1099 } 1100 Delete(nname); 1101} 1102 1103/* ----------------------------------------------------------------------------- 1104 * int Swig_name_match_nameobj() 1105 * 1106 * Apply and check the nameobj's math list to the node 1107 * 1108 * ----------------------------------------------------------------------------- */ 1109 1110static DOH *Swig_get_lattr(Node *n, List *lattr) { 1111 DOH *res = 0; 1112 int ilen = Len(lattr); 1113 int i; 1114 for (i = 0; n && (i < ilen); ++i) { 1115 String *nattr = Getitem(lattr, i); 1116 res = Getattr(n, nattr); 1117#ifdef SWIG_DEBUG 1118 if (!res) { 1119 Printf(stdout, "missing %s %s %s\n", nattr, Getattr(n, "name"), Getattr(n, "member")); 1120 } else { 1121 Printf(stdout, "lattr %d %s %s\n", i, nattr, DohIsString(res) ? res : Getattr(res, "name")); 1122 } 1123#endif 1124 n = res; 1125 } 1126 return res; 1127} 1128 1129#if defined(HAVE_RXSPENCER) 1130#include <sys/types.h> 1131#include <rxspencer/regex.h> 1132#define USE_RXSPENCER 1133#endif 1134 1135#if defined(USE_RXSPENCER) 1136int Swig_name_rxsmatch_value(String *mvalue, String *value) { 1137 int match = 0; 1138 char *cvalue = Char(value); 1139 char *cmvalue = Char(mvalue); 1140 regex_t compiled; 1141 int retval = regcomp(&compiled, cmvalue, REG_EXTENDED | REG_NOSUB); 1142 if (retval != 0) 1143 return 0; 1144 retval = regexec(&compiled, cvalue, 0, 0, 0); 1145 match = (retval == REG_NOMATCH) ? 0 : 1; 1146#ifdef SWIG_DEBUG 1147 Printf(stdout, "rxsmatch_value: %s %s %d\n", cvalue, cmvalue, match); 1148#endif 1149 regfree(&compiled); 1150 return match; 1151} 1152#else 1153int Swig_name_rxsmatch_value(String *mvalue, String *value) { 1154 (void) mvalue; 1155 (void) value; 1156 return 0; 1157} 1158#endif 1159 1160int Swig_name_match_value(String *mvalue, String *value) { 1161#if defined(SWIG_USE_SIMPLE_MATCHOR) 1162 int match = 0; 1163 char *cvalue = Char(value); 1164 char *cmvalue = Char(mvalue); 1165 char *sep = strchr(cmvalue, '|'); 1166 while (sep && !match) { 1167 match = strncmp(cvalue, cmvalue, sep - cmvalue) == 0; 1168#ifdef SWIG_DEBUG 1169 Printf(stdout, "match_value: %s %s %d\n", cvalue, cmvalue, match); 1170#endif 1171 cmvalue = sep + 1; 1172 sep = strchr(cmvalue, '|'); 1173 } 1174 if (!match) { 1175 match = strcmp(cvalue, cmvalue) == 0; 1176#ifdef SWIG_DEBUG 1177 Printf(stdout, "match_value: %s %s %d\n", cvalue, cmvalue, match); 1178#endif 1179 } 1180 return match; 1181#else 1182 return Equal(mvalue, value); 1183#endif 1184} 1185 1186 1187int Swig_name_match_nameobj(Hash *rn, Node *n) { 1188 int match = 1; 1189 List *matchlist = Getattr(rn, "matchlist"); 1190#ifdef SWIG_DEBUG 1191 Printf(stdout, "Swig_name_match_nameobj: %s\n", Getattr(n, "name")); 1192#endif 1193 if (matchlist) { 1194 int ilen = Len(matchlist); 1195 int i; 1196 for (i = 0; match && (i < ilen); ++i) { 1197 Node *mi = Getitem(matchlist, i); 1198 List *lattr = Getattr(mi, "attrlist"); 1199 String *nval = Swig_get_lattr(n, lattr); 1200 int notmatch = GetFlag(mi, "notmatch"); 1201 int rxsmatch = GetFlag(mi, "rxsmatch"); 1202#ifdef SWIG_DEBUG 1203 Printf(stdout, "mi %d %s re %d not %d \n", i, nval, notmatch, rxsmatch); 1204 if (rxsmatch) { 1205 Printf(stdout, "rxsmatch %s\n", lattr); 1206 } 1207#endif 1208 match = 0; 1209 if (nval) { 1210 String *kwval = Getattr(mi, "value"); 1211 match = rxsmatch ? Swig_name_rxsmatch_value(kwval, nval) 1212 : Swig_name_match_value(kwval, nval); 1213#ifdef SWIG_DEBUG 1214 Printf(stdout, "val %s %s %d %d \n", nval, kwval, match, ilen); 1215#endif 1216 } 1217 if (notmatch) 1218 match = !match; 1219 } 1220 } 1221#ifdef SWIG_DEBUG 1222 Printf(stdout, "Swig_name_match_nameobj: %d\n", match); 1223#endif 1224 return match; 1225} 1226 1227/* ----------------------------------------------------------------------------- 1228 * Hash *Swig_name_nameobj_lget() 1229 * 1230 * Get a nameobj (rename/namewarn) from the list of filters 1231 * 1232 * ----------------------------------------------------------------------------- */ 1233 1234Hash *Swig_name_nameobj_lget(List *namelist, Node *n, String *prefix, String *name, String *decl) { 1235 Hash *res = 0; 1236 if (namelist) { 1237 int len = Len(namelist); 1238 int i; 1239 int match = 0; 1240 for (i = 0; !match && (i < len); i++) { 1241 Hash *rn = Getitem(namelist, i); 1242 String *rdecl = Getattr(rn, "decl"); 1243 if (rdecl && (!decl || !Equal(rdecl, decl))) { 1244 continue; 1245 } else if (Swig_name_match_nameobj(rn, n)) { 1246 String *tname = Getattr(rn, "targetname"); 1247 if (tname) { 1248 String *sfmt = Getattr(rn, "sourcefmt"); 1249 String *sname = 0; 1250 int fullname = GetFlag(rn, "fullname"); 1251 int rxstarget = GetFlag(rn, "rxstarget"); 1252 if (sfmt) { 1253 if (fullname && prefix) { 1254 String *pname = NewStringf("%s::%s", prefix, name); 1255 sname = NewStringf(sfmt, pname); 1256 Delete(pname); 1257 } else { 1258 sname = NewStringf(sfmt, name); 1259 } 1260 } else { 1261 if (fullname && prefix) { 1262 sname = NewStringf("%s::%s", prefix, name); 1263 } else { 1264 sname = name; 1265 DohIncref(name); 1266 } 1267 } 1268 match = rxstarget ? Swig_name_rxsmatch_value(tname, sname) : Swig_name_match_value(tname, sname); 1269 Delete(sname); 1270 } else { 1271 match = 1; 1272 } 1273 } 1274 if (match) { 1275 res = rn; 1276 break; 1277 } 1278 } 1279 } 1280 return res; 1281} 1282 1283/* ----------------------------------------------------------------------------- 1284 * Swig_name_namewarn_add 1285 * 1286 * Add a namewarn objects 1287 * 1288 * ----------------------------------------------------------------------------- */ 1289 1290void Swig_name_namewarn_add(String *prefix, String *name, SwigType *decl, Hash *namewrn) { 1291 const char *namewrn_keys[] = { "rename", "error", "fullname", "sourcefmt", "targetfmt", 0 }; 1292 Swig_name_object_attach_keys(namewrn_keys, namewrn); 1293 Swig_name_nameobj_add(Swig_name_namewarn_hash(), Swig_name_namewarn_list(), prefix, name, decl, namewrn); 1294} 1295 1296/* ----------------------------------------------------------------------------- 1297 * Hash *Swig_name_namewarn_get() 1298 * 1299 * Return the namewarn object, if there is one. 1300 * 1301 * ----------------------------------------------------------------------------- */ 1302 1303Hash *Swig_name_namewarn_get(Node *n, String *prefix, String *name, SwigType *decl) { 1304 if (!namewarn_hash && !namewarn_list) 1305 return 0; 1306 if (n) { 1307 /* Return in the obvious cases */ 1308 if (!name || !Swig_need_name_warning(n)) { 1309 return 0; 1310 } else { 1311 String *access = Getattr(n, "access"); 1312 int is_public = !access || Equal(access, "public"); 1313 if (!is_public && !Swig_need_protected(n)) { 1314 return 0; 1315 } 1316 } 1317 } 1318 if (name) { 1319 /* Check to see if the name is in the hash */ 1320 Hash *wrn = Swig_name_object_get(Swig_name_namewarn_hash(), prefix, name, decl); 1321 if (wrn && !Swig_name_match_nameobj(wrn, n)) 1322 wrn = 0; 1323 if (!wrn) { 1324 wrn = Swig_name_nameobj_lget(Swig_name_namewarn_list(), n, prefix, name, decl); 1325 } 1326 if (wrn && Getattr(wrn, "error")) { 1327 if (n) { 1328 Swig_error(Getfile(n), Getline(n), "%s\n", Getattr(wrn, "name")); 1329 } else { 1330 Swig_error(cparse_file, cparse_line, "%s\n", Getattr(wrn, "name")); 1331 } 1332 } 1333 return wrn; 1334 } else { 1335 return 0; 1336 } 1337} 1338 1339/* ----------------------------------------------------------------------------- 1340 * String *Swig_name_warning() 1341 * 1342 * Return the name warning, if there is one. 1343 * 1344 * ----------------------------------------------------------------------------- */ 1345 1346String *Swig_name_warning(Node *n, String *prefix, String *name, SwigType *decl) { 1347 Hash *wrn = Swig_name_namewarn_get(n, prefix, name, decl); 1348 return (name && wrn) ? Getattr(wrn, "name") : 0; 1349} 1350 1351/* ----------------------------------------------------------------------------- 1352 * Swig_name_rename_add() 1353 * 1354 * Manage the rename objects 1355 * 1356 * ----------------------------------------------------------------------------- */ 1357 1358static void single_rename_add(String *prefix, String *name, SwigType *decl, Hash *newname) { 1359 Swig_name_nameobj_add(Swig_name_rename_hash(), Swig_name_rename_list(), prefix, name, decl, newname); 1360} 1361 1362/* Add a new rename. Works much like new_feature including default argument handling. */ 1363void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *newname, ParmList *declaratorparms) { 1364 1365 ParmList *declparms = declaratorparms; 1366 1367 const char *rename_keys[] = { "fullname", "sourcefmt", "targetfmt", "continue", "rxstarget", 0 }; 1368 Swig_name_object_attach_keys(rename_keys, newname); 1369 1370 /* Add the name */ 1371 single_rename_add(prefix, name, decl, newname); 1372 1373 /* Add extra names if there are default parameters in the parameter list */ 1374 if (decl) { 1375 int constqualifier = SwigType_isconst(decl); 1376 while (declparms) { 1377 if (ParmList_has_defaultargs(declparms)) { 1378 1379 /* Create a parameter list for the new rename by copying all 1380 but the last (defaulted) parameter */ 1381 ParmList *newparms = CopyParmListMax(declparms,ParmList_len(declparms)-1); 1382 1383 /* Create new declaration - with the last parameter removed */ 1384 SwigType *newdecl = Copy(decl); 1385 Delete(SwigType_pop_function(newdecl)); /* remove the old parameter list from newdecl */ 1386 SwigType_add_function(newdecl, newparms); 1387 if (constqualifier) 1388 SwigType_add_qualifier(newdecl, "const"); 1389 1390 single_rename_add(prefix, name, newdecl, newname); 1391 declparms = newparms; 1392 Delete(newdecl); 1393 } else { 1394 declparms = 0; 1395 } 1396 } 1397 } 1398} 1399 1400 1401/* Create a name applying rename/namewarn if needed */ 1402static String *apply_rename(String *newname, int fullname, String *prefix, String *name) { 1403 String *result = 0; 1404 if (newname && Len(newname)) { 1405 if (Strcmp(newname, "$ignore") == 0) { 1406 result = Copy(newname); 1407 } else { 1408 char *cnewname = Char(newname); 1409 if (cnewname) { 1410 int destructor = name && (*(Char(name)) == '~'); 1411 String *fmt = newname; 1412 /* use name as a fmt, but avoid C++ "%" and "%=" operators */ 1413 if (Len(newname) > 1 && strchr(cnewname, '%') && !(strcmp(cnewname, "%=") == 0)) { 1414 if (fullname && prefix) { 1415 result = NewStringf(fmt, prefix, name); 1416 } else { 1417 result = NewStringf(fmt, name); 1418 } 1419 } else { 1420 result = Copy(newname); 1421 } 1422 if (destructor && result && (*(Char(result)) != '~')) { 1423 Insert(result, 0, "~"); 1424 } 1425 } 1426 } 1427 } 1428 1429 return result; 1430} 1431 1432/* ----------------------------------------------------------------------------- 1433 * String *Swig_name_make() 1434 * 1435 * Make a name after applying all the rename/namewarn objects 1436 * 1437 * ----------------------------------------------------------------------------- */ 1438 1439String *Swig_name_make(Node *n, String *prefix, const_String_or_char_ptr cname, SwigType *decl, String *oldname) { 1440 String *nname = 0; 1441 String *result = 0; 1442 String *name = NewString(cname); 1443 Hash *wrn = 0; 1444 String *rdecl = 0; 1445 String *rname = 0; 1446 1447 /* very specific hack for template constructors/destructors */ 1448#ifdef SWIG_DEBUG 1449 Printf(stdout, "Swig_name_make: looking for %s %s %s %s\n", prefix, name, decl, oldname); 1450#endif 1451 1452 if (name && n && SwigType_istemplate(name)) { 1453 String *nodetype = nodeType(n); 1454 if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) { 1455 String *nprefix = NewStringEmpty(); 1456 String *nlast = NewStringEmpty(); 1457 String *tprefix; 1458 Swig_scopename_split(name, &nprefix, &nlast); 1459 tprefix = SwigType_templateprefix(nlast); 1460 Delete(nlast); 1461 if (Len(nprefix)) { 1462 Append(nprefix, "::"); 1463 Append(nprefix, tprefix); 1464 Delete(tprefix); 1465 rname = nprefix; 1466 } else { 1467 rname = tprefix; 1468 Delete(nprefix); 1469 } 1470 rdecl = Copy(decl); 1471 Replaceall(rdecl, name, rname); 1472#ifdef SWIG_DEBUG 1473 Printf(stdout, "SWIG_name_make: use new name %s %s : %s %s\n", name, decl, rname, rdecl); 1474#endif 1475 decl = rdecl; 1476 Delete(name); 1477 name = rname; 1478 } 1479 } 1480 1481 1482 if (rename_hash || rename_list || namewarn_hash || namewarn_list) { 1483 Hash *rn = Swig_name_object_get(Swig_name_rename_hash(), prefix, name, decl); 1484 if (!rn || !Swig_name_match_nameobj(rn, n)) { 1485 rn = Swig_name_nameobj_lget(Swig_name_rename_list(), n, prefix, name, decl); 1486 if (rn) { 1487 String *sfmt = Getattr(rn, "sourcefmt"); 1488 int fullname = GetFlag(rn, "fullname"); 1489 if (fullname && prefix) { 1490 String *sname = NewStringf("%s::%s", prefix, name); 1491 Delete(name); 1492 name = sname; 1493 prefix = 0; 1494 } 1495 if (sfmt) { 1496 String *sname = NewStringf(sfmt, name); 1497 Delete(name); 1498 name = sname; 1499 } 1500 } 1501 } 1502 if (rn) { 1503 String *newname = Getattr(rn, "name"); 1504 int fullname = GetFlag(rn, "fullname"); 1505 result = apply_rename(newname, fullname, prefix, name); 1506 } 1507 if (result && !Equal(result, name)) { 1508 /* operators in C++ allow aliases, we look for them */ 1509 char *cresult = Char(result); 1510 if (cresult && (strncmp(cresult, "operator ", 9) == 0)) { 1511 String *nresult = Swig_name_make(n, prefix, result, decl, oldname); 1512 if (!Equal(nresult, result)) { 1513 Delete(result); 1514 result = nresult; 1515 } else { 1516 Delete(nresult); 1517 } 1518 } 1519 } 1520 nname = result ? result : name; 1521 wrn = Swig_name_namewarn_get(n, prefix, nname, decl); 1522 if (wrn) { 1523 String *rename = Getattr(wrn, "rename"); 1524 if (rename) { 1525 String *msg = Getattr(wrn, "name"); 1526 int fullname = GetFlag(wrn, "fullname"); 1527 if (result) 1528 Delete(result); 1529 result = apply_rename(rename, fullname, prefix, name); 1530 if ((msg) && (Len(msg))) { 1531 if (!Getmeta(nname, "already_warned")) { 1532 if (n) { 1533 SWIG_WARN_NODE_BEGIN(n); 1534 Swig_warning(0, Getfile(n), Getline(n), "%s\n", msg); 1535 SWIG_WARN_NODE_END(n); 1536 } else { 1537 Swig_warning(0, Getfile(name), Getline(name), "%s\n", msg); 1538 } 1539 Setmeta(nname, "already_warned", "1"); 1540 } 1541 } 1542 } 1543 } 1544 } 1545 if (!result || !Len(result)) { 1546 if (result) 1547 Delete(result); 1548 if (oldname) { 1549 result = NewString(oldname); 1550 } else { 1551 result = NewString(cname); 1552 } 1553 } 1554 Delete(name); 1555 1556#ifdef SWIG_DEBUG 1557 Printf(stdout, "Swig_name_make: result '%s' '%s'\n", cname, result); 1558#endif 1559 1560 return result; 1561} 1562 1563/* ----------------------------------------------------------------------------- 1564 * void Swig_name_inherit() 1565 * 1566 * Inherit namewarn,rename, and feature objects 1567 * 1568 * ----------------------------------------------------------------------------- */ 1569 1570void Swig_name_inherit(String *base, String *derived) { 1571 /* Printf(stdout,"base = '%s', derived = '%s'\n", base, derived); */ 1572 Swig_name_object_inherit(Swig_name_rename_hash(), base, derived); 1573 Swig_name_object_inherit(Swig_name_namewarn_hash(), base, derived); 1574 Swig_name_object_inherit(Swig_cparse_features(), base, derived); 1575} 1576 1577/* ----------------------------------------------------------------------------- 1578 * void Swig_name_decl() 1579 * 1580 * Return a stringified version of a C/C++ declaration without the return type. 1581 * The node passed in is expected to be a function. Some example return values: 1582 * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()" 1583 * "MyNameSpace::ABC::ABC(int,double)" 1584 * "MyNameSpace::ABC::constmethod(int) const" 1585 * 1586 * ----------------------------------------------------------------------------- */ 1587 1588String *Swig_name_decl(Node *n) { 1589 String *qname; 1590 String *decl; 1591 String *qualifier = Swig_symbol_qualified(n); 1592 String *name = Swig_scopename_last(Getattr(n, "name")); 1593 if (qualifier) 1594 qualifier = SwigType_namestr(qualifier); 1595 1596 /* Very specific hack for template constructors/destructors */ 1597 if (SwigType_istemplate(name)) { 1598 String *nodetype = nodeType(n); 1599 if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) { 1600 String *nprefix = NewStringEmpty(); 1601 String *nlast = NewStringEmpty(); 1602 String *tprefix; 1603 Swig_scopename_split(name, &nprefix, &nlast); 1604 tprefix = SwigType_templateprefix(nlast); 1605 Delete(nlast); 1606 Delete(name); 1607 name = tprefix; 1608 } 1609 } 1610 1611 qname = NewString(""); 1612 if (qualifier && Len(qualifier) > 0) 1613 Printf(qname, "%s::", qualifier); 1614 Printf(qname, "%s", SwigType_str(name, 0)); 1615 1616 decl = NewStringf("%s(%s)%s", qname, ParmList_errorstr(Getattr(n, "parms")), SwigType_isconst(Getattr(n, "decl")) ? " const" : ""); 1617 1618 Delete(name); 1619 Delete(qualifier); 1620 Delete(qname); 1621 1622 return decl; 1623} 1624 1625/* ----------------------------------------------------------------------------- 1626 * void Swig_name_fulldecl() 1627 * 1628 * Return a stringified version of a C/C++ declaration including the return type. 1629 * The node passed in is expected to be a function. Some example return values: 1630 * "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()" 1631 * "MyNameSpace::ABC::ABC(int,double)" 1632 * "int * MyNameSpace::ABC::constmethod(int) const" 1633 * 1634 * ----------------------------------------------------------------------------- */ 1635 1636String *Swig_name_fulldecl(Node *n) { 1637 String *decl = Swig_name_decl(n); 1638 String *type = Getattr(n, "type"); 1639 String *nodetype = nodeType(n); 1640 String *fulldecl; 1641 /* add on the return type */ 1642 if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor"))) { 1643 fulldecl = decl; 1644 } else { 1645 String *t = SwigType_str(type, 0); 1646 fulldecl = NewStringf("%s %s", t, decl); 1647 Delete(decl); 1648 Delete(t); 1649 } 1650 return fulldecl; 1651} 1652 1653