PageRenderTime 57ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/trunk/Source/CParse/parser.y

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