parser.l 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /* -*-C-*-
  2. * IDL Compiler
  3. *
  4. * Copyright 2002 Ove Kaaven
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  19. */
  20. %option stack
  21. %option noinput nounput noyy_top_state
  22. %option 8bit never-interactive prefix="parser_"
  23. nl \r?\n
  24. ws [ \f\t\r]
  25. cident [a-zA-Z_][0-9a-zA-Z_]*
  26. u_suffix (u|U)
  27. l_suffix (l|L)
  28. int [0-9]+({l_suffix}?{u_suffix}?|{u_suffix}?{l_suffix}?)?
  29. hexd [0-9a-fA-F]
  30. hex 0(x|X){hexd}+({l_suffix}?{u_suffix}?|{u_suffix}?{l_suffix}?)?
  31. uuid {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12}
  32. double [0-9]+\.[0-9]+([eE][+-]?[0-9]+)*
  33. %x QUOTE
  34. %x WSTRQUOTE
  35. %x ATTR
  36. %x PP_LINE
  37. %x PP_PRAGMA
  38. %x SQUOTE
  39. %{
  40. #include "config.h"
  41. #include "wine/port.h"
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <ctype.h>
  46. #include <assert.h>
  47. #include <errno.h>
  48. #include <limits.h>
  49. #ifdef HAVE_UNISTD_H
  50. #include <unistd.h>
  51. #else
  52. #define YY_NO_UNISTD_H
  53. #endif
  54. #include "widl.h"
  55. #include "utils.h"
  56. #include "parser.h"
  57. #include "wine/wpp.h"
  58. #include "parser.tab.h"
  59. static void addcchar(char c);
  60. static char *get_buffered_cstring(void);
  61. static char *cbuffer;
  62. static int cbufidx;
  63. static int cbufalloc = 0;
  64. static int kw_token(const char *kw);
  65. static int attr_token(const char *kw);
  66. static void switch_to_acf(void);
  67. static warning_list_t *disabled_warnings = NULL;
  68. #define MAX_IMPORT_DEPTH 20
  69. struct {
  70. YY_BUFFER_STATE state;
  71. char *input_name;
  72. int line_number;
  73. char *temp_name;
  74. } import_stack[MAX_IMPORT_DEPTH];
  75. int import_stack_ptr = 0;
  76. /* converts an integer in string form to an unsigned long and prints an error
  77. * on overflow */
  78. static unsigned int xstrtoul(const char *nptr, char **endptr, int base)
  79. {
  80. unsigned long val;
  81. errno = 0;
  82. val = strtoul(nptr, endptr, base);
  83. if ((val == ULONG_MAX && errno == ERANGE) || ((unsigned int)val != val))
  84. error_loc("integer constant %s is too large\n", nptr);
  85. return val;
  86. }
  87. UUID *parse_uuid(const char *u)
  88. {
  89. UUID* uuid = xmalloc(sizeof(UUID));
  90. char b[3];
  91. /* it would be nice to use UuidFromStringA */
  92. uuid->Data1 = strtoul(u, NULL, 16);
  93. uuid->Data2 = strtoul(u+9, NULL, 16);
  94. uuid->Data3 = strtoul(u+14, NULL, 16);
  95. b[2] = 0;
  96. memcpy(b, u+19, 2); uuid->Data4[0] = strtoul(b, NULL, 16);
  97. memcpy(b, u+21, 2); uuid->Data4[1] = strtoul(b, NULL, 16);
  98. memcpy(b, u+24, 2); uuid->Data4[2] = strtoul(b, NULL, 16);
  99. memcpy(b, u+26, 2); uuid->Data4[3] = strtoul(b, NULL, 16);
  100. memcpy(b, u+28, 2); uuid->Data4[4] = strtoul(b, NULL, 16);
  101. memcpy(b, u+30, 2); uuid->Data4[5] = strtoul(b, NULL, 16);
  102. memcpy(b, u+32, 2); uuid->Data4[6] = strtoul(b, NULL, 16);
  103. memcpy(b, u+34, 2); uuid->Data4[7] = strtoul(b, NULL, 16);
  104. return uuid;
  105. }
  106. %}
  107. /*
  108. **************************************************************************
  109. * The flexer starts here
  110. **************************************************************************
  111. */
  112. %%
  113. <INITIAL>^{ws}*\#{ws}*pragma{ws}+ yy_push_state(PP_PRAGMA);
  114. <INITIAL,ATTR>^{ws}*\#{ws}* yy_push_state(PP_LINE);
  115. <PP_LINE>[^\n]* {
  116. int lineno;
  117. char *cptr, *fname;
  118. yy_pop_state();
  119. lineno = (int)strtol(yytext, &cptr, 10);
  120. if(!lineno)
  121. error_loc("Malformed '#...' line-directive; invalid linenumber\n");
  122. fname = strchr(cptr, '"');
  123. if(!fname)
  124. error_loc("Malformed '#...' line-directive; missing filename\n");
  125. fname++;
  126. cptr = strchr(fname, '"');
  127. if(!cptr)
  128. error_loc("Malformed '#...' line-directive; missing terminating \"\n");
  129. *cptr = '\0';
  130. line_number = lineno - 1; /* We didn't read the newline */
  131. input_name = xstrdup(fname);
  132. }
  133. <PP_PRAGMA>midl_echo[^\n]* yyless(9); yy_pop_state(); return tCPPQUOTE;
  134. <PP_PRAGMA>winrt[^\n]* {
  135. if(import_stack_ptr) {
  136. if(!winrt_mode)
  137. error_loc("winrt IDL file imported in non-winrt mode\n");
  138. }else {
  139. const char *ptr = yytext+5;
  140. winrt_mode = TRUE;
  141. while(isspace(*ptr))
  142. ptr++;
  143. if(!strncmp(ptr, "ns_prefix", 9) && (!*(ptr += 9) || isspace(*ptr)))
  144. use_abi_namespace = TRUE;
  145. }
  146. yy_pop_state();
  147. }
  148. <PP_PRAGMA>[^\n]* parser_lval.str = xstrdup(yytext); yy_pop_state(); return aPRAGMA;
  149. <INITIAL>^{ws}*midl_pragma{ws}+warning return tPRAGMA_WARNING;
  150. <INITIAL,ATTR>\" yy_push_state(QUOTE); cbufidx = 0;
  151. <QUOTE>\" {
  152. yy_pop_state();
  153. parser_lval.str = get_buffered_cstring();
  154. return aSTRING;
  155. }
  156. <INITIAL,ATTR>L\" yy_push_state(WSTRQUOTE); cbufidx = 0;
  157. <WSTRQUOTE>\" {
  158. yy_pop_state();
  159. parser_lval.str = get_buffered_cstring();
  160. return aWSTRING;
  161. }
  162. <INITIAL,ATTR>\' yy_push_state(SQUOTE); cbufidx = 0;
  163. <SQUOTE>\' {
  164. yy_pop_state();
  165. parser_lval.str = get_buffered_cstring();
  166. return aSQSTRING;
  167. }
  168. <QUOTE,WSTRQUOTE,SQUOTE>\\\\ |
  169. <QUOTE,WSTRQUOTE>\\\" addcchar(yytext[1]);
  170. <SQUOTE>\\\' addcchar(yytext[1]);
  171. <QUOTE,WSTRQUOTE,SQUOTE>\\. addcchar('\\'); addcchar(yytext[1]);
  172. <QUOTE,WSTRQUOTE,SQUOTE>. addcchar(yytext[0]);
  173. <INITIAL,ATTR>\[ yy_push_state(ATTR); return '[';
  174. <ATTR>\] yy_pop_state(); return ']';
  175. <ATTR>{cident} return attr_token(yytext);
  176. <ATTR>{uuid} {
  177. parser_lval.uuid = parse_uuid(yytext);
  178. return aUUID;
  179. }
  180. <INITIAL,ATTR>{hex} {
  181. parser_lval.num = xstrtoul(yytext, NULL, 0);
  182. return aHEXNUM;
  183. }
  184. <INITIAL,ATTR>{int} {
  185. parser_lval.num = xstrtoul(yytext, NULL, 0);
  186. return aNUM;
  187. }
  188. <INITIAL>{double} {
  189. parser_lval.dbl = strtod(yytext, NULL);
  190. return aDOUBLE;
  191. }
  192. SAFEARRAY{ws}*/\( return tSAFEARRAY;
  193. {cident} return kw_token(yytext);
  194. <INITIAL,ATTR>\n line_number++;
  195. <INITIAL,ATTR>{ws}
  196. <INITIAL,ATTR>\<\< return SHL;
  197. <INITIAL,ATTR>\>\> return SHR;
  198. <INITIAL,ATTR>\-\> return MEMBERPTR;
  199. <INITIAL,ATTR>== return EQUALITY;
  200. <INITIAL,ATTR>!= return INEQUALITY;
  201. <INITIAL,ATTR>\>= return GREATEREQUAL;
  202. <INITIAL,ATTR>\<= return LESSEQUAL;
  203. <INITIAL,ATTR>\|\| return LOGICALOR;
  204. <INITIAL,ATTR>&& return LOGICALAND;
  205. <INITIAL,ATTR>\.\.\. return ELLIPSIS;
  206. <INITIAL,ATTR>. return yytext[0];
  207. <<EOF>> {
  208. if (import_stack_ptr)
  209. return aEOF;
  210. if (acf_name)
  211. {
  212. switch_to_acf();
  213. return aACF;
  214. }
  215. yyterminate();
  216. }
  217. %%
  218. #ifndef parser_wrap
  219. int parser_wrap(void)
  220. {
  221. return 1;
  222. }
  223. #endif
  224. struct keyword {
  225. const char *kw;
  226. int token;
  227. int winrt_only : 1;
  228. };
  229. /* This table MUST be alphabetically sorted on the kw field */
  230. static const struct keyword keywords[] = {
  231. {"FALSE", tFALSE, 0},
  232. {"NULL", tNULL, 0},
  233. {"TRUE", tTRUE, 0},
  234. {"__cdecl", tCDECL, 0},
  235. {"__fastcall", tFASTCALL, 0},
  236. {"__int32", tINT32, 0},
  237. {"__int3264", tINT3264, 0},
  238. {"__int64", tINT64, 0},
  239. {"__pascal", tPASCAL, 0},
  240. {"__stdcall", tSTDCALL, 0},
  241. {"_cdecl", tCDECL, 0},
  242. {"_fastcall", tFASTCALL, 0},
  243. {"_pascal", tPASCAL, 0},
  244. {"_stdcall", tSTDCALL, 0},
  245. {"apicontract", tAPICONTRACT, 1},
  246. {"boolean", tBOOLEAN, 0},
  247. {"byte", tBYTE, 0},
  248. {"case", tCASE, 0},
  249. {"cdecl", tCDECL, 0},
  250. {"char", tCHAR, 0},
  251. {"coclass", tCOCLASS, 0},
  252. {"const", tCONST, 0},
  253. {"cpp_quote", tCPPQUOTE, 0},
  254. {"declare", tDECLARE, 1},
  255. {"default", tDEFAULT, 0},
  256. {"delegate", tDELEGATE, 1},
  257. {"dispinterface", tDISPINTERFACE, 0},
  258. {"double", tDOUBLE, 0},
  259. {"enum", tENUM, 0},
  260. {"error_status_t", tERRORSTATUST, 0},
  261. {"extern", tEXTERN, 0},
  262. {"float", tFLOAT, 0},
  263. {"handle_t", tHANDLET, 0},
  264. {"hyper", tHYPER, 0},
  265. {"import", tIMPORT, 0},
  266. {"importlib", tIMPORTLIB, 0},
  267. {"inline", tINLINE, 0},
  268. {"int", tINT, 0},
  269. {"interface", tINTERFACE, 0},
  270. {"library", tLIBRARY, 0},
  271. {"long", tLONG, 0},
  272. {"methods", tMETHODS, 0},
  273. {"module", tMODULE, 0},
  274. {"namespace", tNAMESPACE, 1},
  275. {"pascal", tPASCAL, 0},
  276. {"properties", tPROPERTIES, 0},
  277. {"register", tREGISTER, 0},
  278. {"requires", tREQUIRES, 1},
  279. {"runtimeclass", tRUNTIMECLASS, 1},
  280. {"short", tSHORT, 0},
  281. {"signed", tSIGNED, 0},
  282. {"sizeof", tSIZEOF, 0},
  283. {"small", tSMALL, 0},
  284. {"static", tSTATIC, 0},
  285. {"stdcall", tSTDCALL, 0},
  286. {"struct", tSTRUCT, 0},
  287. {"switch", tSWITCH, 0},
  288. {"typedef", tTYPEDEF, 0},
  289. {"union", tUNION, 0},
  290. {"unsigned", tUNSIGNED, 0},
  291. {"void", tVOID, 0},
  292. {"wchar_t", tWCHAR, 0},
  293. };
  294. #define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0]))
  295. /* keywords only recognized in attribute lists
  296. * This table MUST be alphabetically sorted on the kw field
  297. */
  298. static const struct keyword attr_keywords[] =
  299. {
  300. {"activatable", tACTIVATABLE, 1},
  301. {"aggregatable", tAGGREGATABLE, 0},
  302. {"agile", tAGILE, 1},
  303. {"all_nodes", tALLNODES, 0},
  304. {"allocate", tALLOCATE, 0},
  305. {"annotation", tANNOTATION, 0},
  306. {"apartment", tAPARTMENT, 0},
  307. {"appobject", tAPPOBJECT, 0},
  308. {"async", tASYNC, 0},
  309. {"async_uuid", tASYNCUUID, 0},
  310. {"auto_handle", tAUTOHANDLE, 0},
  311. {"bindable", tBINDABLE, 0},
  312. {"both", tBOTH, 0},
  313. {"broadcast", tBROADCAST, 0},
  314. {"byte_count", tBYTECOUNT, 0},
  315. {"call_as", tCALLAS, 0},
  316. {"callback", tCALLBACK, 0},
  317. {"code", tCODE, 0},
  318. {"comm_status", tCOMMSTATUS, 0},
  319. {"context_handle", tCONTEXTHANDLE, 0},
  320. {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE, 0},
  321. {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE, 0},
  322. {"contract", tCONTRACT, 1},
  323. {"contractversion", tCONTRACTVERSION, 1},
  324. {"control", tCONTROL, 0},
  325. {"custom", tCUSTOM, 0},
  326. {"decode", tDECODE, 0},
  327. {"defaultbind", tDEFAULTBIND, 0},
  328. {"defaultcollelem", tDEFAULTCOLLELEM, 0},
  329. {"defaultvalue", tDEFAULTVALUE, 0},
  330. {"defaultvtable", tDEFAULTVTABLE, 0},
  331. {"disable_consistency_check", tDISABLECONSISTENCYCHECK, 0},
  332. {"displaybind", tDISPLAYBIND, 0},
  333. {"dllname", tDLLNAME, 0},
  334. {"dont_free", tDONTFREE, 0},
  335. {"dual", tDUAL, 0},
  336. {"enable_allocate", tENABLEALLOCATE, 0},
  337. {"encode", tENCODE, 0},
  338. {"endpoint", tENDPOINT, 0},
  339. {"entry", tENTRY, 0},
  340. {"eventadd", tEVENTADD, 1},
  341. {"eventremove", tEVENTREMOVE, 1},
  342. {"exclusiveto", tEXCLUSIVETO, 1},
  343. {"explicit_handle", tEXPLICITHANDLE, 0},
  344. {"fault_status", tFAULTSTATUS, 0},
  345. {"flags", tFLAGS, 1},
  346. {"force_allocate", tFORCEALLOCATE, 0},
  347. {"free", tFREE, 0},
  348. {"handle", tHANDLE, 0},
  349. {"helpcontext", tHELPCONTEXT, 0},
  350. {"helpfile", tHELPFILE, 0},
  351. {"helpstring", tHELPSTRING, 0},
  352. {"helpstringcontext", tHELPSTRINGCONTEXT, 0},
  353. {"helpstringdll", tHELPSTRINGDLL, 0},
  354. {"hidden", tHIDDEN, 0},
  355. {"id", tID, 0},
  356. {"idempotent", tIDEMPOTENT, 0},
  357. {"ignore", tIGNORE, 0},
  358. {"iid_is", tIIDIS, 0},
  359. {"immediatebind", tIMMEDIATEBIND, 0},
  360. {"implicit_handle", tIMPLICITHANDLE, 0},
  361. {"in", tIN, 0},
  362. {"in_line", tIN_LINE, 0},
  363. {"input_sync", tINPUTSYNC, 0},
  364. {"lcid", tLCID, 0},
  365. {"length_is", tLENGTHIS, 0},
  366. {"licensed", tLICENSED, 0},
  367. {"local", tLOCAL, 0},
  368. {"marshaling_behavior", tMARSHALINGBEHAVIOR, 1},
  369. {"maybe", tMAYBE, 0},
  370. {"message", tMESSAGE, 0},
  371. {"mta" , tMTA, 0},
  372. {"neutral", tNEUTRAL, 0},
  373. {"nocode", tNOCODE, 0},
  374. {"nonbrowsable", tNONBROWSABLE, 0},
  375. {"noncreatable", tNONCREATABLE, 0},
  376. {"none", tNONE, 1},
  377. {"nonextensible", tNONEXTENSIBLE, 0},
  378. {"notify", tNOTIFY, 0},
  379. {"notify_flag", tNOTIFYFLAG, 0},
  380. {"object", tOBJECT, 0},
  381. {"odl", tODL, 0},
  382. {"oleautomation", tOLEAUTOMATION, 0},
  383. {"optimize", tOPTIMIZE, 0},
  384. {"optional", tOPTIONAL, 0},
  385. {"out", tOUT, 0},
  386. {"partial_ignore", tPARTIALIGNORE, 0},
  387. {"pointer_default", tPOINTERDEFAULT, 0},
  388. {"progid", tPROGID, 0},
  389. {"propget", tPROPGET, 0},
  390. {"propput", tPROPPUT, 0},
  391. {"propputref", tPROPPUTREF, 0},
  392. {"proxy", tPROXY, 0},
  393. {"ptr", tPTR, 0},
  394. {"public", tPUBLIC, 0},
  395. {"range", tRANGE, 0},
  396. {"readonly", tREADONLY, 0},
  397. {"ref", tREF, 0},
  398. {"represent_as", tREPRESENTAS, 0},
  399. {"requestedit", tREQUESTEDIT, 0},
  400. {"restricted", tRESTRICTED, 0},
  401. {"retval", tRETVAL, 0},
  402. {"single", tSINGLE, 0},
  403. {"single_node", tSINGLENODE, 0},
  404. {"size_is", tSIZEIS, 0},
  405. {"source", tSOURCE, 0},
  406. {"standard", tSTANDARD, 1},
  407. {"static", tSTATIC, 1},
  408. {"strict_context_handle", tSTRICTCONTEXTHANDLE, 0},
  409. {"string", tSTRING, 0},
  410. {"switch_is", tSWITCHIS, 0},
  411. {"switch_type", tSWITCHTYPE, 0},
  412. {"threading", tTHREADING, 0},
  413. {"transmit_as", tTRANSMITAS, 0},
  414. {"uidefault", tUIDEFAULT, 0},
  415. {"unique", tUNIQUE, 0},
  416. {"user_marshal", tUSERMARSHAL, 0},
  417. {"usesgetlasterror", tUSESGETLASTERROR, 0},
  418. {"uuid", tUUID, 0},
  419. {"v1_enum", tV1ENUM, 0},
  420. {"vararg", tVARARG, 0},
  421. {"version", tVERSION, 0},
  422. {"vi_progid", tVIPROGID, 0},
  423. {"wire_marshal", tWIREMARSHAL, 0},
  424. };
  425. /* attributes TODO:
  426. first_is
  427. last_is
  428. max_is
  429. min_is
  430. */
  431. #define KWP(p) ((const struct keyword *)(p))
  432. static int kw_cmp_func(const void *s1, const void *s2)
  433. {
  434. return strcmp(KWP(s1)->kw, KWP(s2)->kw);
  435. }
  436. static int kw_token(const char *kw)
  437. {
  438. struct keyword key, *kwp;
  439. key.kw = kw;
  440. kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func);
  441. if (kwp && (!kwp->winrt_only || winrt_mode)) {
  442. parser_lval.str = xstrdup(kwp->kw);
  443. return kwp->token;
  444. }
  445. parser_lval.str = xstrdup(kw);
  446. return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER;
  447. }
  448. static int attr_token(const char *kw)
  449. {
  450. struct keyword key, *kwp;
  451. key.kw = kw;
  452. kwp = bsearch(&key, attr_keywords, sizeof(attr_keywords)/sizeof(attr_keywords[0]),
  453. sizeof(attr_keywords[0]), kw_cmp_func);
  454. if (kwp && (!kwp->winrt_only || winrt_mode)) {
  455. parser_lval.str = xstrdup(kwp->kw);
  456. return kwp->token;
  457. }
  458. return kw_token(kw);
  459. }
  460. static void addcchar(char c)
  461. {
  462. if(cbufidx >= cbufalloc)
  463. {
  464. cbufalloc += 1024;
  465. cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0]));
  466. if(cbufalloc > 65536)
  467. parser_warning("Reallocating string buffer larger than 64kB\n");
  468. }
  469. cbuffer[cbufidx++] = c;
  470. }
  471. static char *get_buffered_cstring(void)
  472. {
  473. addcchar(0);
  474. return xstrdup(cbuffer);
  475. }
  476. void pop_import(void)
  477. {
  478. int ptr = import_stack_ptr-1;
  479. fclose(yyin);
  480. yy_delete_buffer( YY_CURRENT_BUFFER );
  481. yy_switch_to_buffer( import_stack[ptr].state );
  482. if (temp_name) {
  483. unlink(temp_name);
  484. free(temp_name);
  485. }
  486. temp_name = import_stack[ptr].temp_name;
  487. input_name = import_stack[ptr].input_name;
  488. line_number = import_stack[ptr].line_number;
  489. import_stack_ptr--;
  490. }
  491. struct imports {
  492. char *name;
  493. struct imports *next;
  494. } *first_import;
  495. int do_import(char *fname)
  496. {
  497. FILE *f;
  498. char *path, *name;
  499. struct imports *import;
  500. int ptr = import_stack_ptr;
  501. int ret, fd;
  502. import = first_import;
  503. while (import && strcmp(import->name, fname))
  504. import = import->next;
  505. if (import) return 0; /* already imported */
  506. import = xmalloc(sizeof(struct imports));
  507. import->name = xstrdup(fname);
  508. import->next = first_import;
  509. first_import = import;
  510. /* don't search for a file name with a path in the include directories,
  511. * for compatibility with MIDL */
  512. if (strchr( fname, '/' ) || strchr( fname, '\\' ))
  513. path = xstrdup( fname );
  514. else if (!(path = wpp_find_include( fname, input_name )))
  515. error_loc("Unable to open include file %s\n", fname);
  516. if (import_stack_ptr == MAX_IMPORT_DEPTH)
  517. error_loc("Exceeded max import depth\n");
  518. import_stack[ptr].temp_name = temp_name;
  519. import_stack[ptr].input_name = input_name;
  520. import_stack[ptr].line_number = line_number;
  521. import_stack_ptr++;
  522. input_name = path;
  523. line_number = 1;
  524. name = xstrdup( "widl.XXXXXX" );
  525. if((fd = mkstemps( name, 0 )) == -1)
  526. error("Could not generate a temp name from %s\n", name);
  527. temp_name = name;
  528. if (!(f = fdopen(fd, "wt")))
  529. error("Could not open fd %s for writing\n", name);
  530. ret = wpp_parse( path, f );
  531. fclose( f );
  532. if (ret) exit(1);
  533. if((f = fopen(temp_name, "r")) == NULL)
  534. error_loc("Unable to open %s\n", temp_name);
  535. import_stack[ptr].state = YY_CURRENT_BUFFER;
  536. yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
  537. return 1;
  538. }
  539. void abort_import(void)
  540. {
  541. int ptr;
  542. for (ptr=0; ptr<import_stack_ptr; ptr++)
  543. unlink(import_stack[ptr].temp_name);
  544. }
  545. static void switch_to_acf(void)
  546. {
  547. int ptr = import_stack_ptr;
  548. int ret, fd;
  549. char *name;
  550. FILE *f;
  551. assert(import_stack_ptr == 0);
  552. input_name = acf_name;
  553. acf_name = NULL;
  554. line_number = 1;
  555. name = xstrdup( "widl.XXXXXX" );
  556. if((fd = mkstemps( name, 0 )) == -1)
  557. error("Could not generate a temp name from %s\n", name);
  558. temp_name = name;
  559. if (!(f = fdopen(fd, "wt")))
  560. error("Could not open fd %s for writing\n", name);
  561. ret = wpp_parse(input_name, f);
  562. fclose(f);
  563. if (ret) exit(1);
  564. if((f = fopen(temp_name, "r")) == NULL)
  565. error_loc("Unable to open %s\n", temp_name);
  566. import_stack[ptr].state = YY_CURRENT_BUFFER;
  567. yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
  568. }
  569. static void warning_disable(int warning)
  570. {
  571. warning_t *warning_entry;
  572. LIST_FOR_EACH_ENTRY(warning_entry, disabled_warnings, warning_t, entry)
  573. if(warning_entry->num == warning)
  574. return;
  575. warning_entry = xmalloc( sizeof(*warning_entry) );
  576. warning_entry->num = warning;
  577. list_add_tail(disabled_warnings, &warning_entry->entry);
  578. }
  579. static void warning_enable(int warning)
  580. {
  581. warning_t *warning_entry;
  582. LIST_FOR_EACH_ENTRY(warning_entry, disabled_warnings, warning_t, entry)
  583. if(warning_entry->num == warning)
  584. {
  585. list_remove(&warning_entry->entry);
  586. free(warning_entry);
  587. break;
  588. }
  589. }
  590. int do_warning(const char *toggle, warning_list_t *wnum)
  591. {
  592. warning_t *warning, *next;
  593. int ret = 1;
  594. if(!disabled_warnings)
  595. {
  596. disabled_warnings = xmalloc( sizeof(*disabled_warnings) );
  597. list_init( disabled_warnings );
  598. }
  599. if(!strcmp(toggle, "disable"))
  600. LIST_FOR_EACH_ENTRY(warning, wnum, warning_t, entry)
  601. warning_disable(warning->num);
  602. else if(!strcmp(toggle, "enable") || !strcmp(toggle, "default"))
  603. LIST_FOR_EACH_ENTRY(warning, wnum, warning_t, entry)
  604. warning_enable(warning->num);
  605. else
  606. ret = 0;
  607. LIST_FOR_EACH_ENTRY_SAFE(warning, next, wnum, warning_t, entry)
  608. free(warning);
  609. return ret;
  610. }
  611. int is_warning_enabled(int warning)
  612. {
  613. warning_t *warning_entry;
  614. if(!disabled_warnings)
  615. return 1;
  616. LIST_FOR_EACH_ENTRY(warning_entry, disabled_warnings, warning_t, entry)
  617. if(warning_entry->num == warning)
  618. return 0;
  619. return 1;
  620. }