parser.l 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  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. };
  228. /* This table MUST be alphabetically sorted on the kw field */
  229. static const struct keyword keywords[] = {
  230. {"FALSE", tFALSE},
  231. {"NULL", tNULL},
  232. {"TRUE", tTRUE},
  233. {"__cdecl", tCDECL},
  234. {"__fastcall", tFASTCALL},
  235. {"__int32", tINT32},
  236. {"__int3264", tINT3264},
  237. {"__int64", tINT64},
  238. {"__pascal", tPASCAL},
  239. {"__stdcall", tSTDCALL},
  240. {"_cdecl", tCDECL},
  241. {"_fastcall", tFASTCALL},
  242. {"_pascal", tPASCAL},
  243. {"_stdcall", tSTDCALL},
  244. {"boolean", tBOOLEAN},
  245. {"byte", tBYTE},
  246. {"case", tCASE},
  247. {"cdecl", tCDECL},
  248. {"char", tCHAR},
  249. {"coclass", tCOCLASS},
  250. {"const", tCONST},
  251. {"cpp_quote", tCPPQUOTE},
  252. {"default", tDEFAULT},
  253. {"dispinterface", tDISPINTERFACE},
  254. {"double", tDOUBLE},
  255. {"enum", tENUM},
  256. {"error_status_t", tERRORSTATUST},
  257. {"extern", tEXTERN},
  258. {"float", tFLOAT},
  259. {"handle_t", tHANDLET},
  260. {"hyper", tHYPER},
  261. {"import", tIMPORT},
  262. {"importlib", tIMPORTLIB},
  263. {"inline", tINLINE},
  264. {"int", tINT},
  265. {"interface", tINTERFACE},
  266. {"library", tLIBRARY},
  267. {"long", tLONG},
  268. {"methods", tMETHODS},
  269. {"module", tMODULE},
  270. {"namespace", tNAMESPACE},
  271. {"pascal", tPASCAL},
  272. {"properties", tPROPERTIES},
  273. {"register", tREGISTER},
  274. {"short", tSHORT},
  275. {"signed", tSIGNED},
  276. {"sizeof", tSIZEOF},
  277. {"small", tSMALL},
  278. {"static", tSTATIC},
  279. {"stdcall", tSTDCALL},
  280. {"struct", tSTRUCT},
  281. {"switch", tSWITCH},
  282. {"typedef", tTYPEDEF},
  283. {"union", tUNION},
  284. {"unsigned", tUNSIGNED},
  285. {"void", tVOID},
  286. {"wchar_t", tWCHAR},
  287. };
  288. #define NKEYWORDS (sizeof(keywords)/sizeof(keywords[0]))
  289. /* keywords only recognized in attribute lists
  290. * This table MUST be alphabetically sorted on the kw field
  291. */
  292. static const struct keyword attr_keywords[] =
  293. {
  294. {"aggregatable", tAGGREGATABLE},
  295. {"allocate", tALLOCATE},
  296. {"annotation", tANNOTATION},
  297. {"apartment", tAPARTMENT},
  298. {"appobject", tAPPOBJECT},
  299. {"async", tASYNC},
  300. {"async_uuid", tASYNCUUID},
  301. {"auto_handle", tAUTOHANDLE},
  302. {"bindable", tBINDABLE},
  303. {"both", tBOTH},
  304. {"broadcast", tBROADCAST},
  305. {"byte_count", tBYTECOUNT},
  306. {"call_as", tCALLAS},
  307. {"callback", tCALLBACK},
  308. {"code", tCODE},
  309. {"comm_status", tCOMMSTATUS},
  310. {"context_handle", tCONTEXTHANDLE},
  311. {"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE},
  312. {"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE},
  313. {"control", tCONTROL},
  314. {"decode", tDECODE},
  315. {"defaultbind", tDEFAULTBIND},
  316. {"defaultcollelem", tDEFAULTCOLLELEM},
  317. {"defaultvalue", tDEFAULTVALUE},
  318. {"defaultvtable", tDEFAULTVTABLE},
  319. {"disable_consistency_check", tDISABLECONSISTENCYCHECK},
  320. {"displaybind", tDISPLAYBIND},
  321. {"dllname", tDLLNAME},
  322. {"dual", tDUAL},
  323. {"enable_allocate", tENABLEALLOCATE},
  324. {"encode", tENCODE},
  325. {"endpoint", tENDPOINT},
  326. {"entry", tENTRY},
  327. {"explicit_handle", tEXPLICITHANDLE},
  328. {"fault_status", tFAULTSTATUS},
  329. {"force_allocate", tFORCEALLOCATE},
  330. {"free", tFREE},
  331. {"handle", tHANDLE},
  332. {"helpcontext", tHELPCONTEXT},
  333. {"helpfile", tHELPFILE},
  334. {"helpstring", tHELPSTRING},
  335. {"helpstringcontext", tHELPSTRINGCONTEXT},
  336. {"helpstringdll", tHELPSTRINGDLL},
  337. {"hidden", tHIDDEN},
  338. {"id", tID},
  339. {"idempotent", tIDEMPOTENT},
  340. {"ignore", tIGNORE},
  341. {"iid_is", tIIDIS},
  342. {"immediatebind", tIMMEDIATEBIND},
  343. {"implicit_handle", tIMPLICITHANDLE},
  344. {"in", tIN},
  345. {"in_line", tIN_LINE},
  346. {"input_sync", tINPUTSYNC},
  347. {"lcid", tLCID},
  348. {"length_is", tLENGTHIS},
  349. {"licensed", tLICENSED},
  350. {"local", tLOCAL},
  351. {"maybe", tMAYBE},
  352. {"message", tMESSAGE},
  353. {"neutral", tNEUTRAL},
  354. {"nocode", tNOCODE},
  355. {"nonbrowsable", tNONBROWSABLE},
  356. {"noncreatable", tNONCREATABLE},
  357. {"nonextensible", tNONEXTENSIBLE},
  358. {"notify", tNOTIFY},
  359. {"notify_flag", tNOTIFYFLAG},
  360. {"object", tOBJECT},
  361. {"odl", tODL},
  362. {"oleautomation", tOLEAUTOMATION},
  363. {"optimize", tOPTIMIZE},
  364. {"optional", tOPTIONAL},
  365. {"out", tOUT},
  366. {"partial_ignore", tPARTIALIGNORE},
  367. {"pointer_default", tPOINTERDEFAULT},
  368. {"progid", tPROGID},
  369. {"propget", tPROPGET},
  370. {"propput", tPROPPUT},
  371. {"propputref", tPROPPUTREF},
  372. {"proxy", tPROXY},
  373. {"ptr", tPTR},
  374. {"public", tPUBLIC},
  375. {"range", tRANGE},
  376. {"readonly", tREADONLY},
  377. {"ref", tREF},
  378. {"represent_as", tREPRESENTAS},
  379. {"requestedit", tREQUESTEDIT},
  380. {"restricted", tRESTRICTED},
  381. {"retval", tRETVAL},
  382. {"single", tSINGLE},
  383. {"size_is", tSIZEIS},
  384. {"source", tSOURCE},
  385. {"strict_context_handle", tSTRICTCONTEXTHANDLE},
  386. {"string", tSTRING},
  387. {"switch_is", tSWITCHIS},
  388. {"switch_type", tSWITCHTYPE},
  389. {"threading", tTHREADING},
  390. {"transmit_as", tTRANSMITAS},
  391. {"uidefault", tUIDEFAULT},
  392. {"unique", tUNIQUE},
  393. {"user_marshal", tUSERMARSHAL},
  394. {"usesgetlasterror", tUSESGETLASTERROR},
  395. {"uuid", tUUID},
  396. {"v1_enum", tV1ENUM},
  397. {"vararg", tVARARG},
  398. {"version", tVERSION},
  399. {"vi_progid", tVIPROGID},
  400. {"wire_marshal", tWIREMARSHAL},
  401. };
  402. /* attributes TODO:
  403. custom
  404. first_is
  405. last_is
  406. max_is
  407. min_is
  408. */
  409. #define KWP(p) ((const struct keyword *)(p))
  410. static int kw_cmp_func(const void *s1, const void *s2)
  411. {
  412. return strcmp(KWP(s1)->kw, KWP(s2)->kw);
  413. }
  414. static int kw_token(const char *kw)
  415. {
  416. struct keyword key, *kwp;
  417. key.kw = kw;
  418. kwp = bsearch(&key, keywords, NKEYWORDS, sizeof(keywords[0]), kw_cmp_func);
  419. if (kwp && (winrt_mode || kwp->token != tNAMESPACE)) {
  420. parser_lval.str = xstrdup(kwp->kw);
  421. return kwp->token;
  422. }
  423. parser_lval.str = xstrdup(kw);
  424. return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER;
  425. }
  426. static int attr_token(const char *kw)
  427. {
  428. struct keyword key, *kwp;
  429. key.kw = kw;
  430. kwp = bsearch(&key, attr_keywords, sizeof(attr_keywords)/sizeof(attr_keywords[0]),
  431. sizeof(attr_keywords[0]), kw_cmp_func);
  432. if (kwp) {
  433. parser_lval.str = xstrdup(kwp->kw);
  434. return kwp->token;
  435. }
  436. return kw_token(kw);
  437. }
  438. static void addcchar(char c)
  439. {
  440. if(cbufidx >= cbufalloc)
  441. {
  442. cbufalloc += 1024;
  443. cbuffer = xrealloc(cbuffer, cbufalloc * sizeof(cbuffer[0]));
  444. if(cbufalloc > 65536)
  445. parser_warning("Reallocating string buffer larger than 64kB\n");
  446. }
  447. cbuffer[cbufidx++] = c;
  448. }
  449. static char *get_buffered_cstring(void)
  450. {
  451. addcchar(0);
  452. return xstrdup(cbuffer);
  453. }
  454. void pop_import(void)
  455. {
  456. int ptr = import_stack_ptr-1;
  457. fclose(yyin);
  458. yy_delete_buffer( YY_CURRENT_BUFFER );
  459. yy_switch_to_buffer( import_stack[ptr].state );
  460. if (temp_name) {
  461. unlink(temp_name);
  462. free(temp_name);
  463. }
  464. temp_name = import_stack[ptr].temp_name;
  465. input_name = import_stack[ptr].input_name;
  466. line_number = import_stack[ptr].line_number;
  467. import_stack_ptr--;
  468. }
  469. struct imports {
  470. char *name;
  471. struct imports *next;
  472. } *first_import;
  473. int do_import(char *fname)
  474. {
  475. FILE *f;
  476. char *path, *name;
  477. struct imports *import;
  478. int ptr = import_stack_ptr;
  479. int ret, fd;
  480. import = first_import;
  481. while (import && strcmp(import->name, fname))
  482. import = import->next;
  483. if (import) return 0; /* already imported */
  484. import = xmalloc(sizeof(struct imports));
  485. import->name = xstrdup(fname);
  486. import->next = first_import;
  487. first_import = import;
  488. /* don't search for a file name with a path in the include directories,
  489. * for compatibility with MIDL */
  490. if (strchr( fname, '/' ) || strchr( fname, '\\' ))
  491. path = xstrdup( fname );
  492. else if (!(path = wpp_find_include( fname, input_name )))
  493. error_loc("Unable to open include file %s\n", fname);
  494. if (import_stack_ptr == MAX_IMPORT_DEPTH)
  495. error_loc("Exceeded max import depth\n");
  496. import_stack[ptr].temp_name = temp_name;
  497. import_stack[ptr].input_name = input_name;
  498. import_stack[ptr].line_number = line_number;
  499. import_stack_ptr++;
  500. input_name = path;
  501. line_number = 1;
  502. name = xstrdup( "widl.XXXXXX" );
  503. if((fd = mkstemps( name, 0 )) == -1)
  504. error("Could not generate a temp name from %s\n", name);
  505. temp_name = name;
  506. if (!(f = fdopen(fd, "wt")))
  507. error("Could not open fd %s for writing\n", name);
  508. ret = wpp_parse( path, f );
  509. fclose( f );
  510. if (ret) exit(1);
  511. if((f = fopen(temp_name, "r")) == NULL)
  512. error_loc("Unable to open %s\n", temp_name);
  513. import_stack[ptr].state = YY_CURRENT_BUFFER;
  514. yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
  515. return 1;
  516. }
  517. void abort_import(void)
  518. {
  519. int ptr;
  520. for (ptr=0; ptr<import_stack_ptr; ptr++)
  521. unlink(import_stack[ptr].temp_name);
  522. }
  523. static void switch_to_acf(void)
  524. {
  525. int ptr = import_stack_ptr;
  526. int ret, fd;
  527. char *name;
  528. FILE *f;
  529. assert(import_stack_ptr == 0);
  530. input_name = acf_name;
  531. acf_name = NULL;
  532. line_number = 1;
  533. name = xstrdup( "widl.XXXXXX" );
  534. if((fd = mkstemps( name, 0 )) == -1)
  535. error("Could not generate a temp name from %s\n", name);
  536. temp_name = name;
  537. if (!(f = fdopen(fd, "wt")))
  538. error("Could not open fd %s for writing\n", name);
  539. ret = wpp_parse(input_name, f);
  540. fclose(f);
  541. if (ret) exit(1);
  542. if((f = fopen(temp_name, "r")) == NULL)
  543. error_loc("Unable to open %s\n", temp_name);
  544. import_stack[ptr].state = YY_CURRENT_BUFFER;
  545. yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
  546. }
  547. static void warning_disable(int warning)
  548. {
  549. warning_t *warning_entry;
  550. LIST_FOR_EACH_ENTRY(warning_entry, disabled_warnings, warning_t, entry)
  551. if(warning_entry->num == warning)
  552. return;
  553. warning_entry = xmalloc( sizeof(*warning_entry) );
  554. warning_entry->num = warning;
  555. list_add_tail(disabled_warnings, &warning_entry->entry);
  556. }
  557. static void warning_enable(int warning)
  558. {
  559. warning_t *warning_entry;
  560. LIST_FOR_EACH_ENTRY(warning_entry, disabled_warnings, warning_t, entry)
  561. if(warning_entry->num == warning)
  562. {
  563. list_remove(&warning_entry->entry);
  564. free(warning_entry);
  565. break;
  566. }
  567. }
  568. int do_warning(char *toggle, warning_list_t *wnum)
  569. {
  570. warning_t *warning, *next;
  571. int ret = 1;
  572. if(!disabled_warnings)
  573. {
  574. disabled_warnings = xmalloc( sizeof(*disabled_warnings) );
  575. list_init( disabled_warnings );
  576. }
  577. if(!strcmp(toggle, "disable"))
  578. LIST_FOR_EACH_ENTRY(warning, wnum, warning_t, entry)
  579. warning_disable(warning->num);
  580. else if(!strcmp(toggle, "enable"))
  581. LIST_FOR_EACH_ENTRY(warning, wnum, warning_t, entry)
  582. warning_enable(warning->num);
  583. else
  584. ret = 0;
  585. LIST_FOR_EACH_ENTRY_SAFE(warning, next, wnum, warning_t, entry)
  586. free(warning);
  587. return ret;
  588. }
  589. int is_warning_enabled(int warning)
  590. {
  591. warning_t *warning_entry;
  592. if(!disabled_warnings)
  593. return 1;
  594. LIST_FOR_EACH_ENTRY(warning_entry, disabled_warnings, warning_t, entry)
  595. if(warning_entry->num == warning)
  596. return 0;
  597. return 1;
  598. }