1 %{ /* rcparse.y -- parser for Windows rc files
2 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005
3 Free Software Foundation, Inc.
4 Written by Ian Lance Taylor, Cygnus Support.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23 /* This is a parser for Windows rc files. It is based on the parser
24 by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
28 #include "libiberty.h"
30 #include "safe-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
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
53 static unsigned long base_style;
54 static unsigned long default_style;
55 static unsigned long class;
56 static struct res_id res_text_field;
57 static unichar null_unichar;
59 /* This is used for COMBOBOX, LISTBOX and EDITTEXT which
60 do not allow resource 'text' field in control definition. */
61 static const struct res_id res_null_text = { 1, {{0, &null_unichar}}};
67 struct accelerator acc;
68 struct accelerator *pacc;
69 struct dialog_control *dialog_control;
70 struct menuitem *menuitem;
73 struct rcdata_item *first;
74 struct rcdata_item *last;
76 struct rcdata_item *rcdata_item;
77 struct stringtable_data *stringtable;
78 struct fixed_versioninfo *fixver;
79 struct ver_info *verinfo;
80 struct ver_stringinfo *verstring;
81 struct ver_varinfo *vervar;
83 struct res_res_info res_info;
92 /* Nonzero if this number was explicitly specified as long. */
100 unsigned long length;
106 %token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
109 %token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
110 %token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
111 %token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
112 %token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
113 %token BEDIT HEDIT IEDIT
116 %token LANGUAGE CHARACTERISTICS VERSIONK
117 %token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
118 %token MENUBARBREAK MENUBREAK
122 %token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
123 %token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
126 %token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
128 %token <s> QUOTEDSTRING STRING
130 %token <ss> SIZEDSTRING
133 %type <pacc> acc_entries
134 %type <acc> acc_entry acc_event
135 %type <dialog_control> control control_params
136 %type <menuitem> menuitems menuitem menuexitems menuexitem
137 %type <rcdata> optrcdata_data optrcdata_data_int rcdata_data
138 %type <rcdata_item> opt_control_data
139 %type <fixver> fixedverinfo
140 %type <verinfo> verblocks
141 %type <verstring> vervals
142 %type <vervar> vertrans
143 %type <res_info> suboptions memflags_move_discard memflags_move
144 %type <memflags> memflag
145 %type <id> id optresidc resref
146 %type <il> exstyle parennumber
147 %type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
148 %type <is> acc_options acc_option menuitem_flags menuitem_flag
149 %type <s> file_name resname
150 %type <i> sizednumexpr sizedposnumexpr
177 | input IGNORED_TOKEN
180 /* Accelerator resources. */
183 id ACCELERATORS suboptions BEG acc_entries END
185 define_accelerator ($1, &$3, $5);
186 if (yychar != YYEMPTY)
188 rcparse_discard_strings ();
197 | acc_entries acc_entry
199 struct accelerator *a;
201 a = (struct accelerator *) res_alloc (sizeof *a);
207 struct accelerator **pp;
209 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
218 acc_event cposnumexpr
223 | acc_event cposnumexpr ',' acc_options
228 if (($$.flags & ACC_VIRTKEY) == 0
229 && ($$.flags & (ACC_SHIFT | ACC_CONTROL)) != 0)
230 rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
247 $$.flags = ACC_CONTROL | ACC_VIRTKEY;
254 rcparse_warning (_("accelerator should only be one character"));
270 | acc_options ',' acc_option
274 /* I've had one report that the comma is optional. */
275 | acc_options acc_option
288 /* This is just the absence of VIRTKEY. */
309 /* Bitmap resources. */
312 id BITMAP memflags_move file_name
314 define_bitmap ($1, &$3, $4);
315 if (yychar != YYEMPTY)
317 rcparse_discard_strings ();
321 /* Cursor resources. */
324 id CURSOR memflags_move_discard file_name
326 define_cursor ($1, &$3, $4);
327 if (yychar != YYEMPTY)
329 rcparse_discard_strings ();
333 /* Dialog resources. */
336 id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
339 memset (&dialog, 0, sizeof dialog);
344 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
346 dialog.menu.named = 1;
347 dialog.class.named = 1;
350 dialog.controls = NULL;
354 styles BEG controls END
356 define_dialog ($1, &sub_res_info, &dialog);
357 if (yychar != YYEMPTY)
359 rcparse_discard_strings ();
361 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
364 memset (&dialog, 0, sizeof dialog);
369 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
371 dialog.menu.named = 1;
372 dialog.class.named = 1;
374 dialog.ex = ((struct dialog_ex *)
375 res_alloc (sizeof (struct dialog_ex)));
376 memset (dialog.ex, 0, sizeof (struct dialog_ex));
377 dialog.controls = NULL;
381 styles BEG controls END
383 define_dialog ($1, &sub_res_info, &dialog);
384 if (yychar != YYEMPTY)
386 rcparse_discard_strings ();
388 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
391 memset (&dialog, 0, sizeof dialog);
396 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
398 dialog.menu.named = 1;
399 dialog.class.named = 1;
401 dialog.ex = ((struct dialog_ex *)
402 res_alloc (sizeof (struct dialog_ex)));
403 memset (dialog.ex, 0, sizeof (struct dialog_ex));
404 dialog.ex->help = $9;
405 dialog.controls = NULL;
409 styles BEG controls END
411 define_dialog ($1, &sub_res_info, &dialog);
412 if (yychar != YYEMPTY)
414 rcparse_discard_strings ();
423 | EXSTYLE '=' numexpr
431 | styles CAPTION QUOTEDSTRING
433 dialog.style |= WS_CAPTION;
435 unicode_from_ascii ((int *) NULL, &dialog.caption, $3);
444 dialog.style = style;
446 | styles EXSTYLE numexpr
450 | styles CLASS QUOTEDSTRING
452 res_string_to_id (& dialog.class, $3);
454 | styles FONT numexpr ',' QUOTEDSTRING
456 dialog.style |= DS_SETFONT;
458 dialog.pointsize = $3;
459 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
460 if (dialog.ex != NULL)
462 dialog.ex->weight = 0;
463 dialog.ex->italic = 0;
464 dialog.ex->charset = 1;
467 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr
469 dialog.style |= DS_SETFONT;
471 dialog.pointsize = $3;
472 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
473 if (dialog.ex == NULL)
474 rcparse_warning (_("extended FONT requires DIALOGEX"));
477 dialog.ex->weight = $6;
478 dialog.ex->italic = 0;
479 dialog.ex->charset = 1;
482 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr
484 dialog.style |= DS_SETFONT;
486 dialog.pointsize = $3;
487 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
488 if (dialog.ex == NULL)
489 rcparse_warning (_("extended FONT requires DIALOGEX"));
492 dialog.ex->weight = $6;
493 dialog.ex->italic = $7;
494 dialog.ex->charset = 1;
497 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr cnumexpr
499 dialog.style |= DS_SETFONT;
501 dialog.pointsize = $3;
502 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
503 if (dialog.ex == NULL)
504 rcparse_warning (_("extended FONT requires DIALOGEX"));
507 dialog.ex->weight = $6;
508 dialog.ex->italic = $7;
509 dialog.ex->charset = $8;
516 | styles CHARACTERISTICS numexpr
518 sub_res_info.characteristics = $3;
520 | styles LANGUAGE numexpr cnumexpr
522 sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT);
524 | styles VERSIONK numexpr
526 sub_res_info.version = $3;
534 struct dialog_control **pp;
536 for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
545 default_style = BS_AUTO3STATE | WS_TABSTOP;
546 base_style = BS_AUTO3STATE;
554 | AUTOCHECKBOX optresidc
556 default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
557 base_style = BS_AUTOCHECKBOX;
565 | AUTORADIOBUTTON optresidc
567 default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
568 base_style = BS_AUTORADIOBUTTON;
578 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
579 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
586 if (dialog.ex == NULL)
587 rcparse_warning (_("BEDIT requires DIALOGEX"));
588 res_string_to_id (&$$->class, "BEDIT");
592 default_style = BS_CHECKBOX | WS_TABSTOP;
593 base_style = BS_CHECKBOX | WS_TABSTOP;
603 /* This is as per MSDN documentation. With some (???)
604 versions of MS rc.exe their is no default style. */
605 default_style = CBS_SIMPLE | WS_TABSTOP;
607 class = CTL_COMBOBOX;
608 res_text_field = res_null_text;
614 | CONTROL optresidc numexpr cnumexpr control_styleexpr cnumexpr
615 cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
617 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
620 if (dialog.ex == NULL)
621 rcparse_warning (_("control data requires DIALOGEX"));
625 | CONTROL optresidc numexpr cnumexpr control_styleexpr cnumexpr
626 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
628 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
629 if (dialog.ex == NULL)
630 rcparse_warning (_("help ID requires DIALOGEX"));
634 | CONTROL optresidc numexpr ',' QUOTEDSTRING control_styleexpr
635 cnumexpr cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
637 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
640 if (dialog.ex == NULL)
641 rcparse_warning ("control data requires DIALOGEX");
645 unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5);
647 | CONTROL optresidc numexpr ',' QUOTEDSTRING control_styleexpr
648 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
650 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
651 if (dialog.ex == NULL)
652 rcparse_warning ("help ID requires DIALOGEX");
656 unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5);
660 default_style = SS_CENTER | WS_GROUP;
661 base_style = SS_CENTER;
669 | DEFPUSHBUTTON optresidc
671 default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
672 base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
682 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
683 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
685 res_text_field = res_null_text;
693 default_style = BS_GROUPBOX;
694 base_style = BS_GROUPBOX;
704 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
705 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
712 if (dialog.ex == NULL)
713 rcparse_warning (_("IEDIT requires DIALOGEX"));
714 res_string_to_id (&$$->class, "HEDIT");
716 | ICON resref numexpr cnumexpr cnumexpr opt_control_data
718 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $6,
721 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
724 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $8,
727 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
728 icon_styleexpr optcnumexpr opt_control_data
730 $$ = define_icon_control ($2, $3, $4, $5, style, $9, 0, $10,
733 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
734 icon_styleexpr cnumexpr cnumexpr opt_control_data
736 $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11,
741 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
742 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
749 if (dialog.ex == NULL)
750 rcparse_warning (_("IEDIT requires DIALOGEX"));
751 res_string_to_id (&$$->class, "IEDIT");
755 default_style = LBS_NOTIFY | WS_BORDER;
756 base_style = LBS_NOTIFY | WS_BORDER;
758 res_text_field = res_null_text;
766 default_style = SS_LEFT | WS_GROUP;
767 base_style = SS_LEFT;
777 default_style = BS_PUSHBOX | WS_TABSTOP;
778 base_style = BS_PUSHBOX;
785 | PUSHBUTTON optresidc
787 default_style = BS_PUSHBUTTON | WS_TABSTOP;
788 base_style = BS_PUSHBUTTON | WS_TABSTOP;
796 | RADIOBUTTON optresidc
798 default_style = BS_RADIOBUTTON | WS_TABSTOP;
799 base_style = BS_RADIOBUTTON;
809 default_style = SS_RIGHT | WS_GROUP;
810 base_style = SS_RIGHT;
820 default_style = SBS_HORZ;
822 class = CTL_SCROLLBAR;
823 res_text_field = res_null_text;
831 default_style = BS_3STATE | WS_TABSTOP;
832 base_style = BS_3STATE;
840 | USERBUTTON resref numexpr ',' numexpr ',' numexpr ','
841 numexpr ',' numexpr ','
842 { style = WS_CHILD | WS_VISIBLE; }
843 styleexpr optcnumexpr
845 $$ = define_control ($2, $3, $5, $7, $9, $11, CTL_BUTTON,
850 /* Parameters for a control. The static variables DEFAULT_STYLE,
851 BASE_STYLE, and CLASS must be initialized before this nonterminal
852 is used. DEFAULT_STYLE is the style to use if no style expression
853 is specified. BASE_STYLE is the base style to use if a style
854 expression is specified; the style expression modifies the base
855 style. CLASS is the class of the control. */
858 numexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
860 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class,
861 default_style | WS_CHILD | WS_VISIBLE, 0);
864 if (dialog.ex == NULL)
865 rcparse_warning (_("control data requires DIALOGEX"));
869 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
870 control_params_styleexpr optcnumexpr opt_control_data
872 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
875 if (dialog.ex == NULL)
876 rcparse_warning (_("control data requires DIALOGEX"));
880 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
881 control_params_styleexpr cnumexpr cnumexpr opt_control_data
883 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
884 if (dialog.ex == NULL)
885 rcparse_warning (_("help ID requires DIALOGEX"));
894 res_string_to_id (&$$, "");
903 res_string_to_id (&$$, $1);
907 res_string_to_id (&$$, $1);
916 | BEG optrcdata_data END
922 /* These only exist to parse a reduction out of a common case. */
926 { style = WS_CHILD | WS_VISIBLE; }
932 { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
936 control_params_styleexpr:
938 { style = base_style | WS_CHILD | WS_VISIBLE; }
942 /* Font resources. */
945 id FONT memflags_move_discard file_name
947 define_font ($1, &$3, $4);
948 if (yychar != YYEMPTY)
950 rcparse_discard_strings ();
954 /* Icon resources. */
957 id ICON memflags_move_discard file_name
959 define_icon ($1, &$3, $4);
960 if (yychar != YYEMPTY)
962 rcparse_discard_strings ();
966 /* Language command. This changes the static variable language, which
967 affects all subsequent resources. */
970 LANGUAGE numexpr cnumexpr
972 language = $2 | ($3 << SUBLANG_SHIFT);
976 /* Menu resources. */
979 id MENU suboptions BEG menuitems END
981 define_menu ($1, &$3, $5);
982 if (yychar != YYEMPTY)
984 rcparse_discard_strings ();
999 struct menuitem **pp;
1001 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1010 MENUITEM QUOTEDSTRING cnumexpr menuitem_flags
1012 $$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
1014 | MENUITEM SEPARATOR
1016 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1018 | POPUP QUOTEDSTRING menuitem_flags BEG menuitems END
1020 $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
1029 | menuitem_flags ',' menuitem_flag
1033 | menuitem_flags menuitem_flag
1042 $$ = MENUITEM_CHECKED;
1046 $$ = MENUITEM_GRAYED;
1054 $$ = MENUITEM_INACTIVE;
1058 $$ = MENUITEM_MENUBARBREAK;
1062 $$ = MENUITEM_MENUBREAK;
1066 /* Menuex resources. */
1069 id MENUEX suboptions BEG menuexitems END
1071 define_menu ($1, &$3, $5);
1072 if (yychar != YYEMPTY)
1074 rcparse_discard_strings ();
1083 | menuexitems menuexitem
1089 struct menuitem **pp;
1091 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1100 MENUITEM QUOTEDSTRING
1102 $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
1104 | MENUITEM QUOTEDSTRING cnumexpr
1106 $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
1108 | MENUITEM QUOTEDSTRING cnumexpr cnumexpr optcnumexpr
1110 $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
1112 | MENUITEM SEPARATOR
1114 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1116 | POPUP QUOTEDSTRING BEG menuexitems END
1118 $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
1120 | POPUP QUOTEDSTRING cnumexpr BEG menuexitems END
1122 $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
1124 | POPUP QUOTEDSTRING cnumexpr cnumexpr BEG menuexitems END
1126 $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
1128 | POPUP QUOTEDSTRING cnumexpr cnumexpr cnumexpr optcnumexpr
1131 $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
1135 /* Messagetable resources. */
1138 id MESSAGETABLE memflags_move file_name
1140 define_messagetable ($1, &$3, $4);
1141 if (yychar != YYEMPTY)
1143 rcparse_discard_strings ();
1147 /* Rcdata resources. */
1150 id RCDATA suboptions BEG optrcdata_data END
1152 define_rcdata ($1, &$3, $5.first);
1153 if (yychar != YYEMPTY)
1155 rcparse_discard_strings ();
1157 | id RCDATA suboptions file_name
1159 define_rcdata_file ($1, &$3, $4);
1160 if (yychar != YYEMPTY)
1162 rcparse_discard_strings ();
1166 /* We use a different lexing algorithm, because rcdata strings may
1167 contain embedded null bytes, and we need to know the length to use. */
1195 struct rcdata_item *ri;
1197 ri = define_rcdata_string ($1.s, $1.length);
1203 struct rcdata_item *ri;
1205 ri = define_rcdata_number ($1.val, $1.dword);
1209 | rcdata_data ',' SIZEDSTRING
1211 struct rcdata_item *ri;
1213 ri = define_rcdata_string ($3.s, $3.length);
1214 $$.first = $1.first;
1218 | rcdata_data ',' sizednumexpr
1220 struct rcdata_item *ri;
1222 ri = define_rcdata_number ($3.val, $3.dword);
1223 $$.first = $1.first;
1229 /* Stringtable resources. */
1232 STRINGTABLE suboptions BEG
1233 { sub_res_info = $2; }
1239 | string_data numexpr QUOTEDSTRING
1241 define_stringtable (&sub_res_info, $2, $3);
1242 if (yychar != YYEMPTY)
1244 rcparse_discard_strings ();
1246 | string_data numexpr ',' QUOTEDSTRING
1248 define_stringtable (&sub_res_info, $2, $4);
1249 if (yychar != YYEMPTY)
1251 rcparse_discard_strings ();
1255 /* User defined resources. We accept general suboptions in the
1256 file_name case to keep the parser happy. */
1259 id id suboptions BEG optrcdata_data END
1261 define_user_data ($1, $2, &$3, $5.first);
1262 if (yychar != YYEMPTY)
1264 rcparse_discard_strings ();
1266 | id id suboptions file_name
1268 define_user_file ($1, $2, &$3, $4);
1269 if (yychar != YYEMPTY)
1271 rcparse_discard_strings ();
1275 /* Versioninfo resources. */
1278 id VERSIONINFO fixedverinfo BEG verblocks END
1280 define_versioninfo ($1, language, $3, $5);
1281 if (yychar != YYEMPTY)
1283 rcparse_discard_strings ();
1290 $$ = ((struct fixed_versioninfo *)
1291 res_alloc (sizeof (struct fixed_versioninfo)));
1292 memset ($$, 0, sizeof (struct fixed_versioninfo));
1294 | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
1296 $1->file_version_ms = ($3 << 16) | $4;
1297 $1->file_version_ls = ($5 << 16) | $6;
1300 | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
1302 $1->product_version_ms = ($3 << 16) | $4;
1303 $1->product_version_ls = ($5 << 16) | $6;
1306 | fixedverinfo FILEFLAGSMASK numexpr
1308 $1->file_flags_mask = $3;
1311 | fixedverinfo FILEFLAGS numexpr
1313 $1->file_flags = $3;
1316 | fixedverinfo FILEOS numexpr
1321 | fixedverinfo FILETYPE numexpr
1326 | fixedverinfo FILESUBTYPE numexpr
1328 $1->file_subtype = $3;
1333 /* To handle verblocks successfully, the lexer handles BLOCK
1334 specially. A BLOCK "StringFileInfo" is returned as
1335 BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as
1336 BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK
1337 with the string as the value. */
1344 | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
1346 $$ = append_ver_stringfileinfo ($1, $4, $6);
1348 | verblocks BLOCKVARFILEINFO BEG VALUE QUOTEDSTRING vertrans END
1350 $$ = append_ver_varfileinfo ($1, $5, $6);
1359 | vervals VALUE QUOTEDSTRING ',' QUOTEDSTRING
1361 $$ = append_verval ($1, $3, $5);
1370 | vertrans cnumexpr cnumexpr
1372 $$ = append_vertrans ($1, $2, $3);
1376 /* A resource ID. */
1388 /* It seems that resource ID's are forced to upper case. */
1389 copy = xstrdup ($1);
1390 for (s = copy; *s != '\0'; s++)
1392 res_string_to_id (&$$, copy);
1397 /* A resource reference. */
1425 /* It seems that resource ID's are forced to upper case. */
1426 copy = xstrdup ($1);
1427 for (s = copy; *s != '\0'; s++)
1429 res_string_to_id (&$$, copy);
1434 /* Generic suboptions. These may appear before the BEGIN in any
1435 multiline statement. */
1440 memset (&$$, 0, sizeof (struct res_res_info));
1441 $$.language = language;
1442 /* FIXME: Is this the right default? */
1443 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1445 | suboptions memflag
1448 $$.memflags |= $2.on;
1449 $$.memflags &=~ $2.off;
1451 | suboptions CHARACTERISTICS numexpr
1454 $$.characteristics = $3;
1456 | suboptions LANGUAGE numexpr cnumexpr
1459 $$.language = $3 | ($4 << SUBLANG_SHIFT);
1461 | suboptions VERSIONK numexpr
1468 /* Memory flags which default to MOVEABLE and DISCARDABLE. */
1470 memflags_move_discard:
1473 memset (&$$, 0, sizeof (struct res_res_info));
1474 $$.language = language;
1475 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
1477 | memflags_move_discard memflag
1480 $$.memflags |= $2.on;
1481 $$.memflags &=~ $2.off;
1485 /* Memory flags which default to MOVEABLE. */
1490 memset (&$$, 0, sizeof (struct res_res_info));
1491 $$.language = language;
1492 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1494 | memflags_move memflag
1497 $$.memflags |= $2.on;
1498 $$.memflags &=~ $2.off;
1502 /* Memory flags. This returns a struct with two integers, because we
1503 sometimes want to set bits and we sometimes want to clear them. */
1508 $$.on = MEMFLAG_MOVEABLE;
1514 $$.off = MEMFLAG_MOVEABLE;
1518 $$.on = MEMFLAG_PURE;
1524 $$.off = MEMFLAG_PURE;
1528 $$.on = MEMFLAG_PRELOAD;
1534 $$.off = MEMFLAG_PRELOAD;
1538 $$.on = MEMFLAG_DISCARDABLE;
1556 /* A style expression. This changes the static variable STYLE. We do
1557 it this way because rc appears to permit a style to be set to
1559 WS_GROUP | NOT WS_TABSTOP
1560 to mean that a default of WS_TABSTOP should be removed. Anything
1561 which wants to accept a style must first set STYLE to the default
1562 value. The styleexpr nonterminal will change STYLE as specified by
1563 the user. Note that we do not accept arbitrary expressions here,
1564 just numbers separated by '|'. */
1575 | styleexpr '|' parennumber
1579 | styleexpr '|' NOT parennumber
1596 /* An optional expression with a leading comma. */
1609 /* An expression with a leading comma. */
1618 /* A possibly negated numeric expression. */
1627 /* A possibly negated expression with a size. */
1634 | '(' sizednumexpr ')'
1638 | '~' sizednumexpr %prec '~'
1641 $$.dword = $2.dword;
1643 | '-' sizednumexpr %prec NEG
1646 $$.dword = $2.dword;
1648 | sizednumexpr '*' sizednumexpr
1650 $$.val = $1.val * $3.val;
1651 $$.dword = $1.dword || $3.dword;
1653 | sizednumexpr '/' sizednumexpr
1655 $$.val = $1.val / $3.val;
1656 $$.dword = $1.dword || $3.dword;
1658 | sizednumexpr '%' sizednumexpr
1660 $$.val = $1.val % $3.val;
1661 $$.dword = $1.dword || $3.dword;
1663 | sizednumexpr '+' sizednumexpr
1665 $$.val = $1.val + $3.val;
1666 $$.dword = $1.dword || $3.dword;
1668 | sizednumexpr '-' sizednumexpr
1670 $$.val = $1.val - $3.val;
1671 $$.dword = $1.dword || $3.dword;
1673 | sizednumexpr '&' sizednumexpr
1675 $$.val = $1.val & $3.val;
1676 $$.dword = $1.dword || $3.dword;
1678 | sizednumexpr '^' sizednumexpr
1680 $$.val = $1.val ^ $3.val;
1681 $$.dword = $1.dword || $3.dword;
1683 | sizednumexpr '|' sizednumexpr
1685 $$.val = $1.val | $3.val;
1686 $$.dword = $1.dword || $3.dword;
1690 /* An expression with a leading comma which does not use unary
1700 /* An expression which does not use unary negation. */
1709 /* An expression which does not use unary negation. We separate unary
1710 negation to avoid parsing conflicts when two numeric expressions
1711 appear consecutively. */
1718 | '(' sizednumexpr ')'
1722 | '~' sizednumexpr %prec '~'
1725 $$.dword = $2.dword;
1727 | sizedposnumexpr '*' sizednumexpr
1729 $$.val = $1.val * $3.val;
1730 $$.dword = $1.dword || $3.dword;
1732 | sizedposnumexpr '/' sizednumexpr
1734 $$.val = $1.val / $3.val;
1735 $$.dword = $1.dword || $3.dword;
1737 | sizedposnumexpr '%' sizednumexpr
1739 $$.val = $1.val % $3.val;
1740 $$.dword = $1.dword || $3.dword;
1742 | sizedposnumexpr '+' sizednumexpr
1744 $$.val = $1.val + $3.val;
1745 $$.dword = $1.dword || $3.dword;
1747 | sizedposnumexpr '-' sizednumexpr
1749 $$.val = $1.val - $3.val;
1750 $$.dword = $1.dword || $3.dword;
1752 | sizedposnumexpr '&' sizednumexpr
1754 $$.val = $1.val & $3.val;
1755 $$.dword = $1.dword || $3.dword;
1757 | sizedposnumexpr '^' sizednumexpr
1759 $$.val = $1.val ^ $3.val;
1760 $$.dword = $1.dword || $3.dword;
1762 | sizedposnumexpr '|' sizednumexpr
1764 $$.val = $1.val | $3.val;
1765 $$.dword = $1.dword || $3.dword;
1771 /* Set the language from the command line. */
1774 rcparse_set_language (int lang)