PageRenderTime 59ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

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

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