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