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

/branches/gsoc2008-cherylfoil/Source/Swig/naming.c

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