2002-02-18 David O'Brien <obrien@FreeBSD.org>
[binutils.git] / binutils / rcparse.y
blob152c8ee3086060a6d2d9946a136969bbfe86f9ab
1 %{ /* rcparse.y -- parser for Windows rc files
2 Copyright 1997, 1998, 1999, 2000, 2001 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"
29 #include "safe-ctype.h"
31 /* The current language. */
33 static unsigned short language;
35 /* The resource information during a sub statement. */
37 static struct res_res_info sub_res_info;
39 /* Dialog information. This is built by the nonterminals styles and
40 controls. */
42 static struct dialog dialog;
44 /* This is used when building a style. It is modified by the
45 nonterminal styleexpr. */
47 static unsigned long style;
49 /* These are used when building a control. They are set before using
50 control_params. */
52 static unsigned long base_style;
53 static unsigned long default_style;
54 static unsigned long class;
58 %union
60 struct accelerator acc;
61 struct accelerator *pacc;
62 struct dialog_control *dialog_control;
63 struct menuitem *menuitem;
64 struct
66 struct rcdata_item *first;
67 struct rcdata_item *last;
68 } rcdata;
69 struct rcdata_item *rcdata_item;
70 struct stringtable_data *stringtable;
71 struct fixed_versioninfo *fixver;
72 struct ver_info *verinfo;
73 struct ver_stringinfo *verstring;
74 struct ver_varinfo *vervar;
75 struct res_id id;
76 struct res_res_info res_info;
77 struct
79 unsigned short on;
80 unsigned short off;
81 } memflags;
82 struct
84 unsigned long val;
85 /* Nonzero if this number was explicitly specified as long. */
86 int dword;
87 } i;
88 unsigned long il;
89 unsigned short is;
90 const char *s;
91 struct
93 unsigned long length;
94 const char *s;
95 } ss;
98 %token BEG END
99 %token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
100 %token BITMAP
101 %token CURSOR
102 %token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
103 %token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
104 %token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
105 %token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
106 %token BEDIT HEDIT IEDIT
107 %token FONT
108 %token ICON
109 %token LANGUAGE CHARACTERISTICS VERSIONK
110 %token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
111 %token MENUBARBREAK MENUBREAK
112 %token MESSAGETABLE
113 %token RCDATA
114 %token STRINGTABLE
115 %token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
116 %token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
117 %token VALUE
118 %token <s> BLOCK
119 %token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
120 %token NOT
121 %token <s> QUOTEDSTRING STRING
122 %token <i> NUMBER
123 %token <ss> SIZEDSTRING
124 %token IGNORED_TOKEN
126 %type <pacc> acc_entries
127 %type <acc> acc_entry acc_event
128 %type <dialog_control> control control_params
129 %type <menuitem> menuitems menuitem menuexitems menuexitem
130 %type <rcdata> optrcdata_data optrcdata_data_int rcdata_data
131 %type <rcdata_item> opt_control_data
132 %type <fixver> fixedverinfo
133 %type <verinfo> verblocks
134 %type <verstring> vervals
135 %type <vervar> vertrans
136 %type <res_info> suboptions memflags_move_discard memflags_move
137 %type <memflags> memflag
138 %type <id> id resref
139 %type <il> exstyle parennumber
140 %type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
141 %type <is> acc_options acc_option menuitem_flags menuitem_flag
142 %type <s> optstringc file_name resname
143 %type <i> sizednumexpr sizedposnumexpr
145 %left '|'
146 %left '^'
147 %left '&'
148 %left '+' '-'
149 %left '*' '/' '%'
150 %right '~' NEG
154 input:
155 /* empty */
156 | input newcmd accelerator
157 | input newcmd bitmap
158 | input newcmd cursor
159 | input newcmd dialog
160 | input newcmd font
161 | input newcmd icon
162 | input newcmd language
163 | input newcmd menu
164 | input newcmd menuex
165 | input newcmd messagetable
166 | input newcmd rcdata
167 | input newcmd stringtable
168 | input newcmd user
169 | input newcmd versioninfo
170 | input newcmd IGNORED_TOKEN
173 newcmd:
174 /* empty */
176 rcparse_discard_strings ();
180 /* Accelerator resources. */
182 accelerator:
183 id ACCELERATORS suboptions BEG acc_entries END
185 define_accelerator ($1, &$3, $5);
189 acc_entries:
190 /* empty */
192 $$ = NULL;
194 | acc_entries acc_entry
196 struct accelerator *a;
198 a = (struct accelerator *) res_alloc (sizeof *a);
199 *a = $2;
200 if ($1 == NULL)
201 $$ = a;
202 else
204 struct accelerator **pp;
206 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
208 *pp = a;
209 $$ = $1;
214 acc_entry:
215 acc_event cposnumexpr
217 $$ = $1;
218 $$.id = $2;
220 | acc_event cposnumexpr ',' acc_options
222 $$ = $1;
223 $$.id = $2;
224 $$.flags |= $4;
225 if (($$.flags & ACC_VIRTKEY) == 0
226 && ($$.flags & (ACC_SHIFT | ACC_CONTROL | ACC_ALT)) != 0)
227 rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
231 acc_event:
232 QUOTEDSTRING
234 const char *s = $1;
235 char ch;
237 $$.next = NULL;
238 $$.id = 0;
239 ch = *s;
240 if (ch != '^')
241 $$.flags = 0;
242 else
244 $$.flags = ACC_CONTROL | ACC_VIRTKEY;
245 ++s;
246 ch = *s;
247 ch = TOUPPER (ch);
249 $$.key = ch;
250 if (s[1] != '\0')
251 rcparse_warning (_("accelerator should only be one character"));
253 | posnumexpr
255 $$.next = NULL;
256 $$.flags = 0;
257 $$.id = 0;
258 $$.key = $1;
262 acc_options:
263 acc_option
265 $$ = $1;
267 | acc_options ',' acc_option
269 $$ = $1 | $3;
271 /* I've had one report that the comma is optional. */
272 | acc_options acc_option
274 $$ = $1 | $2;
278 acc_option:
279 VIRTKEY
281 $$ = ACC_VIRTKEY;
283 | ASCII
285 /* This is just the absence of VIRTKEY. */
286 $$ = 0;
288 | NOINVERT
290 $$ = ACC_NOINVERT;
292 | SHIFT
294 $$ = ACC_SHIFT;
296 | CONTROL
298 $$ = ACC_CONTROL;
300 | ALT
302 $$ = ACC_ALT;
306 /* Bitmap resources. */
308 bitmap:
309 id BITMAP memflags_move file_name
311 define_bitmap ($1, &$3, $4);
315 /* Cursor resources. */
317 cursor:
318 id CURSOR memflags_move_discard file_name
320 define_cursor ($1, &$3, $4);
324 /* Dialog resources. */
326 dialog:
327 id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
328 cnumexpr
330 memset (&dialog, 0, sizeof dialog);
331 dialog.x = $5;
332 dialog.y = $6;
333 dialog.width = $7;
334 dialog.height = $8;
335 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
336 dialog.exstyle = $4;
337 dialog.menu.named = 1;
338 dialog.class.named = 1;
339 dialog.font = NULL;
340 dialog.ex = NULL;
341 dialog.controls = NULL;
342 sub_res_info = $3;
344 styles BEG controls END
346 define_dialog ($1, &sub_res_info, &dialog);
348 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
349 cnumexpr
351 memset (&dialog, 0, sizeof dialog);
352 dialog.x = $5;
353 dialog.y = $6;
354 dialog.width = $7;
355 dialog.height = $8;
356 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
357 dialog.exstyle = $4;
358 dialog.menu.named = 1;
359 dialog.class.named = 1;
360 dialog.font = NULL;
361 dialog.ex = ((struct dialog_ex *)
362 res_alloc (sizeof (struct dialog_ex)));
363 memset (dialog.ex, 0, sizeof (struct dialog_ex));
364 dialog.controls = NULL;
365 sub_res_info = $3;
367 styles BEG controls END
369 define_dialog ($1, &sub_res_info, &dialog);
371 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
372 cnumexpr cnumexpr
374 memset (&dialog, 0, sizeof dialog);
375 dialog.x = $5;
376 dialog.y = $6;
377 dialog.width = $7;
378 dialog.height = $8;
379 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
380 dialog.exstyle = $4;
381 dialog.menu.named = 1;
382 dialog.class.named = 1;
383 dialog.font = NULL;
384 dialog.ex = ((struct dialog_ex *)
385 res_alloc (sizeof (struct dialog_ex)));
386 memset (dialog.ex, 0, sizeof (struct dialog_ex));
387 dialog.ex->help = $9;
388 dialog.controls = NULL;
389 sub_res_info = $3;
391 styles BEG controls END
393 define_dialog ($1, &sub_res_info, &dialog);
397 exstyle:
398 /* empty */
400 $$ = 0;
402 | EXSTYLE '=' numexpr
404 $$ = $3;
408 styles:
409 /* empty */
410 | styles CAPTION QUOTEDSTRING
412 unicode_from_ascii ((int *) NULL, &dialog.caption, $3);
414 | styles CLASS id
416 dialog.class = $3;
418 | styles STYLE
419 { style = dialog.style; }
420 styleexpr
422 dialog.style = style;
424 | styles EXSTYLE numexpr
426 dialog.exstyle = $3;
428 | styles FONT numexpr ',' QUOTEDSTRING
430 dialog.style |= DS_SETFONT;
431 dialog.pointsize = $3;
432 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
434 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr
436 dialog.style |= DS_SETFONT;
437 dialog.pointsize = $3;
438 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
439 if (dialog.ex == NULL)
440 rcparse_warning (_("extended FONT requires DIALOGEX"));
441 else
443 dialog.ex->weight = $6;
444 dialog.ex->italic = $7;
447 | styles MENU id
449 dialog.menu = $3;
451 | styles CHARACTERISTICS numexpr
453 sub_res_info.characteristics = $3;
455 | styles LANGUAGE numexpr cnumexpr
457 sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT);
459 | styles VERSIONK numexpr
461 sub_res_info.version = $3;
465 controls:
466 /* empty */
467 | controls control
469 struct dialog_control **pp;
471 for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
473 *pp = $2;
477 control:
478 AUTO3STATE
480 default_style = BS_AUTO3STATE | WS_TABSTOP;
481 base_style = BS_AUTO3STATE;
482 class = CTL_BUTTON;
484 control_params
486 $$ = $3;
488 | AUTOCHECKBOX
490 default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
491 base_style = BS_AUTOCHECKBOX;
492 class = CTL_BUTTON;
494 control_params
496 $$ = $3;
498 | AUTORADIOBUTTON
500 default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
501 base_style = BS_AUTORADIOBUTTON;
502 class = CTL_BUTTON;
504 control_params
506 $$ = $3;
508 | BEDIT
510 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
511 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
512 class = CTL_EDIT;
514 control_params
516 $$ = $3;
517 if (dialog.ex == NULL)
518 rcparse_warning (_("IEDIT requires DIALOGEX"));
519 res_string_to_id (&$$->class, "BEDIT");
521 | CHECKBOX
523 default_style = BS_CHECKBOX | WS_TABSTOP;
524 base_style = BS_CHECKBOX | WS_TABSTOP;
525 class = CTL_BUTTON;
527 control_params
529 $$ = $3;
531 | COMBOBOX
533 default_style = CBS_SIMPLE | WS_TABSTOP;
534 base_style = 0;
535 class = CTL_COMBOBOX;
537 control_params
539 $$ = $3;
541 | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
542 cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
544 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
545 if ($11 != NULL)
547 if (dialog.ex == NULL)
548 rcparse_warning (_("control data requires DIALOGEX"));
549 $$->data = $11;
552 | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
553 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
555 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
556 if (dialog.ex == NULL)
557 rcparse_warning (_("help ID requires DIALOGEX"));
558 $$->help = $11;
559 $$->data = $12;
561 | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr
562 cnumexpr cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
564 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
565 if ($12 != NULL)
567 if (dialog.ex == NULL)
568 rcparse_warning ("control data requires DIALOGEX");
569 $$->data = $12;
571 $$->class.named = 1;
572 unicode_from_ascii(&$$->class.u.n.length, &$$->class.u.n.name, $5);
574 | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr
575 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
577 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
578 if (dialog.ex == NULL)
579 rcparse_warning ("help ID requires DIALOGEX");
580 $$->help = $12;
581 $$->data = $13;
582 $$->class.named = 1;
583 unicode_from_ascii(&$$->class.u.n.length, &$$->class.u.n.name, $5);
585 | CTEXT
587 default_style = SS_CENTER | WS_GROUP;
588 base_style = SS_CENTER;
589 class = CTL_STATIC;
591 control_params
593 $$ = $3;
595 | DEFPUSHBUTTON
597 default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
598 base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
599 class = CTL_BUTTON;
601 control_params
603 $$ = $3;
605 | EDITTEXT
607 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
608 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
609 class = CTL_EDIT;
611 control_params
613 $$ = $3;
615 | GROUPBOX
617 default_style = BS_GROUPBOX;
618 base_style = BS_GROUPBOX;
619 class = CTL_BUTTON;
621 control_params
623 $$ = $3;
625 | HEDIT
627 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
628 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
629 class = CTL_EDIT;
631 control_params
633 $$ = $3;
634 if (dialog.ex == NULL)
635 rcparse_warning (_("IEDIT requires DIALOGEX"));
636 res_string_to_id (&$$->class, "HEDIT");
638 | ICON resref numexpr cnumexpr cnumexpr opt_control_data
640 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $6,
641 dialog.ex);
643 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
644 opt_control_data
646 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $8,
647 dialog.ex);
649 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
650 icon_styleexpr optcnumexpr opt_control_data
652 $$ = define_icon_control ($2, $3, $4, $5, style, $9, 0, $10,
653 dialog.ex);
655 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
656 icon_styleexpr cnumexpr cnumexpr opt_control_data
658 $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11,
659 dialog.ex);
661 | IEDIT
663 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
664 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
665 class = CTL_EDIT;
667 control_params
669 $$ = $3;
670 if (dialog.ex == NULL)
671 rcparse_warning (_("IEDIT requires DIALOGEX"));
672 res_string_to_id (&$$->class, "IEDIT");
674 | LISTBOX
676 default_style = LBS_NOTIFY | WS_BORDER;
677 base_style = LBS_NOTIFY | WS_BORDER;
678 class = CTL_LISTBOX;
680 control_params
682 $$ = $3;
684 | LTEXT
686 default_style = SS_LEFT | WS_GROUP;
687 base_style = SS_LEFT;
688 class = CTL_STATIC;
690 control_params
692 $$ = $3;
694 | PUSHBOX
696 default_style = BS_PUSHBOX | WS_TABSTOP;
697 base_style = BS_PUSHBOX;
698 class = CTL_BUTTON;
700 control_params
702 $$ = $3;
704 | PUSHBUTTON
706 default_style = BS_PUSHBUTTON | WS_TABSTOP;
707 base_style = BS_PUSHBUTTON | WS_TABSTOP;
708 class = CTL_BUTTON;
710 control_params
712 $$ = $3;
714 | RADIOBUTTON
716 default_style = BS_RADIOBUTTON | WS_TABSTOP;
717 base_style = BS_RADIOBUTTON;
718 class = CTL_BUTTON;
720 control_params
722 $$ = $3;
724 | RTEXT
726 default_style = SS_RIGHT | WS_GROUP;
727 base_style = SS_RIGHT;
728 class = CTL_STATIC;
730 control_params
732 $$ = $3;
734 | SCROLLBAR
736 default_style = SBS_HORZ;
737 base_style = 0;
738 class = CTL_SCROLLBAR;
740 control_params
742 $$ = $3;
744 | STATE3
746 default_style = BS_3STATE | WS_TABSTOP;
747 base_style = BS_3STATE;
748 class = CTL_BUTTON;
750 control_params
752 $$ = $3;
754 | USERBUTTON QUOTEDSTRING ',' numexpr ',' numexpr ',' numexpr ','
755 numexpr ',' numexpr ','
756 { style = WS_CHILD | WS_VISIBLE; }
757 styleexpr optcnumexpr
759 $$ = define_control ($2, $4, $6, $8, $10, $12, CTL_BUTTON,
760 style, $16);
764 /* Parameters for a control. The static variables DEFAULT_STYLE,
765 BASE_STYLE, and CLASS must be initialized before this nonterminal
766 is used. DEFAULT_STYLE is the style to use if no style expression
767 is specified. BASE_STYLE is the base style to use if a style
768 expression is specified; the style expression modifies the base
769 style. CLASS is the class of the control. */
771 control_params:
772 optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
773 opt_control_data
775 $$ = define_control ($1, $2, $3, $4, $5, $6, class,
776 default_style | WS_CHILD | WS_VISIBLE, 0);
777 if ($7 != NULL)
779 if (dialog.ex == NULL)
780 rcparse_warning (_("control data requires DIALOGEX"));
781 $$->data = $7;
784 | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
785 control_params_styleexpr optcnumexpr opt_control_data
787 $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
788 if ($9 != NULL)
790 if (dialog.ex == NULL)
791 rcparse_warning (_("control data requires DIALOGEX"));
792 $$->data = $9;
795 | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
796 control_params_styleexpr cnumexpr cnumexpr opt_control_data
798 $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
799 if (dialog.ex == NULL)
800 rcparse_warning (_("help ID requires DIALOGEX"));
801 $$->help = $9;
802 $$->data = $10;
806 optstringc:
807 /* empty */
809 $$ = NULL;
811 | QUOTEDSTRING
813 $$ = $1;
815 | QUOTEDSTRING ','
817 $$ = $1;
821 opt_control_data:
822 /* empty */
824 $$ = NULL;
826 | BEG optrcdata_data END
828 $$ = $2.first;
832 /* These only exist to parse a reduction out of a common case. */
834 control_styleexpr:
836 { style = WS_CHILD | WS_VISIBLE; }
837 styleexpr
840 icon_styleexpr:
842 { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
843 styleexpr
846 control_params_styleexpr:
848 { style = base_style | WS_CHILD | WS_VISIBLE; }
849 styleexpr
852 /* Font resources. */
854 font:
855 id FONT memflags_move_discard file_name
857 define_font ($1, &$3, $4);
861 /* Icon resources. */
863 icon:
864 id ICON memflags_move_discard file_name
866 define_icon ($1, &$3, $4);
870 /* Language command. This changes the static variable language, which
871 affects all subsequent resources. */
873 language:
874 LANGUAGE numexpr cnumexpr
876 language = $2 | ($3 << SUBLANG_SHIFT);
880 /* Menu resources. */
882 menu:
883 id MENU suboptions BEG menuitems END
885 define_menu ($1, &$3, $5);
889 menuitems:
890 /* empty */
892 $$ = NULL;
894 | menuitems menuitem
896 if ($1 == NULL)
897 $$ = $2;
898 else
900 struct menuitem **pp;
902 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
904 *pp = $2;
905 $$ = $1;
910 menuitem:
911 MENUITEM QUOTEDSTRING cnumexpr menuitem_flags
913 $$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
915 | MENUITEM SEPARATOR
917 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
919 | POPUP QUOTEDSTRING menuitem_flags BEG menuitems END
921 $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
925 menuitem_flags:
926 /* empty */
928 $$ = 0;
930 | menuitem_flags ',' menuitem_flag
932 $$ = $1 | $3;
934 | menuitem_flags menuitem_flag
936 $$ = $1 | $2;
940 menuitem_flag:
941 CHECKED
943 $$ = MENUITEM_CHECKED;
945 | GRAYED
947 $$ = MENUITEM_GRAYED;
949 | HELP
951 $$ = MENUITEM_HELP;
953 | INACTIVE
955 $$ = MENUITEM_INACTIVE;
957 | MENUBARBREAK
959 $$ = MENUITEM_MENUBARBREAK;
961 | MENUBREAK
963 $$ = MENUITEM_MENUBREAK;
967 /* Menuex resources. */
969 menuex:
970 id MENUEX suboptions BEG menuexitems END
972 define_menu ($1, &$3, $5);
976 menuexitems:
977 /* empty */
979 $$ = NULL;
981 | menuexitems menuexitem
983 if ($1 == NULL)
984 $$ = $2;
985 else
987 struct menuitem **pp;
989 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
991 *pp = $2;
992 $$ = $1;
997 menuexitem:
998 MENUITEM QUOTEDSTRING
1000 $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
1002 | MENUITEM QUOTEDSTRING cnumexpr
1004 $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
1006 | MENUITEM QUOTEDSTRING cnumexpr cnumexpr optcnumexpr
1008 $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
1010 | MENUITEM SEPARATOR
1012 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1014 | POPUP QUOTEDSTRING BEG menuexitems END
1016 $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
1018 | POPUP QUOTEDSTRING cnumexpr BEG menuexitems END
1020 $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
1022 | POPUP QUOTEDSTRING cnumexpr cnumexpr BEG menuexitems END
1024 $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
1026 | POPUP QUOTEDSTRING cnumexpr cnumexpr cnumexpr optcnumexpr
1027 BEG menuexitems END
1029 $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
1033 /* Messagetable resources. */
1035 messagetable:
1036 id MESSAGETABLE memflags_move file_name
1038 define_messagetable ($1, &$3, $4);
1042 /* Rcdata resources. */
1044 rcdata:
1045 id RCDATA suboptions BEG optrcdata_data END
1047 define_rcdata ($1, &$3, $5.first);
1051 /* We use a different lexing algorithm, because rcdata strings may
1052 contain embedded null bytes, and we need to know the length to use. */
1054 optrcdata_data:
1056 rcparse_rcdata ();
1058 optrcdata_data_int
1060 rcparse_normal ();
1061 $$ = $2;
1065 optrcdata_data_int:
1066 /* empty */
1068 $$.first = NULL;
1069 $$.last = NULL;
1071 | rcdata_data
1073 $$ = $1;
1077 rcdata_data:
1078 SIZEDSTRING
1080 struct rcdata_item *ri;
1082 ri = define_rcdata_string ($1.s, $1.length);
1083 $$.first = ri;
1084 $$.last = ri;
1086 | sizednumexpr
1088 struct rcdata_item *ri;
1090 ri = define_rcdata_number ($1.val, $1.dword);
1091 $$.first = ri;
1092 $$.last = ri;
1094 | rcdata_data ',' SIZEDSTRING
1096 struct rcdata_item *ri;
1098 ri = define_rcdata_string ($3.s, $3.length);
1099 $$.first = $1.first;
1100 $1.last->next = ri;
1101 $$.last = ri;
1103 | rcdata_data ',' sizednumexpr
1105 struct rcdata_item *ri;
1107 ri = define_rcdata_number ($3.val, $3.dword);
1108 $$.first = $1.first;
1109 $1.last->next = ri;
1110 $$.last = ri;
1114 /* Stringtable resources. */
1116 stringtable:
1117 STRINGTABLE suboptions BEG
1118 { sub_res_info = $2; }
1119 string_data END
1122 string_data:
1123 /* empty */
1124 | string_data numexpr QUOTEDSTRING
1126 define_stringtable (&sub_res_info, $2, $3);
1128 | string_data numexpr ',' QUOTEDSTRING
1130 define_stringtable (&sub_res_info, $2, $4);
1134 /* User defined resources. We accept general suboptions in the
1135 file_name case to keep the parser happy. */
1137 user:
1138 id id suboptions BEG optrcdata_data END
1140 define_user_data ($1, $2, &$3, $5.first);
1142 | id id suboptions file_name
1144 define_user_file ($1, $2, &$3, $4);
1148 /* Versioninfo resources. */
1150 versioninfo:
1151 id VERSIONINFO fixedverinfo BEG verblocks END
1153 define_versioninfo ($1, language, $3, $5);
1157 fixedverinfo:
1158 /* empty */
1160 $$ = ((struct fixed_versioninfo *)
1161 res_alloc (sizeof (struct fixed_versioninfo)));
1162 memset ($$, 0, sizeof (struct fixed_versioninfo));
1164 | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
1166 $1->file_version_ms = ($3 << 16) | $4;
1167 $1->file_version_ls = ($5 << 16) | $6;
1168 $$ = $1;
1170 | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
1172 $1->product_version_ms = ($3 << 16) | $4;
1173 $1->product_version_ls = ($5 << 16) | $6;
1174 $$ = $1;
1176 | fixedverinfo FILEFLAGSMASK numexpr
1178 $1->file_flags_mask = $3;
1179 $$ = $1;
1181 | fixedverinfo FILEFLAGS numexpr
1183 $1->file_flags = $3;
1184 $$ = $1;
1186 | fixedverinfo FILEOS numexpr
1188 $1->file_os = $3;
1189 $$ = $1;
1191 | fixedverinfo FILETYPE numexpr
1193 $1->file_type = $3;
1194 $$ = $1;
1196 | fixedverinfo FILESUBTYPE numexpr
1198 $1->file_subtype = $3;
1199 $$ = $1;
1203 /* To handle verblocks successfully, the lexer handles BLOCK
1204 specially. A BLOCK "StringFileInfo" is returned as
1205 BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as
1206 BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK
1207 with the string as the value. */
1209 verblocks:
1210 /* empty */
1212 $$ = NULL;
1214 | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
1216 $$ = append_ver_stringfileinfo ($1, $4, $6);
1218 | verblocks BLOCKVARFILEINFO BEG VALUE QUOTEDSTRING vertrans END
1220 $$ = append_ver_varfileinfo ($1, $5, $6);
1224 vervals:
1225 /* empty */
1227 $$ = NULL;
1229 | vervals VALUE QUOTEDSTRING ',' QUOTEDSTRING
1231 $$ = append_verval ($1, $3, $5);
1235 vertrans:
1236 /* empty */
1238 $$ = NULL;
1240 | vertrans cnumexpr cnumexpr
1242 $$ = append_vertrans ($1, $2, $3);
1246 /* A resource ID. */
1249 posnumexpr
1251 $$.named = 0;
1252 $$.u.id = $1;
1254 | STRING
1256 char *copy, *s;
1258 /* It seems that resource ID's are forced to upper case. */
1259 copy = xstrdup ($1);
1260 for (s = copy; *s != '\0'; s++)
1261 *s = TOUPPER (*s);
1262 res_string_to_id (&$$, copy);
1263 free (copy);
1267 /* A resource reference. */
1269 resname:
1270 QUOTEDSTRING
1272 $$ = $1;
1274 | QUOTEDSTRING ','
1276 $$ = $1;
1278 | STRING ','
1280 $$ = $1;
1285 resref:
1286 posnumexpr ','
1288 $$.named = 0;
1289 $$.u.id = $1;
1291 | resname
1293 char *copy, *s;
1295 /* It seems that resource ID's are forced to upper case. */
1296 copy = xstrdup ($1);
1297 for (s = copy; *s != '\0'; s++)
1298 *s = TOUPPER (*s);
1299 res_string_to_id (&$$, copy);
1300 free (copy);
1304 /* Generic suboptions. These may appear before the BEGIN in any
1305 multiline statement. */
1307 suboptions:
1308 /* empty */
1310 memset (&$$, 0, sizeof (struct res_res_info));
1311 $$.language = language;
1312 /* FIXME: Is this the right default? */
1313 $$.memflags = MEMFLAG_MOVEABLE;
1315 | suboptions memflag
1317 $$ = $1;
1318 $$.memflags |= $2.on;
1319 $$.memflags &=~ $2.off;
1321 | suboptions CHARACTERISTICS numexpr
1323 $$ = $1;
1324 $$.characteristics = $3;
1326 | suboptions LANGUAGE numexpr cnumexpr
1328 $$ = $1;
1329 $$.language = $3 | ($4 << SUBLANG_SHIFT);
1331 | suboptions VERSIONK numexpr
1333 $$ = $1;
1334 $$.version = $3;
1338 /* Memory flags which default to MOVEABLE and DISCARDABLE. */
1340 memflags_move_discard:
1341 /* empty */
1343 memset (&$$, 0, sizeof (struct res_res_info));
1344 $$.language = language;
1345 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
1347 | memflags_move_discard memflag
1349 $$ = $1;
1350 $$.memflags |= $2.on;
1351 $$.memflags &=~ $2.off;
1355 /* Memory flags which default to MOVEABLE. */
1357 memflags_move:
1358 /* empty */
1360 memset (&$$, 0, sizeof (struct res_res_info));
1361 $$.language = language;
1362 $$.memflags = MEMFLAG_MOVEABLE;
1364 | memflags_move memflag
1366 $$ = $1;
1367 $$.memflags |= $2.on;
1368 $$.memflags &=~ $2.off;
1372 /* Memory flags. This returns a struct with two integers, because we
1373 sometimes want to set bits and we sometimes want to clear them. */
1375 memflag:
1376 MOVEABLE
1378 $$.on = MEMFLAG_MOVEABLE;
1379 $$.off = 0;
1381 | FIXED
1383 $$.on = 0;
1384 $$.off = MEMFLAG_MOVEABLE;
1386 | PURE
1388 $$.on = MEMFLAG_PURE;
1389 $$.off = 0;
1391 | IMPURE
1393 $$.on = 0;
1394 $$.off = MEMFLAG_PURE;
1396 | PRELOAD
1398 $$.on = MEMFLAG_PRELOAD;
1399 $$.off = 0;
1401 | LOADONCALL
1403 $$.on = 0;
1404 $$.off = MEMFLAG_PRELOAD;
1406 | DISCARDABLE
1408 $$.on = MEMFLAG_DISCARDABLE;
1409 $$.off = 0;
1413 /* A file name. */
1415 file_name:
1416 QUOTEDSTRING
1418 $$ = $1;
1420 | STRING
1422 $$ = $1;
1426 /* A style expression. This changes the static variable STYLE. We do
1427 it this way because rc appears to permit a style to be set to
1428 something like
1429 WS_GROUP | NOT WS_TABSTOP
1430 to mean that a default of WS_TABSTOP should be removed. Anything
1431 which wants to accept a style must first set STYLE to the default
1432 value. The styleexpr nonterminal will change STYLE as specified by
1433 the user. Note that we do not accept arbitrary expressions here,
1434 just numbers separated by '|'. */
1436 styleexpr:
1437 parennumber
1439 style |= $1;
1441 | NOT parennumber
1443 style &=~ $2;
1445 | styleexpr '|' parennumber
1447 style |= $3;
1449 | styleexpr '|' NOT parennumber
1451 style &=~ $4;
1455 parennumber:
1456 NUMBER
1458 $$ = $1.val;
1460 | '(' numexpr ')'
1462 $$ = $2;
1466 /* An optional expression with a leading comma. */
1468 optcnumexpr:
1469 /* empty */
1471 $$ = 0;
1473 | cnumexpr
1475 $$ = $1;
1479 /* An expression with a leading comma. */
1481 cnumexpr:
1482 ',' numexpr
1484 $$ = $2;
1488 /* A possibly negated numeric expression. */
1490 numexpr:
1491 sizednumexpr
1493 $$ = $1.val;
1497 /* A possibly negated expression with a size. */
1499 sizednumexpr:
1500 NUMBER
1502 $$ = $1;
1504 | '(' sizednumexpr ')'
1506 $$ = $2;
1508 | '~' sizednumexpr %prec '~'
1510 $$.val = ~ $2.val;
1511 $$.dword = $2.dword;
1513 | '-' sizednumexpr %prec NEG
1515 $$.val = - $2.val;
1516 $$.dword = $2.dword;
1518 | sizednumexpr '*' sizednumexpr
1520 $$.val = $1.val * $3.val;
1521 $$.dword = $1.dword || $3.dword;
1523 | sizednumexpr '/' sizednumexpr
1525 $$.val = $1.val / $3.val;
1526 $$.dword = $1.dword || $3.dword;
1528 | sizednumexpr '%' sizednumexpr
1530 $$.val = $1.val % $3.val;
1531 $$.dword = $1.dword || $3.dword;
1533 | sizednumexpr '+' sizednumexpr
1535 $$.val = $1.val + $3.val;
1536 $$.dword = $1.dword || $3.dword;
1538 | sizednumexpr '-' sizednumexpr
1540 $$.val = $1.val - $3.val;
1541 $$.dword = $1.dword || $3.dword;
1543 | sizednumexpr '&' sizednumexpr
1545 $$.val = $1.val & $3.val;
1546 $$.dword = $1.dword || $3.dword;
1548 | sizednumexpr '^' sizednumexpr
1550 $$.val = $1.val ^ $3.val;
1551 $$.dword = $1.dword || $3.dword;
1553 | sizednumexpr '|' sizednumexpr
1555 $$.val = $1.val | $3.val;
1556 $$.dword = $1.dword || $3.dword;
1560 /* An expression with a leading comma which does not use unary
1561 negation. */
1563 cposnumexpr:
1564 ',' posnumexpr
1566 $$ = $2;
1570 /* An expression which does not use unary negation. */
1572 posnumexpr:
1573 sizedposnumexpr
1575 $$ = $1.val;
1579 /* An expression which does not use unary negation. We separate unary
1580 negation to avoid parsing conflicts when two numeric expressions
1581 appear consecutively. */
1583 sizedposnumexpr:
1584 NUMBER
1586 $$ = $1;
1588 | '(' sizednumexpr ')'
1590 $$ = $2;
1592 | '~' sizednumexpr %prec '~'
1594 $$.val = ~ $2.val;
1595 $$.dword = $2.dword;
1597 | sizedposnumexpr '*' sizednumexpr
1599 $$.val = $1.val * $3.val;
1600 $$.dword = $1.dword || $3.dword;
1602 | sizedposnumexpr '/' sizednumexpr
1604 $$.val = $1.val / $3.val;
1605 $$.dword = $1.dword || $3.dword;
1607 | sizedposnumexpr '%' sizednumexpr
1609 $$.val = $1.val % $3.val;
1610 $$.dword = $1.dword || $3.dword;
1612 | sizedposnumexpr '+' sizednumexpr
1614 $$.val = $1.val + $3.val;
1615 $$.dword = $1.dword || $3.dword;
1617 | sizedposnumexpr '-' sizednumexpr
1619 $$.val = $1.val - $3.val;
1620 $$.dword = $1.dword || $3.dword;
1622 | sizedposnumexpr '&' sizednumexpr
1624 $$.val = $1.val & $3.val;
1625 $$.dword = $1.dword || $3.dword;
1627 | sizedposnumexpr '^' sizednumexpr
1629 $$.val = $1.val ^ $3.val;
1630 $$.dword = $1.dword || $3.dword;
1632 | sizedposnumexpr '|' sizednumexpr
1634 $$.val = $1.val | $3.val;
1635 $$.dword = $1.dword || $3.dword;
1641 /* Set the language from the command line. */
1643 void
1644 rcparse_set_language (lang)
1645 int lang;
1647 language = lang;