PageRenderTime 64ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/rel-1.3.34/Source/Swig/naming.c

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