shell32: Fix parsing empty arguments in parse_dde_command().
[wine.git] / tools / widl / parser.l
blob61266efb9e329c60ab573c21c2abf64cdf149f27
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     default_overload                            { return tDEFAULT_OVERLOAD; }
258     defaultbind                                 { return tDEFAULTBIND; }
259     defaultcollelem                             { return tDEFAULTCOLLELEM; }
260     defaultvalue                                { return tDEFAULTVALUE; }
261     defaultvtable                               { return tDEFAULTVTABLE; }
262     deprecated                                  { return token_winrt( tDEPRECATED, yytext, yylval ); }
263     disable_consistency_check                   { return tDISABLECONSISTENCYCHECK; }
264     displaybind                                 { return tDISPLAYBIND; }
265     dllname                                     { return tDLLNAME; }
266     dont_free                                   { return tDONTFREE; }
267     dual                                        { return tDUAL; }
268     enable_allocate                             { return tENABLEALLOCATE; }
269     encode                                      { return tENCODE; }
270     endpoint                                    { return tENDPOINT; }
271     entry                                       { return tENTRY; }
272     eventadd                                    { return token_winrt( tEVENTADD, yytext, yylval ); }
273     eventremove                                 { return token_winrt( tEVENTREMOVE, yytext, yylval ); }
274     exclusiveto                                 { return token_winrt( tEXCLUSIVETO, yytext, yylval ); }
275     explicit_handle                             { return tEXPLICITHANDLE; }
276     fault_status                                { return tFAULTSTATUS; }
277     flags                                       { return token_winrt( tFLAGS, yytext, yylval ); }
278     force_allocate                              { return tFORCEALLOCATE; }
279     free                                        { return tFREE; }
280     handle                                      { return tHANDLE; }
281     helpcontext                                 { return tHELPCONTEXT; }
282     helpfile                                    { return tHELPFILE; }
283     helpstring                                  { return tHELPSTRING; }
284     helpstringcontext                           { return tHELPSTRINGCONTEXT; }
285     helpstringdll                               { return tHELPSTRINGDLL; }
286     hidden                                      { return tHIDDEN; }
287     id                                          { return tID; }
288     idempotent                                  { return tIDEMPOTENT; }
289     ignore                                      { return tIGNORE; }
290     iid_is                                      { return tIIDIS; }
291     immediatebind                               { return tIMMEDIATEBIND; }
292     implicit_handle                             { return tIMPLICITHANDLE; }
293     in                                          { return tIN; }
294     in_line                                     { return tIN_LINE; }
295     input_sync                                  { return tINPUTSYNC; }
296     lcid                                        { return tLCID; }
297     length_is                                   { return tLENGTHIS; }
298     licensed                                    { return tLICENSED; }
299     local                                       { return tLOCAL; }
300     marshaling_behavior                         { return token_winrt( tMARSHALINGBEHAVIOR, yytext, yylval ); }
301     maybe                                       { return tMAYBE; }
302     message                                     { return tMESSAGE; }
303     mta                                         { return tMTA; }
304     neutral                                     { return tNEUTRAL; }
305     nocode                                      { return tNOCODE; }
306     nonbrowsable                                { return tNONBROWSABLE; }
307     noncreatable                                { return tNONCREATABLE; }
308     none                                        { return token_winrt( tNONE, yytext, yylval ); }
309     nonextensible                               { return tNONEXTENSIBLE; }
310     notify                                      { return tNOTIFY; }
311     notify_flag                                 { return tNOTIFYFLAG; }
312     object                                      { return tOBJECT; }
313     odl                                         { return tODL; }
314     oleautomation                               { return tOLEAUTOMATION; }
315     optimize                                    { return tOPTIMIZE; }
316     optional                                    { return tOPTIONAL; }
317     out                                         { return tOUT; }
318     overload                                    { return tOVERLOAD; }
319     partial_ignore                              { return tPARTIALIGNORE; }
320     pointer_default                             { return tPOINTERDEFAULT; }
321     progid                                      { return tPROGID; }
322     propget                                     { return tPROPGET; }
323     propput                                     { return tPROPPUT; }
324     propputref                                  { return tPROPPUTREF; }
325     protected                                   { return tPROTECTED; }
326     proxy                                       { return tPROXY; }
327     ptr                                         { return tPTR; }
328     public                                      { return tPUBLIC; }
329     range                                       { return tRANGE; }
330     readonly                                    { return tREADONLY; }
331     ref                                         { return tREF; }
332     represent_as                                { return tREPRESENTAS; }
333     requestedit                                 { return tREQUESTEDIT; }
334     restricted                                  { return tRESTRICTED; }
335     retval                                      { return tRETVAL; }
336     single                                      { return tSINGLE; }
337     single_node                                 { return tSINGLENODE; }
338     size_is                                     { return tSIZEIS; }
339     source                                      { return tSOURCE; }
340     standard                                    { return token_winrt( tSTANDARD, yytext, yylval ); }
341     static                                      { return token_winrt( tSTATIC, yytext, yylval ); }
342     strict_context_handle                       { return tSTRICTCONTEXTHANDLE; }
343     string                                      { return tSTRING; }
344     switch_is                                   { return tSWITCHIS; }
345     switch_type                                 { return tSWITCHTYPE; }
346     threading                                   { return tTHREADING; }
347     transmit_as                                 { return tTRANSMITAS; }
348     uidefault                                   { return tUIDEFAULT; }
349     unique                                      { return tUNIQUE; }
350     user_marshal                                { return tUSERMARSHAL; }
351     usesgetlasterror                            { return tUSESGETLASTERROR; }
352     uuid                                        { return tUUID; }
353     v1_enum                                     { return tV1ENUM; }
354     vararg                                      { return tVARARG; }
355     version                                     { return tVERSION; }
356     vi_progid                                   { return tVIPROGID; }
357     wire_marshal                                { return tWIREMARSHAL; }
360 <INITIAL>{
361     ^{ws}*\#{ws}*pragma{ws}+                    { yy_push_state( PP_PRAGMA ); }
362     ^{ws}*midl_pragma{ws}+warning               { return tPRAGMA_WARNING; }
364     [0-9]+\.[0-9]+([eE][+-]?[0-9]+)*            {
365                                                     yylval->dbl = strtod( yytext, NULL );
366                                                     return aDOUBLE;
367                                                 }
370 SAFEARRAY{ws}*/\(       return tSAFEARRAY;
372 <INITIAL,ATTR>{
373     ^{ws}*\#{ws}*                               { yy_push_state(PP_LINE); }
374     \[                                          { yy_push_state(ATTR); return '['; }
376     FALSE                                       { return tFALSE; }
377     NULL                                        { return tNULL; }
378     TRUE                                        { return tTRUE; }
379     _?_?cdecl                                   { return token_str( tCDECL, "__cdecl", yylval ); }
380     _?_?pascal                                  { return token_str( tPASCAL, "__pascal", yylval ); }
381     _?_?stdcall                                 { return token_str( tSTDCALL, "__stdcall", yylval ); }
382     __?fastcall                                 { return token_str( tFASTCALL, "__fastcall", yylval ); }
383     __int32                                     { return tINT32; }
384     __int3264                                   { return tINT3264; }
385     __int64                                     { return tINT64; }
386     apicontract                                 { return token_winrt( tAPICONTRACT, yytext, yylval ); }
387     boolean                                     { return tBOOLEAN; }
388     byte                                        { return tBYTE; }
389     case                                        { return tCASE; }
390     char                                        { return tCHAR; }
391     coclass                                     { return tCOCLASS; }
392     const                                       { return tCONST; }
393     cpp_quote                                   { return tCPPQUOTE; }
394     declare                                     { return token_winrt( tDECLARE, yytext, yylval ); }
395     default                                     { return tDEFAULT; }
396     delegate                                    { return token_winrt( tDELEGATE, yytext, yylval ); }
397     dispinterface                               { return tDISPINTERFACE; }
398     double                                      { return tDOUBLE; }
399     enum                                        { return tENUM; }
400     error_status_t                              { return tERRORSTATUST; }
401     extern                                      { return tEXTERN; }
402     float                                       { return tFLOAT; }
403     handle_t                                    { return tHANDLET; }
404     hyper                                       { return tHYPER; }
405     import                                      { return tIMPORT; }
406     importlib                                   { return tIMPORTLIB; }
407     inline                                      { return tINLINE; }
408     int                                         { return tINT; }
409     interface                                   { return tINTERFACE; }
410     library                                     { return tLIBRARY; }
411     long                                        { return tLONG; }
412     methods                                     { return tMETHODS; }
413     module                                      { return tMODULE; }
414     namespace                                   { return token_winrt( tNAMESPACE, yytext, yylval ); }
415     properties                                  { return tPROPERTIES; }
416     register                                    { return tREGISTER; }
417     requires                                    { return token_winrt( tREQUIRES, yytext, yylval ); }
418     runtimeclass                                { return token_winrt( tRUNTIMECLASS, yytext, yylval ); }
419     short                                       { return tSHORT; }
420     signed                                      { return tSIGNED; }
421     sizeof                                      { return tSIZEOF; }
422     small                                       { return tSMALL; }
423     static                                      { return tSTATIC; }
424     struct                                      { return tSTRUCT; }
425     switch                                      { return tSWITCH; }
426     typedef                                     { return tTYPEDEF; }
427     union                                       { return tUNION; }
428     unsigned                                    { return tUNSIGNED; }
429     void                                        { return tVOID; }
430     wchar_t                                     { return tWCHAR; }
432     [a-zA-Z_][0-9a-zA-Z_]*                      { return token_ident( yytext, yylval ); }
434     0[xX]{hd}+([lL][uU]?|[uU][lL]?)?            { return token_num( aHEXNUM, yytext, yylval ); }
435     [0-9]+([lL][uU]?|[uU][lL]?)?                { return token_num( aNUM, yytext, yylval ); }
437     L\"(\\.|[^"\\])*\"                          { return token_str( aWSTRING, yytext + 1, yylval ); }
438     \"(\\.|[^"\\])*\"                           { return token_str( aSTRING, yytext, yylval ); }
439     \'(\\.|[^'\\])*\'                           { return token_str( aSQSTRING, yytext, yylval ); }
441     \n                                          { end_of_line( yylloc ); }
442     {ws}                                        {}
443     \<\<                                        { return SHL; }
444     \>\>                                        { return SHR; }
445     \-\>                                        { return MEMBERPTR; }
446     ==                                          { return EQUALITY; }
447     !=                                          { return INEQUALITY; }
448     \>=                                         { return GREATEREQUAL; }
449     \<=                                         { return LESSEQUAL; }
450     \|\|                                        { return LOGICALOR; }
451     &&                                          { return LOGICALAND; }
452     \.\.\.                                      { return ELLIPSIS; }
453     .                                           { return yytext[0]; }
456 <<EOF>>                 {
457                             if (!list_empty( &import_stack ))
458                                 return aEOF;
459                             if (acf_name)
460                             {
461                                 switch_to_acf();
462                                 return aACF;
463                             }
464                             yyterminate();
465                         }
468 static void print_imports(void)
470     struct import_state *state, *next;
472     if (list_empty( &import_stack )) return;
474     fprintf( stderr, "In file included from " );
475     LIST_FOR_EACH_ENTRY_SAFE_REV( state, next, &import_stack, struct import_state, entry )
476     {
477         if (&next->entry == &import_stack) break;
478         fprintf( stderr, "%s:%d,\n", state->input_name, state->where.first_line );
479         fprintf( stderr, "                 from ");
480     }
481     fprintf( stderr, "%s:%d:\n", state->input_name, state->where.first_line );
484 void pop_import( struct location *where )
486     struct list *entry = list_head( &import_stack );
487     struct import_state *state;
488     assert( entry );
490     state = LIST_ENTRY( entry, struct import_state, entry );
491     list_remove( &state->entry );
492     parse_only = !list_empty( &import_stack );
494     if (yyin) fclose( yyin );
495     yy_delete_buffer( YY_CURRENT_BUFFER );
496     yy_switch_to_buffer( state->buffer );
498     input_name = state->input_name;
499     *where = state->where;
500     free( state );
503 void push_import( const char *import_name, struct location *where )
505     struct import_state *state;
506     struct import *import;
507     FILE *file;
509     state = xmalloc( sizeof(struct import_state ));
510     list_add_head( &import_stack, &state->entry );
511     parse_only = !list_empty( &import_stack );
513     state->buffer = YY_CURRENT_BUFFER;
514     state->input_name = input_name;
515     state->where = *where;
516     input_name = NULL;
518     /* reset buffer for <<EOF>>, in case import fails or already imported */
519     yy_scan_string( "" );
521     LIST_FOR_EACH_ENTRY( import, &imports, struct import, entry )
522         if (!strcmp( import->name, import_name )) return;  /* already imported */
523     if (!strcmp( idl_name, import_name )) return;  /* already imported */
525     import = xmalloc( sizeof(struct import) );
526     import->name = xstrdup( import_name );
527     list_add_tail( &imports, &import->entry );
529     input_name = find_input_file( import_name, state->input_name );
530     file = open_input_file( input_name );
531     reset_location( where, input_name );
533     yy_switch_to_buffer( yy_create_buffer( file, YY_BUF_SIZE ) );
536 static void switch_to_acf(void)
538     FILE *file;
540     if (yyin) fclose( yyin );
541     yy_delete_buffer( YY_CURRENT_BUFFER );
543     input_name = xstrdup( acf_name );
544     file = open_input_file( input_name );
545     acf_name = NULL;
547     yy_switch_to_buffer( yy_create_buffer( file, YY_BUF_SIZE ) );
550 static void reset_location( struct location *where, const char *input_name )
552     where->first_line = 1;
553     where->last_line = 1;
554     where->first_column = 1;
555     where->last_column = 1;
556     where->input_name = xstrdup( input_name );
559 static void update_location( struct location *where, const char *yytext )
561     int len = strlen( yytext );
562     previous_location = *where;
563     where->first_column = where->last_column;
564     where->last_column += len;
567 static void end_of_line( struct location *where )
569     where->first_line++;
570     where->last_line++;
571     where->first_column = 1;
572     where->last_column = 1;
575 void init_location( struct location *where, const struct location *begin, const struct location *end )
577     if (!begin) begin = &previous_location;
578     *where = *begin;
580     if (end)
581     {
582         where->last_line   = end->last_line;
583         where->last_column = end->last_column;
584     }
585     else
586     {
587         where->first_line   = begin->last_line;
588         where->first_column = begin->last_column;
589     }
592 static void diagnostic( const struct location *where, const char *type, const char *message )
594     char buffer[1024], *line = NULL;
595     FILE *file;
596     int i;
598     if (!where) where = &previous_location;
600     print_imports();
602     fprintf( stderr, "%s:%d:%d: %s: %s\n", where->input_name, where->first_line, where->first_column, type, message );
604     if (!where->input_name || !(file = fopen( where->input_name, "r" ))) return;
605     for (i = 0; i < where->first_line; i++) if (!(line = fgets( buffer, sizeof(buffer), file ))) break;
606     fclose( file );
607     if (!line) return;
608     fprintf( stderr, "%s", line );
610     line = buffer;
611     for (i = 0; i < where->first_column - 1; i++) line += sprintf( line, " " );
612     line += sprintf( line, "^" );
613     for (i = where->first_column + 1; i < where->last_column; i++) line += sprintf( line, "~" );
614     fprintf( stderr, "%s\n", buffer );
617 void parser_error( const struct location *where, const char *message )
619     diagnostic( where, "error", message );
622 void parser_warning( const struct location *where, const char *message )
624     diagnostic( where, "warning", message );
627 static void warning_disable(int warning)
629     warning_t *warning_entry;
630     LIST_FOR_EACH_ENTRY(warning_entry, disabled_warnings, warning_t, entry)
631         if(warning_entry->num == warning)
632             return;
633     warning_entry = xmalloc( sizeof(*warning_entry) );
634     warning_entry->num = warning;
635     list_add_tail(disabled_warnings, &warning_entry->entry);
638 static void warning_enable(int warning)
640     warning_t *warning_entry;
641     LIST_FOR_EACH_ENTRY(warning_entry, disabled_warnings, warning_t, entry)
642         if(warning_entry->num == warning)
643         {
644             list_remove(&warning_entry->entry);
645             free(warning_entry);
646             break;
647         }
650 int do_warning(const char *toggle, warning_list_t *wnum)
652     warning_t *warning, *next;
653     int ret = 1;
654     if(!disabled_warnings)
655     {
656         disabled_warnings = xmalloc( sizeof(*disabled_warnings) );
657         list_init( disabled_warnings );
658     }
660     if(!strcmp(toggle, "disable"))
661         LIST_FOR_EACH_ENTRY(warning, wnum, warning_t, entry)
662             warning_disable(warning->num);
663     else if(!strcmp(toggle, "enable") || !strcmp(toggle, "default"))
664         LIST_FOR_EACH_ENTRY(warning, wnum, warning_t, entry)
665             warning_enable(warning->num);
666     else
667         ret = 0;
669     LIST_FOR_EACH_ENTRY_SAFE(warning, next, wnum, warning_t, entry)
670         free(warning);
671     return ret;
674 int is_warning_enabled(int warning)
676     warning_t *warning_entry;
677     if(!disabled_warnings)
678         return 1;
679     LIST_FOR_EACH_ENTRY(warning_entry, disabled_warnings, warning_t, entry)
680         if(warning_entry->num == warning)
681             return 0;
682     return 1;