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