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