Reactos
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
21%option bison-bridge
22%option bison-locations
23%option stack
24%option noinput nounput noyy_top_state
25%option noyywrap
26%option 8bit never-interactive prefix="parser_"
27
28ws [ \f\t\r]
29hd [0-9a-fA-F]
30uuid {hd}{8}-{hd}{4}-{hd}{4}-{hd}{4}-{hd}{12}
31
32%x ATTR
33%x PP_LINE
34%x PP_FILE
35%x PP_PRAGMA
36
37%{
38
39#include "config.h"
40
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
50#include "widl.h"
51#include "utils.h"
52#include "parser.h"
53#include "wpp_private.h"
54
55#define YYerror PARSER_error
56#define YYSTYPE PARSER_STYPE
57#define YYLTYPE PARSER_LTYPE
58#define YYUNDEF PARSER_UNDEF
59#define yyerror parser_error
60
61#include "parser.tab.h"
62
63static void reset_location( struct location *where, const char *input_name );
64static void update_location( struct location *where, const char *yytext );
65static void end_of_line( struct location *where );
66
67#define YY_USER_INIT reset_location( yylloc, input_name )
68#define YY_USER_ACTION update_location( yylloc, yytext );
69
70static void switch_to_acf(void);
71
72static warning_list_t *disabled_warnings = NULL;
73
74struct import_state
75{
76 YY_BUFFER_STATE buffer;
77 char *input_name;
78 struct location where;
79 struct list entry;
80};
81static struct list import_stack = LIST_INIT( import_stack );
82int parse_only = 0;
83
84struct import
85{
86 const char *name;
87 struct list entry;
88};
89static struct list imports = LIST_INIT( imports );
90static struct location previous_location;
91
92/* converts an integer in string form to an unsigned long and prints an error
93 * on overflow */
94static unsigned int xstrtoul(const char *nptr, char **endptr, int base)
95{
96 unsigned long val;
97
98 errno = 0;
99 val = strtoul(nptr, endptr, base);
100 if ((val == ULONG_MAX && errno == ERANGE) || ((unsigned int)val != val))
101 error_loc("integer constant %s is too large\n", nptr);
102 return val;
103}
104
105static int token_uuid( const char *str, YYSTYPE *yylval )
106{
107 struct uuid *uuid;
108 char tmp[3] = {0};
109
110 if (*str == '\"') str++;
111
112 uuid = xmalloc( sizeof(*uuid) );
113 uuid->Data1 = strtoul( str , NULL, 16 );
114 uuid->Data2 = strtoul( str + 9, NULL, 16 );
115 uuid->Data3 = strtoul( str + 14, NULL, 16 );
116 memcpy( tmp, str + 19, 2 );
117 uuid->Data4[0] = strtoul( tmp, NULL, 16 );
118 memcpy( tmp, str + 21, 2 );
119 uuid->Data4[1] = strtoul( tmp, NULL, 16 );
120 memcpy( tmp, str + 24, 2 );
121 uuid->Data4[2] = strtoul( tmp, NULL, 16 );
122 memcpy( tmp, str + 26, 2 );
123 uuid->Data4[3] = strtoul( tmp, NULL, 16 );
124 memcpy( tmp, str + 28, 2 );
125 uuid->Data4[4] = strtoul( tmp, NULL, 16 );
126 memcpy( tmp, str + 30, 2 );
127 uuid->Data4[5] = strtoul( tmp, NULL, 16 );
128 memcpy( tmp, str + 32, 2 );
129 uuid->Data4[6] = strtoul( tmp, NULL, 16 );
130 memcpy( tmp, str + 34, 2 );
131 uuid->Data4[7] = strtoul( tmp, NULL, 16 );
132
133 yylval->uuid = uuid;
134 return aUUID;
135}
136
137static int token_str( int token, const char *str, YYSTYPE *yylval )
138{
139 char *tmp = xstrdup( str );
140
141 if (token == aWSTRING || token == aSTRING || token == aSQSTRING)
142 {
143 char *src, *dst;
144 src = dst = ++tmp; /* skip first quote */
145 while (*src)
146 {
147 if (*src == '\\') src++;
148 *dst++ = *src++;
149 }
150 dst[-1] = 0; /* strip last quote */
151 }
152
153 yylval->str = tmp;
154 return token;
155}
156
157static int token_num( const char *yytext, YYSTYPE *yylval, int is_hex )
158{
159 yylval->integer.value = xstrtoul( yytext, NULL, 0 );
160 yylval->integer.is_hex = is_hex;
161 yylval->integer.is_long = !!strchr(yytext, 'l');
162 yylval->integer.is_unsigned = !!strchr(yytext, 'u');
163 return is_hex ? aHEXNUM : aNUM;
164}
165
166static int token_ident( const char *str, YYSTYPE *yylval )
167{
168 return token_str( is_type( str ) ? aKNOWNTYPE : aIDENTIFIER, str, yylval );
169}
170
171static int token_winrt( int token, const char *str, YYSTYPE *yylval )
172{
173 if (winrt_mode) return token;
174 return token_ident( str, yylval );
175}
176
177static void winrt_enable( int ns_prefix )
178{
179 if (!list_empty( &import_stack ) && !winrt_mode) error_loc( "WinRT IDL file imported in non-winrt mode.\n" );
180
181 use_abi_namespace = ns_prefix;
182 winrt_mode = TRUE;
183}
184
185%}
186
187/*
188 **************************************************************************
189 * The flexer starts here
190 **************************************************************************
191 */
192%%
193<PP_PRAGMA>{
194 midl_echo/"(" {
195 yy_pop_state();
196 yylloc->first_line -= 1;
197 return tCPPQUOTE;
198 }
199 winrt{ws}+ns_prefix[^\n]* {
200 yy_pop_state();
201 yylloc->first_line -= 1;
202 winrt_enable( TRUE );
203 }
204 winrt[^\n]* {
205 yy_pop_state();
206 yylloc->first_line -= 1;
207 winrt_enable( FALSE );
208 }
209 [^\n]* {
210 yy_pop_state();
211 yylloc->first_line -= 1;
212 return token_str( aPRAGMA, yytext, yylval );
213 }
214}
215<PP_LINE>[0-9]+{ws}* {
216 yylloc->first_line = strtoul( yytext, NULL, 10 ) - 1;
217 yylloc->last_line = yylloc->first_line;
218 yy_pop_state();
219 yy_push_state(PP_FILE);
220 }
221<PP_FILE>\"(\\[^n]|[^"\\\n])*\"{ws}* {
222 input_name = xstrdup( yytext + 1 );
223 *strchr( input_name, '"' ) = 0;
224 yylloc->input_name = input_name;
225 }
226<PP_FILE>[^"][^\n]* { yy_pop_state(); }
227
228<ATTR>{
229 \] { yy_pop_state(); return ']'; }
230
231 ({uuid}|\"{uuid}\") { return token_uuid( yytext, yylval ); }
232 activatable { return token_winrt( tACTIVATABLE, yytext, yylval ); }
233 aggregatable { return tAGGREGATABLE; }
234 agile { return token_winrt( tAGILE, yytext, yylval ); }
235 all_nodes { return tALLNODES; }
236 allocate { return tALLOCATE; }
237 annotation { return tANNOTATION; }
238 apartment { return tAPARTMENT; }
239 appobject { return tAPPOBJECT; }
240 async { return tASYNC; }
241 async_uuid { return tASYNCUUID; }
242 auto_handle { return tAUTOHANDLE; }
243 bindable { return tBINDABLE; }
244 both { return tBOTH; }
245 broadcast { return tBROADCAST; }
246 byte_count { return tBYTECOUNT; }
247 call_as { return tCALLAS; }
248 callback { return tCALLBACK; }
249 code { return tCODE; }
250 comm_status { return tCOMMSTATUS; }
251 composable { return token_winrt( tCOMPOSABLE, yytext, yylval ); }
252 context_handle { return tCONTEXTHANDLE; }
253 context_handle_noserialize { return tCONTEXTHANDLENOSERIALIZE; }
254 context_handle_serialize { return tCONTEXTHANDLENOSERIALIZE; }
255 contract { return token_winrt( tCONTRACT, yytext, yylval ); }
256 contractversion { return token_winrt( tCONTRACTVERSION, yytext, yylval ); }
257 control { return tCONTROL; }
258 custom { return tCUSTOM; }
259 decode { return tDECODE; }
260 default_overload { return tDEFAULT_OVERLOAD; }
261 defaultbind { return tDEFAULTBIND; }
262 defaultcollelem { return tDEFAULTCOLLELEM; }
263 defaultvalue { return tDEFAULTVALUE; }
264 defaultvtable { return tDEFAULTVTABLE; }
265 deprecated { return token_winrt( tDEPRECATED, yytext, yylval ); }
266 disable_consistency_check { return tDISABLECONSISTENCYCHECK; }
267 displaybind { return tDISPLAYBIND; }
268 dllname { return tDLLNAME; }
269 dont_free { return tDONTFREE; }
270 dual { return tDUAL; }
271 enable_allocate { return tENABLEALLOCATE; }
272 encode { return tENCODE; }
273 endpoint { return tENDPOINT; }
274 entry { return tENTRY; }
275 eventadd { return token_winrt( tEVENTADD, yytext, yylval ); }
276 eventremove { return token_winrt( tEVENTREMOVE, yytext, yylval ); }
277 exclusiveto { return token_winrt( tEXCLUSIVETO, yytext, yylval ); }
278 explicit_handle { return tEXPLICITHANDLE; }
279 fault_status { return tFAULTSTATUS; }
280 flags { return token_winrt( tFLAGS, yytext, yylval ); }
281 force_allocate { return tFORCEALLOCATE; }
282 free { return tFREE; }
283 handle { return tHANDLE; }
284 helpcontext { return tHELPCONTEXT; }
285 helpfile { return tHELPFILE; }
286 helpstring { return tHELPSTRING; }
287 helpstringcontext { return tHELPSTRINGCONTEXT; }
288 helpstringdll { return tHELPSTRINGDLL; }
289 hidden { return tHIDDEN; }
290 id { return tID; }
291 idempotent { return tIDEMPOTENT; }
292 ignore { return tIGNORE; }
293 iid_is { return tIIDIS; }
294 immediatebind { return tIMMEDIATEBIND; }
295 implicit_handle { return tIMPLICITHANDLE; }
296 in { return tIN; }
297 in_line { return tIN_LINE; }
298 input_sync { return tINPUTSYNC; }
299 lcid { return tLCID; }
300 length_is { return tLENGTHIS; }
301 licensed { return tLICENSED; }
302 local { return tLOCAL; }
303 marshaling_behavior { return token_winrt( tMARSHALINGBEHAVIOR, yytext, yylval ); }
304 maybe { return tMAYBE; }
305 message { return tMESSAGE; }
306 mta { return tMTA; }
307 neutral { return tNEUTRAL; }
308 nocode { return tNOCODE; }
309 nonbrowsable { return tNONBROWSABLE; }
310 noncreatable { return tNONCREATABLE; }
311 none { return token_winrt( tNONE, yytext, yylval ); }
312 nonextensible { return tNONEXTENSIBLE; }
313 notify { return tNOTIFY; }
314 notify_flag { return tNOTIFYFLAG; }
315 object { return tOBJECT; }
316 odl { return tODL; }
317 oleautomation { return tOLEAUTOMATION; }
318 optimize { return tOPTIMIZE; }
319 optional { return tOPTIONAL; }
320 out { return tOUT; }
321 overload { return tOVERLOAD; }
322 partial_ignore { return tPARTIALIGNORE; }
323 pointer_default { return tPOINTERDEFAULT; }
324 progid { return tPROGID; }
325 propget { return tPROPGET; }
326 propput { return tPROPPUT; }
327 propputref { return tPROPPUTREF; }
328 protected { return tPROTECTED; }
329 proxy { return tPROXY; }
330 ptr { return tPTR; }
331 public { return tPUBLIC; }
332 range { return tRANGE; }
333 readonly { return tREADONLY; }
334 ref { return tREF; }
335 represent_as { return tREPRESENTAS; }
336 requestedit { return tREQUESTEDIT; }
337 restricted { return tRESTRICTED; }
338 retval { return tRETVAL; }
339 single { return tSINGLE; }
340 single_node { return tSINGLENODE; }
341 size_is { return tSIZEIS; }
342 source { return tSOURCE; }
343 standard { return token_winrt( tSTANDARD, yytext, yylval ); }
344 static { return token_winrt( tSTATIC, yytext, yylval ); }
345 strict_context_handle { return tSTRICTCONTEXTHANDLE; }
346 string { return tSTRING; }
347 switch_is { return tSWITCHIS; }
348 switch_type { return tSWITCHTYPE; }
349 threading { return tTHREADING; }
350 transmit_as { return tTRANSMITAS; }
351 uidefault { return tUIDEFAULT; }
352 unique { return tUNIQUE; }
353 user_marshal { return tUSERMARSHAL; }
354 usesgetlasterror { return tUSESGETLASTERROR; }
355 uuid { return tUUID; }
356 v1_enum { return tV1ENUM; }
357 vararg { return tVARARG; }
358 version { return tVERSION; }
359 vi_progid { return tVIPROGID; }
360 wire_marshal { return tWIREMARSHAL; }
361}
362
363<INITIAL>{
364 ^{ws}*\#{ws}*pragma{ws}+ { yy_push_state( PP_PRAGMA ); }
365 ^{ws}*midl_pragma{ws}+warning { return tPRAGMA_WARNING; }
366
367 [0-9]+\.[0-9]+([eE][+-]?[0-9]+)* {
368 yylval->dbl = strtod( yytext, NULL );
369 return aDOUBLE;
370 }
371}
372
373SAFEARRAY{ws}*/\( return tSAFEARRAY;
374
375<INITIAL,ATTR>{
376 ^{ws}*\#{ws}* { yy_push_state(PP_LINE); }
377 \[ { yy_push_state(ATTR); return '['; }
378
379 FALSE { return tFALSE; }
380 NULL { return tNULL; }
381 TRUE { return tTRUE; }
382 _?_?cdecl { return token_str( tCDECL, "__cdecl", yylval ); }
383 _?_?pascal { return token_str( tPASCAL, "__pascal", yylval ); }
384 _?_?stdcall { return token_str( tSTDCALL, "__stdcall", yylval ); }
385 __?fastcall { return token_str( tFASTCALL, "__fastcall", yylval ); }
386 __int32 { return tINT32; }
387 __int3264 { return tINT3264; }
388 __int64 { return tINT64; }
389 apicontract { return token_winrt( tAPICONTRACT, yytext, yylval ); }
390 boolean { return tBOOLEAN; }
391 byte { return tBYTE; }
392 case { return tCASE; }
393 char { return tCHAR; }
394 coclass { return tCOCLASS; }
395 const { return tCONST; }
396 cpp_quote { return tCPPQUOTE; }
397 declare { return token_winrt( tDECLARE, yytext, yylval ); }
398 default { return tDEFAULT; }
399 delegate { return token_winrt( tDELEGATE, yytext, yylval ); }
400 dispinterface { return tDISPINTERFACE; }
401 double { return tDOUBLE; }
402 enum { return tENUM; }
403 error_status_t { return tERRORSTATUST; }
404 extern { return tEXTERN; }
405 float { return tFLOAT; }
406 handle_t { return tHANDLET; }
407 hyper { return tHYPER; }
408 import { return tIMPORT; }
409 importlib { return tIMPORTLIB; }
410 inline { return tINLINE; }
411 int { return tINT; }
412 interface { return tINTERFACE; }
413 library { return tLIBRARY; }
414 long { return tLONG; }
415 methods { return tMETHODS; }
416 module { return tMODULE; }
417 namespace { return token_winrt( tNAMESPACE, yytext, yylval ); }
418 properties { return tPROPERTIES; }
419 register { return tREGISTER; }
420 requires { return token_winrt( tREQUIRES, yytext, yylval ); }
421 runtimeclass { return token_winrt( tRUNTIMECLASS, yytext, yylval ); }
422 short { return tSHORT; }
423 signed { return tSIGNED; }
424 sizeof { return tSIZEOF; }
425 small { return tSMALL; }
426 static { return tSTATIC; }
427 struct { return tSTRUCT; }
428 switch { return tSWITCH; }
429 typedef { return tTYPEDEF; }
430 union { return tUNION; }
431 unsigned { return tUNSIGNED; }
432 void { return tVOID; }
433 wchar_t { return tWCHAR; }
434
435 [a-zA-Z_][0-9a-zA-Z_]* { return token_ident( yytext, yylval ); }
436
437 0[xX]{hd}+[uU]?[lL]? { return token_num( yytext, yylval, TRUE ); }
438 [0-9]+[uU]?[lL]? { return token_num( yytext, yylval, FALSE ); }
439
440 L\"(\\.|[^"\\])*\" { return token_str( aWSTRING, yytext + 1, yylval ); }
441 \"(\\.|[^"\\])*\" { return token_str( aSTRING, yytext, yylval ); }
442 \'(\\.|[^'\\])*\' { return token_str( aSQSTRING, yytext, yylval ); }
443
444 \n { end_of_line( yylloc ); }
445 {ws} {}
446 \<\< { return SHL; }
447 \>\> { return SHR; }
448 \-\> { return MEMBERPTR; }
449 == { return EQUALITY; }
450 != { return INEQUALITY; }
451 \>= { return GREATEREQUAL; }
452 \<= { return LESSEQUAL; }
453 \|\| { return LOGICALOR; }
454 && { return LOGICALAND; }
455 \.\.\. { return ELLIPSIS; }
456 . { return yytext[0]; }
457}
458
459<<EOF>> {
460 if (!list_empty( &import_stack ))
461 return aEOF;
462 if (acf_name)
463 {
464 switch_to_acf();
465 return aACF;
466 }
467 yyterminate();
468 }
469%%
470
471static void print_imports(void)
472{
473 struct import_state *state, *next;
474
475 if (list_empty( &import_stack )) return;
476
477 fprintf( stderr, "In file included from " );
478 LIST_FOR_EACH_ENTRY_SAFE_REV( state, next, &import_stack, struct import_state, entry )
479 {
480 if (&next->entry == &import_stack) break;
481 fprintf( stderr, "%s:%d,\n", state->input_name, state->where.first_line );
482 fprintf( stderr, " from ");
483 }
484 fprintf( stderr, "%s:%d:\n", state->input_name, state->where.first_line );
485}
486
487struct location pop_import(void)
488{
489 struct list *entry = list_head( &import_stack );
490 struct import_state *state;
491 struct location where;
492 assert( entry );
493
494 state = LIST_ENTRY( entry, struct import_state, entry );
495 list_remove( &state->entry );
496 parse_only = !list_empty( &import_stack );
497
498 if (yyin) fclose( yyin );
499 yy_delete_buffer( YY_CURRENT_BUFFER );
500 yy_switch_to_buffer( state->buffer );
501
502 input_name = state->input_name;
503 where = state->where;
504 free( state );
505 return where;
506}
507
508void push_import( const char *import_name, struct location *where )
509{
510 struct import_state *state;
511 struct import *import;
512 FILE *file;
513
514 state = xmalloc( sizeof(struct import_state ));
515 list_add_head( &import_stack, &state->entry );
516 parse_only = !list_empty( &import_stack );
517
518 state->buffer = YY_CURRENT_BUFFER;
519 state->input_name = input_name;
520 state->where = *where;
521 input_name = NULL;
522
523 /* reset buffer for <<EOF>>, in case import fails or already imported */
524 yy_scan_string( "" );
525
526 LIST_FOR_EACH_ENTRY( import, &imports, struct import, entry )
527 if (!strcmp( import->name, import_name )) return; /* already imported */
528 if (!strcmp( idl_name, import_name )) return; /* already imported */
529
530 import = xmalloc( sizeof(struct import) );
531 import->name = xstrdup( import_name );
532 list_add_tail( &imports, &import->entry );
533
534 input_name = find_input_file( import_name, state->input_name );
535 file = open_input_file( input_name );
536 reset_location( where, input_name );
537
538 yy_switch_to_buffer( yy_create_buffer( file, YY_BUF_SIZE ) );
539}
540
541static void switch_to_acf(void)
542{
543 FILE *file;
544
545 if (yyin) fclose( yyin );
546 yy_delete_buffer( YY_CURRENT_BUFFER );
547
548 input_name = xstrdup( acf_name );
549 file = open_input_file( input_name );
550 acf_name = NULL;
551
552 yy_switch_to_buffer( yy_create_buffer( file, YY_BUF_SIZE ) );
553}
554
555void close_all_inputs(void)
556{
557 while (!list_empty( &import_stack )) pop_import();
558 if (yyin) fclose( yyin );
559}
560
561static void reset_location( struct location *where, const char *input_name )
562{
563 where->first_line = 1;
564 where->last_line = 1;
565 where->first_column = 1;
566 where->last_column = 1;
567 where->input_name = xstrdup( input_name );
568}
569
570static void update_location( struct location *where, const char *yytext )
571{
572 int len = strlen( yytext );
573 previous_location = *where;
574 where->first_column = where->last_column;
575 where->last_column += len;
576}
577
578static void end_of_line( struct location *where )
579{
580 where->first_line++;
581 where->last_line++;
582 where->first_column = 1;
583 where->last_column = 1;
584}
585
586void init_location( struct location *where, const struct location *begin, const struct location *end )
587{
588 if (!begin) begin = &previous_location;
589 *where = *begin;
590
591 if (end)
592 {
593 where->last_line = end->last_line;
594 where->last_column = end->last_column;
595 }
596 else
597 {
598 where->first_line = begin->last_line;
599 where->first_column = begin->last_column;
600 }
601}
602
603static void diagnostic( const struct location *where, const char *type, const char *message )
604{
605 char buffer[1024], *line = NULL;
606 FILE *file;
607 int i;
608
609 if (!where) where = &previous_location;
610
611 print_imports();
612
613 fprintf( stderr, "%s:%d:%d: %s: %s\n", where->input_name, where->first_line, where->first_column, type, message );
614
615 if (!where->input_name || !(file = fopen( where->input_name, "r" ))) return;
616 for (i = 0; i < where->first_line; i++) if (!(line = fgets( buffer, sizeof(buffer), file ))) break;
617 fclose( file );
618 if (!line) return;
619 fprintf( stderr, "%s", line );
620
621 line = buffer;
622 for (i = 0; i < where->first_column - 1; i++) *line++ = ' ';
623 *line++ = '^';
624 for (i = where->first_column + 1; i < where->last_column; i++) *line++ = '~';
625 *line = '\0';
626 fprintf( stderr, "%s\n", buffer );
627}
628
629void parser_error( const struct location *where, const char *message )
630{
631 diagnostic( where, "error", message );
632}
633
634void parser_warning( const struct location *where, const char *message )
635{
636 diagnostic( where, "warning", message );
637}
638
639static void warning_disable(int warning)
640{
641 warning_t *warning_entry;
642 LIST_FOR_EACH_ENTRY(warning_entry, disabled_warnings, warning_t, entry)
643 if(warning_entry->num == warning)
644 return;
645 warning_entry = xmalloc( sizeof(*warning_entry) );
646 warning_entry->num = warning;
647 list_add_tail(disabled_warnings, &warning_entry->entry);
648}
649
650static void warning_enable(int warning)
651{
652 warning_t *warning_entry;
653 LIST_FOR_EACH_ENTRY(warning_entry, disabled_warnings, warning_t, entry)
654 if(warning_entry->num == warning)
655 {
656 list_remove(&warning_entry->entry);
657 free(warning_entry);
658 break;
659 }
660}
661
662int do_warning(const char *toggle, warning_list_t *wnum)
663{
664 warning_t *warning, *next;
665 int ret = 1;
666 if(!disabled_warnings)
667 {
668 disabled_warnings = xmalloc( sizeof(*disabled_warnings) );
669 list_init( disabled_warnings );
670 }
671
672 if(!strcmp(toggle, "disable"))
673 LIST_FOR_EACH_ENTRY(warning, wnum, warning_t, entry)
674 warning_disable(warning->num);
675 else if(!strcmp(toggle, "enable") || !strcmp(toggle, "default"))
676 LIST_FOR_EACH_ENTRY(warning, wnum, warning_t, entry)
677 warning_enable(warning->num);
678 else
679 ret = 0;
680
681 LIST_FOR_EACH_ENTRY_SAFE(warning, next, wnum, warning_t, entry)
682 free(warning);
683 return ret;
684}
685
686int is_warning_enabled(int warning)
687{
688 warning_t *warning_entry;
689 if(!disabled_warnings)
690 return 1;
691 LIST_FOR_EACH_ENTRY(warning_entry, disabled_warnings, warning_t, entry)
692 if(warning_entry->num == warning)
693 return 0;
694 return 1;
695}