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

/tags/rel-1-3-30rc1-afterbeautify/SWIG/Source/Swig/naming.c

#
C | 1567 lines | 1180 code | 144 blank | 243 comment | 357 complexity | 66fcd5c87cb28f3a60216731a4404382 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[] = "$Header$";
  10. #include "swig.h"
  11. #include "cparse.h"
  12. #include "swigkeys.h"
  13. #include <ctype.h>
  14. /* Hash table containing naming data */
  15. static Hash *naming_hash = 0;
  16. #if 0
  17. #define SWIG_DEBUG
  18. #endif
  19. /* -----------------------------------------------------------------------------
  20. * Swig_name_register()
  21. *
  22. * Register a new naming format.
  23. * ----------------------------------------------------------------------------- */
  24. void Swig_name_register(const String_or_char *method, const String_or_char *format) {
  25. if (!naming_hash)
  26. naming_hash = NewHash();
  27. Setattr(naming_hash, method, format);
  28. }
  29. void Swig_name_unregister(const String_or_char *method) {
  30. if (naming_hash) {
  31. Delattr(naming_hash, method);
  32. }
  33. }
  34. static int name_mangle(String *r) {
  35. char *c;
  36. int special;
  37. special = 0;
  38. Replaceall(r, "::", "_");
  39. c = 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 *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 *fname) {
  135. String *r;
  136. String *f;
  137. r = NewStringEmpty();
  138. if (!naming_hash)
  139. naming_hash = NewHash();
  140. f = HashGetAttr(naming_hash, k_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 *classname, const String_or_char *mname) {
  156. String *r;
  157. String *f;
  158. String *rclassname;
  159. char *cname;
  160. rclassname = SwigType_namestr(classname);
  161. r = NewStringEmpty();
  162. if (!naming_hash)
  163. naming_hash = NewHash();
  164. f = HashGetAttr(naming_hash, k_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 *vname) {
  186. String *r;
  187. String *f;
  188. #ifdef SWIG_DEBUG
  189. Printf(stderr, "Swig_name_get: '%s'\n", vname);
  190. #endif
  191. r = NewStringEmpty();
  192. if (!naming_hash)
  193. naming_hash = NewHash();
  194. f = Getattr(naming_hash, k_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 *vname) {
  210. String *r;
  211. String *f;
  212. r = NewStringEmpty();
  213. if (!naming_hash)
  214. naming_hash = NewHash();
  215. f = HashGetAttr(naming_hash, k_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 *classname) {
  231. String *r;
  232. String *f;
  233. String *rclassname;
  234. char *cname;
  235. rclassname = SwigType_namestr(classname);
  236. r = NewStringEmpty();
  237. if (!naming_hash)
  238. naming_hash = NewHash();
  239. f = HashGetAttr(naming_hash, k_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 *classname) {
  259. String *r;
  260. String *f;
  261. String *rclassname;
  262. char *cname;
  263. rclassname = SwigType_namestr(classname);
  264. r = NewStringEmpty();
  265. if (!naming_hash)
  266. naming_hash = NewHash();
  267. f = HashGetAttr(naming_hash, k_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 *classname) {
  287. String *r;
  288. String *f;
  289. String *rclassname;
  290. char *cname;
  291. rclassname = SwigType_namestr(classname);
  292. r = NewStringEmpty();
  293. if (!naming_hash)
  294. naming_hash = NewHash();
  295. f = HashGetAttr(naming_hash, k_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 *classname) {
  315. String *r;
  316. String *f;
  317. String *rclassname;
  318. char *cname;
  319. rclassname = SwigType_namestr(classname);
  320. r = NewStringEmpty();
  321. if (!naming_hash)
  322. naming_hash = NewHash();
  323. f = HashGetAttr(naming_hash, k_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(stderr, "Swig_name_object_set: '%s', '%s'\n", name, decl);
  346. #endif
  347. n = HashGetAttr(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, k_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, k_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(stderr, "Swig_name_object_get: '%s', '%s'\n", 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. if (0 && !rn && SwigType_istemplate(prefix)) {
  432. String *t_prefix = SwigType_templateprefix(prefix);
  433. if (Strcmp(t_prefix, prefix) != 0) {
  434. String *t_name = SwigType_templateprefix(name);
  435. rn = Swig_name_object_get(namehash, t_prefix, t_name, decl);
  436. Delete(t_name);
  437. }
  438. Delete(t_prefix);
  439. }
  440. }
  441. /* A wildcard-based class lookup */
  442. if (!rn) {
  443. Clear(tname);
  444. Printf(tname, "*::%s", name);
  445. rn = name_object_get(namehash, tname, decl, ncdecl);
  446. }
  447. } else {
  448. /* Lookup in the global namespace only */
  449. Clear(tname);
  450. Printf(tname, "::%s", name);
  451. rn = name_object_get(namehash, tname, decl, ncdecl);
  452. }
  453. /* Catch-all */
  454. if (!rn) {
  455. rn = name_object_get(namehash, name, decl, ncdecl);
  456. }
  457. if (!rn && Swig_scopename_check(name)) {
  458. String *nprefix = NewStringEmpty();
  459. String *nlast = NewStringEmpty();
  460. Swig_scopename_split(name, &nprefix, &nlast);
  461. rn = name_object_get(namehash, nlast, decl, ncdecl);
  462. Delete(nlast);
  463. Delete(nprefix);
  464. }
  465. Delete(tname);
  466. #ifdef SWIG_DEBUG
  467. Printf(stderr, "Swig_name_object_get: found %d\n", rn ? 1 : 0);
  468. #endif
  469. return rn;
  470. }
  471. /* -----------------------------------------------------------------------------
  472. * Swig_name_object_inherit()
  473. *
  474. * Implements name-based inheritance scheme.
  475. * ----------------------------------------------------------------------------- */
  476. void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) {
  477. Iterator ki;
  478. String *bprefix;
  479. String *dprefix;
  480. char *cbprefix;
  481. int plen;
  482. if (!namehash)
  483. return;
  484. bprefix = NewStringf("%s::", base);
  485. dprefix = NewStringf("%s::", derived);
  486. cbprefix = Char(bprefix);
  487. plen = strlen(cbprefix);
  488. for (ki = First(namehash); ki.key; ki = Next(ki)) {
  489. char *k = Char(ki.key);
  490. if (strncmp(k, cbprefix, plen) == 0) {
  491. Iterator oi;
  492. String *nkey = NewStringf("%s%s", dprefix, k + plen);
  493. Hash *n = ki.item;
  494. Hash *newh = HashGetAttr(namehash, nkey);
  495. if (!newh) {
  496. newh = NewHash();
  497. Setattr(namehash, nkey, newh);
  498. Delete(newh);
  499. }
  500. for (oi = First(n); oi.key; oi = Next(oi)) {
  501. if (!Getattr(newh, oi.key)) {
  502. String *ci = Copy(oi.item);
  503. Setattr(newh, oi.key, ci);
  504. Delete(ci);
  505. }
  506. }
  507. Delete(nkey);
  508. }
  509. }
  510. Delete(bprefix);
  511. Delete(dprefix);
  512. }
  513. /* -----------------------------------------------------------------------------
  514. * merge_features()
  515. *
  516. * Given a hash, this function merges the features in the hash into the node.
  517. * ----------------------------------------------------------------------------- */
  518. static void merge_features(Hash *features, Node *n) {
  519. Iterator ki;
  520. if (!features)
  521. return;
  522. for (ki = First(features); ki.key; ki = Next(ki)) {
  523. String *ci = Copy(ki.item);
  524. Setattr(n, ki.key, ci);
  525. Delete(ci);
  526. }
  527. }
  528. /* -----------------------------------------------------------------------------
  529. * Swig_features_get()
  530. *
  531. * Attaches any features in the features hash to the node that matches
  532. * the declaration, decl.
  533. * ----------------------------------------------------------------------------- */
  534. static
  535. void features_get(Hash *features, String *tname, SwigType *decl, SwigType *ncdecl, Node *node) {
  536. Node *n = Getattr(features, tname);
  537. #ifdef SWIG_DEBUG
  538. Printf(stderr, " features_get: %s\n", tname);
  539. #endif
  540. if (n) {
  541. merge_features(get_object(n, 0), node);
  542. if (ncdecl)
  543. merge_features(get_object(n, ncdecl), node);
  544. merge_features(get_object(n, decl), node);
  545. }
  546. }
  547. void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *node) {
  548. char *ncdecl = 0;
  549. String *rdecl = 0;
  550. String *rname = 0;
  551. if (!features)
  552. return;
  553. /* MM: This removed to more tightly control feature/name matching */
  554. /*
  555. if ((decl) && (SwigType_isqualifier(decl))) {
  556. ncdecl = strchr(Char(decl),'.');
  557. ncdecl++;
  558. }
  559. */
  560. /* very specific hack for template constructors/destructors */
  561. if (name && SwigType_istemplate(name)) {
  562. String *nodetype = Getattr(node, k_nodetype);
  563. if (nodetype && (Equal(nodetype, k_constructor) || Equal(nodetype, k_destructor))) {
  564. String *nprefix = NewStringEmpty();
  565. String *nlast = NewStringEmpty();
  566. String *tprefix;
  567. Swig_scopename_split(name, &nprefix, &nlast);
  568. tprefix = SwigType_templateprefix(nlast);
  569. Delete(nlast);
  570. if (Len(nprefix)) {
  571. Append(nprefix, "::");
  572. Append(nprefix, tprefix);
  573. Delete(tprefix);
  574. rname = nprefix;
  575. } else {
  576. rname = tprefix;
  577. Delete(nprefix);
  578. }
  579. rdecl = Copy(decl);
  580. Replaceall(rdecl, name, rname);
  581. decl = rdecl;
  582. name = rname;
  583. }
  584. }
  585. #ifdef SWIG_DEBUG
  586. Printf(stderr, "Swig_features_get: %s %s %s\n", prefix, name, decl);
  587. #endif
  588. /* Global features */
  589. features_get(features, empty_string, 0, 0, node);
  590. if (name) {
  591. String *tname = NewStringEmpty();
  592. /* add features for 'root' template */
  593. if (SwigType_istemplate(name)) {
  594. String *dname = SwigType_templateprefix(name);
  595. features_get(features, dname, decl, ncdecl, node);
  596. Delete(dname);
  597. }
  598. /* Catch-all */
  599. features_get(features, name, decl, ncdecl, node);
  600. /* Perform a class-based lookup (if class prefix supplied) */
  601. if (prefix) {
  602. /* A class-generic feature */
  603. if (Len(prefix)) {
  604. Printf(tname, "%s::", prefix);
  605. features_get(features, tname, decl, ncdecl, node);
  606. }
  607. /* A wildcard-based class lookup */
  608. Clear(tname);
  609. Printf(tname, "*::%s", name);
  610. features_get(features, tname, decl, ncdecl, node);
  611. /* A specific class lookup */
  612. if (Len(prefix)) {
  613. /* A template-based class lookup */
  614. if (SwigType_istemplate(prefix)) {
  615. String *tprefix = SwigType_templateprefix(prefix);
  616. Clear(tname);
  617. Printf(tname, "%s::%s", tprefix, name);
  618. features_get(features, tname, decl, ncdecl, node);
  619. Delete(tprefix);
  620. }
  621. Clear(tname);
  622. Printf(tname, "%s::%s", prefix, name);
  623. features_get(features, tname, decl, ncdecl, node);
  624. }
  625. } else {
  626. /* Lookup in the global namespace only */
  627. Clear(tname);
  628. Printf(tname, "::%s", name);
  629. features_get(features, tname, decl, ncdecl, node);
  630. }
  631. Delete(tname);
  632. }
  633. if (name && SwigType_istemplate(name)) {
  634. /* add features for complete template type */
  635. String *dname = Swig_symbol_template_deftype(name, 0);
  636. if (!Equal(dname, name)) {
  637. Swig_features_get(features, prefix, dname, decl, node);
  638. }
  639. Delete(dname);
  640. }
  641. if (rname)
  642. Delete(rname);
  643. if (rdecl)
  644. Delete(rdecl);
  645. }
  646. /* -----------------------------------------------------------------------------
  647. * Swig_feature_set()
  648. *
  649. * Sets a feature name and value. Also sets optional feature attributes as
  650. * passed in by featureattribs. Optional feature attributes are given a full name
  651. * concatenating the feature name plus ':' plus the attribute name.
  652. * ----------------------------------------------------------------------------- */
  653. void Swig_feature_set(Hash *features, const String_or_char *name, SwigType *decl, const String_or_char *featurename, String *value, Hash *featureattribs) {
  654. Hash *n;
  655. Hash *fhash;
  656. #ifdef SWIG_DEBUG
  657. Printf(stderr, "Swig_feature_set: %s %s %s %s\n", name, decl, featurename, value);
  658. #endif
  659. n = Getattr(features, name);
  660. if (!n) {
  661. n = NewHash();
  662. Setattr(features, name, n);
  663. Delete(n);
  664. }
  665. if (!decl) {
  666. fhash = Getattr(n, k_start);
  667. if (!fhash) {
  668. fhash = NewHash();
  669. Setattr(n, k_start, fhash);
  670. Delete(fhash);
  671. }
  672. } else {
  673. fhash = Getattr(n, decl);
  674. if (!fhash) {
  675. String *cdecl_ = Copy(decl);
  676. fhash = NewHash();
  677. Setattr(n, cdecl_, fhash);
  678. Delete(cdecl_);
  679. Delete(fhash);
  680. }
  681. }
  682. if (value) {
  683. Setattr(fhash, featurename, value);
  684. } else {
  685. Delattr(fhash, featurename);
  686. }
  687. {
  688. /* Add in the optional feature attributes */
  689. Hash *attribs = featureattribs;
  690. while (attribs) {
  691. String *attribname = Getattr(attribs, k_name);
  692. String *featureattribname = NewStringf("%s:%s", featurename, attribname);
  693. if (value) {
  694. String *attribvalue = Getattr(attribs, k_value);
  695. Setattr(fhash, featureattribname, attribvalue);
  696. } else {
  697. Delattr(fhash, featureattribname);
  698. }
  699. attribs = nextSibling(attribs);
  700. Delete(featureattribname);
  701. }
  702. }
  703. if (name && SwigType_istemplate(name)) {
  704. String *dname = Swig_symbol_template_deftype(name, 0);
  705. if (Strcmp(dname, name)) {
  706. Swig_feature_set(features, dname, decl, featurename, value, featureattribs);
  707. }
  708. Delete(dname);
  709. }
  710. }
  711. /* -----------------------------------------------------------------------------
  712. * The rename/namewarn engine
  713. *
  714. * Code below was in parser.y for a while
  715. * ----------------------------------------------------------------------------- */
  716. static Hash *namewarn_hash = 0;
  717. Hash *Swig_name_namewarn_hash() {
  718. if (!namewarn_hash)
  719. namewarn_hash = NewHash();
  720. return namewarn_hash;
  721. }
  722. static Hash *rename_hash = 0;
  723. Hash *Swig_name_rename_hash() {
  724. if (!rename_hash)
  725. rename_hash = NewHash();
  726. return rename_hash;
  727. }
  728. static List *namewarn_list = 0;
  729. List *Swig_name_namewarn_list() {
  730. if (!namewarn_list)
  731. namewarn_list = NewList();
  732. return namewarn_list;
  733. }
  734. static List *rename_list = 0;
  735. List *Swig_name_rename_list() {
  736. if (!rename_list)
  737. rename_list = NewList();
  738. return rename_list;
  739. }
  740. /* -----------------------------------------------------------------------------
  741. * int Swig_need_name_warning(Node *n)
  742. *
  743. * Detects if a node needs name warnings
  744. *
  745. * ----------------------------------------------------------------------------- */
  746. int Swig_need_name_warning(Node *n) {
  747. int need = 1;
  748. /*
  749. we don't use name warnings for:
  750. - class forwards, no symbol is generated at the target language.
  751. - template declarations, only for real instances using %template(name).
  752. - typedefs, they have no effect at the target language.
  753. */
  754. if (checkAttribute(n, k_nodetype, k_classforward)) {
  755. need = 0;
  756. } else if (checkAttribute(n, k_storage, k_typedef)) {
  757. need = 0;
  758. } else if (Getattr(n, k_hidden)) {
  759. need = 0;
  760. } else if (Getattr(n, k_ignore)) {
  761. need = 0;
  762. } else if (Getattr(n, k_templatetype)) {
  763. need = 0;
  764. }
  765. return need;
  766. }
  767. /* -----------------------------------------------------------------------------
  768. * int Swig_need_redefined_warn()
  769. *
  770. * Detects when a redefined object needs a warning
  771. *
  772. * ----------------------------------------------------------------------------- */
  773. static int nodes_are_equivalent(Node *a, Node *b, int a_inclass) {
  774. /* they must have the same type */
  775. String *ta = Getattr(a, k_nodetype);
  776. String *tb = Getattr(b, k_nodetype);
  777. if (Cmp(ta, tb) != 0)
  778. return 0;
  779. /* cdecl case */
  780. if (Cmp(ta, k_cdecl) == 0) {
  781. /* typedef */
  782. String *a_storage = Getattr(a, k_storage);
  783. String *b_storage = Getattr(b, k_storage);
  784. if ((Cmp(a_storage, k_typedef) == 0)
  785. || (Cmp(b_storage, k_typedef) == 0)) {
  786. if (Cmp(a_storage, b_storage) == 0) {
  787. String *a_type = (Getattr(a, k_type));
  788. String *b_type = (Getattr(b, k_type));
  789. if (Cmp(a_type, b_type) == 0)
  790. return 1;
  791. }
  792. return 0;
  793. }
  794. /* static functions */
  795. if ((Cmp(a_storage, k_static) == 0)
  796. || (Cmp(b_storage, k_static) == 0)) {
  797. if (Cmp(a_storage, b_storage) != 0)
  798. return 0;
  799. }
  800. /* friend methods */
  801. if (!a_inclass || (Cmp(a_storage, k_friend) == 0)) {
  802. /* check declaration */
  803. String *a_decl = (Getattr(a, k_decl));
  804. String *b_decl = (Getattr(b, k_decl));
  805. if (Cmp(a_decl, b_decl) == 0) {
  806. /* check return type */
  807. String *a_type = (Getattr(a, k_type));
  808. String *b_type = (Getattr(b, k_type));
  809. if (Cmp(a_type, b_type) == 0) {
  810. /* check parameters */
  811. Parm *ap = (Getattr(a, k_parms));
  812. Parm *bp = (Getattr(b, k_parms));
  813. while (ap && bp) {
  814. SwigType *at = Getattr(ap, k_type);
  815. SwigType *bt = Getattr(bp, k_type);
  816. if (Cmp(at, bt) != 0)
  817. return 0;
  818. ap = nextSibling(ap);
  819. bp = nextSibling(bp);
  820. }
  821. if (ap || bp) {
  822. return 0;
  823. } else {
  824. Node *a_template = Getattr(a, k_template);
  825. Node *b_template = Getattr(b, k_template);
  826. /* Not equivalent if one is a template instantiation (via %template) and the other is a non-templated function */
  827. if ((a_template && !b_template) || (!a_template && b_template))
  828. return 0;
  829. }
  830. return 1;
  831. }
  832. }
  833. }
  834. } else {
  835. /* %constant case */
  836. String *a_storage = Getattr(a, k_storage);
  837. String *b_storage = Getattr(b, k_storage);
  838. if ((Cmp(a_storage, "%constant") == 0)
  839. || (Cmp(b_storage, "%constant") == 0)) {
  840. if (Cmp(a_storage, b_storage) == 0) {
  841. String *a_type = (Getattr(a, k_type));
  842. String *b_type = (Getattr(b, k_type));
  843. if ((Cmp(a_type, b_type) == 0)
  844. && (Cmp(Getattr(a, k_value), Getattr(b, k_value)) == 0))
  845. return 1;
  846. }
  847. return 0;
  848. }
  849. }
  850. return 0;
  851. }
  852. int Swig_need_redefined_warn(Node *a, Node *b, int InClass) {
  853. String *a_name = Getattr(a, k_name);
  854. String *b_name = Getattr(b, k_name);
  855. String *a_symname = Getattr(a, k_symname);
  856. String *b_symname = Getattr(b, k_symname);
  857. /* always send a warning if a 'rename' is involved */
  858. if ((a_symname && !Equal(a_symname, a_name))
  859. || (b_symname && !Equal(b_symname, b_name))) {
  860. if (!Equal(a_name, b_name)) {
  861. return 1;
  862. }
  863. }
  864. return !nodes_are_equivalent(a, b, InClass);
  865. }
  866. /* -----------------------------------------------------------------------------
  867. * int Swig_need_protected(Node* n)
  868. *
  869. * Detects when we need to fully register the protected member.
  870. *
  871. * ----------------------------------------------------------------------------- */
  872. int Swig_need_protected(Node *n) {
  873. /* First, 'n' looks like a function */
  874. /* if (!Swig_director_mode()) return 0; */
  875. String *nodetype = Getattr(n, k_nodetype);
  876. if ((Equal(nodetype, k_cdecl)) && SwigType_isfunction(Getattr(n, k_decl))) {
  877. String *storage = Getattr(n, k_storage);
  878. /* and the function is declared like virtual, or it has no
  879. storage. This eliminates typedef, static and so on. */
  880. return !storage || Equal(storage, k_virtual);
  881. } else if (Equal(nodetype, k_constructor) || Equal(nodetype, k_destructor)) {
  882. return 1;
  883. }
  884. return 0;
  885. }
  886. /* -----------------------------------------------------------------------------
  887. * void Swig_name_nameobj_add()
  888. *
  889. * Add nameobj (rename/namewarn)
  890. *
  891. * ----------------------------------------------------------------------------- */
  892. static List *Swig_make_attrlist(const char *ckey) {
  893. List *list = NewList();
  894. const char *cattr = strchr(ckey, '$');
  895. if (cattr) {
  896. String *nattr;
  897. const char *rattr = strchr(++cattr, '$');
  898. while (rattr) {
  899. nattr = NewStringWithSize(cattr, rattr - cattr);
  900. Append(list, nattr);
  901. Delete(nattr);
  902. cattr = rattr + 1;
  903. rattr = strchr(cattr, '$');
  904. }
  905. nattr = NewString(cattr);
  906. Append(list, nattr);
  907. Delete(nattr);
  908. } else {
  909. Append(list, k_nodetype);
  910. }
  911. return list;
  912. }
  913. static void Swig_name_object_attach_keys(const char *keys[], Hash *nameobj) {
  914. Node *kw = nextSibling(nameobj);
  915. List *matchlist = 0;
  916. while (kw) {
  917. Node *next = nextSibling(kw);
  918. String *kname = Getattr(kw, k_name);
  919. char *ckey = kname ? Char(kname) : 0;
  920. if (ckey) {
  921. const char **rkey;
  922. int isnotmatch = 0;
  923. int isrxsmatch = 0;
  924. if ((strncmp(ckey, "match", 5) == 0)
  925. || (isnotmatch = (strncmp(ckey, "notmatch", 8) == 0))
  926. || (isrxsmatch = (strncmp(ckey, "rxsmatch", 8) == 0))
  927. || (isnotmatch = isrxsmatch = (strncmp(ckey, "notrxsmatch", 11) == 0))) {
  928. Hash *mi = NewHash();
  929. List *attrlist = Swig_make_attrlist(ckey);
  930. if (!matchlist)
  931. matchlist = NewList();
  932. Setattr(mi, k_value, Getattr(kw, k_value));
  933. Setattr(mi, k_attrlist, attrlist);
  934. #ifdef SWIG_DEBUG
  935. if (isrxsmatch)
  936. Printf(stderr, "rxsmatch to use: %s %s %s\n", ckey, Getattr(kw, k_value), attrlist);
  937. #endif
  938. if (isnotmatch)
  939. SetFlag(mi, k_notmatch);
  940. if (isrxsmatch)
  941. SetFlag(mi, k_rxsmatch);
  942. Delete(attrlist);
  943. Append(matchlist, mi);
  944. Delete(mi);
  945. deleteNode(kw);
  946. } else {
  947. for (rkey = keys; *rkey != 0; ++rkey) {
  948. if (strcmp(ckey, *rkey) == 0) {
  949. Setattr(nameobj, *rkey, Getattr(kw, k_value));
  950. deleteNode(kw);
  951. }
  952. }
  953. }
  954. }
  955. kw = next;
  956. }
  957. if (matchlist) {
  958. Setattr(nameobj, k_matchlist, matchlist);
  959. Delete(matchlist);
  960. }
  961. }
  962. void Swig_name_nameobj_add(Hash *name_hash, List *name_list, String *prefix, String *name, SwigType *decl, Hash *nameobj) {
  963. String *nname = 0;
  964. if (name && Len(name)) {
  965. String *target_fmt = Getattr(nameobj, k_targetfmt);
  966. nname = prefix ? NewStringf("%s::%s", prefix, name) : NewString(name);
  967. if (target_fmt) {
  968. String *tmp = NewStringf(target_fmt, nname);
  969. Delete(nname);
  970. nname = tmp;
  971. }
  972. }
  973. if (!nname || !Len(nname) || Getattr(nameobj, k_fullname) || /* any of these options trigger a 'list' nameobj */
  974. Getattr(nameobj, k_sourcefmt) || Getattr(nameobj, k_matchlist)) {
  975. if (decl)
  976. Setattr(nameobj, k_decl, decl);
  977. if (nname && Len(nname))
  978. Setattr(nameobj, k_targetname, nname);
  979. /* put the new nameobj at the beginnig of the list, such that the
  980. last inserted rule take precedence */
  981. Insert(name_list, 0, nameobj);
  982. } else {
  983. /* here we add an old 'hash' nameobj, simple and fast */
  984. Swig_name_object_set(name_hash, nname, decl, nameobj);
  985. }
  986. Delete(nname);
  987. }
  988. /* -----------------------------------------------------------------------------
  989. * int Swig_name_match_nameobj()
  990. *
  991. * Apply and check the nameobj's math list to the node
  992. *
  993. * ----------------------------------------------------------------------------- */
  994. static DOH *Swig_get_lattr(Node *n, List *lattr) {
  995. DOH *res = 0;
  996. int ilen = Len(lattr);
  997. int i;
  998. for (i = 0; n && (i < ilen); ++i) {
  999. String *nattr = Getitem(lattr, i);
  1000. res = Getattr(n, nattr);
  1001. #ifdef SWIG_DEBUG
  1002. if (!res) {
  1003. Printf(stderr, "missing %s %s %s\n", nattr, Getattr(n, k_name), Getattr(n, "member"));
  1004. } else {
  1005. Printf(stderr, "lattr %d %s %s\n", i, nattr, DohIsString(res) ? res : Getattr(res, k_name));
  1006. }
  1007. #endif
  1008. n = res;
  1009. }
  1010. return res;
  1011. }
  1012. #if defined(HAVE_RXSPENCER)
  1013. #include <sys/types.h>
  1014. #include <rxspencer/regex.h>
  1015. #define USE_RXSPENCER
  1016. #endif
  1017. #if defined(USE_RXSPENCER)
  1018. int Swig_name_rxsmatch_value(String *mvalue, String *value) {
  1019. int match = 0;
  1020. char *cvalue = Char(value);
  1021. char *cmvalue = Char(mvalue);
  1022. regex_t compiled;
  1023. int retval = regcomp(&compiled, cmvalue, REG_EXTENDED | REG_NOSUB);
  1024. if (retval != 0)
  1025. return 0;
  1026. retval = regexec(&compiled, cvalue, 0, 0, 0);
  1027. match = (retval == REG_NOMATCH) ? 0 : 1;
  1028. #ifdef SWIG_DEBUG
  1029. Printf(stderr, "rxsmatch_value: %s %s %d\n", cvalue, cmvalue, match);
  1030. #endif
  1031. regfree(&compiled);
  1032. return match;
  1033. }
  1034. #else
  1035. int Swig_name_rxsmatch_value(String *mvalue, String *value) {
  1036. (void) mvalue;
  1037. (void) value;
  1038. return 0;
  1039. }
  1040. #endif
  1041. int Swig_name_match_value(String *mvalue, String *value) {
  1042. #if defined(SWIG_USE_SIMPLE_MATCHOR)
  1043. int match = 0;
  1044. char *cvalue = Char(value);
  1045. char *cmvalue = Char(mvalue);
  1046. char *sep = strchr(cmvalue, '|');
  1047. while (sep && !match) {
  1048. match = strncmp(cvalue, cmvalue, sep - cmvalue) == 0;
  1049. #ifdef SWIG_DEBUG
  1050. Printf(stderr, "match_value: %s %s %d\n", cvalue, cmvalue, match);
  1051. #endif
  1052. cmvalue = sep + 1;
  1053. sep = strchr(cmvalue, '|');
  1054. }
  1055. if (!match) {
  1056. match = strcmp(cvalue, cmvalue) == 0;
  1057. #ifdef SWIG_DEBUG
  1058. Printf(stderr, "match_value: %s %s %d\n", cvalue, cmvalue, match);
  1059. #endif
  1060. }
  1061. return match;
  1062. #else
  1063. return StringEqual(mvalue, value);
  1064. #endif
  1065. }
  1066. int Swig_name_match_nameobj(Hash *rn, Node *n) {
  1067. int match = 1;
  1068. List *matchlist = HashGetAttr(rn, k_matchlist);
  1069. #ifdef SWIG_DEBUG
  1070. Printf(stderr, "Swig_name_match_nameobj: %s\n", Getattr(n, "name"));
  1071. #endif
  1072. if (matchlist) {
  1073. int ilen = Len(matchlist);
  1074. int i;
  1075. for (i = 0; match && (i < ilen); ++i) {
  1076. Node *mi = Getitem(matchlist, i);
  1077. List *lattr = Getattr(mi, k_attrlist);
  1078. String *nval = Swig_get_lattr(n, lattr);
  1079. int notmatch = GetFlag(mi, k_notmatch);
  1080. int rxsmatch = GetFlag(mi, k_rxsmatch);
  1081. #ifdef SWIG_DEBUG
  1082. Printf(stderr, "mi %d %s re %d not %d \n", i, nval, notmatch, rxsmatch);
  1083. if (rxsmatch) {
  1084. Printf(stderr, "rxsmatch %s\n", lattr);
  1085. }
  1086. #endif
  1087. match = 0;
  1088. if (nval) {
  1089. String *kwval = Getattr(mi, k_value);
  1090. match = rxsmatch ? Swig_name_rxsmatch_value(kwval, nval)
  1091. : Swig_name_match_value(kwval, nval);
  1092. #ifdef SWIG_DEBUG
  1093. Printf(stderr, "val %s %s %d %d \n", nval, kwval, match, ilen);
  1094. #endif
  1095. }
  1096. if (notmatch)
  1097. match = !match;
  1098. }
  1099. }
  1100. #ifdef SWIG_DEBUG
  1101. Printf(stderr, "Swig_name_match_nameobj: %d\n", match);
  1102. #endif
  1103. return match;
  1104. }
  1105. /* -----------------------------------------------------------------------------
  1106. * Hash *Swig_name_nameobj_lget()
  1107. *
  1108. * Get a nameobj (rename/namewarn) from the list of filters
  1109. *
  1110. * ----------------------------------------------------------------------------- */
  1111. Hash *Swig_name_nameobj_lget(List *namelist, Node *n, String *prefix, String *name, String *decl) {
  1112. Hash *res = 0;
  1113. if (namelist) {
  1114. int len = Len(namelist);
  1115. int i;
  1116. int match = 0;
  1117. for (i = 0; !match && (i < len); i++) {
  1118. Hash *rn = Getitem(namelist, i);
  1119. String *rdecl = HashGetAttr(rn, k_decl);
  1120. if (rdecl && (!decl || !Equal(rdecl, decl))) {
  1121. continue;
  1122. } else if (Swig_name_match_nameobj(rn, n)) {
  1123. String *tname = HashGetAttr(rn, k_targetname);
  1124. if (tname) {
  1125. String *sfmt = HashGetAttr(rn, k_sourcefmt);
  1126. String *sname = 0;
  1127. int fullname = GetFlag(rn, k_fullname);
  1128. int rxstarget = GetFlag(rn, k_rxstarget);
  1129. if (sfmt) {
  1130. if (fullname && prefix) {
  1131. String *pname = NewStringf("%s::%s", prefix, name);
  1132. sname = NewStringf(sfmt, pname);
  1133. Delete(pname);
  1134. } else {
  1135. sname = NewStringf(sfmt, name);
  1136. }
  1137. } else {
  1138. if (fullname && prefix) {
  1139. sname = NewStringf("%s::%s", prefix, name);
  1140. } else {
  1141. sname = name;
  1142. DohIncref(name);
  1143. }
  1144. }
  1145. match = rxstarget ? Swig_name_rxsmatch_value(tname, sname) : Swig_name_match_value(tname, sname);
  1146. Delete(sname);
  1147. } else {
  1148. match = 1;
  1149. }
  1150. }
  1151. if (match) {
  1152. res = rn;
  1153. break;
  1154. }
  1155. }
  1156. }
  1157. return res;
  1158. }
  1159. /* -----------------------------------------------------------------------------
  1160. * Swig_name_namewarn_add
  1161. *
  1162. * Add a namewarn objects
  1163. *
  1164. * ----------------------------------------------------------------------------- */
  1165. void Swig_name_namewarn_add(String *prefix, String *name, SwigType *decl, Hash *namewrn) {
  1166. const char *namewrn_keys[] = { "rename", "error", "fullname", "sourcefmt", "targetfmt", 0 };
  1167. Swig_name_object_attach_keys(namewrn_keys, namewrn);
  1168. Swig_name_nameobj_add(Swig_name_namewarn_hash(), Swig_name_namewarn_list(), prefix, name, decl, namewrn);
  1169. }
  1170. /* -----------------------------------------------------------------------------
  1171. * Hash *Swig_name_namewarn_get()
  1172. *
  1173. * Return the namewarn object, if there is one.
  1174. *
  1175. * ----------------------------------------------------------------------------- */
  1176. Hash *Swig_name_namewarn_get(Node *n, String *prefix, String *name, SwigType *decl) {
  1177. if (!namewarn_hash && !namewarn_list)
  1178. return 0;
  1179. if (n) {
  1180. /* Return in the obvious cases */
  1181. if (!name || !Swig_need_name_warning(n)) {
  1182. return 0;
  1183. } else {
  1184. String *access = Getattr(n, k_access);
  1185. int is_public = !access || Equal(access, k_public);
  1186. if (!is_public && !Swig_need_protected(n)) {
  1187. return 0;
  1188. }
  1189. }
  1190. }
  1191. if (name) {
  1192. /* Check to see if the name is in the hash */
  1193. Hash *wrn = Swig_name_object_get(Swig_name_namewarn_hash(), prefix, name, decl);
  1194. if (wrn && !Swig_name_match_nameobj(wrn, n))
  1195. wrn = 0;
  1196. if (!wrn) {
  1197. wrn = Swig_name_nameobj_lget(Swig_name_namewarn_list(), n, prefix, name, decl);
  1198. }
  1199. if (wrn && HashGetAttr(wrn, k_error)) {
  1200. if (n) {
  1201. Swig_error(Getfile(n), Getline(n), "%s\n", HashGetAttr(wrn, k_name));
  1202. } else {
  1203. Swig_error(cparse_file, cparse_line, "%s\n", HashGetAttr(wrn, k_name));
  1204. }
  1205. }
  1206. return wrn;
  1207. } else {
  1208. return 0;
  1209. }
  1210. }
  1211. /* -----------------------------------------------------------------------------
  1212. * String *Swig_name_warning()
  1213. *
  1214. * Return the name warning, if there is one.
  1215. *
  1216. * ----------------------------------------------------------------------------- */
  1217. String *Swig_name_warning(Node *n, String *prefix, String *name, SwigType *decl) {
  1218. Hash *wrn = Swig_name_namewarn_get(n, prefix, name, decl);
  1219. return (name && wrn) ? HashGetAttr(wrn, k_name) : 0;
  1220. }
  1221. /* -----------------------------------------------------------------------------
  1222. * Swig_name_rename_add()
  1223. *
  1224. * Manage the rename objects
  1225. *
  1226. * ----------------------------------------------------------------------------- */
  1227. static void single_rename_add(String *prefix, String *name, SwigType *decl, Hash *newname) {
  1228. Swig_name_nameobj_add(Swig_name_rename_hash(), Swig_name_rename_list(), prefix, name, decl, newname);
  1229. }
  1230. /* Add a new rename. Works much like new_feature including default argument handling. */
  1231. void Swig_name_rename_add(String *prefix, String *name, SwigType *decl, Hash *newname, ParmList *declaratorparms) {
  1232. ParmList *declparms = declaratorparms;
  1233. const char *rename_keys[] = { "fullname", "sourcefmt", "targetfmt", "continue", "rxstarget", 0 };
  1234. Swig_name_object_attach_keys(rename_keys, newname);
  1235. /* Add the name */
  1236. single_rename_add(prefix, name, decl, newname);
  1237. /* Add extra names if there are default parameters in the parameter list */
  1238. if (decl) {
  1239. int constqualifier = SwigType_isconst(decl);
  1240. while (declparms) {
  1241. if (ParmList_has_defaultargs(declparms)) {
  1242. /* Create a parameter list for the new rename by copying all
  1243. but the last (defaulted) parameter */
  1244. ParmList *newparms = ParmList_copy_all_except_last_parm(declparms);
  1245. /* Create new declaration - with the last parameter removed */
  1246. SwigType *newdecl = Copy(decl);
  1247. Delete(SwigType_pop_function(newdecl)); /* remove the old parameter list from newdecl */
  1248. SwigType_add_function(newdecl, newparms);
  1249. if (constqualifier)
  1250. SwigType_add_qualifier(newdecl, "const");
  1251. single_rename_add(prefix, name, newdecl, newname);
  1252. declparms = newparms;
  1253. Delete(newdecl);
  1254. } else {
  1255. declparms = 0;
  1256. }
  1257. }
  1258. }
  1259. }
  1260. /* -----------------------------------------------------------------------------
  1261. * String *Swig_name_make()
  1262. *
  1263. * Make a name after applying all the rename/namewarn objects
  1264. *
  1265. * ----------------------------------------------------------------------------- */
  1266. /* Create a name applying rename/namewarn if needed */
  1267. static String *apply_rename(String *newname, int fullname, String *prefix, String *name) {
  1268. String *result = 0;
  1269. if (newname && Len(newname)) {
  1270. if (Strcmp(newname, "$ignore") == 0) {
  1271. result = Copy(newname);
  1272. } else {
  1273. char *cnewname = Char(newname);
  1274. if (cnewname) {
  1275. int destructor = name && (*(Char(name)) == '~');
  1276. String *fmt = newname;
  1277. /* use name as a fmt, but avoid C++ "%" and "%=" operators */
  1278. if (Len(newname) > 1 && strchr(cnewname, '%') && !(strcmp(cnewname, "%=") == 0)) {
  1279. if (fullname && prefix) {
  1280. result = NewStringf(fmt, prefix, name);
  1281. } else {
  1282. result = NewStringf(fmt, name);
  1283. }
  1284. } else {
  1285. result = Copy(newname);
  1286. }
  1287. if (destructor && result && (*(Char(result)) != '~')) {
  1288. Insert(result, 0, "~");
  1289. }
  1290. }
  1291. }
  1292. }
  1293. return result;
  1294. }
  1295. String *Swig_name_make(Node *n, String *prefix, String_or_char *cname, SwigType *decl, String *oldname) {
  1296. String *nname = 0;
  1297. String *result = 0;
  1298. String *name = NewString(cname);
  1299. Hash *wrn = 0;
  1300. String *rdecl = 0;
  1301. String *rname = 0;
  1302. /* very specific hack for template constructors/destructors */
  1303. #ifdef SWIG_DEBUG
  1304. Printf(stderr, "SWIG_name_make: looking for %s %s %s %s\n", prefix, name, decl, oldname);
  1305. #endif
  1306. if (name && n && SwigType_istemplate(name)) {
  1307. String *nodetype = Getattr(n, k_nodetype);
  1308. if (nodetype && (Equal(nodetype, k_constructor) || Equal(nodetype, k_destructor))) {
  1309. String *nprefix = NewStringEmpty();
  1310. String *nlast = NewStringEmpty();
  1311. String *tprefix;
  1312. Swig_scopename_split(name, &nprefix, &nlast);
  1313. tprefix = SwigType_templateprefix(nlast);
  1314. Delete(nlast);
  1315. if (Len(nprefix)) {
  1316. Append(nprefix, "::");
  1317. Append(nprefix, tprefix);
  1318. Delete(tprefix);
  1319. rname = nprefix;
  1320. } else {
  1321. rname = tprefix;
  1322. Delete(nprefix);
  1323. }
  1324. rdecl = Copy(decl);
  1325. Replaceall(rdecl, name, rname);
  1326. #ifdef SWIG_DEBUG
  1327. Printf(stderr, "SWIG_name_make: use new name %s %s : %s %s\n", name, decl, rname, rdecl);
  1328. #endif
  1329. decl = rdecl;
  1330. Delete(name);
  1331. name = rname;
  1332. }
  1333. }
  1334. if (rename_hash || rename_list) {
  1335. Hash *rn = Swig_name_object_get(Swig_name_rename_hash(), prefix, name, decl);
  1336. if (!rn || !Swig_name_match_nameobj(rn, n)) {
  1337. rn = Swig_name_nameobj_lget(Swig_name_rename_list(), n, prefix, name, decl);
  1338. if (rn) {
  1339. String *sfmt = HashGetAttr(rn, k_sourcefmt);
  1340. int fullname = GetFlag(rn, k_fullname);
  1341. if (fullname && prefix) {
  1342. String *sname = NewStringf("%s::%s", prefix, name);
  1343. Delete(name);
  1344. name = sname;
  1345. prefix = 0;
  1346. }
  1347. if (sfmt) {
  1348. String *sname = NewStringf(sfmt, name);
  1349. Delete(name);
  1350. name = sname;
  1351. }
  1352. }
  1353. }
  1354. if (rn) {
  1355. String *newname = HashGetAttr(rn, k_name);
  1356. int fullname = GetFlag(rn, k_fullname);
  1357. result = apply_rename(newname, fullname, prefix, name);
  1358. }
  1359. if (result && !Equal(result, name)) {
  1360. /* operators in C++ allow aliases, we look for them */
  1361. char *cresult = Char(result);
  1362. if (cresult && (strncmp(cresult, "operator ", 9) == 0)) {
  1363. String *nresult = Swig_name_make(n, prefix, result, decl, oldname);
  1364. if (!Equal(nresult, result)) {
  1365. Delete(result);
  1366. result = nresult;
  1367. } else {
  1368. Delete(nresult);
  1369. }
  1370. }
  1371. }
  1372. nname = result ? result : name;
  1373. wrn = Swig_name_namewarn_get(n, prefix, nname, decl);
  1374. if (wrn) {
  1375. String *rename = HashGetAttr(wrn, k_rename);
  1376. if (rename) {
  1377. String *msg = HashGetAttr(wrn, k_name);
  1378. int fullname = GetFlag(wrn, k_fullname);
  1379. if (result)
  1380. Delete(result);
  1381. result = apply_rename(rename, fullname, prefix, name);
  1382. if ((msg) && (Len(msg))) {
  1383. if (!Getmeta(nname, "already_warned")) {
  1384. if (n) {
  1385. SWIG_WARN_NODE_BEGIN(n);
  1386. Swig_warning(0, Getfile(n), Getline(n), "%s\n", msg);
  1387. SWIG_WARN_NODE_END(n);
  1388. } else {
  1389. Swig_warning(0, Getfile(name), Getline(name), "%s\n", msg);
  1390. }
  1391. Setmeta(nname, "already_warned", "1");
  1392. }
  1393. }
  1394. }
  1395. }
  1396. }
  1397. if (!result || !Len(result)) {
  1398. if (result)
  1399. Delete(result);
  1400. if (oldname) {
  1401. result = NewString(oldname);
  1402. } else {
  1403. result = NewString(cname);
  1404. }
  1405. }
  1406. Delete(name);
  1407. #ifdef SWIG_DEBUG
  1408. Printf(stderr, "Swig_name_make: result '%s' '%s'\n", cname, result);
  1409. #endif
  1410. return result;
  1411. }
  1412. /* -----------------------------------------------------------------------------
  1413. * void Swig_name_inherit()
  1414. *
  1415. * Inherit namewarn,rename, and feature objects
  1416. *
  1417. * ----------------------------------------------------------------------------- */
  1418. void Swig_name_inherit(String *base, String *derived) {
  1419. /* Printf(stderr,"base = '%s', derived = '%s'\n", base, derived); */
  1420. Swig_name_object_inherit(Swig_name_rename_hash(), base, derived);
  1421. Swig_name_object_inherit(Swig_name_namewarn_hash(), base, derived);
  1422. Swig_name_object_inherit(Swig_cparse_features(), base, derived);
  1423. }