Fix year.
[binutils.git] / binutils / rcparse.y
blob03cbbdc5b67e194bc894f96c364a0f0400a43c5f
1 %{ /* rcparse.y -- parser for Windows rc files
2 Copyright 1997, 1998 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support.
5 This file is part of GNU Binutils.
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.
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.
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. */
22 /* This is a parser for Windows rc files. It is based on the parser
23 by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
25 #include "bfd.h"
26 #include "bucomm.h"
27 #include "libiberty.h"
28 #include "windres.h"
30 #include <ctype.h>
32 /* The current language. */
34 static unsigned short language;
36 /* The resource information during a sub statement. */
38 static struct res_res_info sub_res_info;
40 /* Dialog information. This is built by the nonterminals styles and
41 controls. */
43 static struct dialog dialog;
45 /* This is used when building a style. It is modified by the
46 nonterminal styleexpr. */
48 static unsigned long style;
50 /* These are used when building a control. They are set before using
51 control_params. */
53 static unsigned long base_style;
54 static unsigned long default_style;
55 static unsigned long class;
59 %union
61 struct accelerator acc;
62 struct accelerator *pacc;
63 struct dialog_control *dialog_control;
64 struct menuitem *menuitem;
65 struct
67 struct rcdata_item *first;
68 struct rcdata_item *last;
69 } rcdata;
70 struct rcdata_item *rcdata_item;
71 struct stringtable_data *stringtable;
72 struct fixed_versioninfo *fixver;
73 struct ver_info *verinfo;
74 struct ver_stringinfo *verstring;
75 struct ver_varinfo *vervar;
76 struct res_id id;
77 struct res_res_info res_info;
78 struct
80 unsigned short on;
81 unsigned short off;
82 } memflags;
83 struct
85 unsigned long val;
86 /* Nonzero if this number was explicitly specified as long. */
87 int dword;
88 } i;
89 unsigned long il;
90 unsigned short is;
91 const char *s;
92 struct
94 unsigned long length;
95 const char *s;
96 } ss;
99 %token BEG END
100 %token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
101 %token BITMAP
102 %token CURSOR
103 %token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
104 %token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
105 %token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
106 %token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
107 %token BEDIT HEDIT IEDIT
108 %token FONT
109 %token ICON
110 %token LANGUAGE CHARACTERISTICS VERSIONK
111 %token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
112 %token MENUBARBREAK MENUBREAK
113 %token MESSAGETABLE
114 %token RCDATA
115 %token STRINGTABLE
116 %token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
117 %token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
118 %token VALUE
119 %token <s> BLOCK
120 %token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
121 %token NOT
122 %token <s> QUOTEDSTRING STRING
123 %token <i> NUMBER
124 %token <ss> SIZEDSTRING
125 %token IGNORED_TOKEN
127 %type <pacc> acc_entries
128 %type <acc> acc_entry acc_event
129 %type <dialog_control> control control_params
130 %type <menuitem> menuitems menuitem menuexitems menuexitem
131 %type <rcdata> optrcdata_data optrcdata_data_int rcdata_data
132 %type <rcdata_item> opt_control_data
133 %type <fixver> fixedverinfo
134 %type <verinfo> verblocks
135 %type <verstring> vervals
136 %type <vervar> vertrans
137 %type <res_info> suboptions memflags_move_discard memflags_move
138 %type <memflags> memflag
139 %type <id> id
140 %type <il> exstyle parennumber
141 %type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
142 %type <is> acc_options acc_option menuitem_flags menuitem_flag
143 %type <s> optstringc file_name
144 %type <i> sizednumexpr sizedposnumexpr
146 %left '|'
147 %left '^'
148 %left '&'
149 %left '+' '-'
150 %left '*' '/' '%'
151 %right '~' NEG
155 input:
156 /* empty */
157 | input newcmd accelerator
158 | input newcmd bitmap
159 | input newcmd cursor
160 | input newcmd dialog
161 | input newcmd font
162 | input newcmd icon
163 | input newcmd language
164 | input newcmd menu
165 | input newcmd menuex
166 | input newcmd messagetable
167 | input newcmd rcdata
168 | input newcmd stringtable
169 | input newcmd user
170 | input newcmd versioninfo
171 | input newcmd IGNORED_TOKEN
174 newcmd:
175 /* empty */
177 rcparse_discard_strings ();
181 /* Accelerator resources. */
183 accelerator:
184 id ACCELERATORS suboptions BEG acc_entries END
186 define_accelerator ($1, &$3, $5);
190 acc_entries:
191 /* empty */
193 $$ = NULL;
195 | acc_entries acc_entry
197 struct accelerator *a;
199 a = (struct accelerator *) res_alloc (sizeof *a);
200 *a = $2;
201 if ($1 == NULL)
202 $$ = a;
203 else
205 struct accelerator **pp;
207 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
209 *pp = a;
210 $$ = $1;
215 acc_entry:
216 acc_event cposnumexpr
218 $$ = $1;
219 $$.id = $2;
221 | acc_event cposnumexpr ',' acc_options
223 $$ = $1;
224 $$.id = $2;
225 $$.flags |= $4;
226 if (($$.flags & ACC_VIRTKEY) == 0
227 && ($$.flags & (ACC_SHIFT | ACC_CONTROL | ACC_ALT)) != 0)
228 rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
232 acc_event:
233 QUOTEDSTRING
235 const char *s = $1;
236 char ch;
238 $$.next = NULL;
239 $$.id = 0;
240 ch = *s;
241 if (ch != '^')
242 $$.flags = 0;
243 else
245 $$.flags = ACC_CONTROL | ACC_VIRTKEY;
246 ++s;
247 ch = *s;
248 ch = toupper ((unsigned char) ch);
250 $$.key = ch;
251 if (s[1] != '\0')
252 rcparse_warning (_("accelerator should only be one character"));
254 | posnumexpr
256 $$.next = NULL;
257 $$.flags = 0;
258 $$.id = 0;
259 $$.key = $1;
263 acc_options:
264 acc_option
266 $$ = $1;
268 | acc_options ',' acc_option
270 $$ = $1 | $3;
272 /* I've had one report that the comma is optional. */
273 | acc_options acc_option
275 $$ = $1 | $2;
279 acc_option:
280 VIRTKEY
282 $$ = ACC_VIRTKEY;
284 | ASCII
286 /* This is just the absence of VIRTKEY. */
287 $$ = 0;
289 | NOINVERT
291 $$ = ACC_NOINVERT;
293 | SHIFT
295 $$ = ACC_SHIFT;
297 | CONTROL
299 $$ = ACC_CONTROL;
301 | ALT
303 $$ = ACC_ALT;
307 /* Bitmap resources. */
309 bitmap:
310 id BITMAP memflags_move file_name
312 define_bitmap ($1, &$3, $4);
316 /* Cursor resources. */
318 cursor:
319 id CURSOR memflags_move_discard file_name
321 define_cursor ($1, &$3, $4);
325 /* Dialog resources. */
327 dialog:
328 id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
329 cnumexpr
331 memset (&dialog, 0, sizeof dialog);
332 dialog.x = $5;
333 dialog.y = $6;
334 dialog.width = $7;
335 dialog.height = $8;
336 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
337 dialog.exstyle = $4;
338 dialog.menu.named = 1;
339 dialog.class.named = 1;
340 dialog.font = NULL;
341 dialog.ex = NULL;
342 dialog.controls = NULL;
343 sub_res_info = $3;
345 styles BEG controls END
347 define_dialog ($1, &sub_res_info, &dialog);
349 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
350 cnumexpr
352 memset (&dialog, 0, sizeof dialog);
353 dialog.x = $5;
354 dialog.y = $6;
355 dialog.width = $7;
356 dialog.height = $8;
357 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
358 dialog.exstyle = $4;
359 dialog.menu.named = 1;
360 dialog.class.named = 1;
361 dialog.font = NULL;
362 dialog.ex = ((struct dialog_ex *)
363 res_alloc (sizeof (struct dialog_ex)));
364 memset (dialog.ex, 0, sizeof (struct dialog_ex));
365 dialog.controls = NULL;
366 sub_res_info = $3;
368 styles BEG controls END
370 define_dialog ($1, &sub_res_info, &dialog);
372 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
373 cnumexpr cnumexpr
375 memset (&dialog, 0, sizeof dialog);
376 dialog.x = $5;
377 dialog.y = $6;
378 dialog.width = $7;
379 dialog.height = $8;
380 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
381 dialog.exstyle = $4;
382 dialog.menu.named = 1;
383 dialog.class.named = 1;
384 dialog.font = NULL;
385 dialog.ex = ((struct dialog_ex *)
386 res_alloc (sizeof (struct dialog_ex)));
387 memset (dialog.ex, 0, sizeof (struct dialog_ex));
388 dialog.ex->help = $9;
389 dialog.controls = NULL;
390 sub_res_info = $3;
392 styles BEG controls END
394 define_dialog ($1, &sub_res_info, &dialog);
398 exstyle:
399 /* empty */
401 $$ = 0;
403 | EXSTYLE '=' numexpr
405 $$ = $3;
409 styles:
410 /* empty */
411 | styles CAPTION QUOTEDSTRING
413 unicode_from_ascii ((int *) NULL, &dialog.caption, $3);
415 | styles CLASS id
417 dialog.class = $3;
419 | styles STYLE
420 { style = dialog.style; }
421 styleexpr
423 dialog.style = style;
425 | styles EXSTYLE numexpr
427 dialog.exstyle = $3;
429 | styles FONT numexpr ',' QUOTEDSTRING
431 dialog.style |= DS_SETFONT;
432 dialog.pointsize = $3;
433 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
435 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr
437 dialog.style |= DS_SETFONT;
438 dialog.pointsize = $3;
439 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
440 if (dialog.ex == NULL)
441 rcparse_warning (_("extended FONT requires DIALOGEX"));
442 else
444 dialog.ex->weight = $6;
445 dialog.ex->italic = $7;
448 | styles MENU id
450 dialog.menu = $3;
452 | styles CHARACTERISTICS numexpr
454 sub_res_info.characteristics = $3;
456 | styles LANGUAGE numexpr cnumexpr
458 sub_res_info.language = $3 | ($4 << 8);
460 | styles VERSIONK numexpr
462 sub_res_info.version = $3;
466 controls:
467 /* empty */
468 | controls control
470 struct dialog_control **pp;
472 for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
474 *pp = $2;
478 control:
479 AUTO3STATE
481 default_style = BS_AUTO3STATE | WS_TABSTOP;
482 base_style = BS_AUTO3STATE;
483 class = CTL_BUTTON;
485 control_params
487 $$ = $3;
489 | AUTOCHECKBOX
491 default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
492 base_style = BS_AUTOCHECKBOX;
493 class = CTL_BUTTON;
495 control_params
497 $$ = $3;
499 | AUTORADIOBUTTON
501 default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
502 base_style = BS_AUTORADIOBUTTON;
503 class = CTL_BUTTON;
505 control_params
507 $$ = $3;
509 | BEDIT
511 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
512 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
513 class = CTL_EDIT;
515 control_params
517 $$ = $3;
518 if (dialog.ex == NULL)
519 rcparse_warning (_("IEDIT requires DIALOGEX"));
520 res_string_to_id (&$$->class, "BEDIT");
522 | CHECKBOX
524 default_style = BS_CHECKBOX | WS_TABSTOP;
525 base_style = BS_CHECKBOX | WS_TABSTOP;
526 class = CTL_BUTTON;
528 control_params
530 $$ = $3;
532 | COMBOBOX
534 default_style = CBS_SIMPLE | WS_TABSTOP;
535 base_style = 0;
536 class = CTL_COMBOBOX;
538 control_params
540 $$ = $3;
542 | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
543 cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
545 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
546 if ($11 != NULL)
548 if (dialog.ex == NULL)
549 rcparse_warning (_("control data requires DIALOGEX"));
550 $$->data = $11;
553 | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
554 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
556 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
557 if (dialog.ex == NULL)
558 rcparse_warning (_("help ID requires DIALOGEX"));
559 $$->help = $11;
560 $$->data = $12;
562 | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr
563 cnumexpr cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
565 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
566 if ($12 != NULL)
568 if (dialog.ex == NULL)
569 rcparse_warning ("control data requires DIALOGEX");
570 $$->data = $12;
572 $$->class.named = 1;
573 unicode_from_ascii(&$$->class.u.n.length, &$$->class.u.n.name, $5);
575 | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr
576 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
578 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
579 if (dialog.ex == NULL)
580 rcparse_warning ("help ID requires DIALOGEX");
581 $$->help = $12;
582 $$->data = $13;
583 $$->class.named = 1;
584 unicode_from_ascii(&$$->class.u.n.length, &$$->class.u.n.name, $5);
586 | CTEXT
588 default_style = SS_CENTER | WS_GROUP;
589 base_style = SS_CENTER;
590 class = CTL_STATIC;
592 control_params
594 $$ = $3;
596 | DEFPUSHBUTTON
598 default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
599 base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
600 class = CTL_BUTTON;
602 control_params
604 $$ = $3;
606 | EDITTEXT
608 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
609 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
610 class = CTL_EDIT;
612 control_params
614 $$ = $3;
616 | GROUPBOX
618 default_style = BS_GROUPBOX;
619 base_style = BS_GROUPBOX;
620 class = CTL_BUTTON;
622 control_params
624 $$ = $3;
626 | HEDIT
628 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
629 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
630 class = CTL_EDIT;
632 control_params
634 $$ = $3;
635 if (dialog.ex == NULL)
636 rcparse_warning (_("IEDIT requires DIALOGEX"));
637 res_string_to_id (&$$->class, "HEDIT");
639 | ICON optstringc numexpr cnumexpr cnumexpr opt_control_data
641 $$ = define_control ($2, $3, $4, $5, 0, 0, CTL_STATIC,
642 SS_ICON | WS_CHILD | WS_VISIBLE, 0);
643 if ($6 != NULL)
645 if (dialog.ex == NULL)
646 rcparse_warning (_("control data requires DIALOGEX"));
647 $$->data = $6;
650 | ICON optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
651 icon_styleexpr optcnumexpr opt_control_data
653 $$ = define_control ($2, $3, $4, $5, $6, $7, CTL_STATIC,
654 style, $9);
655 if ($10 != NULL)
657 if (dialog.ex == NULL)
658 rcparse_warning (_("control data requires DIALOGEX"));
659 $$->data = $10;
662 | ICON optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
663 icon_styleexpr cnumexpr cnumexpr opt_control_data
665 $$ = define_control ($2, $3, $4, $5, $6, $7, CTL_STATIC,
666 style, $9);
667 if (dialog.ex == NULL)
668 rcparse_warning (_("help ID requires DIALOGEX"));
669 $$->help = $10;
670 $$->data = $11;
672 | IEDIT
674 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
675 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
676 class = CTL_EDIT;
678 control_params
680 $$ = $3;
681 if (dialog.ex == NULL)
682 rcparse_warning (_("IEDIT requires DIALOGEX"));
683 res_string_to_id (&$$->class, "IEDIT");
685 | LISTBOX
687 default_style = LBS_NOTIFY | WS_BORDER;
688 base_style = LBS_NOTIFY | WS_BORDER;
689 class = CTL_LISTBOX;
691 control_params
693 $$ = $3;
695 | LTEXT
697 default_style = SS_LEFT | WS_GROUP;
698 base_style = SS_LEFT;
699 class = CTL_STATIC;
701 control_params
703 $$ = $3;
705 | PUSHBOX
707 default_style = BS_PUSHBOX | WS_TABSTOP;
708 base_style = BS_PUSHBOX;
709 class = CTL_BUTTON;
711 control_params
713 $$ = $3;
715 | PUSHBUTTON
717 default_style = BS_PUSHBUTTON | WS_TABSTOP;
718 base_style = BS_PUSHBUTTON | WS_TABSTOP;
719 class = CTL_BUTTON;
721 control_params
723 $$ = $3;
725 | RADIOBUTTON
727 default_style = BS_RADIOBUTTON | WS_TABSTOP;
728 base_style = BS_RADIOBUTTON;
729 class = CTL_BUTTON;
731 control_params
733 $$ = $3;
735 | RTEXT
737 default_style = SS_RIGHT | WS_GROUP;
738 base_style = SS_RIGHT;
739 class = CTL_STATIC;
741 control_params
743 $$ = $3;
745 | SCROLLBAR
747 default_style = SBS_HORZ;
748 base_style = 0;
749 class = CTL_SCROLLBAR;
751 control_params
753 $$ = $3;
755 | STATE3
757 default_style = BS_3STATE | WS_TABSTOP;
758 base_style = BS_3STATE;
759 class = CTL_BUTTON;
761 control_params
763 $$ = $3;
765 | USERBUTTON QUOTEDSTRING ',' numexpr ',' numexpr ',' numexpr ','
766 numexpr ',' numexpr ','
767 { style = WS_CHILD | WS_VISIBLE; }
768 styleexpr optcnumexpr
770 $$ = define_control ($2, $4, $6, $8, $10, $12, CTL_BUTTON,
771 style, $16);
775 /* Parameters for a control. The static variables DEFAULT_STYLE,
776 BASE_STYLE, and CLASS must be initialized before this nonterminal
777 is used. DEFAULT_STYLE is the style to use if no style expression
778 is specified. BASE_STYLE is the base style to use if a style
779 expression is specified; the style expression modifies the base
780 style. CLASS is the class of the control. */
782 control_params:
783 optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
784 opt_control_data
786 $$ = define_control ($1, $2, $3, $4, $5, $6, class,
787 default_style | WS_CHILD | WS_VISIBLE, 0);
788 if ($7 != NULL)
790 if (dialog.ex == NULL)
791 rcparse_warning (_("control data requires DIALOGEX"));
792 $$->data = $7;
795 | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
796 control_params_styleexpr optcnumexpr opt_control_data
798 $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
799 if ($9 != NULL)
801 if (dialog.ex == NULL)
802 rcparse_warning (_("control data requires DIALOGEX"));
803 $$->data = $9;
806 | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
807 control_params_styleexpr cnumexpr cnumexpr opt_control_data
809 $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
810 if (dialog.ex == NULL)
811 rcparse_warning (_("help ID requires DIALOGEX"));
812 $$->help = $9;
813 $$->data = $10;
817 optstringc:
818 /* empty */
820 $$ = NULL;
822 | QUOTEDSTRING ','
824 $$ = $1;
828 opt_control_data:
829 /* empty */
831 $$ = NULL;
833 | BEG optrcdata_data END
835 $$ = $2.first;
839 /* These only exist to parse a reduction out of a common case. */
841 control_styleexpr:
843 { style = WS_CHILD | WS_VISIBLE; }
844 styleexpr
847 icon_styleexpr:
849 { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
850 styleexpr
853 control_params_styleexpr:
855 { style = base_style | WS_CHILD | WS_VISIBLE; }
856 styleexpr
859 /* Font resources. */
861 font:
862 id FONT memflags_move_discard file_name
864 define_font ($1, &$3, $4);
868 /* Icon resources. */
870 icon:
871 id ICON memflags_move_discard file_name
873 define_icon ($1, &$3, $4);
877 /* Language command. This changes the static variable language, which
878 affects all subsequent resources. */
880 language:
881 LANGUAGE numexpr cnumexpr
883 language = $2 | ($3 << 8);
887 /* Menu resources. */
889 menu:
890 id MENU suboptions BEG menuitems END
892 define_menu ($1, &$3, $5);
896 menuitems:
897 /* empty */
899 $$ = NULL;
901 | menuitems menuitem
903 if ($1 == NULL)
904 $$ = $2;
905 else
907 struct menuitem **pp;
909 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
911 *pp = $2;
912 $$ = $1;
917 menuitem:
918 MENUITEM QUOTEDSTRING cnumexpr menuitem_flags
920 $$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
922 | MENUITEM SEPARATOR
924 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
926 | POPUP QUOTEDSTRING menuitem_flags BEG menuitems END
928 $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
932 menuitem_flags:
933 /* empty */
935 $$ = 0;
937 | menuitem_flags ',' menuitem_flag
939 $$ = $1 | $3;
941 | menuitem_flags menuitem_flag
943 $$ = $1 | $2;
947 menuitem_flag:
948 CHECKED
950 $$ = MENUITEM_CHECKED;
952 | GRAYED
954 $$ = MENUITEM_GRAYED;
956 | HELP
958 $$ = MENUITEM_HELP;
960 | INACTIVE
962 $$ = MENUITEM_INACTIVE;
964 | MENUBARBREAK
966 $$ = MENUITEM_MENUBARBREAK;
968 | MENUBREAK
970 $$ = MENUITEM_MENUBREAK;
974 /* Menuex resources. */
976 menuex:
977 id MENUEX suboptions BEG menuexitems END
979 define_menu ($1, &$3, $5);
983 menuexitems:
984 /* empty */
986 $$ = NULL;
988 | menuexitems menuexitem
990 if ($1 == NULL)
991 $$ = $2;
992 else
994 struct menuitem **pp;
996 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
998 *pp = $2;
999 $$ = $1;
1004 menuexitem:
1005 MENUITEM QUOTEDSTRING
1007 $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
1009 | MENUITEM QUOTEDSTRING cnumexpr
1011 $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
1013 | MENUITEM QUOTEDSTRING cnumexpr cnumexpr optcnumexpr
1015 $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
1017 | MENUITEM SEPARATOR
1019 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1021 | POPUP QUOTEDSTRING BEG menuexitems END
1023 $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
1025 | POPUP QUOTEDSTRING cnumexpr BEG menuexitems END
1027 $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
1029 | POPUP QUOTEDSTRING cnumexpr cnumexpr BEG menuexitems END
1031 $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
1033 | POPUP QUOTEDSTRING cnumexpr cnumexpr cnumexpr optcnumexpr
1034 BEG menuexitems END
1036 $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
1040 /* Messagetable resources. */
1042 messagetable:
1043 id MESSAGETABLE memflags_move file_name
1045 define_messagetable ($1, &$3, $4);
1049 /* Rcdata resources. */
1051 rcdata:
1052 id RCDATA suboptions BEG optrcdata_data END
1054 define_rcdata ($1, &$3, $5.first);
1058 /* We use a different lexing algorithm, because rcdata strings may
1059 contain embedded null bytes, and we need to know the length to use. */
1061 optrcdata_data:
1063 rcparse_rcdata ();
1065 optrcdata_data_int
1067 rcparse_normal ();
1068 $$ = $2;
1072 optrcdata_data_int:
1073 /* empty */
1075 $$.first = NULL;
1076 $$.last = NULL;
1078 | rcdata_data
1080 $$ = $1;
1084 rcdata_data:
1085 SIZEDSTRING
1087 struct rcdata_item *ri;
1089 ri = define_rcdata_string ($1.s, $1.length);
1090 $$.first = ri;
1091 $$.last = ri;
1093 | sizednumexpr
1095 struct rcdata_item *ri;
1097 ri = define_rcdata_number ($1.val, $1.dword);
1098 $$.first = ri;
1099 $$.last = ri;
1101 | rcdata_data ',' SIZEDSTRING
1103 struct rcdata_item *ri;
1105 ri = define_rcdata_string ($3.s, $3.length);
1106 $$.first = $1.first;
1107 $1.last->next = ri;
1108 $$.last = ri;
1110 | rcdata_data ',' sizednumexpr
1112 struct rcdata_item *ri;
1114 ri = define_rcdata_number ($3.val, $3.dword);
1115 $$.first = $1.first;
1116 $1.last->next = ri;
1117 $$.last = ri;
1121 /* Stringtable resources. */
1123 stringtable:
1124 STRINGTABLE suboptions BEG
1125 { sub_res_info = $2; }
1126 string_data END
1129 string_data:
1130 /* empty */
1131 | string_data numexpr QUOTEDSTRING
1133 define_stringtable (&sub_res_info, $2, $3);
1135 | string_data numexpr ',' QUOTEDSTRING
1137 define_stringtable (&sub_res_info, $2, $4);
1141 /* User defined resources. We accept general suboptions in the
1142 file_name case to keep the parser happy. */
1144 user:
1145 id id suboptions BEG optrcdata_data END
1147 define_user_data ($1, $2, &$3, $5.first);
1149 | id id suboptions file_name
1151 define_user_file ($1, $2, &$3, $4);
1155 /* Versioninfo resources. */
1157 versioninfo:
1158 id VERSIONINFO fixedverinfo BEG verblocks END
1160 define_versioninfo ($1, language, $3, $5);
1164 fixedverinfo:
1165 /* empty */
1167 $$ = ((struct fixed_versioninfo *)
1168 res_alloc (sizeof (struct fixed_versioninfo)));
1169 memset ($$, 0, sizeof (struct fixed_versioninfo));
1171 | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
1173 $1->file_version_ms = ($3 << 16) | $4;
1174 $1->file_version_ls = ($5 << 16) | $6;
1175 $$ = $1;
1177 | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
1179 $1->product_version_ms = ($3 << 16) | $4;
1180 $1->product_version_ls = ($5 << 16) | $6;
1181 $$ = $1;
1183 | fixedverinfo FILEFLAGSMASK numexpr
1185 $1->file_flags_mask = $3;
1186 $$ = $1;
1188 | fixedverinfo FILEFLAGS numexpr
1190 $1->file_flags = $3;
1191 $$ = $1;
1193 | fixedverinfo FILEOS numexpr
1195 $1->file_os = $3;
1196 $$ = $1;
1198 | fixedverinfo FILETYPE numexpr
1200 $1->file_type = $3;
1201 $$ = $1;
1203 | fixedverinfo FILESUBTYPE numexpr
1205 $1->file_subtype = $3;
1206 $$ = $1;
1210 /* To handle verblocks successfully, the lexer handles BLOCK
1211 specially. A BLOCK "StringFileInfo" is returned as
1212 BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as
1213 BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK
1214 with the string as the value. */
1216 verblocks:
1217 /* empty */
1219 $$ = NULL;
1221 | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
1223 $$ = append_ver_stringfileinfo ($1, $4, $6);
1225 | verblocks BLOCKVARFILEINFO BEG VALUE QUOTEDSTRING vertrans END
1227 $$ = append_ver_varfileinfo ($1, $5, $6);
1231 vervals:
1232 /* empty */
1234 $$ = NULL;
1236 | vervals VALUE QUOTEDSTRING ',' QUOTEDSTRING
1238 $$ = append_verval ($1, $3, $5);
1242 vertrans:
1243 /* empty */
1245 $$ = NULL;
1247 | vertrans cnumexpr cnumexpr
1249 $$ = append_vertrans ($1, $2, $3);
1253 /* A resource ID. */
1256 posnumexpr
1258 $$.named = 0;
1259 $$.u.id = $1;
1261 | STRING
1263 char *copy, *s;
1265 /* It seems that resource ID's are forced to upper case. */
1266 copy = xstrdup ($1);
1267 for (s = copy; *s != '\0'; s++)
1268 if (islower ((unsigned char) *s))
1269 *s = toupper ((unsigned char) *s);
1270 res_string_to_id (&$$, copy);
1271 free (copy);
1275 /* Generic suboptions. These may appear before the BEGIN in any
1276 multiline statement. */
1278 suboptions:
1279 /* empty */
1281 memset (&$$, 0, sizeof (struct res_res_info));
1282 $$.language = language;
1283 /* FIXME: Is this the right default? */
1284 $$.memflags = MEMFLAG_MOVEABLE;
1286 | suboptions memflag
1288 $$ = $1;
1289 $$.memflags |= $2.on;
1290 $$.memflags &=~ $2.off;
1292 | suboptions CHARACTERISTICS numexpr
1294 $$ = $1;
1295 $$.characteristics = $3;
1297 | suboptions LANGUAGE numexpr cnumexpr
1299 $$ = $1;
1300 $$.language = $3 | ($4 << 8);
1302 | suboptions VERSIONK numexpr
1304 $$ = $1;
1305 $$.version = $3;
1309 /* Memory flags which default to MOVEABLE and DISCARDABLE. */
1311 memflags_move_discard:
1312 /* empty */
1314 memset (&$$, 0, sizeof (struct res_res_info));
1315 $$.language = language;
1316 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
1318 | memflags_move_discard memflag
1320 $$ = $1;
1321 $$.memflags |= $2.on;
1322 $$.memflags &=~ $2.off;
1326 /* Memory flags which default to MOVEABLE. */
1328 memflags_move:
1329 /* empty */
1331 memset (&$$, 0, sizeof (struct res_res_info));
1332 $$.language = language;
1333 $$.memflags = MEMFLAG_MOVEABLE;
1335 | memflags_move memflag
1337 $$ = $1;
1338 $$.memflags |= $2.on;
1339 $$.memflags &=~ $2.off;
1343 /* Memory flags. This returns a struct with two integers, because we
1344 sometimes want to set bits and we sometimes want to clear them. */
1346 memflag:
1347 MOVEABLE
1349 $$.on = MEMFLAG_MOVEABLE;
1350 $$.off = 0;
1352 | FIXED
1354 $$.on = 0;
1355 $$.off = MEMFLAG_MOVEABLE;
1357 | PURE
1359 $$.on = MEMFLAG_PURE;
1360 $$.off = 0;
1362 | IMPURE
1364 $$.on = 0;
1365 $$.off = MEMFLAG_PURE;
1367 | PRELOAD
1369 $$.on = MEMFLAG_PRELOAD;
1370 $$.off = 0;
1372 | LOADONCALL
1374 $$.on = 0;
1375 $$.off = MEMFLAG_PRELOAD;
1377 | DISCARDABLE
1379 $$.on = MEMFLAG_DISCARDABLE;
1380 $$.off = 0;
1384 /* A file name. */
1386 file_name:
1387 QUOTEDSTRING
1389 $$ = $1;
1391 | STRING
1393 $$ = $1;
1397 /* A style expression. This changes the static variable STYLE. We do
1398 it this way because rc appears to permit a style to be set to
1399 something like
1400 WS_GROUP | NOT WS_TABSTOP
1401 to mean that a default of WS_TABSTOP should be removed. Anything
1402 which wants to accept a style must first set STYLE to the default
1403 value. The styleexpr nonterminal will change STYLE as specified by
1404 the user. Note that we do not accept arbitrary expressions here,
1405 just numbers separated by '|'. */
1407 styleexpr:
1408 parennumber
1410 style |= $1;
1412 | NOT parennumber
1414 style &=~ $2;
1416 | styleexpr '|' parennumber
1418 style |= $3;
1420 | styleexpr '|' NOT parennumber
1422 style &=~ $4;
1426 parennumber:
1427 NUMBER
1429 $$ = $1.val;
1431 | '(' numexpr ')'
1433 $$ = $2;
1437 /* An optional expression with a leading comma. */
1439 optcnumexpr:
1440 /* empty */
1442 $$ = 0;
1444 | cnumexpr
1446 $$ = $1;
1450 /* An expression with a leading comma. */
1452 cnumexpr:
1453 ',' numexpr
1455 $$ = $2;
1459 /* A possibly negated numeric expression. */
1461 numexpr:
1462 sizednumexpr
1464 $$ = $1.val;
1468 /* A possibly negated expression with a size. */
1470 sizednumexpr:
1471 NUMBER
1473 $$ = $1;
1475 | '(' sizednumexpr ')'
1477 $$ = $2;
1479 | '~' sizednumexpr %prec '~'
1481 $$.val = ~ $2.val;
1482 $$.dword = $2.dword;
1484 | '-' sizednumexpr %prec NEG
1486 $$.val = - $2.val;
1487 $$.dword = $2.dword;
1489 | sizednumexpr '*' sizednumexpr
1491 $$.val = $1.val * $3.val;
1492 $$.dword = $1.dword || $3.dword;
1494 | sizednumexpr '/' sizednumexpr
1496 $$.val = $1.val / $3.val;
1497 $$.dword = $1.dword || $3.dword;
1499 | sizednumexpr '%' sizednumexpr
1501 $$.val = $1.val % $3.val;
1502 $$.dword = $1.dword || $3.dword;
1504 | sizednumexpr '+' sizednumexpr
1506 $$.val = $1.val + $3.val;
1507 $$.dword = $1.dword || $3.dword;
1509 | sizednumexpr '-' sizednumexpr
1511 $$.val = $1.val - $3.val;
1512 $$.dword = $1.dword || $3.dword;
1514 | sizednumexpr '&' sizednumexpr
1516 $$.val = $1.val & $3.val;
1517 $$.dword = $1.dword || $3.dword;
1519 | sizednumexpr '^' sizednumexpr
1521 $$.val = $1.val ^ $3.val;
1522 $$.dword = $1.dword || $3.dword;
1524 | sizednumexpr '|' sizednumexpr
1526 $$.val = $1.val | $3.val;
1527 $$.dword = $1.dword || $3.dword;
1531 /* An expression with a leading comma which does not use unary
1532 negation. */
1534 cposnumexpr:
1535 ',' posnumexpr
1537 $$ = $2;
1541 /* An expression which does not use unary negation. */
1543 posnumexpr:
1544 sizedposnumexpr
1546 $$ = $1.val;
1550 /* An expression which does not use unary negation. We separate unary
1551 negation to avoid parsing conflicts when two numeric expressions
1552 appear consecutively. */
1554 sizedposnumexpr:
1555 NUMBER
1557 $$ = $1;
1559 | '(' sizednumexpr ')'
1561 $$ = $2;
1563 | '~' sizednumexpr %prec '~'
1565 $$.val = ~ $2.val;
1566 $$.dword = $2.dword;
1568 | sizedposnumexpr '*' sizednumexpr
1570 $$.val = $1.val * $3.val;
1571 $$.dword = $1.dword || $3.dword;
1573 | sizedposnumexpr '/' sizednumexpr
1575 $$.val = $1.val / $3.val;
1576 $$.dword = $1.dword || $3.dword;
1578 | sizedposnumexpr '%' sizednumexpr
1580 $$.val = $1.val % $3.val;
1581 $$.dword = $1.dword || $3.dword;
1583 | sizedposnumexpr '+' sizednumexpr
1585 $$.val = $1.val + $3.val;
1586 $$.dword = $1.dword || $3.dword;
1588 | sizedposnumexpr '-' sizednumexpr
1590 $$.val = $1.val - $3.val;
1591 $$.dword = $1.dword || $3.dword;
1593 | sizedposnumexpr '&' sizednumexpr
1595 $$.val = $1.val & $3.val;
1596 $$.dword = $1.dword || $3.dword;
1598 | sizedposnumexpr '^' sizednumexpr
1600 $$.val = $1.val ^ $3.val;
1601 $$.dword = $1.dword || $3.dword;
1603 | sizedposnumexpr '|' sizednumexpr
1605 $$.val = $1.val | $3.val;
1606 $$.dword = $1.dword || $3.dword;
1612 /* Set the language from the command line. */
1614 void
1615 rcparse_set_language (lang)
1616 int lang;
1618 language = lang;