PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/branches/swig-2.0/Source/Swig/naming.c

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