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

/Source/CParse/parser.y

https://github.com/sunaku/swig-ruby-ffi
Happy | 6160 lines | 5664 code | 496 blank | 0 comment | 0 complexity | 5047041a5413e359e0c7cf3902b63bb0 MD5 | raw file
Possible License(s): 0BSD, GPL-2.0, LGPL-2.1

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

  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. * parser.y
  6. *
  7. * YACC parser for SWIG. The grammar is a somewhat broken subset of C/C++.
  8. * This file is a bit of a mess and probably needs to be rewritten at
  9. * some point. Beware.
  10. * ----------------------------------------------------------------------------- */
  11. %{
  12. #define yylex yylex
  13. char cvsroot_parser_y[] = "$Id$";
  14. #include "swig.h"
  15. #include "cparse.h"
  16. #include "preprocessor.h"
  17. #include <ctype.h>
  18. /* We do this for portability */
  19. #undef alloca
  20. #define alloca malloc
  21. /* -----------------------------------------------------------------------------
  22. * Externals
  23. * ----------------------------------------------------------------------------- */
  24. int yyparse();
  25. /* NEW Variables */
  26. static Node *top = 0; /* Top of the generated parse tree */
  27. static int unnamed = 0; /* Unnamed datatype counter */
  28. static Hash *extendhash = 0; /* Hash table of added methods */
  29. static Hash *classes = 0; /* Hash table of classes */
  30. static Symtab *prev_symtab = 0;
  31. static Node *current_class = 0;
  32. String *ModuleName = 0;
  33. static Node *module_node = 0;
  34. static String *Classprefix = 0;
  35. static String *Namespaceprefix = 0;
  36. static int inclass = 0;
  37. static int nested_template = 0; /* template class/function definition within a class */
  38. static char *last_cpptype = 0;
  39. static int inherit_list = 0;
  40. static Parm *template_parameters = 0;
  41. static int extendmode = 0;
  42. static int compact_default_args = 0;
  43. static int template_reduce = 0;
  44. static int cparse_externc = 0;
  45. static int max_class_levels = 0;
  46. static int class_level = 0;
  47. static Node **class_decl = NULL;
  48. /* -----------------------------------------------------------------------------
  49. * Assist Functions
  50. * ----------------------------------------------------------------------------- */
  51. /* Called by the parser (yyparse) when an error is found.*/
  52. static void yyerror (const char *e) {
  53. (void)e;
  54. }
  55. static Node *new_node(const_String_or_char_ptr tag) {
  56. Node *n = NewHash();
  57. set_nodeType(n,tag);
  58. Setfile(n,cparse_file);
  59. Setline(n,cparse_line);
  60. return n;
  61. }
  62. /* Copies a node. Does not copy tree links or symbol table data (except for
  63. sym:name) */
  64. static Node *copy_node(Node *n) {
  65. Node *nn;
  66. Iterator k;
  67. nn = NewHash();
  68. Setfile(nn,Getfile(n));
  69. Setline(nn,Getline(n));
  70. for (k = First(n); k.key; k = Next(k)) {
  71. String *ci;
  72. String *key = k.key;
  73. char *ckey = Char(key);
  74. if ((strcmp(ckey,"nextSibling") == 0) ||
  75. (strcmp(ckey,"previousSibling") == 0) ||
  76. (strcmp(ckey,"parentNode") == 0) ||
  77. (strcmp(ckey,"lastChild") == 0)) {
  78. continue;
  79. }
  80. if (Strncmp(key,"csym:",5) == 0) continue;
  81. /* We do copy sym:name. For templates */
  82. if ((strcmp(ckey,"sym:name") == 0) ||
  83. (strcmp(ckey,"sym:weak") == 0) ||
  84. (strcmp(ckey,"sym:typename") == 0)) {
  85. String *ci = Copy(k.item);
  86. Setattr(nn,key, ci);
  87. Delete(ci);
  88. continue;
  89. }
  90. if (strcmp(ckey,"sym:symtab") == 0) {
  91. Setattr(nn,"sym:needs_symtab", "1");
  92. }
  93. /* We don't copy any other symbol table attributes */
  94. if (strncmp(ckey,"sym:",4) == 0) {
  95. continue;
  96. }
  97. /* If children. We copy them recursively using this function */
  98. if (strcmp(ckey,"firstChild") == 0) {
  99. /* Copy children */
  100. Node *cn = k.item;
  101. while (cn) {
  102. Node *copy = copy_node(cn);
  103. appendChild(nn,copy);
  104. Delete(copy);
  105. cn = nextSibling(cn);
  106. }
  107. continue;
  108. }
  109. /* We don't copy the symbol table. But we drop an attribute
  110. requires_symtab so that functions know it needs to be built */
  111. if (strcmp(ckey,"symtab") == 0) {
  112. /* Node defined a symbol table. */
  113. Setattr(nn,"requires_symtab","1");
  114. continue;
  115. }
  116. /* Can't copy nodes */
  117. if (strcmp(ckey,"node") == 0) {
  118. continue;
  119. }
  120. if ((strcmp(ckey,"parms") == 0) || (strcmp(ckey,"pattern") == 0) || (strcmp(ckey,"throws") == 0)
  121. || (strcmp(ckey,"kwargs") == 0)) {
  122. ParmList *pl = CopyParmList(k.item);
  123. Setattr(nn,key,pl);
  124. Delete(pl);
  125. continue;
  126. }
  127. /* Looks okay. Just copy the data using Copy */
  128. ci = Copy(k.item);
  129. Setattr(nn, key, ci);
  130. Delete(ci);
  131. }
  132. return nn;
  133. }
  134. /* -----------------------------------------------------------------------------
  135. * Variables
  136. * ----------------------------------------------------------------------------- */
  137. static char *typemap_lang = 0; /* Current language setting */
  138. static int cplus_mode = 0;
  139. static String *class_rename = 0;
  140. /* C++ modes */
  141. #define CPLUS_PUBLIC 1
  142. #define CPLUS_PRIVATE 2
  143. #define CPLUS_PROTECTED 3
  144. /* include types */
  145. static int import_mode = 0;
  146. void SWIG_typemap_lang(const char *tm_lang) {
  147. typemap_lang = Swig_copy_string(tm_lang);
  148. }
  149. void SWIG_cparse_set_compact_default_args(int defargs) {
  150. compact_default_args = defargs;
  151. }
  152. int SWIG_cparse_template_reduce(int treduce) {
  153. template_reduce = treduce;
  154. return treduce;
  155. }
  156. /* -----------------------------------------------------------------------------
  157. * Assist functions
  158. * ----------------------------------------------------------------------------- */
  159. static int promote_type(int t) {
  160. if (t <= T_UCHAR || t == T_CHAR) return T_INT;
  161. return t;
  162. }
  163. /* Perform type-promotion for binary operators */
  164. static int promote(int t1, int t2) {
  165. t1 = promote_type(t1);
  166. t2 = promote_type(t2);
  167. return t1 > t2 ? t1 : t2;
  168. }
  169. static String *yyrename = 0;
  170. /* Forward renaming operator */
  171. static String *resolve_node_scope(String *cname);
  172. Hash *Swig_cparse_features(void) {
  173. static Hash *features_hash = 0;
  174. if (!features_hash) features_hash = NewHash();
  175. return features_hash;
  176. }
  177. static String *feature_identifier_fix(String *s) {
  178. if (SwigType_istemplate(s)) {
  179. String *tp, *ts, *ta, *tq;
  180. tp = SwigType_templateprefix(s);
  181. ts = SwigType_templatesuffix(s);
  182. ta = SwigType_templateargs(s);
  183. tq = Swig_symbol_type_qualify(ta,0);
  184. Append(tp,tq);
  185. Append(tp,ts);
  186. Delete(ts);
  187. Delete(ta);
  188. Delete(tq);
  189. return tp;
  190. } else {
  191. return NewString(s);
  192. }
  193. }
  194. /* Generate the symbol table name for an object */
  195. /* This is a bit of a mess. Need to clean up */
  196. static String *add_oldname = 0;
  197. static String *make_name(Node *n, String *name,SwigType *decl) {
  198. int destructor = name && (*(Char(name)) == '~');
  199. if (yyrename) {
  200. String *s = NewString(yyrename);
  201. Delete(yyrename);
  202. yyrename = 0;
  203. if (destructor && (*(Char(s)) != '~')) {
  204. Insert(s,0,"~");
  205. }
  206. return s;
  207. }
  208. if (!name) return 0;
  209. return Swig_name_make(n,Namespaceprefix,name,decl,add_oldname);
  210. }
  211. /* Generate an unnamed identifier */
  212. static String *make_unnamed() {
  213. unnamed++;
  214. return NewStringf("$unnamed%d$",unnamed);
  215. }
  216. /* Return if the node is a friend declaration */
  217. static int is_friend(Node *n) {
  218. return Cmp(Getattr(n,"storage"),"friend") == 0;
  219. }
  220. static int is_operator(String *name) {
  221. return Strncmp(name,"operator ", 9) == 0;
  222. }
  223. /* Add declaration list to symbol table */
  224. static int add_only_one = 0;
  225. static void add_symbols(Node *n) {
  226. String *decl;
  227. String *wrn = 0;
  228. if (nested_template) {
  229. if (!(n && Equal(nodeType(n), "template"))) {
  230. return;
  231. }
  232. /* continue if template function, but not template class, declared within a class */
  233. }
  234. if (inclass && n) {
  235. cparse_normalize_void(n);
  236. }
  237. while (n) {
  238. String *symname = 0;
  239. /* for friends, we need to pop the scope once */
  240. String *old_prefix = 0;
  241. Symtab *old_scope = 0;
  242. int isfriend = inclass && is_friend(n);
  243. int iscdecl = Cmp(nodeType(n),"cdecl") == 0;
  244. int only_csymbol = 0;
  245. if (extendmode) {
  246. Setattr(n,"isextension","1");
  247. }
  248. if (inclass) {
  249. String *name = Getattr(n, "name");
  250. if (isfriend) {
  251. /* for friends, we need to add the scopename if needed */
  252. String *prefix = name ? Swig_scopename_prefix(name) : 0;
  253. old_prefix = Namespaceprefix;
  254. old_scope = Swig_symbol_popscope();
  255. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  256. if (!prefix) {
  257. if (name && !is_operator(name) && Namespaceprefix) {
  258. String *nname = NewStringf("%s::%s", Namespaceprefix, name);
  259. Setattr(n,"name",nname);
  260. Delete(nname);
  261. }
  262. } else {
  263. Symtab *st = Swig_symbol_getscope(prefix);
  264. String *ns = st ? Getattr(st,"name") : prefix;
  265. String *base = Swig_scopename_last(name);
  266. String *nname = NewStringf("%s::%s", ns, base);
  267. Setattr(n,"name",nname);
  268. Delete(nname);
  269. Delete(base);
  270. Delete(prefix);
  271. }
  272. Namespaceprefix = 0;
  273. } else {
  274. /* for member functions, we need to remove the redundant
  275. class scope if provided, as in
  276. struct Foo {
  277. int Foo::method(int a);
  278. };
  279. */
  280. String *prefix = name ? Swig_scopename_prefix(name) : 0;
  281. if (prefix) {
  282. if (Classprefix && (Equal(prefix,Classprefix))) {
  283. String *base = Swig_scopename_last(name);
  284. Setattr(n,"name",base);
  285. Delete(base);
  286. }
  287. Delete(prefix);
  288. }
  289. /*
  290. if (!Getattr(n,"parentNode") && class_level) set_parentNode(n,class_decl[class_level - 1]);
  291. */
  292. Setattr(n,"ismember","1");
  293. }
  294. }
  295. if (!isfriend && inclass) {
  296. if ((cplus_mode != CPLUS_PUBLIC)) {
  297. only_csymbol = 1;
  298. if (cplus_mode == CPLUS_PROTECTED) {
  299. Setattr(n,"access", "protected");
  300. only_csymbol = !Swig_need_protected(n);
  301. } else {
  302. Setattr(n,"access", "private");
  303. /* private are needed only when they are pure virtuals - why? */
  304. if ((Cmp(Getattr(n,"storage"),"virtual") == 0) && (Cmp(Getattr(n,"value"),"0") == 0)) {
  305. only_csymbol = 0;
  306. }
  307. }
  308. } else {
  309. Setattr(n,"access", "public");
  310. }
  311. }
  312. if (Getattr(n,"sym:name")) {
  313. n = nextSibling(n);
  314. continue;
  315. }
  316. decl = Getattr(n,"decl");
  317. if (!SwigType_isfunction(decl)) {
  318. String *name = Getattr(n,"name");
  319. String *makename = Getattr(n,"parser:makename");
  320. if (iscdecl) {
  321. String *storage = Getattr(n, "storage");
  322. if (Cmp(storage,"typedef") == 0) {
  323. Setattr(n,"kind","typedef");
  324. } else {
  325. SwigType *type = Getattr(n,"type");
  326. String *value = Getattr(n,"value");
  327. Setattr(n,"kind","variable");
  328. if (value && Len(value)) {
  329. Setattr(n,"hasvalue","1");
  330. }
  331. if (type) {
  332. SwigType *ty;
  333. SwigType *tmp = 0;
  334. if (decl) {
  335. ty = tmp = Copy(type);
  336. SwigType_push(ty,decl);
  337. } else {
  338. ty = type;
  339. }
  340. if (!SwigType_ismutable(ty)) {
  341. SetFlag(n,"hasconsttype");
  342. SetFlag(n,"feature:immutable");
  343. }
  344. if (tmp) Delete(tmp);
  345. }
  346. if (!type) {
  347. Printf(stderr,"notype name %s\n", name);
  348. }
  349. }
  350. }
  351. Swig_features_get(Swig_cparse_features(), Namespaceprefix, name, 0, n);
  352. if (makename) {
  353. symname = make_name(n, makename,0);
  354. Delattr(n,"parser:makename"); /* temporary information, don't leave it hanging around */
  355. } else {
  356. makename = name;
  357. symname = make_name(n, makename,0);
  358. }
  359. if (!symname) {
  360. symname = Copy(Getattr(n,"unnamed"));
  361. }
  362. if (symname) {
  363. wrn = Swig_name_warning(n, Namespaceprefix, symname,0);
  364. }
  365. } else {
  366. String *name = Getattr(n,"name");
  367. SwigType *fdecl = Copy(decl);
  368. SwigType *fun = SwigType_pop_function(fdecl);
  369. if (iscdecl) {
  370. Setattr(n,"kind","function");
  371. }
  372. Swig_features_get(Swig_cparse_features(),Namespaceprefix,name,fun,n);
  373. symname = make_name(n, name,fun);
  374. wrn = Swig_name_warning(n, Namespaceprefix,symname,fun);
  375. Delete(fdecl);
  376. Delete(fun);
  377. }
  378. if (!symname) {
  379. n = nextSibling(n);
  380. continue;
  381. }
  382. if (only_csymbol || GetFlag(n,"feature:ignore")) {
  383. /* Only add to C symbol table and continue */
  384. Swig_symbol_add(0, n);
  385. } else if (strncmp(Char(symname),"$ignore",7) == 0) {
  386. char *c = Char(symname)+7;
  387. SetFlag(n,"feature:ignore");
  388. if (strlen(c)) {
  389. SWIG_WARN_NODE_BEGIN(n);
  390. Swig_warning(0,Getfile(n), Getline(n), "%s\n",c+1);
  391. SWIG_WARN_NODE_END(n);
  392. }
  393. Swig_symbol_add(0, n);
  394. } else {
  395. Node *c;
  396. if ((wrn) && (Len(wrn))) {
  397. String *metaname = symname;
  398. if (!Getmeta(metaname,"already_warned")) {
  399. SWIG_WARN_NODE_BEGIN(n);
  400. Swig_warning(0,Getfile(n),Getline(n), "%s\n", wrn);
  401. SWIG_WARN_NODE_END(n);
  402. Setmeta(metaname,"already_warned","1");
  403. }
  404. }
  405. c = Swig_symbol_add(symname,n);
  406. if (c != n) {
  407. /* symbol conflict attempting to add in the new symbol */
  408. if (Getattr(n,"sym:weak")) {
  409. Setattr(n,"sym:name",symname);
  410. } else {
  411. String *e = NewStringEmpty();
  412. String *en = NewStringEmpty();
  413. String *ec = NewStringEmpty();
  414. int redefined = Swig_need_redefined_warn(n,c,inclass);
  415. if (redefined) {
  416. Printf(en,"Identifier '%s' redefined (ignored)",symname);
  417. Printf(ec,"previous definition of '%s'",symname);
  418. } else {
  419. Printf(en,"Redundant redeclaration of '%s'",symname);
  420. Printf(ec,"previous declaration of '%s'",symname);
  421. }
  422. if (Cmp(symname,Getattr(n,"name"))) {
  423. Printf(en," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name")));
  424. }
  425. Printf(en,",");
  426. if (Cmp(symname,Getattr(c,"name"))) {
  427. Printf(ec," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name")));
  428. }
  429. Printf(ec,".");
  430. SWIG_WARN_NODE_BEGIN(n);
  431. if (redefined) {
  432. Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
  433. Swig_warning(WARN_PARSE_REDEFINED,Getfile(c),Getline(c),"%s\n",ec);
  434. } else if (!is_friend(n) && !is_friend(c)) {
  435. Swig_warning(WARN_PARSE_REDUNDANT,Getfile(n),Getline(n),"%s\n",en);
  436. Swig_warning(WARN_PARSE_REDUNDANT,Getfile(c),Getline(c),"%s\n",ec);
  437. }
  438. SWIG_WARN_NODE_END(n);
  439. Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(n),Getline(n),en,
  440. Getfile(c),Getline(c),ec);
  441. Setattr(n,"error",e);
  442. Delete(e);
  443. Delete(en);
  444. Delete(ec);
  445. }
  446. }
  447. }
  448. /* restore the class scope if needed */
  449. if (isfriend) {
  450. Swig_symbol_setscope(old_scope);
  451. if (old_prefix) {
  452. Delete(Namespaceprefix);
  453. Namespaceprefix = old_prefix;
  454. }
  455. }
  456. Delete(symname);
  457. if (add_only_one) return;
  458. n = nextSibling(n);
  459. }
  460. }
  461. /* add symbols a parse tree node copy */
  462. static void add_symbols_copy(Node *n) {
  463. String *name;
  464. int emode = 0;
  465. while (n) {
  466. char *cnodeType = Char(nodeType(n));
  467. if (strcmp(cnodeType,"access") == 0) {
  468. String *kind = Getattr(n,"kind");
  469. if (Strcmp(kind,"public") == 0) {
  470. cplus_mode = CPLUS_PUBLIC;
  471. } else if (Strcmp(kind,"private") == 0) {
  472. cplus_mode = CPLUS_PRIVATE;
  473. } else if (Strcmp(kind,"protected") == 0) {
  474. cplus_mode = CPLUS_PROTECTED;
  475. }
  476. n = nextSibling(n);
  477. continue;
  478. }
  479. add_oldname = Getattr(n,"sym:name");
  480. if ((add_oldname) || (Getattr(n,"sym:needs_symtab"))) {
  481. int old_inclass = -1;
  482. Node *old_current_class = 0;
  483. if (add_oldname) {
  484. DohIncref(add_oldname);
  485. /* Disable this, it prevents %rename to work with templates */
  486. /* If already renamed, we used that name */
  487. /*
  488. if (Strcmp(add_oldname, Getattr(n,"name")) != 0) {
  489. Delete(yyrename);
  490. yyrename = Copy(add_oldname);
  491. }
  492. */
  493. }
  494. Delattr(n,"sym:needs_symtab");
  495. Delattr(n,"sym:name");
  496. add_only_one = 1;
  497. add_symbols(n);
  498. if (Getattr(n,"partialargs")) {
  499. Swig_symbol_cadd(Getattr(n,"partialargs"),n);
  500. }
  501. add_only_one = 0;
  502. name = Getattr(n,"name");
  503. if (Getattr(n,"requires_symtab")) {
  504. Swig_symbol_newscope();
  505. Swig_symbol_setscopename(name);
  506. Delete(Namespaceprefix);
  507. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  508. }
  509. if (strcmp(cnodeType,"class") == 0) {
  510. old_inclass = inclass;
  511. inclass = 1;
  512. old_current_class = current_class;
  513. current_class = n;
  514. if (Strcmp(Getattr(n,"kind"),"class") == 0) {
  515. cplus_mode = CPLUS_PRIVATE;
  516. } else {
  517. cplus_mode = CPLUS_PUBLIC;
  518. }
  519. }
  520. if (strcmp(cnodeType,"extend") == 0) {
  521. emode = cplus_mode;
  522. cplus_mode = CPLUS_PUBLIC;
  523. }
  524. add_symbols_copy(firstChild(n));
  525. if (strcmp(cnodeType,"extend") == 0) {
  526. cplus_mode = emode;
  527. }
  528. if (Getattr(n,"requires_symtab")) {
  529. Setattr(n,"symtab", Swig_symbol_popscope());
  530. Delattr(n,"requires_symtab");
  531. Delete(Namespaceprefix);
  532. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  533. }
  534. if (add_oldname) {
  535. Delete(add_oldname);
  536. add_oldname = 0;
  537. }
  538. if (strcmp(cnodeType,"class") == 0) {
  539. inclass = old_inclass;
  540. current_class = old_current_class;
  541. }
  542. } else {
  543. if (strcmp(cnodeType,"extend") == 0) {
  544. emode = cplus_mode;
  545. cplus_mode = CPLUS_PUBLIC;
  546. }
  547. add_symbols_copy(firstChild(n));
  548. if (strcmp(cnodeType,"extend") == 0) {
  549. cplus_mode = emode;
  550. }
  551. }
  552. n = nextSibling(n);
  553. }
  554. }
  555. /* Extension merge. This function is used to handle the %extend directive
  556. when it appears before a class definition. To handle this, the %extend
  557. actually needs to take precedence. Therefore, we will selectively nuke symbols
  558. from the current symbol table, replacing them with the added methods */
  559. static void merge_extensions(Node *cls, Node *am) {
  560. Node *n;
  561. Node *csym;
  562. n = firstChild(am);
  563. while (n) {
  564. String *symname;
  565. if (Strcmp(nodeType(n),"constructor") == 0) {
  566. symname = Getattr(n,"sym:name");
  567. if (symname) {
  568. if (Strcmp(symname,Getattr(n,"name")) == 0) {
  569. /* If the name and the sym:name of a constructor are the same,
  570. then it hasn't been renamed. However---the name of the class
  571. itself might have been renamed so we need to do a consistency
  572. check here */
  573. if (Getattr(cls,"sym:name")) {
  574. Setattr(n,"sym:name", Getattr(cls,"sym:name"));
  575. }
  576. }
  577. }
  578. }
  579. symname = Getattr(n,"sym:name");
  580. DohIncref(symname);
  581. if ((symname) && (!Getattr(n,"error"))) {
  582. /* Remove node from its symbol table */
  583. Swig_symbol_remove(n);
  584. csym = Swig_symbol_add(symname,n);
  585. if (csym != n) {
  586. /* Conflict with previous definition. Nuke previous definition */
  587. String *e = NewStringEmpty();
  588. String *en = NewStringEmpty();
  589. String *ec = NewStringEmpty();
  590. Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname);
  591. Printf(en,"%%extend definition of '%s'.",symname);
  592. SWIG_WARN_NODE_BEGIN(n);
  593. Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec);
  594. Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
  595. SWIG_WARN_NODE_END(n);
  596. Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec,
  597. Getfile(n),Getline(n),en);
  598. Setattr(csym,"error",e);
  599. Delete(e);
  600. Delete(en);
  601. Delete(ec);
  602. Swig_symbol_remove(csym); /* Remove class definition */
  603. Swig_symbol_add(symname,n); /* Insert extend definition */
  604. }
  605. }
  606. n = nextSibling(n);
  607. }
  608. }
  609. static void append_previous_extension(Node *cls, Node *am) {
  610. Node *n, *ne;
  611. Node *pe = 0;
  612. Node *ae = 0;
  613. if (!am) return;
  614. n = firstChild(am);
  615. while (n) {
  616. ne = nextSibling(n);
  617. set_nextSibling(n,0);
  618. /* typemaps and fragments need to be prepended */
  619. if (((Cmp(nodeType(n),"typemap") == 0) || (Cmp(nodeType(n),"fragment") == 0))) {
  620. if (!pe) pe = new_node("extend");
  621. appendChild(pe, n);
  622. } else {
  623. if (!ae) ae = new_node("extend");
  624. appendChild(ae, n);
  625. }
  626. n = ne;
  627. }
  628. if (pe) prependChild(cls,pe);
  629. if (ae) appendChild(cls,ae);
  630. }
  631. /* Check for unused %extend. Special case, don't report unused
  632. extensions for templates */
  633. static void check_extensions() {
  634. Iterator ki;
  635. if (!extendhash) return;
  636. for (ki = First(extendhash); ki.key; ki = Next(ki)) {
  637. if (!Strchr(ki.key,'<')) {
  638. SWIG_WARN_NODE_BEGIN(ki.item);
  639. Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", ki.key);
  640. SWIG_WARN_NODE_END(ki.item);
  641. }
  642. }
  643. }
  644. /* Check a set of declarations to see if any are pure-abstract */
  645. static List *pure_abstract(Node *n) {
  646. List *abs = 0;
  647. while (n) {
  648. if (Cmp(nodeType(n),"cdecl") == 0) {
  649. String *decl = Getattr(n,"decl");
  650. if (SwigType_isfunction(decl)) {
  651. String *init = Getattr(n,"value");
  652. if (Cmp(init,"0") == 0) {
  653. if (!abs) {
  654. abs = NewList();
  655. }
  656. Append(abs,n);
  657. Setattr(n,"abstract","1");
  658. }
  659. }
  660. } else if (Cmp(nodeType(n),"destructor") == 0) {
  661. if (Cmp(Getattr(n,"value"),"0") == 0) {
  662. if (!abs) {
  663. abs = NewList();
  664. }
  665. Append(abs,n);
  666. Setattr(n,"abstract","1");
  667. }
  668. }
  669. n = nextSibling(n);
  670. }
  671. return abs;
  672. }
  673. /* Make a classname */
  674. static String *make_class_name(String *name) {
  675. String *nname = 0;
  676. if (Namespaceprefix) {
  677. nname= NewStringf("%s::%s", Namespaceprefix, name);
  678. } else {
  679. nname = NewString(name);
  680. }
  681. if (SwigType_istemplate(nname)) {
  682. String *prefix, *args, *qargs;
  683. prefix = SwigType_templateprefix(nname);
  684. args = SwigType_templateargs(nname);
  685. qargs = Swig_symbol_type_qualify(args,0);
  686. Append(prefix,qargs);
  687. Delete(nname);
  688. Delete(args);
  689. Delete(qargs);
  690. nname = prefix;
  691. }
  692. return nname;
  693. }
  694. static List *make_inherit_list(String *clsname, List *names) {
  695. int i, ilen;
  696. String *derived;
  697. List *bases = NewList();
  698. if (Namespaceprefix) derived = NewStringf("%s::%s", Namespaceprefix,clsname);
  699. else derived = NewString(clsname);
  700. ilen = Len(names);
  701. for (i = 0; i < ilen; i++) {
  702. Node *s;
  703. String *base;
  704. String *n = Getitem(names,i);
  705. /* Try to figure out where this symbol is */
  706. s = Swig_symbol_clookup(n,0);
  707. if (s) {
  708. while (s && (Strcmp(nodeType(s),"class") != 0)) {
  709. /* Not a class. Could be a typedef though. */
  710. String *storage = Getattr(s,"storage");
  711. if (storage && (Strcmp(storage,"typedef") == 0)) {
  712. String *nn = Getattr(s,"type");
  713. s = Swig_symbol_clookup(nn,Getattr(s,"sym:symtab"));
  714. } else {
  715. break;
  716. }
  717. }
  718. if (s && ((Strcmp(nodeType(s),"class") == 0) || (Strcmp(nodeType(s),"template") == 0))) {
  719. String *q = Swig_symbol_qualified(s);
  720. Append(bases,s);
  721. if (q) {
  722. base = NewStringf("%s::%s", q, Getattr(s,"name"));
  723. Delete(q);
  724. } else {
  725. base = NewString(Getattr(s,"name"));
  726. }
  727. } else {
  728. base = NewString(n);
  729. }
  730. } else {
  731. base = NewString(n);
  732. }
  733. if (base) {
  734. Swig_name_inherit(base,derived);
  735. Delete(base);
  736. }
  737. }
  738. return bases;
  739. }
  740. /* If the class name is qualified. We need to create or lookup namespace entries */
  741. static Symtab *set_scope_to_global() {
  742. Symtab *symtab = Swig_symbol_global_scope();
  743. Swig_symbol_setscope(symtab);
  744. return symtab;
  745. }
  746. /* Remove the block braces, { and }, if the 'noblock' attribute is set.
  747. * Node *kw can be either a Hash or Parmlist. */
  748. static String *remove_block(Node *kw, const String *inputcode) {
  749. String *modified_code = 0;
  750. while (kw) {
  751. String *name = Getattr(kw,"name");
  752. if (name && (Cmp(name,"noblock") == 0)) {
  753. char *cstr = Char(inputcode);
  754. size_t len = Len(inputcode);
  755. if (len && cstr[0] == '{') {
  756. --len; ++cstr;
  757. if (len && cstr[len - 1] == '}') { --len; }
  758. /* we now remove the extra spaces */
  759. while (len && isspace((int)cstr[0])) { --len; ++cstr; }
  760. while (len && isspace((int)cstr[len - 1])) { --len; }
  761. modified_code = NewStringWithSize(cstr, len);
  762. break;
  763. }
  764. }
  765. kw = nextSibling(kw);
  766. }
  767. return modified_code;
  768. }
  769. static Node *nscope = 0;
  770. static Node *nscope_inner = 0;
  771. /* Remove the scope prefix from cname and return the base name without the prefix.
  772. * The scopes specified in the prefix are found, or created in the current namespace.
  773. * So ultimately the scope is changed to that required for the base name.
  774. * For example AA::BB::CC as input returns CC and creates the namespace AA then inner
  775. * namespace BB in the current scope. If no scope separator (::) in the input, then nothing happens! */
  776. static String *resolve_node_scope(String *cname) {
  777. Symtab *gscope = 0;
  778. nscope = 0;
  779. nscope_inner = 0;
  780. if (Swig_scopename_check(cname)) {
  781. Node *ns;
  782. String *prefix = Swig_scopename_prefix(cname);
  783. String *base = Swig_scopename_last(cname);
  784. if (prefix && (Strncmp(prefix,"::",2) == 0)) {
  785. /* Use the global scope */
  786. String *nprefix = NewString(Char(prefix)+2);
  787. Delete(prefix);
  788. prefix= nprefix;
  789. gscope = set_scope_to_global();
  790. }
  791. if (!prefix || (Len(prefix) == 0)) {
  792. /* Use the global scope, but we need to add a 'global' namespace. */
  793. if (!gscope) gscope = set_scope_to_global();
  794. /* note that this namespace is not the "unnamed" one,
  795. and we don't use Setattr(nscope,"name", ""),
  796. because the unnamed namespace is private */
  797. nscope = new_node("namespace");
  798. Setattr(nscope,"symtab", gscope);;
  799. nscope_inner = nscope;
  800. return base;
  801. }
  802. /* Try to locate the scope */
  803. ns = Swig_symbol_clookup(prefix,0);
  804. if (!ns) {
  805. Swig_error(cparse_file,cparse_line,"Undefined scope '%s'\n", prefix);
  806. } else {
  807. Symtab *nstab = Getattr(ns,"symtab");
  808. if (!nstab) {
  809. Swig_error(cparse_file,cparse_line,
  810. "'%s' is not defined as a valid scope.\n", prefix);
  811. ns = 0;
  812. } else {
  813. /* Check if the node scope is the current scope */
  814. String *tname = Swig_symbol_qualifiedscopename(0);
  815. String *nname = Swig_symbol_qualifiedscopename(nstab);
  816. if (tname && (Strcmp(tname,nname) == 0)) {
  817. ns = 0;
  818. cname = base;
  819. }
  820. Delete(tname);
  821. Delete(nname);
  822. }
  823. if (ns) {
  824. /* we will try to create a new node using the namespaces we
  825. can find in the scope name */
  826. List *scopes;
  827. String *sname;
  828. Iterator si;
  829. String *name = NewString(prefix);
  830. scopes = NewList();
  831. while (name) {
  832. String *base = Swig_scopename_last(name);
  833. String *tprefix = Swig_scopename_prefix(name);
  834. Insert(scopes,0,base);
  835. Delete(base);
  836. Delete(name);
  837. name = tprefix;
  838. }
  839. for (si = First(scopes); si.item; si = Next(si)) {
  840. Node *ns1,*ns2;
  841. sname = si.item;
  842. ns1 = Swig_symbol_clookup(sname,0);
  843. assert(ns1);
  844. if (Strcmp(nodeType(ns1),"namespace") == 0) {
  845. if (Getattr(ns1,"alias")) {
  846. ns1 = Getattr(ns1,"namespace");
  847. }
  848. } else {
  849. /* now this last part is a class */
  850. si = Next(si);
  851. ns1 = Swig_symbol_clookup(sname,0);
  852. /* or a nested class tree, which is unrolled here */
  853. for (; si.item; si = Next(si)) {
  854. if (si.item) {
  855. Printf(sname,"::%s",si.item);
  856. }
  857. }
  858. /* we get the 'inner' class */
  859. nscope_inner = Swig_symbol_clookup(sname,0);
  860. /* set the scope to the inner class */
  861. Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
  862. /* save the last namespace prefix */
  863. Delete(Namespaceprefix);
  864. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  865. /* and return the node name, including the inner class prefix */
  866. break;
  867. }
  868. /* here we just populate the namespace tree as usual */
  869. ns2 = new_node("namespace");
  870. Setattr(ns2,"name",sname);
  871. Setattr(ns2,"symtab", Getattr(ns1,"symtab"));
  872. add_symbols(ns2);
  873. Swig_symbol_setscope(Getattr(ns1,"symtab"));
  874. Delete(Namespaceprefix);
  875. Namespaceprefix = Swig_symbol_qualifiedscopename(0);
  876. if (nscope_inner) {
  877. if (Getattr(nscope_inner,"symtab") != Getattr(ns2,"symtab")) {
  878. appendChild(nscope_inner,ns2);
  879. Delete(ns2);
  880. }
  881. }
  882. nscope_inner = ns2;
  883. if (!nscope) nscope = ns2;
  884. }
  885. cname = base;
  886. Delete(scopes);
  887. }
  888. }
  889. Delete(prefix);
  890. }
  891. return cname;
  892. }
  893. /* Structures for handling code fragments built for nested classes */
  894. typedef struct Nested {
  895. String *code; /* Associated code fragment */
  896. int line; /* line number where it starts */
  897. char *name; /* Name associated with this nested class */
  898. char *kind; /* Kind of class */
  899. int unnamed; /* unnamed class */
  900. SwigType *type; /* Datatype associated with the name */
  901. struct Nested *next; /* Next code fragment in list */
  902. } Nested;
  903. /* Some internal variables for saving nested class information */
  904. static Nested *nested_list = 0;
  905. /* Add a function to the nested list */
  906. static void add_nested(Nested *n) {
  907. Nested *n1;
  908. if (!nested_list) nested_list = n;
  909. else {
  910. n1 = nested_list;
  911. while (n1->next) n1 = n1->next;
  912. n1->next = n;
  913. }
  914. }
  915. /* Strips C-style and C++-style comments from string in-place. */
  916. static void strip_comments(char *string) {
  917. int state = 0; /*
  918. * 0 - not in comment
  919. * 1 - in c-style comment
  920. * 2 - in c++-style comment
  921. * 3 - in string
  922. * 4 - after reading / not in comments
  923. * 5 - after reading * in c-style comments
  924. * 6 - after reading \ in strings
  925. */
  926. char * c = string;
  927. while (*c) {
  928. switch (state) {
  929. case 0:
  930. if (*c == '\"')
  931. state = 3;
  932. else if (*c == '/')
  933. state = 4;
  934. break;
  935. case 1:
  936. if (*c == '*')
  937. state = 5;
  938. *c = ' ';
  939. break;
  940. case 2:
  941. if (*c == '\n')
  942. state = 0;
  943. else
  944. *c = ' ';
  945. break;
  946. case 3:
  947. if (*c == '\"')
  948. state = 0;
  949. else if (*c == '\\')
  950. state = 6;
  951. break;
  952. case 4:
  953. if (*c == '/') {
  954. *(c-1) = ' ';
  955. *c = ' ';
  956. state = 2;
  957. } else if (*c == '*') {
  958. *(c-1) = ' ';
  959. *c = ' ';
  960. state = 1;
  961. } else
  962. state = 0;
  963. break;
  964. case 5:
  965. if (*c == '/')
  966. state = 0;
  967. else
  968. state = 1;
  969. *c = ' ';
  970. break;
  971. case 6:
  972. state = 3;
  973. break;
  974. }
  975. ++c;
  976. }
  977. }
  978. /* Dump all of the nested class declarations to the inline processor
  979. * However. We need to do a few name replacements and other munging
  980. * first. This function must be called before closing a class! */
  981. static Node *dump_nested(const char *parent) {
  982. Nested *n,*n1;
  983. Node *ret = 0;
  984. n = nested_list;
  985. if (!parent) {
  986. nested_list = 0;
  987. return 0;
  988. }
  989. while (n) {
  990. Node *retx;
  991. SwigType *nt;
  992. /* Token replace the name of the parent class */
  993. Replace(n->code, "$classname", parent, DOH_REPLACE_ANY);
  994. /* Fix up the name of the datatype (for building typedefs and other stuff) */
  995. Append(n->type,parent);
  996. Append(n->type,"_");
  997. Append(n->type,n->name);
  998. /* Add the appropriate declaration to the C++ processor */
  999. retx = new_node("cdecl");
  1000. Setattr(retx,"name",n->name);
  1001. nt = Copy(n->type);
  1002. Setattr(retx,"type",nt);
  1003. Delete(nt);
  1004. Setattr(retx,"nested",parent);
  1005. if (n->unnamed) {
  1006. Setattr(retx,"unnamed","1");
  1007. }
  1008. add_symbols(retx);
  1009. if (ret) {
  1010. set_nextSibling(retx,ret);
  1011. Delete(ret);
  1012. }
  1013. ret = retx;
  1014. /* Insert a forward class declaration */
  1015. /* Disabled: [ 597599 ] union in class: incorrect scope
  1016. retx = new_node("classforward");
  1017. Setattr(retx,"kind",n->kind);
  1018. Setattr(retx,"name",Copy(n->type));
  1019. Setattr(retx,"sym:name", make_name(n->type,0));
  1020. set_nextSibling(retx,ret);
  1021. ret = retx;
  1022. */
  1023. /* Strip comments - further code may break in presence of comments. */
  1024. strip_comments(Char(n->code));
  1025. /* Make all SWIG created typedef structs/unions/classes unnamed else
  1026. redefinition errors occur - nasty hack alert.*/
  1027. {
  1028. const char* types_array[3] = {"struct", "union", "class"};
  1029. int i;
  1030. for (i=0; i<3; i++) {
  1031. char* code_ptr = Char(n->code);
  1032. while (code_ptr) {
  1033. /* Replace struct name (as in 'struct name {...}' ) with whitespace
  1034. name will be between struct and opening brace */
  1035. code_ptr = strstr(code_ptr, types_array[i]);
  1036. if (code_ptr) {
  1037. char *open_bracket_pos;
  1038. code_ptr += strlen(types_array[i]);
  1039. open_bracket_pos = strchr(code_ptr, '{');
  1040. if (open_bracket_pos) {
  1041. /* Make sure we don't have something like struct A a; */
  1042. char* semi_colon_pos = strchr(code_ptr, ';');
  1043. if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos)))
  1044. while (code_ptr < open_bracket_pos)
  1045. *code_ptr++ = ' ';
  1046. }
  1047. }
  1048. }
  1049. }
  1050. }
  1051. {
  1052. /* Remove SWIG directive %constant which may be left in the SWIG created typedefs */
  1053. char* code_ptr = Char(n->code);
  1054. while (code_ptr) {
  1055. code_ptr = strstr(code_ptr, "%constant");
  1056. if (code_ptr) {
  1057. char* directive_end_pos = strchr(code_ptr, ';');
  1058. if (directive_end_pos) {
  1059. while (code_ptr <= directive_end_pos)
  1060. *code_ptr++ = ' ';
  1061. }
  1062. }
  1063. }
  1064. }
  1065. {
  1066. Node *head = new_node("insert");
  1067. String *code = NewStringf("\n%s\n",n->code);
  1068. Setattr(head,"code", code);
  1069. Delete(code);
  1070. set_nextSibling(head,ret);
  1071. Delete(ret);
  1072. ret = head;
  1073. }
  1074. /* Dump the code to the scanner */
  1075. start_inline(Char(n->code),n->line);
  1076. n1 = n->next;
  1077. Delete(n->code);
  1078. free(n);
  1079. n = n1;
  1080. }
  1081. nested_list = 0;
  1082. return ret;
  1083. }
  1084. Node *Swig_cparse(File *f) {
  1085. scanner_file(f);
  1086. top = 0;
  1087. yyparse();
  1088. return top;
  1089. }
  1090. static void single_new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
  1091. String *fname;
  1092. String *name;
  1093. String *fixname;
  1094. SwigType *t = Copy(type);
  1095. /* Printf(stdout, "single_new_feature: [%s] [%s] [%s] [%s] [%s] [%s]\n", featurename, val, declaratorid, t, ParmList_str_defaultargs(declaratorparms), qualifier); */
  1096. fname = NewStringf("feature:%s",featurename);
  1097. if (declaratorid) {
  1098. fixname = feature_identifier_fix(declaratorid);
  1099. } else {
  1100. fixname = NewStringEmpty();
  1101. }
  1102. if (Namespaceprefix) {
  1103. name = NewStringf("%s::%s",Namespaceprefix, fixname);
  1104. } else {
  1105. name = fixname;
  1106. }
  1107. if (declaratorparms) Setmeta(val,"parms",declaratorparms);
  1108. if (!Len(t)) t = 0;
  1109. if (t) {
  1110. if (qualifier) SwigType_push(t,qualifier);
  1111. if (SwigType_isfunction(t)) {
  1112. SwigType *decl = SwigType_pop_function(t);
  1113. if (SwigType_ispointer(t)) {
  1114. String *nname = NewStringf("*%s",name);
  1115. Swig_feature_set(Swig_cparse_features(), nname, decl, fname, val, featureattribs);
  1116. Delete(nname);
  1117. } else {
  1118. Swig_feature_set(Swig_cparse_features(), name, decl, fname, val, featureattribs);
  1119. }
  1120. Delete(decl);
  1121. } else if (SwigType_ispointer(t)) {
  1122. String *nname = NewStringf("*%s",name);
  1123. Swig_feature_set(Swig_cparse_features(),nname,0,fname,val, featureattribs);
  1124. Delete(nname);
  1125. }
  1126. } else {
  1127. /* Global feature, that is, feature not associated with any particular symbol */
  1128. Swig_feature_set(Swig_cparse_features(),name,0,fname,val, featureattribs);
  1129. }
  1130. Delete(fname);
  1131. Delete(name);
  1132. }
  1133. /* Add a new feature to the Hash. Additional features are added if the feature has a parameter list (declaratorparms)
  1134. * and one or more of the parameters have a default argument. An extra feature is added for each defaulted parameter,
  1135. * simulating the equivalent overloaded method. */
  1136. static void new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
  1137. ParmList *declparms = declaratorparms;
  1138. /* remove the { and } braces if the noblock attribute is set */
  1139. String *newval = remove_block(featureattribs, val);
  1140. val = newval ? newval : val;
  1141. /* Add the feature */
  1142. single_new_feature(featurename, val, featureattribs, declaratorid, type, declaratorparms, qualifier);
  1143. /* Add extra features if there are default parameters in the parameter list */
  1144. if (type) {
  1145. while (declparms) {
  1146. if (ParmList_has_defaultargs(declparms)) {
  1147. /* Create a parameter list for the new feature by copying all
  1148. but the last (defaulted) parameter */
  1149. ParmList* newparms = CopyParmListMax(declparms, ParmList_len(declparms)-1);
  1150. /* Create new declaration - with the last parameter removed */
  1151. SwigType *newtype = Copy(type);
  1152. Delete(SwigType_pop_function(newtype)); /* remove the old parameter list from newtype */
  1153. SwigType_add_function(newtype,newparms);
  1154. single_new_feature(featurename, Copy(val), featureattribs, declaratorid, newtype, newparms, qualifier);
  1155. declparms = newparms;
  1156. } else {
  1157. declparms = 0;
  1158. }
  1159. }
  1160. }
  1161. }
  1162. /* check if a function declaration is a plain C object */
  1163. static int is_cfunction(Node *n) {
  1164. if (!cparse_cplusplus || cparse_externc) return 1;
  1165. if (Cmp(Getattr(n,"storage"),"externc") == 0) {
  1166. return 1;
  1167. }
  1168. return 0;
  1169. }
  1170. /* If the Node is a function with parameters, check to see if any of the parameters
  1171. * have default arguments. If so create a new function for each defaulted argument.
  1172. * The additional functions form a linked list of nodes with the head being the original Node n. */
  1173. static void default_arguments(Node *n) {
  1174. Node *function = n;
  1175. if (function) {
  1176. ParmList *varargs = Getattr(function,"feature:varargs");
  1177. if (varargs) {
  1178. /* Handles the %varargs directive by looking for "feature:varargs" and
  1179. * substituting ... with an alternative set of arguments. */
  1180. Parm *p = Getattr(function,"parms");
  1181. Parm *pp = 0;
  1182. while (p) {
  1183. SwigType *t = Getattr(p,"type");
  1184. if (Strcmp(t,"v(...)") == 0) {
  1185. if (pp) {
  1186. ParmList *cv = Copy(varargs);
  1187. set_nextSibling(pp,cv);
  1188. Delete(cv);
  1189. } else {
  1190. ParmList *cv = Copy(varargs);
  1191. Setattr(function,"parms", cv);
  1192. Delete(cv);
  1193. }
  1194. break;
  1195. }
  1196. pp = p;
  1197. p = nextSibling(p);
  1198. }
  1199. }
  1200. /* Do not add in functions if kwargs is being used or if user wants old default argument wrapping
  1201. (one wrapped method per function irrespective of number of default arguments) */
  1202. if (compact_default_args
  1203. || is_cfunction(function)
  1204. || GetFlag(function,"feature:compactdefaultargs")
  1205. || GetFlag(function,"feature:kwargs")) {
  1206. ParmList *p = Getattr(function,"parms");
  1207. if (p)
  1208. Setattr(p,"compactdefargs", "1"); /* mark parameters for special handling */
  1209. function = 0; /* don't add in extra methods */
  1210. }
  1211. }
  1212. while (function) {
  1213. ParmList *parms = Getattr(function,"parms");
  1214. if (ParmList_has_defaultargs(parms)) {
  1215. /* Create a parameter list for the new function by copying all
  1216. but the last (defaulted) parameter */
  1217. ParmList* newparms = CopyParmListMax(parms,ParmList_len(parms)-1);
  1218. /* Create new function and add to symbol table */
  1219. {
  1220. SwigType *ntype = Copy(nodeType(function));
  1221. char *cntype = Char(ntype);
  1222. Node *new_function = new_node(ntype);
  1223. SwigType *decl = Copy(Getattr(function,"decl"));
  1224. int constqualifier = SwigType_isconst(decl);
  1225. String *ccode = Copy(Getattr(function,"code"));
  1226. String *cstorage = Copy(Getattr(function,"storage"));
  1227. String *cvalue = Copy(Getattr(function,"value"));
  1228. SwigType *ctype = Copy(Getattr(function,"type"));
  1229. String *cthrow = Copy(Getattr(function,"throw"));
  1230. Delete(SwigType_pop_function(decl)); /* remove the old parameter list from decl */
  1231. SwigType_add_function(decl,newparms);
  1232. if (constqualifier)
  1233. SwigType_add_qualifier(decl,"const");
  1234. Setattr(new_function,"name", Getattr(function,"name"));
  1235. Setattr(new_function,"code", ccode);
  1236. Setattr(new_function,"decl", decl);
  1237. Setattr(new_function,"parms", newparms);
  1238. Setattr(new_function,"storage", cstorage);
  1239. Setattr(new_function,"value", cvalue);
  1240. Setattr(new_function,"type", ctype);
  1241. Setattr(new_function,"throw", cthrow);
  1242. Delete(ccode);
  1243. Delete(cstorage);
  1244. Delete(cvalue);
  1245. Delete(ctype);
  1246. Delete(cthrow);
  1247. Delete(decl);
  1248. {
  1249. Node *throws = Getattr(function,"throws");
  1250. ParmList *pl = CopyParmList(throws);
  1251. if (throws) Setattr(new_function,"throws",pl);
  1252. Delete(pl);
  1253. }
  1254. /* copy specific attributes for global (or in a namespace) template functions - these are not templated class methods */
  1255. if (strcmp(cntype,"template") == 0) {
  1256. Node *templatetype = Getattr(function,"templatetype");
  1257. Node *symtypename = Getattr(function,"sym:typename");
  1258. Parm *templateparms = Getattr(function,"templateparms");
  1259. if (templatetype) {
  1260. Node *tmp = Copy(templatetype);
  1261. Setattr(new_function,"templatetype",tmp);
  1262. Delete(tmp);
  1263. }
  1264. if (symtypename) {
  1265. Node *tmp = Copy(symtypename);
  1266. Setattr(new_function,"sym:typename",tmp);
  1267. Delete(tmp);
  1268. }
  1269. if (templateparms) {
  1270. Parm *tmp = CopyParmList(templateparms);
  1271. Setattr(new_function,"templateparms",tmp);
  1272. Delete(tmp);
  1273. }
  1274. } else if (strcmp(cntype,"constructor") == 0) {
  1275. /* only copied for constructors as this is not a user defined feature - it is hard coded in the parser */
  1276. if (GetFlag(function,"feature:new")) SetFlag(new_function,"feature:new");
  1277. }
  1278. add_symbols(new_function);
  1279. /* mark added functions as ones with overloaded parameters and point to the parsed method */
  1280. Setattr(new_function,"defaultargs", n);
  1281. /* Point to the new function, extending the linked list */
  1282. set_nextSibling(function, new_function);
  1283. Delete(new_function);
  1284. function = new_function;
  1285. Delete(ntype);
  1286. }
  1287. } else {
  1288. function = 0;
  1289. }
  1290. }
  1291. }
  1292. /* -----------------------------------------------------------------------------
  1293. * nested_forward_declaration()
  1294. *
  1295. * Treat the nested class/struct/union as a forward declaration until a proper
  1296. * nested class solution is implemented.
  1297. * ----------------------------------------------------------------------------- */
  1298. static Node *nested_forward_declaration(const char *kind, const char *name) {
  1299. Node *n = new_node("classforward");
  1300. Setfile(n,cparse_file);
  1301. Setline(n,cparse_line);
  1302. Setattr(n,"kind", kind);
  1303. Setattr(n,"name", name);
  1304. Setattr(n,"sym:weak", "1");
  1305. add_symbols(n);
  1306. if (GetFlag(n, "feature:nestedworkaround")) {
  1307. Swig_symbol_remove(n);
  1308. n = 0;
  1309. } else {
  1310. SWIG_WARN_NODE_BEGIN(n);
  1311. Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, name);
  1312. SWIG_WARN_NODE_END(n);
  1313. }
  1314. return n;
  1315. }
  1316. /* -----------------------------------------------------------------------------
  1317. * tag_nodes()
  1318. *
  1319. * Used by the parser to mark subtypes with extra information.
  1320. * ----------------------------------------------------------------------------- */
  1321. static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) {
  1322. while (n) {
  1323. Setattr(n, attrname, value);
  1324. tag_nodes(firstChild(n), attrname, value);
  1325. n = nextSibling(n);
  1326. }
  1327. }
  1328. %}
  1329. %union {
  1330. char *id;
  1331. List *bases;
  1332. struct Define {
  1333. String *val;
  1334. String *rawval;
  1335. int type;
  1336. String *qualifier;
  1337. String *bitfield;
  1338. Parm *throws;
  1339. String *throwf;
  1340. } dtype;
  1341. struct {
  1342. char *type;
  1343. String *filename;
  1344. int line;
  1345. } loc;
  1346. struct {
  1347. char *id;
  1348. SwigType *type;
  1349. String *defarg;
  1350. ParmList *parms;
  1351. short have_parms;
  1352. ParmList *throws;
  1353. String *throwf;
  1354. } decl;
  1355. Parm *tparms;
  1356. struct {
  1357. String *method;
  1358. Hash *kwargs;
  1359. } tmap;
  1360. struct {
  1361. String *type;
  1362. String *us;
  1363. } ptype;
  1364. SwigType *type;
  1365. String *str;
  1366. Parm *p;
  1367. ParmList *pl;
  1368. int ivalue;
  1369. Node *node;
  1370. };
  1371. %token <id> ID
  1372. %token <str> HBLOCK
  1373. %token <id> POUND
  1374. %token <id> STRING
  1375. %token <loc> INCLUDE IMPORT INSERT
  1376. %token <str> CHARCONST
  1377. %token <dtype> NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG NUM_BOOL
  1378. %token <ivalue> TYPEDEF
  1379. %token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_WCHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_COMPLEX TYPE_TYPEDEF TYPE_RAW TYPE_NON_ISO_INT8 TYPE_NON_ISO_INT16 TYPE_NON_ISO_INT32 TYPE_NON_ISO_INT64
  1380. %token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD
  1381. %token CONST_QUAL VOLATILE REGISTER STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET
  1382. %token ILLEGAL CONSTANT
  1383. %token NAME RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS
  1384. %token ENUM
  1385. %token CLASS TYPENAME PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND THROW CATCH EXPLICIT
  1386. %token USING
  1387. %token <node> NAMESPACE
  1388. %token NATIVE INLINE
  1389. %token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT
  1390. %token WARN
  1391. %token LESSTHAN GREATERTHAN MODULO DELETE_KW
  1392. %token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO
  1393. %token QUESTIONMARK
  1394. %token TYPES PARMS
  1395. %token NONID DSTAR DCNOT
  1396. %token <ivalue> TEMPLATE
  1397. %token <str> OPERATOR
  1398. %token <str> COPERATOR
  1399. %token PARSETYPE PARSEPARM PARSEPARMS
  1400. %left CAST
  1401. %left QUESTIONMARK
  1402. %left LOR
  1403. %left LAND
  1404. %left OR
  1405. %left XOR
  1406. %left AND
  1407. %left EQUALTO NOTEQUALTO
  1408. %left GREATERTHAN LESSTHAN GREATERTHANOREQUALTO LESSTHANOREQUALTO
  1409. %left LSHIFT RSHIFT
  1410. %left PLUS MINUS
  1411. %left STAR SLASH MODULUS
  1412. %left UMINUS NOT LNOT
  1413. %left DCOLON
  1414. %type <node> program interface declaration swig_directive ;
  1415. /* SWIG directives */
  1416. %type <node> extend_directive apply_directive clear_directive constant_directive ;
  1417. %type <node> echo_directive except_directive fragment_directive include_directive inline_directive ;
  1418. %type <node> insert_directive module_directive name_directive native_directive ;
  1419. %type <node> pragma_directive rename_directive feature_directive varargs_directive typemap_directive ;
  1420. %type <node> types_directive template_directive warn_directive ;
  1421. /* C declarations */
  1422. %type <node> c_declaration c_decl c_decl_tail c_enum_decl c_enum_forward_decl c_constructor_decl ;
  1423. %type <node> enumlist edecl;
  1424. /* C++ declarations */
  1425. %type <node> cpp_declaration cpp_class_decl cpp_forward_class_decl cpp_template_decl;
  1426. %type <node> cpp_members cpp_member;
  1427. %type <node> cpp_constructor_decl cpp_destructor_decl cpp_protection_decl cpp_conversion_operator;
  1428. %type <node> cpp_swig_directive cpp_temp_possible cpp_nested cpp_opt_declarators ;
  1429. %type <node> cpp_using_decl cpp_namespace_decl cpp_catch_decl ;
  1430. %type <node> kwargs options;
  1431. /* Misc */
  1432. %type <dtype> initializer cpp_const ;
  1433. %type <id> storage_class;
  1434. %type <pl> parms ptail rawparms varargs_parms;
  1435. %type <pl> templateparameters templateparameterstail;
  1436. %type <p> parm valparm rawvalparms valparms valptail ;
  1437. %type <p> typemap_parm tm_list tm_tail ;
  1438. %type <p> templateparameter ;
  1439. %type <id> templcpptype cpptype access_specifier;
  1440. %type <node> base_specifier
  1441. %type <type> type rawtype type_right ;
  1442. %type <bases> base_list inherit raw_inherit;
  1443. %type <dtype> definetype def_args etype;
  1444. %type <dtype> expr exprnum exprcompound valexpr;
  1445. %type <id> ename ;
  1446. %type <id> template_decl;
  1447. %type <str> type_qualifier ;
  1448. %type <id> type_qualifier_raw;
  1449. %type <id> idstring idstringopt;
  1450. %type <id> pragma_lang;
  1451. %type <str> pragma_arg;
  1452. %type <loc> includetype;
  1453. %type <type> pointer primitive_type;
  1454. %type <decl> declarator direct_declarator notso_direct_declarator parameter_declarator typemap_parameter_declarator nested_decl;
  1455. %type <decl> abstract_declarator direct_abstract_declarator ctor_end;
  1456. %type <tmap> typemap_type;
  1457. %type <str> idcolon idcolontail idcolonnt idcolontailnt idtemplate stringbrace stringbracesemi;
  1458. %type <id> string stringnum ;
  1459. %type <tparms> template_parms;
  1460. %type <dtype> cpp_end cpp_vend;
  1461. %type <ivalue> rename_namewarn;
  1462. %type <ptype> type_specifier primitive_type_list ;
  1463. %type <node> fname stringtype;
  1464. %type <node> featattr;
  1465. %%
  1466. /* ======================================================================
  1467. * High-level Interface file
  1468. *
  1469. * An interface is just a sequence of declarations which may be SWIG directives
  1470. * or normal C declarations.
  1471. * ====================================================================== */
  1472. program : interface {
  1473. if (!classes) classes = NewHash();
  1474. Setattr($1,"classes",classes);
  1475. Setattr($1,"name",ModuleName);
  1476. if ((!module_node) && ModuleName) {
  1477. module_node = new_node("module");
  1478. Setattr(module_node,"name",ModuleName);
  1479. }
  1480. Setattr($1,"module",module_node);
  1481. check_extensions();
  1482. top = $1;
  1483. }
  1484. | PARSETYPE parm SEMI {
  1485. top = Copy(Getattr($2,"type"));
  1486. Delete($2);
  1487. }
  1488. | PARSETYPE error {
  1489. top = 0;
  1490. }
  1491. | PARSEPARM parm SEMI {
  1492. top = $2;
  1493. }
  1494. | PARSEPARM error {
  1495. top = 0;
  1496. }
  1497. | PARSEPARMS LPAREN parms RPAREN SEMI {
  1498. top = $3;
  1499. }
  1500. | PARSEPARMS error SEMI {
  1501. top = 0;
  1502. }
  1503. ;
  1504. interface : interface declaration {
  1505. /* add declaration to end of linked list (the declaration isn't always a single declaration, sometimes it is a linked list itself) */
  1506. appendChild($1,$2);
  1507. $$ = $1;
  1508. }
  1509. | empty {
  1510. $$ = new_node("top");
  1511. }
  1512. ;
  1513. declaration : swig_directive { $$ = $1; }
  1514. | c_declaration { $$ = $1; }
  1515. | cpp_declaration { $$ = $1; }
  1516. | SEMI { $$ = 0; }
  1517. | error {
  1518. $$ = 0;
  1519. Swig_error(cparse_file, cparse_line,"Syntax error in…

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