parser.l 24 KB

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