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

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

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