rcparse.y revision 99461
138589Sabial%{ /* rcparse.y -- parser for Windows rc files 238589Sabial Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 338589Sabial Written by Ian Lance Taylor, Cygnus Support. 438589Sabial 538589Sabial This file is part of GNU Binutils. 638589Sabial 738589Sabial This program is free software; you can redistribute it and/or modify 838589Sabial it under the terms of the GNU General Public License as published by 938589Sabial the Free Software Foundation; either version 2 of the License, or 1038589Sabial (at your option) any later version. 1138589Sabial 1238589Sabial This program is distributed in the hope that it will be useful, 1338589Sabial but WITHOUT ANY WARRANTY; without even the implied warranty of 1438589Sabial MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1538589Sabial GNU General Public License for more details. 1638589Sabial 1738589Sabial You should have received a copy of the GNU General Public License 1838589Sabial along with this program; if not, write to the Free Software 1938589Sabial Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 2038589Sabial 02111-1307, USA. */ 2138589Sabial 2238589Sabial/* This is a parser for Windows rc files. It is based on the parser 2338589Sabial by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */ 2438589Sabial 2538589Sabial#include "bfd.h" 2638589Sabial#include "bucomm.h" 2738589Sabial#include "libiberty.h" 2838589Sabial#include "windres.h" 2938589Sabial#include "safe-ctype.h" 3038589Sabial 3138589Sabial/* The current language. */ 3238589Sabial 3338589Sabialstatic unsigned short language; 3438589Sabial 3538589Sabial/* The resource information during a sub statement. */ 3638589Sabial 3738589Sabialstatic struct res_res_info sub_res_info; 3838589Sabial 3938589Sabial/* Dialog information. This is built by the nonterminals styles and 4038589Sabial controls. */ 4138589Sabial 4238589Sabialstatic struct dialog dialog; 4338589Sabial 4438589Sabial/* This is used when building a style. It is modified by the 4538589Sabial nonterminal styleexpr. */ 4638589Sabial 4738589Sabialstatic unsigned long style; 4838589Sabial 4938589Sabial/* These are used when building a control. They are set before using 5038589Sabial control_params. */ 5138589Sabial 5238589Sabialstatic unsigned long base_style; 5338589Sabialstatic unsigned long default_style; 5438589Sabialstatic unsigned long class; 5538589Sabial 5638589Sabial%} 5738589Sabial 5838589Sabial%union 5938589Sabial{ 6038589Sabial struct accelerator acc; 6138589Sabial struct accelerator *pacc; 6238589Sabial struct dialog_control *dialog_control; 6338589Sabial struct menuitem *menuitem; 6438589Sabial struct 6538589Sabial { 6638589Sabial struct rcdata_item *first; 6738589Sabial struct rcdata_item *last; 6838589Sabial } rcdata; 6938589Sabial struct rcdata_item *rcdata_item; 7038589Sabial struct stringtable_data *stringtable; 7138589Sabial struct fixed_versioninfo *fixver; 7238589Sabial struct ver_info *verinfo; 7338589Sabial struct ver_stringinfo *verstring; 7438589Sabial struct ver_varinfo *vervar; 7538589Sabial struct res_id id; 7638589Sabial struct res_res_info res_info; 7738589Sabial struct 7838589Sabial { 7938589Sabial unsigned short on; 8038589Sabial unsigned short off; 8138589Sabial } memflags; 8238589Sabial struct 8338589Sabial { 8438589Sabial unsigned long val; 8538589Sabial /* Nonzero if this number was explicitly specified as long. */ 8638589Sabial int dword; 8738589Sabial } i; 8838589Sabial unsigned long il; 8938589Sabial unsigned short is; 9038589Sabial const char *s; 9138589Sabial struct 9238589Sabial { 9338589Sabial unsigned long length; 9438589Sabial const char *s; 9538589Sabial } ss; 9638589Sabial}; 9738589Sabial 9838589Sabial%token BEG END 9938589Sabial%token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT 10038589Sabial%token BITMAP 10138589Sabial%token CURSOR 10238589Sabial%token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE 10338589Sabial%token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT 10438589Sabial%token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON 10538589Sabial%token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON 10638589Sabial%token BEDIT HEDIT IEDIT 10738589Sabial%token FONT 10838589Sabial%token ICON 10938589Sabial%token LANGUAGE CHARACTERISTICS VERSIONK 11038589Sabial%token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE 11138589Sabial%token MENUBARBREAK MENUBREAK 11238589Sabial%token MESSAGETABLE 11338589Sabial%token RCDATA 11438589Sabial%token STRINGTABLE 11538589Sabial%token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS 11638589Sabial%token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO 11738589Sabial%token VALUE 11838589Sabial%token <s> BLOCK 11938589Sabial%token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE 12038589Sabial%token NOT 12140813Sabial%token <s> QUOTEDSTRING STRING 12238589Sabial%token <i> NUMBER 12350479Speter%token <ss> SIZEDSTRING 124%token IGNORED_TOKEN 125 126%type <pacc> acc_entries 127%type <acc> acc_entry acc_event 128%type <dialog_control> control control_params 129%type <menuitem> menuitems menuitem menuexitems menuexitem 130%type <rcdata> optrcdata_data optrcdata_data_int rcdata_data 131%type <rcdata_item> opt_control_data 132%type <fixver> fixedverinfo 133%type <verinfo> verblocks 134%type <verstring> vervals 135%type <vervar> vertrans 136%type <res_info> suboptions memflags_move_discard memflags_move 137%type <memflags> memflag 138%type <id> id resref 139%type <il> exstyle parennumber 140%type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr 141%type <is> acc_options acc_option menuitem_flags menuitem_flag 142%type <s> optstringc file_name resname 143%type <i> sizednumexpr sizedposnumexpr 144 145%left '|' 146%left '^' 147%left '&' 148%left '+' '-' 149%left '*' '/' '%' 150%right '~' NEG 151 152%% 153 154input: 155 /* empty */ 156 | input accelerator 157 | input bitmap 158 | input cursor 159 | input dialog 160 | input font 161 | input icon 162 | input language 163 | input menu 164 | input menuex 165 | input messagetable 166 | input rcdata 167 | input stringtable 168 | input user 169 | input versioninfo 170 | input IGNORED_TOKEN 171 ; 172 173/* Accelerator resources. */ 174 175accelerator: 176 id ACCELERATORS suboptions BEG acc_entries END 177 { 178 define_accelerator ($1, &$3, $5); 179 if (yychar != YYEMPTY) 180 YYERROR; 181 rcparse_discard_strings (); 182 } 183 ; 184 185acc_entries: 186 /* empty */ 187 { 188 $$ = NULL; 189 } 190 | acc_entries acc_entry 191 { 192 struct accelerator *a; 193 194 a = (struct accelerator *) res_alloc (sizeof *a); 195 *a = $2; 196 if ($1 == NULL) 197 $$ = a; 198 else 199 { 200 struct accelerator **pp; 201 202 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next) 203 ; 204 *pp = a; 205 $$ = $1; 206 } 207 } 208 ; 209 210acc_entry: 211 acc_event cposnumexpr 212 { 213 $$ = $1; 214 $$.id = $2; 215 } 216 | acc_event cposnumexpr ',' acc_options 217 { 218 $$ = $1; 219 $$.id = $2; 220 $$.flags |= $4; 221 if (($$.flags & ACC_VIRTKEY) == 0 222 && ($$.flags & (ACC_SHIFT | ACC_CONTROL | ACC_ALT)) != 0) 223 rcparse_warning (_("inappropriate modifiers for non-VIRTKEY")); 224 } 225 ; 226 227acc_event: 228 QUOTEDSTRING 229 { 230 const char *s = $1; 231 char ch; 232 233 $$.next = NULL; 234 $$.id = 0; 235 ch = *s; 236 if (ch != '^') 237 $$.flags = 0; 238 else 239 { 240 $$.flags = ACC_CONTROL | ACC_VIRTKEY; 241 ++s; 242 ch = *s; 243 ch = TOUPPER (ch); 244 } 245 $$.key = ch; 246 if (s[1] != '\0') 247 rcparse_warning (_("accelerator should only be one character")); 248 } 249 | posnumexpr 250 { 251 $$.next = NULL; 252 $$.flags = 0; 253 $$.id = 0; 254 $$.key = $1; 255 } 256 ; 257 258acc_options: 259 acc_option 260 { 261 $$ = $1; 262 } 263 | acc_options ',' acc_option 264 { 265 $$ = $1 | $3; 266 } 267 /* I've had one report that the comma is optional. */ 268 | acc_options acc_option 269 { 270 $$ = $1 | $2; 271 } 272 ; 273 274acc_option: 275 VIRTKEY 276 { 277 $$ = ACC_VIRTKEY; 278 } 279 | ASCII 280 { 281 /* This is just the absence of VIRTKEY. */ 282 $$ = 0; 283 } 284 | NOINVERT 285 { 286 $$ = ACC_NOINVERT; 287 } 288 | SHIFT 289 { 290 $$ = ACC_SHIFT; 291 } 292 | CONTROL 293 { 294 $$ = ACC_CONTROL; 295 } 296 | ALT 297 { 298 $$ = ACC_ALT; 299 } 300 ; 301 302/* Bitmap resources. */ 303 304bitmap: 305 id BITMAP memflags_move file_name 306 { 307 define_bitmap ($1, &$3, $4); 308 if (yychar != YYEMPTY) 309 YYERROR; 310 rcparse_discard_strings (); 311 } 312 ; 313 314/* Cursor resources. */ 315 316cursor: 317 id CURSOR memflags_move_discard file_name 318 { 319 define_cursor ($1, &$3, $4); 320 if (yychar != YYEMPTY) 321 YYERROR; 322 rcparse_discard_strings (); 323 } 324 ; 325 326/* Dialog resources. */ 327 328dialog: 329 id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr 330 cnumexpr 331 { 332 memset (&dialog, 0, sizeof dialog); 333 dialog.x = $5; 334 dialog.y = $6; 335 dialog.width = $7; 336 dialog.height = $8; 337 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU; 338 dialog.exstyle = $4; 339 dialog.menu.named = 1; 340 dialog.class.named = 1; 341 dialog.font = NULL; 342 dialog.ex = NULL; 343 dialog.controls = NULL; 344 sub_res_info = $3; 345 style = 0; 346 } 347 styles BEG controls END 348 { 349 define_dialog ($1, &sub_res_info, &dialog); 350 if (yychar != YYEMPTY) 351 YYERROR; 352 rcparse_discard_strings (); 353 } 354 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr 355 cnumexpr 356 { 357 memset (&dialog, 0, sizeof dialog); 358 dialog.x = $5; 359 dialog.y = $6; 360 dialog.width = $7; 361 dialog.height = $8; 362 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU; 363 dialog.exstyle = $4; 364 dialog.menu.named = 1; 365 dialog.class.named = 1; 366 dialog.font = NULL; 367 dialog.ex = ((struct dialog_ex *) 368 res_alloc (sizeof (struct dialog_ex))); 369 memset (dialog.ex, 0, sizeof (struct dialog_ex)); 370 dialog.controls = NULL; 371 sub_res_info = $3; 372 style = 0; 373 } 374 styles BEG controls END 375 { 376 define_dialog ($1, &sub_res_info, &dialog); 377 if (yychar != YYEMPTY) 378 YYERROR; 379 rcparse_discard_strings (); 380 } 381 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr 382 cnumexpr cnumexpr 383 { 384 memset (&dialog, 0, sizeof dialog); 385 dialog.x = $5; 386 dialog.y = $6; 387 dialog.width = $7; 388 dialog.height = $8; 389 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU; 390 dialog.exstyle = $4; 391 dialog.menu.named = 1; 392 dialog.class.named = 1; 393 dialog.font = NULL; 394 dialog.ex = ((struct dialog_ex *) 395 res_alloc (sizeof (struct dialog_ex))); 396 memset (dialog.ex, 0, sizeof (struct dialog_ex)); 397 dialog.ex->help = $9; 398 dialog.controls = NULL; 399 sub_res_info = $3; 400 style = 0; 401 } 402 styles BEG controls END 403 { 404 define_dialog ($1, &sub_res_info, &dialog); 405 if (yychar != YYEMPTY) 406 YYERROR; 407 rcparse_discard_strings (); 408 } 409 ; 410 411exstyle: 412 /* empty */ 413 { 414 $$ = 0; 415 } 416 | EXSTYLE '=' numexpr 417 { 418 $$ = $3; 419 } 420 ; 421 422styles: 423 /* empty */ 424 | styles CAPTION QUOTEDSTRING 425 { 426 dialog.style |= WS_CAPTION; 427 style |= WS_CAPTION; 428 unicode_from_ascii ((int *) NULL, &dialog.caption, $3); 429 } 430 | styles CLASS id 431 { 432 dialog.class = $3; 433 } 434 | styles STYLE 435 styleexpr 436 { 437 dialog.style = style; 438 } 439 | styles EXSTYLE numexpr 440 { 441 dialog.exstyle = $3; 442 } 443 | styles CLASS QUOTEDSTRING 444 { 445 res_string_to_id (& dialog.class, $3); 446 } 447 | styles FONT numexpr ',' QUOTEDSTRING 448 { 449 dialog.style |= DS_SETFONT; 450 style |= DS_SETFONT; 451 dialog.pointsize = $3; 452 unicode_from_ascii ((int *) NULL, &dialog.font, $5); 453 if (dialog.ex != NULL) 454 { 455 dialog.ex->weight = 0; 456 dialog.ex->italic = 0; 457 dialog.ex->charset = 1; 458 } 459 } 460 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr 461 { 462 dialog.style |= DS_SETFONT; 463 style |= DS_SETFONT; 464 dialog.pointsize = $3; 465 unicode_from_ascii ((int *) NULL, &dialog.font, $5); 466 if (dialog.ex == NULL) 467 rcparse_warning (_("extended FONT requires DIALOGEX")); 468 else 469 { 470 dialog.ex->weight = $6; 471 dialog.ex->italic = 0; 472 dialog.ex->charset = 1; 473 } 474 } 475 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr 476 { 477 dialog.style |= DS_SETFONT; 478 style |= DS_SETFONT; 479 dialog.pointsize = $3; 480 unicode_from_ascii ((int *) NULL, &dialog.font, $5); 481 if (dialog.ex == NULL) 482 rcparse_warning (_("extended FONT requires DIALOGEX")); 483 else 484 { 485 dialog.ex->weight = $6; 486 dialog.ex->italic = $7; 487 dialog.ex->charset = 1; 488 } 489 } 490 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr cnumexpr 491 { 492 dialog.style |= DS_SETFONT; 493 style |= DS_SETFONT; 494 dialog.pointsize = $3; 495 unicode_from_ascii ((int *) NULL, &dialog.font, $5); 496 if (dialog.ex == NULL) 497 rcparse_warning (_("extended FONT requires DIALOGEX")); 498 else 499 { 500 dialog.ex->weight = $6; 501 dialog.ex->italic = $7; 502 dialog.ex->charset = $8; 503 } 504 } 505 | styles MENU id 506 { 507 dialog.menu = $3; 508 } 509 | styles CHARACTERISTICS numexpr 510 { 511 sub_res_info.characteristics = $3; 512 } 513 | styles LANGUAGE numexpr cnumexpr 514 { 515 sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT); 516 } 517 | styles VERSIONK numexpr 518 { 519 sub_res_info.version = $3; 520 } 521 ; 522 523controls: 524 /* empty */ 525 | controls control 526 { 527 struct dialog_control **pp; 528 529 for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next) 530 ; 531 *pp = $2; 532 } 533 ; 534 535control: 536 AUTO3STATE 537 { 538 default_style = BS_AUTO3STATE | WS_TABSTOP; 539 base_style = BS_AUTO3STATE; 540 class = CTL_BUTTON; 541 } 542 control_params 543 { 544 $$ = $3; 545 } 546 | AUTOCHECKBOX 547 { 548 default_style = BS_AUTOCHECKBOX | WS_TABSTOP; 549 base_style = BS_AUTOCHECKBOX; 550 class = CTL_BUTTON; 551 } 552 control_params 553 { 554 $$ = $3; 555 } 556 | AUTORADIOBUTTON 557 { 558 default_style = BS_AUTORADIOBUTTON | WS_TABSTOP; 559 base_style = BS_AUTORADIOBUTTON; 560 class = CTL_BUTTON; 561 } 562 control_params 563 { 564 $$ = $3; 565 } 566 | BEDIT 567 { 568 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 569 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 570 class = CTL_EDIT; 571 } 572 control_params 573 { 574 $$ = $3; 575 if (dialog.ex == NULL) 576 rcparse_warning (_("BEDIT requires DIALOGEX")); 577 res_string_to_id (&$$->class, "BEDIT"); 578 } 579 | CHECKBOX 580 { 581 default_style = BS_CHECKBOX | WS_TABSTOP; 582 base_style = BS_CHECKBOX | WS_TABSTOP; 583 class = CTL_BUTTON; 584 } 585 control_params 586 { 587 $$ = $3; 588 } 589 | COMBOBOX 590 { 591 default_style = CBS_SIMPLE | WS_TABSTOP; 592 base_style = 0; 593 class = CTL_COMBOBOX; 594 } 595 control_params 596 { 597 $$ = $3; 598 } 599 | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr 600 cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data 601 { 602 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10); 603 if ($11 != NULL) 604 { 605 if (dialog.ex == NULL) 606 rcparse_warning (_("control data requires DIALOGEX")); 607 $$->data = $11; 608 } 609 } 610 | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr 611 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data 612 { 613 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10); 614 if (dialog.ex == NULL) 615 rcparse_warning (_("help ID requires DIALOGEX")); 616 $$->help = $11; 617 $$->data = $12; 618 } 619 | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr 620 cnumexpr cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data 621 { 622 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11); 623 if ($12 != NULL) 624 { 625 if (dialog.ex == NULL) 626 rcparse_warning ("control data requires DIALOGEX"); 627 $$->data = $12; 628 } 629 $$->class.named = 1; 630 unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5); 631 } 632 | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr 633 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data 634 { 635 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11); 636 if (dialog.ex == NULL) 637 rcparse_warning ("help ID requires DIALOGEX"); 638 $$->help = $12; 639 $$->data = $13; 640 $$->class.named = 1; 641 unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5); 642 } 643 | CTEXT 644 { 645 default_style = SS_CENTER | WS_GROUP; 646 base_style = SS_CENTER; 647 class = CTL_STATIC; 648 } 649 control_params 650 { 651 $$ = $3; 652 } 653 | DEFPUSHBUTTON 654 { 655 default_style = BS_DEFPUSHBUTTON | WS_TABSTOP; 656 base_style = BS_DEFPUSHBUTTON | WS_TABSTOP; 657 class = CTL_BUTTON; 658 } 659 control_params 660 { 661 $$ = $3; 662 } 663 | EDITTEXT 664 { 665 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 666 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 667 class = CTL_EDIT; 668 } 669 control_params 670 { 671 $$ = $3; 672 } 673 | GROUPBOX 674 { 675 default_style = BS_GROUPBOX; 676 base_style = BS_GROUPBOX; 677 class = CTL_BUTTON; 678 } 679 control_params 680 { 681 $$ = $3; 682 } 683 | HEDIT 684 { 685 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 686 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 687 class = CTL_EDIT; 688 } 689 control_params 690 { 691 $$ = $3; 692 if (dialog.ex == NULL) 693 rcparse_warning (_("IEDIT requires DIALOGEX")); 694 res_string_to_id (&$$->class, "HEDIT"); 695 } 696 | ICON resref numexpr cnumexpr cnumexpr opt_control_data 697 { 698 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $6, 699 dialog.ex); 700 } 701 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr 702 opt_control_data 703 { 704 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $8, 705 dialog.ex); 706 } 707 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr 708 icon_styleexpr optcnumexpr opt_control_data 709 { 710 $$ = define_icon_control ($2, $3, $4, $5, style, $9, 0, $10, 711 dialog.ex); 712 } 713 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr 714 icon_styleexpr cnumexpr cnumexpr opt_control_data 715 { 716 $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11, 717 dialog.ex); 718 } 719 | IEDIT 720 { 721 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 722 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 723 class = CTL_EDIT; 724 } 725 control_params 726 { 727 $$ = $3; 728 if (dialog.ex == NULL) 729 rcparse_warning (_("IEDIT requires DIALOGEX")); 730 res_string_to_id (&$$->class, "IEDIT"); 731 } 732 | LISTBOX 733 { 734 default_style = LBS_NOTIFY | WS_BORDER; 735 base_style = LBS_NOTIFY | WS_BORDER; 736 class = CTL_LISTBOX; 737 } 738 control_params 739 { 740 $$ = $3; 741 } 742 | LTEXT 743 { 744 default_style = SS_LEFT | WS_GROUP; 745 base_style = SS_LEFT; 746 class = CTL_STATIC; 747 } 748 control_params 749 { 750 $$ = $3; 751 } 752 | PUSHBOX 753 { 754 default_style = BS_PUSHBOX | WS_TABSTOP; 755 base_style = BS_PUSHBOX; 756 class = CTL_BUTTON; 757 } 758 control_params 759 { 760 $$ = $3; 761 } 762 | PUSHBUTTON 763 { 764 default_style = BS_PUSHBUTTON | WS_TABSTOP; 765 base_style = BS_PUSHBUTTON | WS_TABSTOP; 766 class = CTL_BUTTON; 767 } 768 control_params 769 { 770 $$ = $3; 771 } 772 | RADIOBUTTON 773 { 774 default_style = BS_RADIOBUTTON | WS_TABSTOP; 775 base_style = BS_RADIOBUTTON; 776 class = CTL_BUTTON; 777 } 778 control_params 779 { 780 $$ = $3; 781 } 782 | RTEXT 783 { 784 default_style = SS_RIGHT | WS_GROUP; 785 base_style = SS_RIGHT; 786 class = CTL_STATIC; 787 } 788 control_params 789 { 790 $$ = $3; 791 } 792 | SCROLLBAR 793 { 794 default_style = SBS_HORZ; 795 base_style = 0; 796 class = CTL_SCROLLBAR; 797 } 798 control_params 799 { 800 $$ = $3; 801 } 802 | STATE3 803 { 804 default_style = BS_3STATE | WS_TABSTOP; 805 base_style = BS_3STATE; 806 class = CTL_BUTTON; 807 } 808 control_params 809 { 810 $$ = $3; 811 } 812 | USERBUTTON QUOTEDSTRING ',' numexpr ',' numexpr ',' numexpr ',' 813 numexpr ',' numexpr ',' 814 { style = WS_CHILD | WS_VISIBLE; } 815 styleexpr optcnumexpr 816 { 817 $$ = define_control ($2, $4, $6, $8, $10, $12, CTL_BUTTON, 818 style, $16); 819 } 820 ; 821 822/* Parameters for a control. The static variables DEFAULT_STYLE, 823 BASE_STYLE, and CLASS must be initialized before this nonterminal 824 is used. DEFAULT_STYLE is the style to use if no style expression 825 is specified. BASE_STYLE is the base style to use if a style 826 expression is specified; the style expression modifies the base 827 style. CLASS is the class of the control. */ 828 829control_params: 830 optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr 831 opt_control_data 832 { 833 $$ = define_control ($1, $2, $3, $4, $5, $6, class, 834 default_style | WS_CHILD | WS_VISIBLE, 0); 835 if ($7 != NULL) 836 { 837 if (dialog.ex == NULL) 838 rcparse_warning (_("control data requires DIALOGEX")); 839 $$->data = $7; 840 } 841 } 842 | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr 843 control_params_styleexpr optcnumexpr opt_control_data 844 { 845 $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8); 846 if ($9 != NULL) 847 { 848 if (dialog.ex == NULL) 849 rcparse_warning (_("control data requires DIALOGEX")); 850 $$->data = $9; 851 } 852 } 853 | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr 854 control_params_styleexpr cnumexpr cnumexpr opt_control_data 855 { 856 $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8); 857 if (dialog.ex == NULL) 858 rcparse_warning (_("help ID requires DIALOGEX")); 859 $$->help = $9; 860 $$->data = $10; 861 } 862 ; 863 864optstringc: 865 /* empty */ 866 { 867 $$ = NULL; 868 } 869 | QUOTEDSTRING 870 { 871 $$ = $1; 872 } 873 | QUOTEDSTRING ',' 874 { 875 $$ = $1; 876 } 877 ; 878 879opt_control_data: 880 /* empty */ 881 { 882 $$ = NULL; 883 } 884 | BEG optrcdata_data END 885 { 886 $$ = $2.first; 887 } 888 ; 889 890/* These only exist to parse a reduction out of a common case. */ 891 892control_styleexpr: 893 ',' 894 { style = WS_CHILD | WS_VISIBLE; } 895 styleexpr 896 ; 897 898icon_styleexpr: 899 ',' 900 { style = SS_ICON | WS_CHILD | WS_VISIBLE; } 901 styleexpr 902 ; 903 904control_params_styleexpr: 905 ',' 906 { style = base_style | WS_CHILD | WS_VISIBLE; } 907 styleexpr 908 ; 909 910/* Font resources. */ 911 912font: 913 id FONT memflags_move_discard file_name 914 { 915 define_font ($1, &$3, $4); 916 if (yychar != YYEMPTY) 917 YYERROR; 918 rcparse_discard_strings (); 919 } 920 ; 921 922/* Icon resources. */ 923 924icon: 925 id ICON memflags_move_discard file_name 926 { 927 define_icon ($1, &$3, $4); 928 if (yychar != YYEMPTY) 929 YYERROR; 930 rcparse_discard_strings (); 931 } 932 ; 933 934/* Language command. This changes the static variable language, which 935 affects all subsequent resources. */ 936 937language: 938 LANGUAGE numexpr cnumexpr 939 { 940 language = $2 | ($3 << SUBLANG_SHIFT); 941 } 942 ; 943 944/* Menu resources. */ 945 946menu: 947 id MENU suboptions BEG menuitems END 948 { 949 define_menu ($1, &$3, $5); 950 if (yychar != YYEMPTY) 951 YYERROR; 952 rcparse_discard_strings (); 953 } 954 ; 955 956menuitems: 957 /* empty */ 958 { 959 $$ = NULL; 960 } 961 | menuitems menuitem 962 { 963 if ($1 == NULL) 964 $$ = $2; 965 else 966 { 967 struct menuitem **pp; 968 969 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next) 970 ; 971 *pp = $2; 972 $$ = $1; 973 } 974 } 975 ; 976 977menuitem: 978 MENUITEM QUOTEDSTRING cnumexpr menuitem_flags 979 { 980 $$ = define_menuitem ($2, $3, $4, 0, 0, NULL); 981 } 982 | MENUITEM SEPARATOR 983 { 984 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL); 985 } 986 | POPUP QUOTEDSTRING menuitem_flags BEG menuitems END 987 { 988 $$ = define_menuitem ($2, 0, $3, 0, 0, $5); 989 } 990 ; 991 992menuitem_flags: 993 /* empty */ 994 { 995 $$ = 0; 996 } 997 | menuitem_flags ',' menuitem_flag 998 { 999 $$ = $1 | $3; 1000 } 1001 | menuitem_flags menuitem_flag 1002 { 1003 $$ = $1 | $2; 1004 } 1005 ; 1006 1007menuitem_flag: 1008 CHECKED 1009 { 1010 $$ = MENUITEM_CHECKED; 1011 } 1012 | GRAYED 1013 { 1014 $$ = MENUITEM_GRAYED; 1015 } 1016 | HELP 1017 { 1018 $$ = MENUITEM_HELP; 1019 } 1020 | INACTIVE 1021 { 1022 $$ = MENUITEM_INACTIVE; 1023 } 1024 | MENUBARBREAK 1025 { 1026 $$ = MENUITEM_MENUBARBREAK; 1027 } 1028 | MENUBREAK 1029 { 1030 $$ = MENUITEM_MENUBREAK; 1031 } 1032 ; 1033 1034/* Menuex resources. */ 1035 1036menuex: 1037 id MENUEX suboptions BEG menuexitems END 1038 { 1039 define_menu ($1, &$3, $5); 1040 if (yychar != YYEMPTY) 1041 YYERROR; 1042 rcparse_discard_strings (); 1043 } 1044 ; 1045 1046menuexitems: 1047 /* empty */ 1048 { 1049 $$ = NULL; 1050 } 1051 | menuexitems menuexitem 1052 { 1053 if ($1 == NULL) 1054 $$ = $2; 1055 else 1056 { 1057 struct menuitem **pp; 1058 1059 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next) 1060 ; 1061 *pp = $2; 1062 $$ = $1; 1063 } 1064 } 1065 ; 1066 1067menuexitem: 1068 MENUITEM QUOTEDSTRING 1069 { 1070 $$ = define_menuitem ($2, 0, 0, 0, 0, NULL); 1071 } 1072 | MENUITEM QUOTEDSTRING cnumexpr 1073 { 1074 $$ = define_menuitem ($2, $3, 0, 0, 0, NULL); 1075 } 1076 | MENUITEM QUOTEDSTRING cnumexpr cnumexpr optcnumexpr 1077 { 1078 $$ = define_menuitem ($2, $3, $4, $5, 0, NULL); 1079 } 1080 | MENUITEM SEPARATOR 1081 { 1082 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL); 1083 } 1084 | POPUP QUOTEDSTRING BEG menuexitems END 1085 { 1086 $$ = define_menuitem ($2, 0, 0, 0, 0, $4); 1087 } 1088 | POPUP QUOTEDSTRING cnumexpr BEG menuexitems END 1089 { 1090 $$ = define_menuitem ($2, $3, 0, 0, 0, $5); 1091 } 1092 | POPUP QUOTEDSTRING cnumexpr cnumexpr BEG menuexitems END 1093 { 1094 $$ = define_menuitem ($2, $3, $4, 0, 0, $6); 1095 } 1096 | POPUP QUOTEDSTRING cnumexpr cnumexpr cnumexpr optcnumexpr 1097 BEG menuexitems END 1098 { 1099 $$ = define_menuitem ($2, $3, $4, $5, $6, $8); 1100 } 1101 ; 1102 1103/* Messagetable resources. */ 1104 1105messagetable: 1106 id MESSAGETABLE memflags_move file_name 1107 { 1108 define_messagetable ($1, &$3, $4); 1109 if (yychar != YYEMPTY) 1110 YYERROR; 1111 rcparse_discard_strings (); 1112 } 1113 ; 1114 1115/* Rcdata resources. */ 1116 1117rcdata: 1118 id RCDATA suboptions BEG optrcdata_data END 1119 { 1120 define_rcdata ($1, &$3, $5.first); 1121 if (yychar != YYEMPTY) 1122 YYERROR; 1123 rcparse_discard_strings (); 1124 } 1125 ; 1126 1127/* We use a different lexing algorithm, because rcdata strings may 1128 contain embedded null bytes, and we need to know the length to use. */ 1129 1130optrcdata_data: 1131 { 1132 rcparse_rcdata (); 1133 } 1134 optrcdata_data_int 1135 { 1136 rcparse_normal (); 1137 $$ = $2; 1138 } 1139 ; 1140 1141optrcdata_data_int: 1142 /* empty */ 1143 { 1144 $$.first = NULL; 1145 $$.last = NULL; 1146 } 1147 | rcdata_data 1148 { 1149 $$ = $1; 1150 } 1151 ; 1152 1153rcdata_data: 1154 SIZEDSTRING 1155 { 1156 struct rcdata_item *ri; 1157 1158 ri = define_rcdata_string ($1.s, $1.length); 1159 $$.first = ri; 1160 $$.last = ri; 1161 } 1162 | sizednumexpr 1163 { 1164 struct rcdata_item *ri; 1165 1166 ri = define_rcdata_number ($1.val, $1.dword); 1167 $$.first = ri; 1168 $$.last = ri; 1169 } 1170 | rcdata_data ',' SIZEDSTRING 1171 { 1172 struct rcdata_item *ri; 1173 1174 ri = define_rcdata_string ($3.s, $3.length); 1175 $$.first = $1.first; 1176 $1.last->next = ri; 1177 $$.last = ri; 1178 } 1179 | rcdata_data ',' sizednumexpr 1180 { 1181 struct rcdata_item *ri; 1182 1183 ri = define_rcdata_number ($3.val, $3.dword); 1184 $$.first = $1.first; 1185 $1.last->next = ri; 1186 $$.last = ri; 1187 } 1188 ; 1189 1190/* Stringtable resources. */ 1191 1192stringtable: 1193 STRINGTABLE suboptions BEG 1194 { sub_res_info = $2; } 1195 string_data END 1196 ; 1197 1198string_data: 1199 /* empty */ 1200 | string_data numexpr QUOTEDSTRING 1201 { 1202 define_stringtable (&sub_res_info, $2, $3); 1203 if (yychar != YYEMPTY) 1204 YYERROR; 1205 rcparse_discard_strings (); 1206 } 1207 | string_data numexpr ',' QUOTEDSTRING 1208 { 1209 define_stringtable (&sub_res_info, $2, $4); 1210 if (yychar != YYEMPTY) 1211 YYERROR; 1212 rcparse_discard_strings (); 1213 } 1214 ; 1215 1216/* User defined resources. We accept general suboptions in the 1217 file_name case to keep the parser happy. */ 1218 1219user: 1220 id id suboptions BEG optrcdata_data END 1221 { 1222 define_user_data ($1, $2, &$3, $5.first); 1223 if (yychar != YYEMPTY) 1224 YYERROR; 1225 rcparse_discard_strings (); 1226 } 1227 | id id suboptions file_name 1228 { 1229 define_user_file ($1, $2, &$3, $4); 1230 if (yychar != YYEMPTY) 1231 YYERROR; 1232 rcparse_discard_strings (); 1233 } 1234 ; 1235 1236/* Versioninfo resources. */ 1237 1238versioninfo: 1239 id VERSIONINFO fixedverinfo BEG verblocks END 1240 { 1241 define_versioninfo ($1, language, $3, $5); 1242 if (yychar != YYEMPTY) 1243 YYERROR; 1244 rcparse_discard_strings (); 1245 } 1246 ; 1247 1248fixedverinfo: 1249 /* empty */ 1250 { 1251 $$ = ((struct fixed_versioninfo *) 1252 res_alloc (sizeof (struct fixed_versioninfo))); 1253 memset ($$, 0, sizeof (struct fixed_versioninfo)); 1254 } 1255 | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr 1256 { 1257 $1->file_version_ms = ($3 << 16) | $4; 1258 $1->file_version_ls = ($5 << 16) | $6; 1259 $$ = $1; 1260 } 1261 | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr 1262 { 1263 $1->product_version_ms = ($3 << 16) | $4; 1264 $1->product_version_ls = ($5 << 16) | $6; 1265 $$ = $1; 1266 } 1267 | fixedverinfo FILEFLAGSMASK numexpr 1268 { 1269 $1->file_flags_mask = $3; 1270 $$ = $1; 1271 } 1272 | fixedverinfo FILEFLAGS numexpr 1273 { 1274 $1->file_flags = $3; 1275 $$ = $1; 1276 } 1277 | fixedverinfo FILEOS numexpr 1278 { 1279 $1->file_os = $3; 1280 $$ = $1; 1281 } 1282 | fixedverinfo FILETYPE numexpr 1283 { 1284 $1->file_type = $3; 1285 $$ = $1; 1286 } 1287 | fixedverinfo FILESUBTYPE numexpr 1288 { 1289 $1->file_subtype = $3; 1290 $$ = $1; 1291 } 1292 ; 1293 1294/* To handle verblocks successfully, the lexer handles BLOCK 1295 specially. A BLOCK "StringFileInfo" is returned as 1296 BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as 1297 BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK 1298 with the string as the value. */ 1299 1300verblocks: 1301 /* empty */ 1302 { 1303 $$ = NULL; 1304 } 1305 | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END 1306 { 1307 $$ = append_ver_stringfileinfo ($1, $4, $6); 1308 } 1309 | verblocks BLOCKVARFILEINFO BEG VALUE QUOTEDSTRING vertrans END 1310 { 1311 $$ = append_ver_varfileinfo ($1, $5, $6); 1312 } 1313 ; 1314 1315vervals: 1316 /* empty */ 1317 { 1318 $$ = NULL; 1319 } 1320 | vervals VALUE QUOTEDSTRING ',' QUOTEDSTRING 1321 { 1322 $$ = append_verval ($1, $3, $5); 1323 } 1324 ; 1325 1326vertrans: 1327 /* empty */ 1328 { 1329 $$ = NULL; 1330 } 1331 | vertrans cnumexpr cnumexpr 1332 { 1333 $$ = append_vertrans ($1, $2, $3); 1334 } 1335 ; 1336 1337/* A resource ID. */ 1338 1339id: 1340 posnumexpr 1341 { 1342 $$.named = 0; 1343 $$.u.id = $1; 1344 } 1345 | STRING 1346 { 1347 char *copy, *s; 1348 1349 /* It seems that resource ID's are forced to upper case. */ 1350 copy = xstrdup ($1); 1351 for (s = copy; *s != '\0'; s++) 1352 *s = TOUPPER (*s); 1353 res_string_to_id (&$$, copy); 1354 free (copy); 1355 } 1356 ; 1357 1358/* A resource reference. */ 1359 1360resname: 1361 QUOTEDSTRING 1362 { 1363 $$ = $1; 1364 } 1365 | QUOTEDSTRING ',' 1366 { 1367 $$ = $1; 1368 } 1369 | STRING ',' 1370 { 1371 $$ = $1; 1372 } 1373 ; 1374 1375 1376resref: 1377 posnumexpr ',' 1378 { 1379 $$.named = 0; 1380 $$.u.id = $1; 1381 } 1382 | resname 1383 { 1384 char *copy, *s; 1385 1386 /* It seems that resource ID's are forced to upper case. */ 1387 copy = xstrdup ($1); 1388 for (s = copy; *s != '\0'; s++) 1389 *s = TOUPPER (*s); 1390 res_string_to_id (&$$, copy); 1391 free (copy); 1392 } 1393 ; 1394 1395/* Generic suboptions. These may appear before the BEGIN in any 1396 multiline statement. */ 1397 1398suboptions: 1399 /* empty */ 1400 { 1401 memset (&$$, 0, sizeof (struct res_res_info)); 1402 $$.language = language; 1403 /* FIXME: Is this the right default? */ 1404 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE; 1405 } 1406 | suboptions memflag 1407 { 1408 $$ = $1; 1409 $$.memflags |= $2.on; 1410 $$.memflags &=~ $2.off; 1411 } 1412 | suboptions CHARACTERISTICS numexpr 1413 { 1414 $$ = $1; 1415 $$.characteristics = $3; 1416 } 1417 | suboptions LANGUAGE numexpr cnumexpr 1418 { 1419 $$ = $1; 1420 $$.language = $3 | ($4 << SUBLANG_SHIFT); 1421 } 1422 | suboptions VERSIONK numexpr 1423 { 1424 $$ = $1; 1425 $$.version = $3; 1426 } 1427 ; 1428 1429/* Memory flags which default to MOVEABLE and DISCARDABLE. */ 1430 1431memflags_move_discard: 1432 /* empty */ 1433 { 1434 memset (&$$, 0, sizeof (struct res_res_info)); 1435 $$.language = language; 1436 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE; 1437 } 1438 | memflags_move_discard memflag 1439 { 1440 $$ = $1; 1441 $$.memflags |= $2.on; 1442 $$.memflags &=~ $2.off; 1443 } 1444 ; 1445 1446/* Memory flags which default to MOVEABLE. */ 1447 1448memflags_move: 1449 /* empty */ 1450 { 1451 memset (&$$, 0, sizeof (struct res_res_info)); 1452 $$.language = language; 1453 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE; 1454 } 1455 | memflags_move memflag 1456 { 1457 $$ = $1; 1458 $$.memflags |= $2.on; 1459 $$.memflags &=~ $2.off; 1460 } 1461 ; 1462 1463/* Memory flags. This returns a struct with two integers, because we 1464 sometimes want to set bits and we sometimes want to clear them. */ 1465 1466memflag: 1467 MOVEABLE 1468 { 1469 $$.on = MEMFLAG_MOVEABLE; 1470 $$.off = 0; 1471 } 1472 | FIXED 1473 { 1474 $$.on = 0; 1475 $$.off = MEMFLAG_MOVEABLE; 1476 } 1477 | PURE 1478 { 1479 $$.on = MEMFLAG_PURE; 1480 $$.off = 0; 1481 } 1482 | IMPURE 1483 { 1484 $$.on = 0; 1485 $$.off = MEMFLAG_PURE; 1486 } 1487 | PRELOAD 1488 { 1489 $$.on = MEMFLAG_PRELOAD; 1490 $$.off = 0; 1491 } 1492 | LOADONCALL 1493 { 1494 $$.on = 0; 1495 $$.off = MEMFLAG_PRELOAD; 1496 } 1497 | DISCARDABLE 1498 { 1499 $$.on = MEMFLAG_DISCARDABLE; 1500 $$.off = 0; 1501 } 1502 ; 1503 1504/* A file name. */ 1505 1506file_name: 1507 QUOTEDSTRING 1508 { 1509 $$ = $1; 1510 } 1511 | STRING 1512 { 1513 $$ = $1; 1514 } 1515 ; 1516 1517/* A style expression. This changes the static variable STYLE. We do 1518 it this way because rc appears to permit a style to be set to 1519 something like 1520 WS_GROUP | NOT WS_TABSTOP 1521 to mean that a default of WS_TABSTOP should be removed. Anything 1522 which wants to accept a style must first set STYLE to the default 1523 value. The styleexpr nonterminal will change STYLE as specified by 1524 the user. Note that we do not accept arbitrary expressions here, 1525 just numbers separated by '|'. */ 1526 1527styleexpr: 1528 parennumber 1529 { 1530 style |= $1; 1531 } 1532 | NOT parennumber 1533 { 1534 style &=~ $2; 1535 } 1536 | styleexpr '|' parennumber 1537 { 1538 style |= $3; 1539 } 1540 | styleexpr '|' NOT parennumber 1541 { 1542 style &=~ $4; 1543 } 1544 ; 1545 1546parennumber: 1547 NUMBER 1548 { 1549 $$ = $1.val; 1550 } 1551 | '(' numexpr ')' 1552 { 1553 $$ = $2; 1554 } 1555 ; 1556 1557/* An optional expression with a leading comma. */ 1558 1559optcnumexpr: 1560 /* empty */ 1561 { 1562 $$ = 0; 1563 } 1564 | cnumexpr 1565 { 1566 $$ = $1; 1567 } 1568 ; 1569 1570/* An expression with a leading comma. */ 1571 1572cnumexpr: 1573 ',' numexpr 1574 { 1575 $$ = $2; 1576 } 1577 ; 1578 1579/* A possibly negated numeric expression. */ 1580 1581numexpr: 1582 sizednumexpr 1583 { 1584 $$ = $1.val; 1585 } 1586 ; 1587 1588/* A possibly negated expression with a size. */ 1589 1590sizednumexpr: 1591 NUMBER 1592 { 1593 $$ = $1; 1594 } 1595 | '(' sizednumexpr ')' 1596 { 1597 $$ = $2; 1598 } 1599 | '~' sizednumexpr %prec '~' 1600 { 1601 $$.val = ~ $2.val; 1602 $$.dword = $2.dword; 1603 } 1604 | '-' sizednumexpr %prec NEG 1605 { 1606 $$.val = - $2.val; 1607 $$.dword = $2.dword; 1608 } 1609 | sizednumexpr '*' sizednumexpr 1610 { 1611 $$.val = $1.val * $3.val; 1612 $$.dword = $1.dword || $3.dword; 1613 } 1614 | sizednumexpr '/' sizednumexpr 1615 { 1616 $$.val = $1.val / $3.val; 1617 $$.dword = $1.dword || $3.dword; 1618 } 1619 | sizednumexpr '%' sizednumexpr 1620 { 1621 $$.val = $1.val % $3.val; 1622 $$.dword = $1.dword || $3.dword; 1623 } 1624 | sizednumexpr '+' sizednumexpr 1625 { 1626 $$.val = $1.val + $3.val; 1627 $$.dword = $1.dword || $3.dword; 1628 } 1629 | sizednumexpr '-' sizednumexpr 1630 { 1631 $$.val = $1.val - $3.val; 1632 $$.dword = $1.dword || $3.dword; 1633 } 1634 | sizednumexpr '&' sizednumexpr 1635 { 1636 $$.val = $1.val & $3.val; 1637 $$.dword = $1.dword || $3.dword; 1638 } 1639 | sizednumexpr '^' sizednumexpr 1640 { 1641 $$.val = $1.val ^ $3.val; 1642 $$.dword = $1.dword || $3.dword; 1643 } 1644 | sizednumexpr '|' sizednumexpr 1645 { 1646 $$.val = $1.val | $3.val; 1647 $$.dword = $1.dword || $3.dword; 1648 } 1649 ; 1650 1651/* An expression with a leading comma which does not use unary 1652 negation. */ 1653 1654cposnumexpr: 1655 ',' posnumexpr 1656 { 1657 $$ = $2; 1658 } 1659 ; 1660 1661/* An expression which does not use unary negation. */ 1662 1663posnumexpr: 1664 sizedposnumexpr 1665 { 1666 $$ = $1.val; 1667 } 1668 ; 1669 1670/* An expression which does not use unary negation. We separate unary 1671 negation to avoid parsing conflicts when two numeric expressions 1672 appear consecutively. */ 1673 1674sizedposnumexpr: 1675 NUMBER 1676 { 1677 $$ = $1; 1678 } 1679 | '(' sizednumexpr ')' 1680 { 1681 $$ = $2; 1682 } 1683 | '~' sizednumexpr %prec '~' 1684 { 1685 $$.val = ~ $2.val; 1686 $$.dword = $2.dword; 1687 } 1688 | sizedposnumexpr '*' sizednumexpr 1689 { 1690 $$.val = $1.val * $3.val; 1691 $$.dword = $1.dword || $3.dword; 1692 } 1693 | sizedposnumexpr '/' sizednumexpr 1694 { 1695 $$.val = $1.val / $3.val; 1696 $$.dword = $1.dword || $3.dword; 1697 } 1698 | sizedposnumexpr '%' sizednumexpr 1699 { 1700 $$.val = $1.val % $3.val; 1701 $$.dword = $1.dword || $3.dword; 1702 } 1703 | sizedposnumexpr '+' sizednumexpr 1704 { 1705 $$.val = $1.val + $3.val; 1706 $$.dword = $1.dword || $3.dword; 1707 } 1708 | sizedposnumexpr '-' sizednumexpr 1709 { 1710 $$.val = $1.val - $3.val; 1711 $$.dword = $1.dword || $3.dword; 1712 } 1713 | sizedposnumexpr '&' sizednumexpr 1714 { 1715 $$.val = $1.val & $3.val; 1716 $$.dword = $1.dword || $3.dword; 1717 } 1718 | sizedposnumexpr '^' sizednumexpr 1719 { 1720 $$.val = $1.val ^ $3.val; 1721 $$.dword = $1.dword || $3.dword; 1722 } 1723 | sizedposnumexpr '|' sizednumexpr 1724 { 1725 $$.val = $1.val | $3.val; 1726 $$.dword = $1.dword || $3.dword; 1727 } 1728 ; 1729 1730%% 1731 1732/* Set the language from the command line. */ 1733 1734void 1735rcparse_set_language (lang) 1736 int lang; 1737{ 1738 language = lang; 1739} 1740