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