PageRenderTime 63ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/talby-perl5-improvements/Source/Swig/naming.c

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