PageRenderTime 38ms CodeModel.GetById 0ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Source/Modules/lang.cxx

#
C++ | 2114 lines | 1520 code | 245 blank | 349 comment | 431 complexity | 485c5f59523f975a11d4b5a7ab8eefc9 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  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. * lang.cxx
  10. *
  11. * Language base class functions. Default C++ handling is also implemented here.
  12. * ----------------------------------------------------------------------------- */
  13. char cvsroot_lang_cxx[] = "$Id: lang.cxx 12830 2011-10-30 21:51:50Z wsfulton $";
  14. #include "swigmod.h"
  15. #include "cparse.h"
  16. #include <ctype.h>
  17. /* default mode settings */
  18. static int director_mode = 0;
  19. static int director_protected_mode = 1;
  20. static int all_protected_mode = 0;
  21. static int naturalvar_mode = 0;
  22. Language* Language::this_ = 0;
  23. /* Set director_protected_mode */
  24. void Wrapper_director_mode_set(int flag) {
  25. director_mode = flag;
  26. }
  27. void Wrapper_director_protected_mode_set(int flag) {
  28. director_protected_mode = flag;
  29. }
  30. void Wrapper_all_protected_mode_set(int flag) {
  31. all_protected_mode = flag;
  32. }
  33. void Wrapper_naturalvar_mode_set(int flag) {
  34. naturalvar_mode = flag;
  35. }
  36. extern "C" {
  37. int Swig_director_mode() {
  38. return director_mode;
  39. }
  40. int Swig_director_protected_mode() {
  41. return director_protected_mode;
  42. }
  43. int Swig_all_protected_mode() {
  44. return all_protected_mode;
  45. }
  46. void Language_replace_special_variables(String *method, String *tm, Parm *parm) {
  47. Language::instance()->replaceSpecialVariables(method, tm, parm);
  48. }
  49. }
  50. /* Some status variables used during parsing */
  51. static int InClass = 0; /* Parsing C++ or not */
  52. static String *ClassName = 0; /* This is the real name of the current class */
  53. static String *ClassPrefix = 0; /* Class prefix */
  54. static String *NSpace = 0; /* Namespace for the nspace feature */
  55. static String *ClassType = 0; /* Fully qualified type name to use */
  56. static String *DirectorClassName = 0; /* Director name of the current class */
  57. int Abstract = 0;
  58. int ImportMode = 0;
  59. int IsVirtual = 0;
  60. static String *AttributeFunctionGet = 0;
  61. static String *AttributeFunctionSet = 0;
  62. static Node *CurrentClass = 0;
  63. int line_number = 0;
  64. String *input_file = 0;
  65. int SmartPointer = 0;
  66. static Hash *classhash;
  67. extern int GenerateDefault;
  68. extern int ForceExtern;
  69. extern int AddExtern;
  70. /* import modes */
  71. #define IMPORT_MODE 1
  72. #define IMPORT_MODULE 2
  73. /* ----------------------------------------------------------------------
  74. * Dispatcher::emit_one()
  75. *
  76. * Dispatch a single node
  77. * ---------------------------------------------------------------------- */
  78. int Dispatcher::emit_one(Node *n) {
  79. String *wrn;
  80. int ret = SWIG_OK;
  81. char *tag = Char(nodeType(n));
  82. if (!tag) {
  83. /* Printf(stderr,"SWIG: Fatal internal error. Malformed parse tree
  84. node!\n"); */
  85. return SWIG_OK;
  86. }
  87. /* Do not proceed if marked with an error */
  88. if (Getattr(n, "error"))
  89. return SWIG_OK;
  90. /* Look for warnings */
  91. wrn = Getattr(n, "feature:warnfilter");
  92. if (wrn) {
  93. Swig_warnfilter(wrn, 1);
  94. }
  95. /* ============================================================
  96. * C/C++ parsing
  97. * ============================================================ */
  98. if (strcmp(tag, "extern") == 0) {
  99. ret = externDeclaration(n);
  100. } else if (strcmp(tag, "cdecl") == 0) {
  101. ret = cDeclaration(n);
  102. } else if (strcmp(tag, "enum") == 0) {
  103. ret = enumDeclaration(n);
  104. } else if (strcmp(tag, "enumitem") == 0) {
  105. ret = enumvalueDeclaration(n);
  106. } else if (strcmp(tag, "enumforward") == 0) {
  107. ret = enumforwardDeclaration(n);
  108. } else if (strcmp(tag, "class") == 0) {
  109. ret = classDeclaration(n);
  110. } else if (strcmp(tag, "classforward") == 0) {
  111. ret = classforwardDeclaration(n);
  112. } else if (strcmp(tag, "constructor") == 0) {
  113. ret = constructorDeclaration(n);
  114. } else if (strcmp(tag, "destructor") == 0) {
  115. ret = destructorDeclaration(n);
  116. } else if (strcmp(tag, "access") == 0) {
  117. ret = accessDeclaration(n);
  118. } else if (strcmp(tag, "using") == 0) {
  119. ret = usingDeclaration(n);
  120. } else if (strcmp(tag, "namespace") == 0) {
  121. ret = namespaceDeclaration(n);
  122. } else if (strcmp(tag, "template") == 0) {
  123. ret = templateDeclaration(n);
  124. }
  125. /* ===============================================================
  126. * SWIG directives
  127. * =============================================================== */
  128. else if (strcmp(tag, "top") == 0) {
  129. ret = top(n);
  130. } else if (strcmp(tag, "extend") == 0) {
  131. ret = extendDirective(n);
  132. } else if (strcmp(tag, "apply") == 0) {
  133. ret = applyDirective(n);
  134. } else if (strcmp(tag, "clear") == 0) {
  135. ret = clearDirective(n);
  136. } else if (strcmp(tag, "constant") == 0) {
  137. ret = constantDirective(n);
  138. } else if (strcmp(tag, "fragment") == 0) {
  139. ret = fragmentDirective(n);
  140. } else if (strcmp(tag, "import") == 0) {
  141. ret = importDirective(n);
  142. } else if (strcmp(tag, "include") == 0) {
  143. ret = includeDirective(n);
  144. } else if (strcmp(tag, "insert") == 0) {
  145. ret = insertDirective(n);
  146. } else if (strcmp(tag, "module") == 0) {
  147. ret = moduleDirective(n);
  148. } else if (strcmp(tag, "native") == 0) {
  149. ret = nativeDirective(n);
  150. } else if (strcmp(tag, "pragma") == 0) {
  151. ret = pragmaDirective(n);
  152. } else if (strcmp(tag, "typemap") == 0) {
  153. ret = typemapDirective(n);
  154. } else if (strcmp(tag, "typemapcopy") == 0) {
  155. ret = typemapcopyDirective(n);
  156. } else if (strcmp(tag, "typemapitem") == 0) {
  157. ret = typemapitemDirective(n);
  158. } else if (strcmp(tag, "types") == 0) {
  159. ret = typesDirective(n);
  160. } else {
  161. Swig_error(input_file, line_number, "Unrecognized parse tree node type '%s'\n", tag);
  162. ret = SWIG_ERROR;
  163. }
  164. if (wrn) {
  165. Swig_warnfilter(wrn, 0);
  166. }
  167. return ret;
  168. }
  169. /* ----------------------------------------------------------------------
  170. * Dispatcher::emit_children()
  171. *
  172. * Emit all children that match the given type. type = 0 means all types.
  173. * ---------------------------------------------------------------------- */
  174. int Dispatcher::emit_children(Node *n) {
  175. Node *c;
  176. char *eo = Char(Getattr(n, "feature:emitonlychildren"));
  177. for (c = firstChild(n); c; c = nextSibling(c)) {
  178. if (eo) {
  179. const char *tag = Char(nodeType(c));
  180. if (strcmp(tag, "cdecl") == 0) {
  181. if (checkAttribute(c, "storage", "typedef"))
  182. tag = "typedef";
  183. }
  184. if (strstr(eo, tag) == 0) {
  185. continue;
  186. }
  187. }
  188. emit_one(c);
  189. }
  190. return SWIG_OK;
  191. }
  192. /* Stubs for dispatcher class. We don't do anything by default---up to derived class
  193. to fill in traversal code */
  194. int Dispatcher::defaultHandler(Node *) {
  195. return SWIG_OK;
  196. }
  197. int Dispatcher::extendDirective(Node *n) {
  198. return defaultHandler(n);
  199. }
  200. int Dispatcher::applyDirective(Node *n) {
  201. return defaultHandler(n);
  202. }
  203. int Dispatcher::clearDirective(Node *n) {
  204. return defaultHandler(n);
  205. }
  206. int Dispatcher::constantDirective(Node *n) {
  207. return defaultHandler(n);
  208. }
  209. int Dispatcher::fragmentDirective(Node *n) {
  210. return defaultHandler(n);
  211. }
  212. int Dispatcher::importDirective(Node *n) {
  213. return defaultHandler(n);
  214. }
  215. int Dispatcher::includeDirective(Node *n) {
  216. return defaultHandler(n);
  217. }
  218. int Dispatcher::insertDirective(Node *n) {
  219. return defaultHandler(n);
  220. }
  221. int Dispatcher::moduleDirective(Node *n) {
  222. return defaultHandler(n);
  223. }
  224. int Dispatcher::nativeDirective(Node *n) {
  225. return defaultHandler(n);
  226. }
  227. int Dispatcher::pragmaDirective(Node *n) {
  228. return defaultHandler(n);
  229. }
  230. int Dispatcher::typemapDirective(Node *n) {
  231. return defaultHandler(n);
  232. }
  233. int Dispatcher::typemapitemDirective(Node *n) {
  234. return defaultHandler(n);
  235. }
  236. int Dispatcher::typemapcopyDirective(Node *n) {
  237. return defaultHandler(n);
  238. }
  239. int Dispatcher::typesDirective(Node *n) {
  240. return defaultHandler(n);
  241. }
  242. int Dispatcher::cDeclaration(Node *n) {
  243. return defaultHandler(n);
  244. }
  245. int Dispatcher::externDeclaration(Node *n) {
  246. return defaultHandler(n);
  247. }
  248. int Dispatcher::enumDeclaration(Node *n) {
  249. return defaultHandler(n);
  250. }
  251. int Dispatcher::enumvalueDeclaration(Node *n) {
  252. return defaultHandler(n);
  253. }
  254. int Dispatcher::enumforwardDeclaration(Node *n) {
  255. return defaultHandler(n);
  256. }
  257. int Dispatcher::classDeclaration(Node *n) {
  258. return defaultHandler(n);
  259. }
  260. int Dispatcher::templateDeclaration(Node *n) {
  261. return defaultHandler(n);
  262. }
  263. int Dispatcher::classforwardDeclaration(Node *n) {
  264. return defaultHandler(n);
  265. }
  266. int Dispatcher::constructorDeclaration(Node *n) {
  267. return defaultHandler(n);
  268. }
  269. int Dispatcher::destructorDeclaration(Node *n) {
  270. return defaultHandler(n);
  271. }
  272. int Dispatcher::accessDeclaration(Node *n) {
  273. return defaultHandler(n);
  274. }
  275. int Dispatcher::usingDeclaration(Node *n) {
  276. return defaultHandler(n);
  277. }
  278. int Dispatcher::namespaceDeclaration(Node *n) {
  279. return defaultHandler(n);
  280. }
  281. /* Allocators */
  282. Language::Language():
  283. none_comparison(NewString("$arg != 0")),
  284. director_ctor_code(NewString("")),
  285. director_prot_ctor_code(0),
  286. symtabs(NewHash()),
  287. classtypes(NewHash()),
  288. enumtypes(NewHash()),
  289. overloading(0),
  290. multiinput(0),
  291. cplus_runtime(0),
  292. directors(0) {
  293. Hash *symbols = NewHash();
  294. Setattr(symtabs, "", symbols); // create top level/global symbol table scope
  295. argc_template_string = NewString("argc");
  296. argv_template_string = NewString("argv[%d]");
  297. /* Default director constructor code, passed to Swig_ConstructorToFunction */
  298. Printv(director_ctor_code, "if ( $comparison ) { /* subclassed */\n", " $director_new \n", "} else {\n", " $nondirector_new \n", "}\n", NIL);
  299. /*
  300. Default director 'protected' constructor code, disabled by
  301. default. Each language that needs it, has to define it.
  302. */
  303. director_prot_ctor_code = 0;
  304. director_multiple_inheritance = 1;
  305. director_language = 0;
  306. assert(!this_);
  307. this_ = this;
  308. }
  309. Language::~Language() {
  310. Delete(symtabs);
  311. Delete(classtypes);
  312. Delete(enumtypes);
  313. Delete(director_ctor_code);
  314. Delete(none_comparison);
  315. this_ = 0;
  316. }
  317. /* ----------------------------------------------------------------------
  318. emit_one()
  319. ---------------------------------------------------------------------- */
  320. int Language::emit_one(Node *n) {
  321. int ret;
  322. int oldext;
  323. if (!n)
  324. return SWIG_OK;
  325. if (GetFlag(n, "feature:ignore")
  326. && !Getattr(n, "feature:onlychildren"))
  327. return SWIG_OK;
  328. oldext = Extend;
  329. if (Getattr(n, "feature:extend"))
  330. Extend = 1;
  331. line_number = Getline(n);
  332. input_file = Getfile(n);
  333. /*
  334. symtab = Getattr(n,"symtab");
  335. if (symtab) {
  336. symtab = Swig_symbol_setscope(symtab);
  337. }
  338. */
  339. ret = Dispatcher::emit_one(n);
  340. /*
  341. if (symtab) {
  342. Swig_symbol_setscope(symtab);
  343. }
  344. */
  345. Extend = oldext;
  346. return ret;
  347. }
  348. static Parm *nonvoid_parms(Parm *p) {
  349. if (p) {
  350. SwigType *t = Getattr(p, "type");
  351. if (SwigType_type(t) == T_VOID)
  352. return 0;
  353. }
  354. return p;
  355. }
  356. /* -----------------------------------------------------------------------------
  357. * cplus_value_type()
  358. *
  359. * Returns the alternative value type needed in C++ for class value
  360. * types. When swig is not sure about using a plain $ltype value,
  361. * since the class doesn't have a default constructor, or it can't be
  362. * assigned, you will get back 'SwigValueWrapper<type >'.
  363. *
  364. * ----------------------------------------------------------------------------- */
  365. SwigType *cplus_value_type(SwigType *t) {
  366. return SwigType_alttype(t, 0);
  367. }
  368. static Node *first_nontemplate(Node *n) {
  369. while (n) {
  370. if (Strcmp(nodeType(n), "template") != 0)
  371. return n;
  372. n = Getattr(n, "sym:nextSibling");
  373. }
  374. return n;
  375. }
  376. /* --------------------------------------------------------------------------
  377. * swig_pragma()
  378. *
  379. * Handle swig pragma directives.
  380. * -------------------------------------------------------------------------- */
  381. void swig_pragma(char *lang, char *name, char *value) {
  382. if (strcmp(lang, "swig") == 0) {
  383. if ((strcmp(name, "make_default") == 0) || ((strcmp(name, "makedefault") == 0))) {
  384. GenerateDefault = 1;
  385. } else if ((strcmp(name, "no_default") == 0) || ((strcmp(name, "nodefault") == 0))) {
  386. Swig_warning(WARN_DEPRECATED_NODEFAULT, "SWIG", 1, "dangerous, use %%nodefaultctor, %%nodefaultdtor instead.\n");
  387. GenerateDefault = 0;
  388. } else if (strcmp(name, "attributefunction") == 0) {
  389. String *nvalue = NewString(value);
  390. char *s = strchr(Char(nvalue), ':');
  391. if (!s) {
  392. Swig_error(input_file, line_number, "Bad value for attributefunction. Expected \"fmtget:fmtset\".\n");
  393. } else {
  394. *s = 0;
  395. AttributeFunctionGet = NewString(Char(nvalue));
  396. AttributeFunctionSet = NewString(s + 1);
  397. }
  398. Delete(nvalue);
  399. } else if (strcmp(name, "noattributefunction") == 0) {
  400. AttributeFunctionGet = 0;
  401. AttributeFunctionSet = 0;
  402. }
  403. }
  404. }
  405. /* --------------------------------------------------------------------------
  406. * use_naturalvar_mode()
  407. * -------------------------------------------------------------------------- */
  408. int use_naturalvar_mode(Node *n) {
  409. if (Getattr(n, "unnamed"))
  410. return 0;
  411. int nvar = naturalvar_mode || GetFlag(n, "feature:naturalvar");
  412. if (!nvar) {
  413. /* look for feature in the class */
  414. SwigType *ty = Getattr(n, "type");
  415. SwigType *fullty = SwigType_typedef_resolve_all(ty);
  416. if (SwigType_isclass(fullty)) {
  417. Node *m = Copy(n);
  418. SwigType *tys = SwigType_strip_qualifiers(fullty);
  419. Swig_features_get(Swig_cparse_features(), 0, tys, 0, m);
  420. nvar = GetFlag(m, "feature:naturalvar");
  421. Delete(tys);
  422. Delete(m);
  423. }
  424. Delete(fullty);
  425. }
  426. return nvar ? CWRAP_NATURAL_VAR : 0;
  427. }
  428. /* ----------------------------------------------------------------------
  429. * Language::top() - Top of parsing tree
  430. * ---------------------------------------------------------------------- */
  431. int Language::top(Node *n) {
  432. Node *mod = Getattr(n, "module");
  433. if (mod) {
  434. Node *options = Getattr(mod, "options");
  435. if (options) {
  436. if (Getattr(options, "naturalvar")) {
  437. naturalvar_mode = 1;
  438. }
  439. if (Getattr(options, "nonaturalvar")) {
  440. naturalvar_mode = 0;
  441. }
  442. }
  443. }
  444. classhash = Getattr(n, "classes");
  445. return emit_children(n);
  446. }
  447. /* ----------------------------------------------------------------------
  448. * Language::extendDirective()
  449. * ---------------------------------------------------------------------- */
  450. int Language::extendDirective(Node *n) {
  451. int oldam = Extend;
  452. AccessMode oldmode = cplus_mode;
  453. Extend = CWRAP_EXTEND;
  454. cplus_mode = PUBLIC;
  455. emit_children(n);
  456. Extend = oldam;
  457. cplus_mode = oldmode;
  458. return SWIG_OK;
  459. }
  460. /* ----------------------------------------------------------------------
  461. * Language::applyDirective()
  462. * ---------------------------------------------------------------------- */
  463. int Language::applyDirective(Node *n) {
  464. Parm *pattern = Getattr(n, "pattern");
  465. Node *c = firstChild(n);
  466. while (c) {
  467. Parm *apattern = Getattr(c, "pattern");
  468. if (ParmList_len(pattern) != ParmList_len(apattern)) {
  469. Swig_error(input_file, line_number, "Can't apply (%s) to (%s). Number of arguments don't match.\n", ParmList_str(pattern), ParmList_str(apattern));
  470. } else {
  471. if (!Swig_typemap_apply(pattern, apattern)) {
  472. Swig_warning(WARN_TYPEMAP_APPLY_UNDEF, input_file, line_number, "Can't apply (%s). No typemaps are defined.\n", ParmList_str(pattern));
  473. }
  474. }
  475. c = nextSibling(c);
  476. }
  477. return SWIG_OK;
  478. }
  479. /* ----------------------------------------------------------------------
  480. * Language::clearDirective()
  481. * ---------------------------------------------------------------------- */
  482. int Language::clearDirective(Node *n) {
  483. Node *p;
  484. for (p = firstChild(n); p; p = nextSibling(p)) {
  485. ParmList *pattern = Getattr(p, "pattern");
  486. Swig_typemap_clear_apply(pattern);
  487. }
  488. return SWIG_OK;
  489. }
  490. /* ----------------------------------------------------------------------
  491. * Language::constantDirective()
  492. * ---------------------------------------------------------------------- */
  493. int Language::constantDirective(Node *n) {
  494. if (CurrentClass && (cplus_mode != PUBLIC))
  495. return SWIG_NOWRAP;
  496. if (!GetFlag(n, "feature:allowexcept")) {
  497. UnsetFlag(n, "feature:except");
  498. }
  499. if (Getattr(n, "feature:exceptvar")) {
  500. Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
  501. }
  502. if (!ImportMode) {
  503. Swig_require("constantDirective", n, "name", "?value", NIL);
  504. String *name = Getattr(n, "name");
  505. String *value = Getattr(n, "value");
  506. if (!value) {
  507. value = Copy(name);
  508. } else {
  509. /* if (checkAttribute(n,"type","char")) {
  510. value = NewString(value);
  511. } else {
  512. value = NewStringf("%(escape)s", value);
  513. }
  514. */
  515. Setattr(n, "rawvalue", value);
  516. value = NewStringf("%(escape)s", value);
  517. if (!Len(value))
  518. Append(value, "\\0");
  519. /* Printf(stdout,"'%s' = '%s'\n", name, value); */
  520. }
  521. Setattr(n, "value", value);
  522. this->constantWrapper(n);
  523. Swig_restore(n);
  524. return SWIG_OK;
  525. }
  526. return SWIG_NOWRAP;
  527. }
  528. /* ----------------------------------------------------------------------
  529. * Language::fragmentDirective()
  530. * ---------------------------------------------------------------------- */
  531. int Language::fragmentDirective(Node *n) {
  532. Swig_fragment_register(n);
  533. return SWIG_OK;
  534. }
  535. /* ----------------------------------------------------------------------
  536. * Language::importDirective()
  537. * ---------------------------------------------------------------------- */
  538. int Language::importDirective(Node *n) {
  539. int oldim = ImportMode;
  540. ImportMode = IMPORT_MODE;
  541. emit_children(n);
  542. ImportMode = oldim;
  543. return SWIG_OK;
  544. }
  545. /* ----------------------------------------------------------------------
  546. * Language::includeDirective()
  547. * ---------------------------------------------------------------------- */
  548. int Language::includeDirective(Node *n) {
  549. emit_children(n);
  550. return SWIG_OK;
  551. }
  552. /* ----------------------------------------------------------------------
  553. * Language::insertDirective()
  554. * ---------------------------------------------------------------------- */
  555. int Language::insertDirective(Node *n) {
  556. /* %insert directive */
  557. if ((!ImportMode) || Getattr(n, "generated")) {
  558. String *code = Getattr(n, "code");
  559. String *section = Getattr(n, "section");
  560. File *f = 0;
  561. if (!section) { /* %{ ... %} */
  562. f = Swig_filebyname("header");
  563. } else {
  564. f = Swig_filebyname(section);
  565. }
  566. if (f) {
  567. Printf(f, "%s\n", code);
  568. } else {
  569. Swig_error(input_file, line_number, "Unknown target '%s' for %%insert directive.\n", section);
  570. }
  571. return SWIG_OK;
  572. } else {
  573. return SWIG_NOWRAP;
  574. }
  575. }
  576. /* ----------------------------------------------------------------------
  577. * Language::moduleDirective()
  578. * ---------------------------------------------------------------------- */
  579. int Language::moduleDirective(Node *n) {
  580. (void) n;
  581. /* %module directive */
  582. return SWIG_OK;
  583. }
  584. /* ----------------------------------------------------------------------
  585. * Language::nativeDirective()
  586. * ---------------------------------------------------------------------- */
  587. int Language::nativeDirective(Node *n) {
  588. if (!ImportMode) {
  589. return nativeWrapper(n);
  590. } else {
  591. return SWIG_NOWRAP;
  592. }
  593. }
  594. /* ----------------------------------------------------------------------
  595. * Language::pragmaDirective()
  596. * ---------------------------------------------------------------------- */
  597. int Language::pragmaDirective(Node *n) {
  598. /* %pragma directive */
  599. if (!ImportMode) {
  600. String *lan = Getattr(n, "lang");
  601. String *name = Getattr(n, "name");
  602. String *value = Getattr(n, "value");
  603. swig_pragma(Char(lan), Char(name), Char(value));
  604. /* pragma(Char(lan),Char(name),Char(value)); */
  605. return SWIG_OK;
  606. }
  607. return SWIG_OK;
  608. }
  609. /* ----------------------------------------------------------------------
  610. * Language::typemapDirective()
  611. * ---------------------------------------------------------------------- */
  612. int Language::typemapDirective(Node *n) {
  613. /* %typemap directive */
  614. String *method = Getattr(n, "method");
  615. String *code = Getattr(n, "code");
  616. Parm *kwargs = Getattr(n, "kwargs");
  617. Node *items = firstChild(n);
  618. static int namewarn = 0;
  619. if (code && (Strstr(code, "$source") || (Strstr(code, "$target")))) {
  620. Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n), "Deprecated typemap feature ($source/$target).\n");
  621. if (!namewarn) {
  622. Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n), "The use of $source and $target in a typemap declaration is deprecated.\n\
  623. For typemaps related to argument input (in,ignore,default,arginit,check), replace\n\
  624. $source by $input and $target by $1. For typemaps related to return values (out,\n\
  625. argout,ret,except), replace $source by $1 and $target by $result. See the file\n\
  626. Doc/Manual/Typemaps.html for complete details.\n");
  627. namewarn = 1;
  628. }
  629. }
  630. if (Strcmp(method, "except") == 0) {
  631. Swig_warning(WARN_DEPRECATED_EXCEPT_TM, Getfile(n), Getline(n), "%%typemap(except) is deprecated. Use the %%exception directive.\n");
  632. }
  633. if (Strcmp(method, "in") == 0) {
  634. Hash *k;
  635. k = kwargs;
  636. while (k) {
  637. if (checkAttribute(k, "name", "numinputs")) {
  638. if (!multiinput && (GetInt(k, "value") > 1)) {
  639. Swig_error(Getfile(n), Getline(n), "Multiple-input typemaps (numinputs > 1) not supported by this target language module.\n");
  640. return SWIG_ERROR;
  641. }
  642. break;
  643. }
  644. k = nextSibling(k);
  645. }
  646. if (!k) {
  647. k = NewHash();
  648. Setattr(k, "name", "numinputs");
  649. Setattr(k, "value", "1");
  650. set_nextSibling(k, kwargs);
  651. Setattr(n, "kwargs", k);
  652. kwargs = k;
  653. }
  654. }
  655. if (Strcmp(method, "ignore") == 0) {
  656. Swig_warning(WARN_DEPRECATED_IGNORE_TM, Getfile(n), Getline(n), "%%typemap(ignore) has been replaced by %%typemap(in,numinputs=0).\n");
  657. Clear(method);
  658. Append(method, "in");
  659. Hash *k = NewHash();
  660. Setattr(k, "name", "numinputs");
  661. Setattr(k, "value", "0");
  662. set_nextSibling(k, kwargs);
  663. Setattr(n, "kwargs", k);
  664. kwargs = k;
  665. }
  666. /* Replace $descriptor() macros */
  667. if (code) {
  668. Setfile(code, Getfile(n));
  669. Setline(code, Getline(n));
  670. Swig_cparse_replace_descriptor(code);
  671. }
  672. while (items) {
  673. Parm *pattern = Getattr(items, "pattern");
  674. Parm *parms = Getattr(items, "parms");
  675. if (code) {
  676. Swig_typemap_register(method, pattern, code, parms, kwargs);
  677. } else {
  678. Swig_typemap_clear(method, pattern);
  679. }
  680. items = nextSibling(items);
  681. }
  682. return SWIG_OK;
  683. }
  684. /* ----------------------------------------------------------------------
  685. * Language::typemapcopyDirective()
  686. * ---------------------------------------------------------------------- */
  687. int Language::typemapcopyDirective(Node *n) {
  688. String *method = Getattr(n, "method");
  689. Parm *pattern = Getattr(n, "pattern");
  690. Node *items = firstChild(n);
  691. int nsrc = 0;
  692. nsrc = ParmList_len(pattern);
  693. while (items) {
  694. ParmList *npattern = Getattr(items, "pattern");
  695. if (nsrc != ParmList_len(npattern)) {
  696. Swig_error(input_file, line_number, "Can't copy typemap. Number of types differ.\n");
  697. } else {
  698. if (Swig_typemap_copy(method, pattern, npattern) < 0) {
  699. Swig_error(input_file, line_number, "Can't copy typemap (%s) %s = %s\n", method, ParmList_str(pattern), ParmList_str(npattern));
  700. }
  701. }
  702. items = nextSibling(items);
  703. }
  704. return SWIG_OK;
  705. }
  706. /* ----------------------------------------------------------------------
  707. * Language::typesDirective()
  708. * ---------------------------------------------------------------------- */
  709. int Language::typesDirective(Node *n) {
  710. Parm *parms = Getattr(n, "parms");
  711. String *convcode = Getattr(n, "convcode"); /* optional user supplied conversion code for custom casting */
  712. while (parms) {
  713. SwigType *t = Getattr(parms, "type");
  714. String *v = Getattr(parms, "value");
  715. if (!v) {
  716. SwigType_remember(t);
  717. } else {
  718. if (SwigType_issimple(t)) {
  719. SwigType_inherit(t, v, 0, convcode);
  720. }
  721. }
  722. parms = nextSibling(parms);
  723. }
  724. return SWIG_OK;
  725. }
  726. /* ----------------------------------------------------------------------
  727. * Language::cDeclaration()
  728. * ---------------------------------------------------------------------- */
  729. int Language::cDeclaration(Node *n) {
  730. String *name = Getattr(n, "name");
  731. String *symname = Getattr(n, "sym:name");
  732. SwigType *type = Getattr(n, "type");
  733. SwigType *decl = Getattr(n, "decl");
  734. String *storage = Getattr(n, "storage");
  735. Node *over;
  736. File *f_header = 0;
  737. SwigType *ty, *fullty;
  738. /* discards nodes following the access control rules */
  739. if (cplus_mode != PUBLIC || !is_public(n)) {
  740. /* except for friends, they are not affected by access control */
  741. int isfriend = storage && (Cmp(storage, "friend") == 0);
  742. if (!isfriend) {
  743. /* Check what the director needs. If the method is pure virtual, it is always needed.
  744. * Also wrap non-virtual protected members if asked for (allprotected mode). */
  745. if (!(directorsEnabled() && ((is_member_director(CurrentClass, n) && need_nonpublic_member(n)) || is_non_virtual_protected_access(n)))) {
  746. return SWIG_NOWRAP;
  747. }
  748. // Prevent wrapping protected overloaded director methods more than once -
  749. // This bit of code is only needed due to the cDeclaration call in classHandler()
  750. String *wrapname = NewStringf("nonpublic_%s%s", symname, Getattr(n, "sym:overname"));
  751. if (Getattr(CurrentClass, wrapname)) {
  752. Delete(wrapname);
  753. return SWIG_NOWRAP;
  754. }
  755. SetFlag(CurrentClass, wrapname);
  756. Delete(wrapname);
  757. }
  758. }
  759. if (Cmp(storage, "typedef") == 0) {
  760. Swig_save("cDeclaration", n, "type", NIL);
  761. SwigType *t = Copy(type);
  762. if (t) {
  763. SwigType_push(t, decl);
  764. Setattr(n, "type", t);
  765. typedefHandler(n);
  766. }
  767. Swig_restore(n);
  768. return SWIG_OK;
  769. }
  770. /* If in import mode, we proceed no further */
  771. if (ImportMode)
  772. return SWIG_NOWRAP;
  773. /* If we're in extend mode and there is code, replace the $descriptor macros */
  774. if (Extend) {
  775. String *code = Getattr(n, "code");
  776. if (code) {
  777. Setfile(code, Getfile(n));
  778. Setline(code, Getline(n));
  779. Swig_cparse_replace_descriptor(code);
  780. }
  781. }
  782. /* Overloaded symbol check */
  783. over = Swig_symbol_isoverloaded(n);
  784. if (!overloading) {
  785. if (over)
  786. over = first_nontemplate(over);
  787. if (over && (over != n)) {
  788. Swig_warning(WARN_LANG_OVERLOAD_DECL, input_file, line_number, "Overloaded declaration ignored. %s\n", Swig_name_decl(n));
  789. Swig_warning(WARN_LANG_OVERLOAD_DECL, Getfile(over), Getline(over), "Previous declaration is %s\n", Swig_name_decl(over));
  790. return SWIG_NOWRAP;
  791. }
  792. }
  793. if (symname && !validIdentifier(symname)) {
  794. Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap '%s' unless renamed to a valid identifier.\n", symname);
  795. return SWIG_NOWRAP;
  796. }
  797. ty = NewString(type);
  798. SwigType_push(ty, decl);
  799. fullty = SwigType_typedef_resolve_all(ty);
  800. if (SwigType_isfunction(fullty)) {
  801. if (!SwigType_isfunction(ty)) {
  802. Delete(ty);
  803. ty = fullty;
  804. fullty = 0;
  805. ParmList *parms = SwigType_function_parms(ty, n);
  806. Setattr(n, "parms", parms);
  807. }
  808. /* Transform the node into a 'function' node and emit */
  809. if (!CurrentClass) {
  810. f_header = Swig_filebyname("header");
  811. if (AddExtern) {
  812. if (f_header) {
  813. if ((Cmp(storage, "extern") == 0) || (ForceExtern && !storage)) {
  814. /* we don't need the 'extern' part in the C/C++ declaration,
  815. and it produces some problems when namespace and SUN
  816. Studio is used.
  817. Printf(f_header,"extern %s", SwigType_str(ty,name));
  818. In fact generating extern declarations is quite error prone and is
  819. no longer the default. Getting it right seems impossible with namespaces
  820. and default arguments and when a method is declared with the various Windows
  821. calling conventions - SWIG doesn't understand Windows (non standard) calling
  822. conventions in the first place, so can't regenerate them.
  823. */
  824. String *str = SwigType_str(ty, name);
  825. Printf(f_header, "%s", str);
  826. Delete(str);
  827. {
  828. DOH *t = Getattr(n, "throws");
  829. if (t) {
  830. Printf(f_header, " throw(");
  831. while (t) {
  832. Printf(f_header, "%s", Getattr(t, "type"));
  833. t = nextSibling(t);
  834. if (t)
  835. Printf(f_header, ",");
  836. }
  837. Printf(f_header, ")");
  838. }
  839. }
  840. Printf(f_header, ";\n");
  841. } else if (Cmp(storage, "externc") == 0) {
  842. /* here 'extern "C"' is needed */
  843. String *str = SwigType_str(ty, name);
  844. Printf(f_header, "extern \"C\" %s;\n", str);
  845. Delete(str);
  846. }
  847. }
  848. }
  849. }
  850. /* This needs to check qualifiers */
  851. if (SwigType_isqualifier(ty)) {
  852. SwigType *qual = SwigType_pop(ty);
  853. Setattr(n, "qualifier", qual);
  854. Delete(qual);
  855. }
  856. Delete(SwigType_pop_function(ty));
  857. DohIncref(type);
  858. Setattr(n, "type", ty);
  859. if (GetFlag(n, "feature:onlychildren") && !GetFlag(n, "feature:ignore")) {
  860. // Found an unignored templated method that has a an empty template instantiation (%template())
  861. // Ignore it unless it has been %rename'd
  862. if (Strncmp(symname, "__dummy_", 8) == 0) {
  863. SetFlag(n, "feature:ignore");
  864. Swig_warning(WARN_LANG_TEMPLATE_METHOD_IGNORE, input_file, line_number,
  865. "%%template() contains no name. Template method ignored: %s\n", Swig_name_decl(n));
  866. }
  867. }
  868. if (!GetFlag(n, "feature:ignore"))
  869. functionHandler(n);
  870. Setattr(n, "type", type);
  871. Delete(ty);
  872. Delete(type);
  873. return SWIG_OK;
  874. } else {
  875. /* Some kind of variable declaration */
  876. String *declaration = Copy(decl);
  877. Delattr(n, "decl");
  878. if (Getattr(n, "nested"))
  879. SetFlag(n, "feature:immutable");
  880. if (!CurrentClass) {
  881. if ((Cmp(storage, "extern") == 0) || ForceExtern) {
  882. f_header = Swig_filebyname("header");
  883. if (AddExtern) {
  884. if (f_header) {
  885. String *str = SwigType_str(ty, name);
  886. Printf(f_header, "extern %s;\n", str);
  887. Delete(str);
  888. }
  889. }
  890. }
  891. }
  892. if (!SwigType_ismutable(ty)) {
  893. SetFlag(n, "feature:immutable");
  894. }
  895. /* If an array and elements are const, then read-only */
  896. if (SwigType_isarray(ty)) {
  897. SwigType *tya = SwigType_array_type(ty);
  898. if (SwigType_isconst(tya)) {
  899. SetFlag(n, "feature:immutable");
  900. }
  901. Delete(tya);
  902. }
  903. DohIncref(type);
  904. Setattr(n, "type", ty);
  905. variableHandler(n);
  906. Setattr(n, "type", type);
  907. Setattr(n, "decl", declaration);
  908. Delete(ty);
  909. Delete(type);
  910. Delete(fullty);
  911. return SWIG_OK;
  912. }
  913. }
  914. /* ----------------------------------------------------------------------
  915. * Language::functionHandler()
  916. * ---------------------------------------------------------------------- */
  917. int Language::functionHandler(Node *n) {
  918. String *storage = Getattr(n, "storage");
  919. int isfriend = CurrentClass && Cmp(storage, "friend") == 0;
  920. int isstatic = CurrentClass && Cmp(storage, "static") == 0 && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"));
  921. Parm *p = Getattr(n, "parms");
  922. if (GetFlag(n, "feature:del")) {
  923. /* the method acts like a delete operator, ie, we need to disown the parameter */
  924. if (CurrentClass && !isstatic && !isfriend) {
  925. SetFlag(n, "feature:self:disown");
  926. } else {
  927. if (p)
  928. SetFlag(p, "wrap:disown");
  929. }
  930. }
  931. if (!CurrentClass) {
  932. globalfunctionHandler(n);
  933. } else {
  934. if (isstatic) {
  935. staticmemberfunctionHandler(n);
  936. } else if (isfriend) {
  937. int oldInClass = InClass;
  938. InClass = 0;
  939. globalfunctionHandler(n);
  940. InClass = oldInClass;
  941. } else {
  942. Node *explicit_n = 0;
  943. if (directorsEnabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) {
  944. bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0));
  945. if (virtual_but_not_pure_virtual) {
  946. // Add additional wrapper which makes an explicit call to the virtual method (ie not a virtual call)
  947. explicit_n = Copy(n);
  948. String *new_symname = Copy(Getattr(n, "sym:name"));
  949. String *suffix = Getattr(parentNode(n), "sym:name");
  950. Printv(new_symname, "SwigExplicit", suffix, NIL);
  951. Setattr(explicit_n, "sym:name", new_symname);
  952. Delattr(explicit_n, "storage");
  953. Delattr(explicit_n, "override");
  954. Delattr(explicit_n, "hides");
  955. SetFlag(explicit_n, "explicitcall");
  956. Setattr(n, "explicitcallnode", explicit_n);
  957. }
  958. }
  959. memberfunctionHandler(n);
  960. if (explicit_n) {
  961. memberfunctionHandler(explicit_n);
  962. Delattr(explicit_n, "explicitcall");
  963. Delete(explicit_n);
  964. }
  965. }
  966. }
  967. return SWIG_OK;
  968. }
  969. /* ----------------------------------------------------------------------
  970. * Language::globalfunctionHandler()
  971. * ---------------------------------------------------------------------- */
  972. int Language::globalfunctionHandler(Node *n) {
  973. Swig_require("globalfunctionHandler", n, "name", "sym:name", "type", "?parms", NIL);
  974. String *name = Getattr(n, "name");
  975. String *symname = Getattr(n, "sym:name");
  976. SwigType *type = Getattr(n, "type");
  977. ParmList *parms = Getattr(n, "parms");
  978. /* Check for callback mode */
  979. String *cb = GetFlagAttr(n, "feature:callback");
  980. if (cb) {
  981. String *cbname = Getattr(n, "feature:callback:name");
  982. if (!cbname) {
  983. cbname = NewStringf(cb, symname);
  984. Setattr(n, "feature:callback:name", cbname);
  985. }
  986. callbackfunctionHandler(n);
  987. if (Cmp(cbname, symname) == 0) {
  988. Delete(cbname);
  989. Swig_restore(n);
  990. return SWIG_NOWRAP;
  991. }
  992. Delete(cbname);
  993. }
  994. Setattr(n, "parms", nonvoid_parms(parms));
  995. String *call = Swig_cfunction_call(name, parms);
  996. String *cres = Swig_cresult(type, Swig_cresult_name(), call);
  997. Setattr(n, "wrap:action", cres);
  998. Delete(cres);
  999. Delete(call);
  1000. functionWrapper(n);
  1001. Swig_restore(n);
  1002. return SWIG_OK;
  1003. }
  1004. /* ----------------------------------------------------------------------
  1005. * Language::callbackfunctionHandler()
  1006. * ---------------------------------------------------------------------- */
  1007. int Language::callbackfunctionHandler(Node *n) {
  1008. Swig_require("callbackfunctionHandler", n, "name", "*sym:name", "*type", "?value", NIL);
  1009. String *symname = Getattr(n, "sym:name");
  1010. String *type = Getattr(n, "type");
  1011. String *name = Getattr(n, "name");
  1012. String *parms = Getattr(n, "parms");
  1013. String *cb = GetFlagAttr(n, "feature:callback");
  1014. String *cbname = Getattr(n, "feature:callback:name");
  1015. String *calltype = NewStringf("(%s (*)(%s))(%s)", SwigType_str(type, 0), ParmList_str(parms), SwigType_namestr(name));
  1016. SwigType *cbty = Copy(type);
  1017. SwigType_add_function(cbty, parms);
  1018. SwigType_add_pointer(cbty);
  1019. if (!cbname) {
  1020. cbname = NewStringf(cb, symname);
  1021. Setattr(n, "feature:callback:name", cbname);
  1022. }
  1023. Setattr(n, "sym:name", cbname);
  1024. Setattr(n, "type", cbty);
  1025. Setattr(n, "value", calltype);
  1026. Node *ns = symbolLookup(cbname);
  1027. if (!ns)
  1028. constantWrapper(n);
  1029. Delete(cbname);
  1030. Delete(cbty);
  1031. Swig_restore(n);
  1032. return SWIG_OK;
  1033. }
  1034. /* ----------------------------------------------------------------------
  1035. * Language::memberfunctionHandler()
  1036. * ---------------------------------------------------------------------- */
  1037. int Language::memberfunctionHandler(Node *n) {
  1038. Swig_require("memberfunctionHandler", n, "*name", "*sym:name", "*type", "?parms", "?value", NIL);
  1039. String *storage = Getattr(n, "storage");
  1040. String *name = Getattr(n, "name");
  1041. String *symname = Getattr(n, "sym:name");
  1042. SwigType *type = Getattr(n, "type");
  1043. String *value = Getattr(n, "value");
  1044. ParmList *parms = Getattr(n, "parms");
  1045. String *cb = GetFlagAttr(n, "feature:callback");
  1046. if (Cmp(storage, "virtual") == 0) {
  1047. if (Cmp(value, "0") == 0) {
  1048. IsVirtual = PURE_VIRTUAL;
  1049. } else {
  1050. IsVirtual = PLAIN_VIRTUAL;
  1051. }
  1052. } else {
  1053. IsVirtual = 0;
  1054. }
  1055. if (cb) {
  1056. Node *cbn = NewHash();
  1057. String *cbname = Getattr(n, "feature:callback:name");
  1058. if (!cbname) {
  1059. cbname = NewStringf(cb, symname);
  1060. }
  1061. SwigType *cbty = Copy(type);
  1062. SwigType_add_function(cbty, parms);
  1063. SwigType_add_memberpointer(cbty, ClassName);
  1064. String *cbvalue = NewStringf("&%s::%s", ClassName, name);
  1065. Setattr(cbn, "sym:name", cbname);
  1066. Setattr(cbn, "type", cbty);
  1067. Setattr(cbn, "value", cbvalue);
  1068. Setattr(cbn, "name", name);
  1069. Setfile(cbn, Getfile(n));
  1070. Setline(cbn, Getline(n));
  1071. memberconstantHandler(cbn);
  1072. Setattr(n, "feature:callback:name", Swig_name_member(NSpace, ClassPrefix, cbname));
  1073. Delete(cb);
  1074. Delete(cbn);
  1075. Delete(cbvalue);
  1076. Delete(cbty);
  1077. Delete(cbname);
  1078. if (Cmp(cbname, symname) == 0) {
  1079. Swig_restore(n);
  1080. return SWIG_NOWRAP;
  1081. }
  1082. }
  1083. String *fname = Swig_name_member(NSpace, ClassPrefix, symname);
  1084. if (Extend && SmartPointer) {
  1085. if (!Getattr(n, "classname")) {
  1086. Setattr(n, "classname", Getattr(CurrentClass, "allocate:smartpointerbase"));
  1087. }
  1088. }
  1089. // Set up the type for the cast to this class for use when wrapping const director (virtual) methods.
  1090. // Note: protected director methods or when allprotected mode turned on.
  1091. String *director_type = 0;
  1092. if (!is_public(n) && (is_member_director(CurrentClass, n) || GetFlag(n, "explicitcall") || is_non_virtual_protected_access(n))) {
  1093. director_type = Copy(DirectorClassName);
  1094. String *qualifier = Getattr(n, "qualifier");
  1095. if (qualifier)
  1096. SwigType_push(director_type, qualifier);
  1097. SwigType_add_pointer(director_type);
  1098. }
  1099. int DirectorExtraCall = 0;
  1100. if (directorsEnabled() && is_member_director(CurrentClass, n) && !SmartPointer)
  1101. if (extraDirectorProtectedCPPMethodsRequired())
  1102. DirectorExtraCall = CWRAP_DIRECTOR_TWO_CALLS;
  1103. if (GetFlag(n, "explicitcall"))
  1104. DirectorExtraCall = CWRAP_DIRECTOR_ONE_CALL;
  1105. Swig_MethodToFunction(n, NSpace, ClassType, Getattr(n, "template") ? SmartPointer : Extend | SmartPointer | DirectorExtraCall, director_type,
  1106. is_member_director(CurrentClass, n));
  1107. Setattr(n, "sym:name", fname);
  1108. functionWrapper(n);
  1109. Delete(director_type);
  1110. Delete(fname);
  1111. Swig_restore(n);
  1112. return SWIG_OK;
  1113. }
  1114. /* ----------------------------------------------------------------------
  1115. * Language::staticmemberfunctionHandler()
  1116. * ---------------------------------------------------------------------- */
  1117. int Language::staticmemberfunctionHandler(Node *n) {
  1118. Swig_require("staticmemberfunctionHandler", n, "*name", "*sym:name", "*type", NIL);
  1119. Swig_save("staticmemberfunctionHandler", n, "storage", NIL);
  1120. String *name = Getattr(n, "name");
  1121. String *symname = Getattr(n, "sym:name");
  1122. SwigType *type = Getattr(n, "type");
  1123. ParmList *parms = Getattr(n, "parms");
  1124. String *cb = GetFlagAttr(n, "feature:callback");
  1125. String *cname, *mrename;
  1126. if (!Extend) {
  1127. Node *sb = Getattr(n, "cplus:staticbase");
  1128. String *sname = Getattr(sb, "name");
  1129. if (is_non_virtual_protected_access(n))
  1130. cname = NewStringf("%s::%s", DirectorClassName, name);
  1131. else
  1132. cname = NewStringf("%s::%s", sname, name);
  1133. } else {
  1134. String *mname = Swig_name_mangle(ClassName);
  1135. cname = Swig_name_member(NSpace, mname, name);
  1136. Delete(mname);
  1137. }
  1138. mrename = Swig_name_member(NSpace, ClassPrefix, symname);
  1139. if (Extend) {
  1140. String *code = Getattr(n, "code");
  1141. String *defaultargs = Getattr(n, "defaultargs");
  1142. String *mangled = Swig_name_mangle(mrename);
  1143. Delete(mrename);
  1144. mrename = mangled;
  1145. if (Getattr(n, "sym:overloaded") && code) {
  1146. Append(cname, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
  1147. }
  1148. if (!defaultargs && code) {
  1149. /* Hmmm. An added static member. We have to create a little wrapper for this */
  1150. Swig_add_extension_code(n, cname, parms, type, code, CPlusPlus, 0);
  1151. }
  1152. }
  1153. Setattr(n, "name", cname);
  1154. Setattr(n, "sym:name", mrename);
  1155. if (cb) {
  1156. String *cbname = NewStringf(cb, symname);
  1157. Setattr(n, "feature:callback:name", Swig_name_member(NSpace, ClassPrefix, cbname));
  1158. Setattr(n, "feature:callback:staticname", name);
  1159. }
  1160. Delattr(n, "storage");
  1161. globalfunctionHandler(n);
  1162. Delete(cname);
  1163. Delete(mrename);
  1164. Swig_restore(n);
  1165. return SWIG_OK;
  1166. }
  1167. /* ----------------------------------------------------------------------
  1168. * Language::variableHandler()
  1169. * ---------------------------------------------------------------------- */
  1170. int Language::variableHandler(Node *n) {
  1171. /* If not a smart-pointer access or added method. We clear
  1172. feature:except. There is no way C++ or C would throw
  1173. an exception merely for accessing a member data.
  1174. Caveat: Some compilers seem to route attribute access through
  1175. methods which can generate exceptions. The feature:allowexcept
  1176. allows this. Also, the feature:exceptvar can be used to match
  1177. only variables.
  1178. */
  1179. if (!(Extend | SmartPointer)) {
  1180. if (!GetFlag(n, "feature:allowexcept")) {
  1181. UnsetFlag(n, "feature:except");
  1182. }
  1183. if (Getattr(n, "feature:exceptvar")) {
  1184. Setattr(n, "feature:except", Getattr(n, "feature:exceptvar"));
  1185. }
  1186. }
  1187. if (!CurrentClass) {
  1188. globalvariableHandler(n);
  1189. } else {
  1190. String *storage = Getattr(n, "storage");
  1191. Swig_save("variableHandler", n, "feature:immutable", NIL);
  1192. if (SmartPointer) {
  1193. /* If a smart-pointer and it's a constant access, we have to set immutable */
  1194. if (!Getattr(CurrentClass, "allocate:smartpointermutable")) {
  1195. SetFlag(n, "feature:immutable");
  1196. }
  1197. }
  1198. if ((Cmp(storage, "static") == 0) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"))) {
  1199. staticmembervariableHandler(n);
  1200. } else {
  1201. membervariableHandler(n);
  1202. }
  1203. Swig_restore(n);
  1204. }
  1205. return SWIG_OK;
  1206. }
  1207. /* ----------------------------------------------------------------------
  1208. * Language::globalvariableHandler()
  1209. * ---------------------------------------------------------------------- */
  1210. int Language::globalvariableHandler(Node *n) {
  1211. variableWrapper(n);
  1212. return SWIG_OK;
  1213. }
  1214. /* ----------------------------------------------------------------------
  1215. * Language::membervariableHandler()
  1216. * ---------------------------------------------------------------------- */
  1217. int Language::membervariableHandler(Node *n) {
  1218. Swig_require("membervariableHandler", n, "*name", "*sym:name", "*type", NIL);
  1219. Swig_save("membervariableHandler", n, "parms", NIL);
  1220. String *name = Getattr(n, "name");
  1221. String *symname = Getattr(n, "sym:name");
  1222. SwigType *type = Getattr(n, "type");
  1223. if (!AttributeFunctionGet) {
  1224. String *mname = Swig_name_member(0, ClassPrefix, symname);
  1225. String *mrename_get = Swig_name_get(NSpace, mname);
  1226. String *mrename_set = Swig_name_set(NSpace, mname);
  1227. Delete(mname);
  1228. /* Create a function to set the value of the variable */
  1229. int assignable = is_assignable(n);
  1230. if (SmartPointer) {
  1231. if (!Getattr(CurrentClass, "allocate:smartpointermutable")) {
  1232. assignable = 0;
  1233. }
  1234. }
  1235. if (assignable) {
  1236. int make_set_wrapper = 1;
  1237. String *tm = 0;
  1238. String *target = 0;
  1239. if (!Extend) {
  1240. if (SmartPointer) {
  1241. if (checkAttribute(n, "storage", "static")) {
  1242. Node *sn = Getattr(n, "cplus:staticbase");
  1243. String *base = Getattr(sn, "name");
  1244. target = NewStringf("%s::%s", base, name);
  1245. } else {
  1246. String *pname = Swig_cparm_name(0, 0);
  1247. target = NewStringf("(*%s)->%s", pname, name);
  1248. Delete(pname);
  1249. }
  1250. } else {
  1251. String *pname = is_non_virtual_protected_access(n) ? NewString("darg") : Swig_cparm_name(0, 0);
  1252. target = NewStringf("%s->%s", pname, name);
  1253. Delete(pname);
  1254. }
  1255. tm = Swig_typemap_lookup("memberin", n, target, 0);
  1256. }
  1257. int flags = Extend | SmartPointer | use_naturalvar_mode(n);
  1258. if (is_non_virtual_protected_access(n))
  1259. flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
  1260. Swig_MembersetToFunction(n, ClassType, flags);
  1261. Setattr(n, "memberset", "1");
  1262. if (!Extend) {
  1263. /* Check for a member in typemap here */
  1264. if (!tm) {
  1265. if (SwigType_isarray(type)) {
  1266. Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
  1267. make_set_wrapper = 0;
  1268. }
  1269. } else {
  1270. String *pname0 = Swig_cparm_name(0, 0);
  1271. String *pname1 = Swig_cparm_name(0, 1);
  1272. Replace(tm, "$source", pname1, DOH_REPLACE_ANY);
  1273. Replace(tm, "$target", target, DOH_REPLACE_ANY);
  1274. Replace(tm, "$input", pname1, DOH_REPLACE_ANY);
  1275. Replace(tm, "$self", pname0, DOH_REPLACE_ANY);
  1276. Setattr(n, "wrap:action", tm);
  1277. Delete(tm);
  1278. Delete(pname0);
  1279. Delete(pname1);
  1280. }
  1281. Delete(target);
  1282. }
  1283. if (make_set_wrapper) {
  1284. Setattr(n, "sym:name", mrename_set);
  1285. functionWrapper(n);
  1286. } else {
  1287. SetFlag(n, "feature:immutable");
  1288. }
  1289. /* Restore parameters */
  1290. Setattr(n, "type", type);
  1291. Setattr(n, "name", name);
  1292. Setattr(n, "sym:name", symname);
  1293. /* Delete all attached typemaps and typemap attributes */
  1294. Iterator ki;
  1295. for (ki = First(n); ki.key; ki = Next(ki)) {
  1296. if (Strncmp(ki.key, "tmap:", 5) == 0)
  1297. Delattr(n, ki.key);
  1298. }
  1299. }
  1300. /* Emit get function */
  1301. {
  1302. int flags = Extend | SmartPointer | use_naturalvar_mode(n);
  1303. if (is_non_virtual_protected_access(n))
  1304. flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
  1305. Swig_MembergetToFunction(n, ClassType, flags);
  1306. Setattr(n, "sym:name", mrename_get);
  1307. Setattr(n, "memberget", "1");
  1308. functionWrapper(n);
  1309. }
  1310. Delete(mrename_get);
  1311. Delete(mrename_set);
  1312. } else {
  1313. /* This code is used to support the attributefunction directive
  1314. where member variables are converted automagically to
  1315. accessor functions */
  1316. #if 0
  1317. Parm *p;
  1318. String *gname;
  1319. SwigType *vty;
  1320. p = NewParm(type, 0, n);
  1321. gname = NewStringf(AttributeFunctionGet, symname);
  1322. if (!Extend) {
  1323. ActionFunc = Copy(Swig_cmemberget_call(name, type));
  1324. cpp_member_func(Char(gname), Char(gname), type, 0);
  1325. Delete(ActionFunc);
  1326. } else {
  1327. String *cname = Swig_name_get(NSpace, name);
  1328. cpp_member_func(Char(cname), Char(gname), type, 0);
  1329. Delete(cname);
  1330. }
  1331. Delete(gname);
  1332. if (!GetFlag(n, "feature:immutable")) {
  1333. gname = NewStringf(AttributeFunctionSet, symname);
  1334. vty = NewString("void");
  1335. if (!Extend) {
  1336. ActionFunc = Copy(Swig_cmemberset_call(name, type));
  1337. cpp_member_func(Char(gname), Char(gname), vty, p);
  1338. Delete(ActionFunc);
  1339. } else {
  1340. String *cname = Swig_name_set(NSpace, name);
  1341. cpp_member_func(Char(cname), Char(gname), vty, p);
  1342. Delete(cname);
  1343. }
  1344. Delete(gname);
  1345. }
  1346. ActionFunc = 0;
  1347. #endif
  1348. }
  1349. Swig_restore(n);
  1350. return SWIG_OK;
  1351. }
  1352. /* ----------------------------------------------------------------------
  1353. * Language::staticmembervariableHandler()
  1354. * ---------------------------------------------------------------------- */
  1355. int Language::staticmembervariableHandler(Node *n) {
  1356. Swig_require("staticmembervariableHandler", n, "*name", "*sym:name", "*type", "?value", NIL);
  1357. String *value = Getattr(n, "value");
  1358. String *classname = !SmartPointer ? (is_non_virtual_protected_access(n) ? DirectorClassName : ClassName) : Getattr(CurrentClass, "allocate:smartpointerbase");
  1359. if (!value || !Getattr(n, "hasconsttype")) {
  1360. String *name = Getattr(n, "name");
  1361. String *symname = Getattr(n, "sym:name");
  1362. String *cname, *mrename;
  1363. /* Create the variable name */
  1364. mrename = Swig_name_member(0, ClassPrefix, symname);
  1365. cname = NewStringf("%s::%s", classname, name);
  1366. Setattr(n, "sym:name", mrename);
  1367. Setattr(n, "name", cname);
  1368. /* Wrap as an ordinary global variable */
  1369. variableWrapper(n);
  1370. Delete(mrename);
  1371. Delete(cname);
  1372. } else {
  1373. /* This is a C++ static member declaration with an initializer and it's const.
  1374. Certain C++ compilers optimize this out so that there is no linkage to a
  1375. memory address. Example:
  1376. class Foo {
  1377. public:
  1378. static const int x = 3;
  1379. };
  1380. Some discussion of this in section 9.4 of the C++ draft standard.
  1381. Also, we have to manage the case:
  1382. class Foo {
  1383. public:
  1384. %extend {
  1385. static const int x = 3;
  1386. }
  1387. };
  1388. in which there's no actual Foo::x variable to refer to. In this case,
  1389. the best we can do is to wrap the given value verbatim.
  1390. */
  1391. String *name = Getattr(n, "name");
  1392. String *cname = NewStringf("%s::%s", classname, name);
  1393. if (Extend) {
  1394. /* the variable is a synthesized one.
  1395. There's nothing we can do; we just keep the given value */
  1396. } else {
  1397. /* we refer to the value as Foo::x */
  1398. String *value = SwigType_namestr(cname);
  1399. Setattr(n, "value", value);
  1400. }
  1401. SwigType *t1 = SwigType_typedef_resolve_all(Getattr(n, "type"));
  1402. SwigType *t2 = SwigType_strip_qualifiers(t1);
  1403. Setattr(n, "type", t2);
  1404. Delete(t1);
  1405. Delete(t2);
  1406. SetFlag(n, "wrappedasconstant");
  1407. memberconstantHandler(n);
  1408. Delete(cname);
  1409. }
  1410. Swig_restore(n);
  1411. return SWIG_OK;
  1412. }
  1413. /* ----------------------------------------------------------------------
  1414. * Language::externDeclaration()
  1415. * ---------------------------------------------------------------------- */
  1416. int Language::externDeclaration(Node *n) {
  1417. return emit_children(n);
  1418. }
  1419. /* ----------------------------------------------------------------------
  1420. * Language::enumDeclaration()
  1421. * ---------------------------------------------------------------------- */
  1422. int Language::enumDeclaration(Node *n) {
  1423. String *oldNSpace = NSpace;
  1424. NSpace = Getattr(n, "sym:nspace");
  1425. if (!ImportMode) {
  1426. emit_children(n);
  1427. }
  1428. NSpace = oldNSpace;
  1429. return SWIG_OK;
  1430. }
  1431. /* ----------------------------------------------------------------------
  1432. * Language::enumvalueDeclaration()
  1433. * ---------------------------------------------------------------------- */
  1434. int Language

Large files files are truncated, but you can click here to view the full file