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