1 %
{ /* rcparse.y -- parser for Windows rc files
2 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support.
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
22 /* This is a parser for Windows rc files. It is based on the parser
23 by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
27 #include "libiberty.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
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
52 static unsigned long base_style
;
53 static unsigned long default_style
;
54 static unsigned long class
;
55 static struct res_id res_text_field
;
57 /* This is used for COMBOBOX, LISTBOX and EDITTEXT which
58 do not allow resource 'text' field in control definition. */
59 static const struct res_id res_null_text
= { 1, {{0, L
""}}};
65 struct accelerator acc
;
66 struct accelerator
*pacc
;
67 struct dialog_control
*dialog_control
;
68 struct menuitem
*menuitem
;
71 struct rcdata_item
*first
;
72 struct rcdata_item
*last
;
74 struct rcdata_item
*rcdata_item
;
75 struct stringtable_data
*stringtable
;
76 struct fixed_versioninfo
*fixver
;
77 struct ver_info
*verinfo
;
78 struct ver_stringinfo
*verstring
;
79 struct ver_varinfo
*vervar
;
81 struct res_res_info res_info
;
90 /* Nonzero if this number was explicitly specified as long. */
104 %token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
107 %token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
108 %token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
109 %token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
110 %token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
111 %token BEDIT HEDIT IEDIT
114 %token LANGUAGE CHARACTERISTICS VERSIONK
115 %token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
116 %token MENUBARBREAK MENUBREAK
120 %token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
121 %token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
124 %token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
126 %token
<s
> QUOTEDSTRING STRING
128 %token
<ss
> SIZEDSTRING
131 %type
<pacc
> acc_entries
132 %type
<acc
> acc_entry acc_event
133 %type
<dialog_control
> control control_params
134 %type
<menuitem
> menuitems menuitem menuexitems menuexitem
135 %type
<rcdata
> optrcdata_data optrcdata_data_int rcdata_data
136 %type
<rcdata_item
> opt_control_data
137 %type
<fixver
> fixedverinfo
138 %type
<verinfo
> verblocks
139 %type
<verstring
> vervals
140 %type
<vervar
> vertrans
141 %type
<res_info
> suboptions memflags_move_discard memflags_move
142 %type
<memflags
> memflag
143 %type
<id
> id optresidc resref
144 %type
<il
> exstyle parennumber
145 %type
<il
> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
146 %type
<is
> acc_options acc_option menuitem_flags menuitem_flag
147 %type
<s
> file_name resname
148 %type
<i
> sizednumexpr sizedposnumexpr
175 | input IGNORED_TOKEN
178 /* Accelerator resources. */
181 id ACCELERATORS suboptions BEG acc_entries END
183 define_accelerator
($1, &$3, $5);
184 if
(yychar != YYEMPTY
)
186 rcparse_discard_strings
();
195 | acc_entries acc_entry
197 struct accelerator
*a
;
199 a
= (struct accelerator
*) res_alloc
(sizeof
*a
);
205 struct accelerator
**pp
;
207 for
(pp
= &$1->next
; *pp
!= NULL
; pp
= &(*pp
)->next
)
216 acc_event cposnumexpr
221 | acc_event cposnumexpr
',' acc_options
226 if
(($$.flags
& ACC_VIRTKEY
) == 0
227 && ($$.flags
& (ACC_SHIFT | ACC_CONTROL
)) != 0)
228 rcparse_warning
(_
("inappropriate modifiers for non-VIRTKEY"));
245 $$.flags
= ACC_CONTROL | ACC_VIRTKEY
;
252 rcparse_warning
(_
("accelerator should only be one character"));
268 | acc_options
',' acc_option
272 /* I've had one report that the comma is optional. */
273 | acc_options acc_option
286 /* This is just the absence of VIRTKEY. */
307 /* Bitmap resources. */
310 id BITMAP memflags_move file_name
312 define_bitmap
($1, &$3, $4);
313 if
(yychar != YYEMPTY
)
315 rcparse_discard_strings
();
319 /* Cursor resources. */
322 id CURSOR memflags_move_discard file_name
324 define_cursor
($1, &$3, $4);
325 if
(yychar != YYEMPTY
)
327 rcparse_discard_strings
();
331 /* Dialog resources. */
334 id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
337 memset
(&dialog
, 0, sizeof dialog
);
342 dialog.style
= WS_POPUP | WS_BORDER | WS_SYSMENU
;
344 dialog.menu.named
= 1;
345 dialog.class.named
= 1;
348 dialog.controls
= NULL
;
352 styles BEG controls END
354 define_dialog
($1, &sub_res_info
, &dialog
);
355 if
(yychar != YYEMPTY
)
357 rcparse_discard_strings
();
359 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
362 memset
(&dialog
, 0, sizeof dialog
);
367 dialog.style
= WS_POPUP | WS_BORDER | WS_SYSMENU
;
369 dialog.menu.named
= 1;
370 dialog.class.named
= 1;
372 dialog.ex
= ((struct dialog_ex
*)
373 res_alloc
(sizeof
(struct dialog_ex
)));
374 memset
(dialog.ex
, 0, sizeof
(struct dialog_ex
));
375 dialog.controls
= NULL
;
379 styles BEG controls END
381 define_dialog
($1, &sub_res_info
, &dialog
);
382 if
(yychar != YYEMPTY
)
384 rcparse_discard_strings
();
386 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
389 memset
(&dialog
, 0, sizeof dialog
);
394 dialog.style
= WS_POPUP | WS_BORDER | WS_SYSMENU
;
396 dialog.menu.named
= 1;
397 dialog.class.named
= 1;
399 dialog.ex
= ((struct dialog_ex
*)
400 res_alloc
(sizeof
(struct dialog_ex
)));
401 memset
(dialog.ex
, 0, sizeof
(struct dialog_ex
));
402 dialog.ex
->help
= $9;
403 dialog.controls
= NULL
;
407 styles BEG controls END
409 define_dialog
($1, &sub_res_info
, &dialog
);
410 if
(yychar != YYEMPTY
)
412 rcparse_discard_strings
();
421 | EXSTYLE
'=' numexpr
429 | styles CAPTION QUOTEDSTRING
431 dialog.style |
= WS_CAPTION
;
433 unicode_from_ascii
((int *) NULL
, &dialog.caption
, $3);
442 dialog.style
= style
;
444 | styles EXSTYLE numexpr
448 | styles CLASS QUOTEDSTRING
450 res_string_to_id
(& dialog.class
, $3);
452 | styles FONT numexpr
',' QUOTEDSTRING
454 dialog.style |
= DS_SETFONT
;
456 dialog.pointsize
= $3;
457 unicode_from_ascii
((int *) NULL
, &dialog.font
, $5);
458 if
(dialog.ex
!= NULL
)
460 dialog.ex
->weight
= 0;
461 dialog.ex
->italic
= 0;
462 dialog.ex
->charset
= 1;
465 | styles FONT numexpr
',' QUOTEDSTRING cnumexpr
467 dialog.style |
= DS_SETFONT
;
469 dialog.pointsize
= $3;
470 unicode_from_ascii
((int *) NULL
, &dialog.font
, $5);
471 if
(dialog.ex
== NULL
)
472 rcparse_warning
(_
("extended FONT requires DIALOGEX"));
475 dialog.ex
->weight
= $6;
476 dialog.ex
->italic
= 0;
477 dialog.ex
->charset
= 1;
480 | styles FONT numexpr
',' QUOTEDSTRING cnumexpr cnumexpr
482 dialog.style |
= DS_SETFONT
;
484 dialog.pointsize
= $3;
485 unicode_from_ascii
((int *) NULL
, &dialog.font
, $5);
486 if
(dialog.ex
== NULL
)
487 rcparse_warning
(_
("extended FONT requires DIALOGEX"));
490 dialog.ex
->weight
= $6;
491 dialog.ex
->italic
= $7;
492 dialog.ex
->charset
= 1;
495 | styles FONT numexpr
',' QUOTEDSTRING cnumexpr cnumexpr cnumexpr
497 dialog.style |
= DS_SETFONT
;
499 dialog.pointsize
= $3;
500 unicode_from_ascii
((int *) NULL
, &dialog.font
, $5);
501 if
(dialog.ex
== NULL
)
502 rcparse_warning
(_
("extended FONT requires DIALOGEX"));
505 dialog.ex
->weight
= $6;
506 dialog.ex
->italic
= $7;
507 dialog.ex
->charset
= $8;
514 | styles CHARACTERISTICS numexpr
516 sub_res_info.characteristics
= $3;
518 | styles LANGUAGE numexpr cnumexpr
520 sub_res_info.language
= $3 |
($4 << SUBLANG_SHIFT
);
522 | styles VERSIONK numexpr
524 sub_res_info.version
= $3;
532 struct dialog_control
**pp
;
534 for
(pp
= &dialog.controls
; *pp
!= NULL
; pp
= &(*pp
)->next
)
543 default_style
= BS_AUTO3STATE | WS_TABSTOP
;
544 base_style
= BS_AUTO3STATE
;
552 | AUTOCHECKBOX optresidc
554 default_style
= BS_AUTOCHECKBOX | WS_TABSTOP
;
555 base_style
= BS_AUTOCHECKBOX
;
563 | AUTORADIOBUTTON optresidc
565 default_style
= BS_AUTORADIOBUTTON | WS_TABSTOP
;
566 base_style
= BS_AUTORADIOBUTTON
;
576 default_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
577 base_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
584 if
(dialog.ex
== NULL
)
585 rcparse_warning
(_
("BEDIT requires DIALOGEX"));
586 res_string_to_id
(&$$
->class
, "BEDIT");
590 default_style
= BS_CHECKBOX | WS_TABSTOP
;
591 base_style
= BS_CHECKBOX | WS_TABSTOP
;
601 /* This is as per MSDN documentation. With some (???)
602 versions of MS rc.exe their is no default style. */
603 default_style
= CBS_SIMPLE | WS_TABSTOP
;
605 class
= CTL_COMBOBOX
;
606 res_text_field
= res_null_text
;
612 | CONTROL optresidc numexpr cnumexpr control_styleexpr cnumexpr
613 cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
615 $$
= define_control
($2, $3, $6, $7, $8, $9, $4, style
, $10);
618 if
(dialog.ex
== NULL
)
619 rcparse_warning
(_
("control data requires DIALOGEX"));
623 | CONTROL optresidc numexpr cnumexpr control_styleexpr cnumexpr
624 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
626 $$
= define_control
($2, $3, $6, $7, $8, $9, $4, style
, $10);
627 if
(dialog.ex
== NULL
)
628 rcparse_warning
(_
("help ID requires DIALOGEX"));
632 | CONTROL optresidc numexpr
',' QUOTEDSTRING control_styleexpr
633 cnumexpr cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
635 $$
= define_control
($2, $3, $7, $8, $9, $10, 0, style
, $11);
638 if
(dialog.ex
== NULL
)
639 rcparse_warning
("control data requires DIALOGEX");
643 unicode_from_ascii
(&$$
->class.u.n.length
, &$$
->class.u.n.name
, $5);
645 | CONTROL optresidc numexpr
',' QUOTEDSTRING control_styleexpr
646 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
648 $$
= define_control
($2, $3, $7, $8, $9, $10, 0, style
, $11);
649 if
(dialog.ex
== NULL
)
650 rcparse_warning
("help ID requires DIALOGEX");
654 unicode_from_ascii
(&$$
->class.u.n.length
, &$$
->class.u.n.name
, $5);
658 default_style
= SS_CENTER | WS_GROUP
;
659 base_style
= SS_CENTER
;
667 | DEFPUSHBUTTON optresidc
669 default_style
= BS_DEFPUSHBUTTON | WS_TABSTOP
;
670 base_style
= BS_DEFPUSHBUTTON | WS_TABSTOP
;
680 default_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
681 base_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
683 res_text_field
= res_null_text
;
691 default_style
= BS_GROUPBOX
;
692 base_style
= BS_GROUPBOX
;
702 default_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
703 base_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
710 if
(dialog.ex
== NULL
)
711 rcparse_warning
(_
("IEDIT requires DIALOGEX"));
712 res_string_to_id
(&$$
->class
, "HEDIT");
714 | ICON resref numexpr cnumexpr cnumexpr opt_control_data
716 $$
= define_icon_control
($2, $3, $4, $5, 0, 0, 0, $6,
719 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
722 $$
= define_icon_control
($2, $3, $4, $5, 0, 0, 0, $8,
725 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
726 icon_styleexpr optcnumexpr opt_control_data
728 $$
= define_icon_control
($2, $3, $4, $5, style
, $9, 0, $10,
731 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
732 icon_styleexpr cnumexpr cnumexpr opt_control_data
734 $$
= define_icon_control
($2, $3, $4, $5, style
, $9, $10, $11,
739 default_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
740 base_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
747 if
(dialog.ex
== NULL
)
748 rcparse_warning
(_
("IEDIT requires DIALOGEX"));
749 res_string_to_id
(&$$
->class
, "IEDIT");
753 default_style
= LBS_NOTIFY | WS_BORDER
;
754 base_style
= LBS_NOTIFY | WS_BORDER
;
756 res_text_field
= res_null_text
;
764 default_style
= SS_LEFT | WS_GROUP
;
765 base_style
= SS_LEFT
;
775 default_style
= BS_PUSHBOX | WS_TABSTOP
;
776 base_style
= BS_PUSHBOX
;
783 | PUSHBUTTON optresidc
785 default_style
= BS_PUSHBUTTON | WS_TABSTOP
;
786 base_style
= BS_PUSHBUTTON | WS_TABSTOP
;
794 | RADIOBUTTON optresidc
796 default_style
= BS_RADIOBUTTON | WS_TABSTOP
;
797 base_style
= BS_RADIOBUTTON
;
807 default_style
= SS_RIGHT | WS_GROUP
;
808 base_style
= SS_RIGHT
;
818 default_style
= SBS_HORZ
;
820 class
= CTL_SCROLLBAR
;
821 res_text_field
= res_null_text
;
829 default_style
= BS_3STATE | WS_TABSTOP
;
830 base_style
= BS_3STATE
;
838 | USERBUTTON resref numexpr
',' numexpr
',' numexpr
','
839 numexpr
',' numexpr
','
840 { style
= WS_CHILD | WS_VISIBLE
; }
841 styleexpr optcnumexpr
843 $$
= define_control
($2, $3, $5, $7, $9, $11, CTL_BUTTON
,
848 /* Parameters for a control. The static variables DEFAULT_STYLE,
849 BASE_STYLE, and CLASS must be initialized before this nonterminal
850 is used. DEFAULT_STYLE is the style to use if no style expression
851 is specified. BASE_STYLE is the base style to use if a style
852 expression is specified; the style expression modifies the base
853 style. CLASS is the class of the control. */
856 numexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
858 $$
= define_control
(res_text_field
, $1, $2, $3, $4, $5, class
,
859 default_style | WS_CHILD | WS_VISIBLE
, 0);
862 if
(dialog.ex
== NULL
)
863 rcparse_warning
(_
("control data requires DIALOGEX"));
867 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
868 control_params_styleexpr optcnumexpr opt_control_data
870 $$
= define_control
(res_text_field
, $1, $2, $3, $4, $5, class
, style
, $7);
873 if
(dialog.ex
== NULL
)
874 rcparse_warning
(_
("control data requires DIALOGEX"));
878 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
879 control_params_styleexpr cnumexpr cnumexpr opt_control_data
881 $$
= define_control
(res_text_field
, $1, $2, $3, $4, $5, class
, style
, $7);
882 if
(dialog.ex
== NULL
)
883 rcparse_warning
(_
("help ID requires DIALOGEX"));
892 res_string_to_id
(&$$
, "");
901 res_string_to_id
(&$$
, $1);
905 res_string_to_id
(&$$
, $1);
914 | BEG optrcdata_data END
920 /* These only exist to parse a reduction out of a common case. */
924 { style
= WS_CHILD | WS_VISIBLE
; }
930 { style
= SS_ICON | WS_CHILD | WS_VISIBLE
; }
934 control_params_styleexpr:
936 { style
= base_style | WS_CHILD | WS_VISIBLE
; }
940 /* Font resources. */
943 id FONT memflags_move_discard file_name
945 define_font
($1, &$3, $4);
946 if
(yychar != YYEMPTY
)
948 rcparse_discard_strings
();
952 /* Icon resources. */
955 id ICON memflags_move_discard file_name
957 define_icon
($1, &$3, $4);
958 if
(yychar != YYEMPTY
)
960 rcparse_discard_strings
();
964 /* Language command. This changes the static variable language, which
965 affects all subsequent resources. */
968 LANGUAGE numexpr cnumexpr
970 language
= $2 |
($3 << SUBLANG_SHIFT
);
974 /* Menu resources. */
977 id MENU suboptions BEG menuitems END
979 define_menu
($1, &$3, $5);
980 if
(yychar != YYEMPTY
)
982 rcparse_discard_strings
();
997 struct menuitem
**pp
;
999 for
(pp
= &$1->next
; *pp
!= NULL
; pp
= &(*pp
)->next
)
1008 MENUITEM QUOTEDSTRING cnumexpr menuitem_flags
1010 $$
= define_menuitem
($2, $3, $4, 0, 0, NULL
);
1012 | MENUITEM SEPARATOR
1014 $$
= define_menuitem
(NULL
, 0, 0, 0, 0, NULL
);
1016 | POPUP QUOTEDSTRING menuitem_flags BEG menuitems END
1018 $$
= define_menuitem
($2, 0, $3, 0, 0, $5);
1027 | menuitem_flags
',' menuitem_flag
1031 | menuitem_flags menuitem_flag
1040 $$
= MENUITEM_CHECKED
;
1044 $$
= MENUITEM_GRAYED
;
1052 $$
= MENUITEM_INACTIVE
;
1056 $$
= MENUITEM_MENUBARBREAK
;
1060 $$
= MENUITEM_MENUBREAK
;
1064 /* Menuex resources. */
1067 id MENUEX suboptions BEG menuexitems END
1069 define_menu
($1, &$3, $5);
1070 if
(yychar != YYEMPTY
)
1072 rcparse_discard_strings
();
1081 | menuexitems menuexitem
1087 struct menuitem
**pp
;
1089 for
(pp
= &$1->next
; *pp
!= NULL
; pp
= &(*pp
)->next
)
1098 MENUITEM QUOTEDSTRING
1100 $$
= define_menuitem
($2, 0, 0, 0, 0, NULL
);
1102 | MENUITEM QUOTEDSTRING cnumexpr
1104 $$
= define_menuitem
($2, $3, 0, 0, 0, NULL
);
1106 | MENUITEM QUOTEDSTRING cnumexpr cnumexpr optcnumexpr
1108 $$
= define_menuitem
($2, $3, $4, $5, 0, NULL
);
1110 | MENUITEM SEPARATOR
1112 $$
= define_menuitem
(NULL
, 0, 0, 0, 0, NULL
);
1114 | POPUP QUOTEDSTRING BEG menuexitems END
1116 $$
= define_menuitem
($2, 0, 0, 0, 0, $4);
1118 | POPUP QUOTEDSTRING cnumexpr BEG menuexitems END
1120 $$
= define_menuitem
($2, $3, 0, 0, 0, $5);
1122 | POPUP QUOTEDSTRING cnumexpr cnumexpr BEG menuexitems END
1124 $$
= define_menuitem
($2, $3, $4, 0, 0, $6);
1126 | POPUP QUOTEDSTRING cnumexpr cnumexpr cnumexpr optcnumexpr
1129 $$
= define_menuitem
($2, $3, $4, $5, $6, $8);
1133 /* Messagetable resources. */
1136 id MESSAGETABLE memflags_move file_name
1138 define_messagetable
($1, &$3, $4);
1139 if
(yychar != YYEMPTY
)
1141 rcparse_discard_strings
();
1145 /* Rcdata resources. */
1148 id RCDATA suboptions BEG optrcdata_data END
1150 define_rcdata
($1, &$3, $5.first
);
1151 if
(yychar != YYEMPTY
)
1153 rcparse_discard_strings
();
1157 /* We use a different lexing algorithm, because rcdata strings may
1158 contain embedded null bytes, and we need to know the length to use. */
1186 struct rcdata_item
*ri
;
1188 ri
= define_rcdata_string
($1.s
, $1.length
);
1194 struct rcdata_item
*ri
;
1196 ri
= define_rcdata_number
($1.val
, $1.dword
);
1200 | rcdata_data
',' SIZEDSTRING
1202 struct rcdata_item
*ri
;
1204 ri
= define_rcdata_string
($3.s
, $3.length
);
1205 $$.first
= $1.first
;
1209 | rcdata_data
',' sizednumexpr
1211 struct rcdata_item
*ri
;
1213 ri
= define_rcdata_number
($3.val
, $3.dword
);
1214 $$.first
= $1.first
;
1220 /* Stringtable resources. */
1223 STRINGTABLE suboptions BEG
1224 { sub_res_info
= $2; }
1230 | string_data numexpr QUOTEDSTRING
1232 define_stringtable
(&sub_res_info
, $2, $3);
1233 if
(yychar != YYEMPTY
)
1235 rcparse_discard_strings
();
1237 | string_data numexpr
',' QUOTEDSTRING
1239 define_stringtable
(&sub_res_info
, $2, $4);
1240 if
(yychar != YYEMPTY
)
1242 rcparse_discard_strings
();
1246 /* User defined resources. We accept general suboptions in the
1247 file_name case to keep the parser happy. */
1250 id id suboptions BEG optrcdata_data END
1252 define_user_data
($1, $2, &$3, $5.first
);
1253 if
(yychar != YYEMPTY
)
1255 rcparse_discard_strings
();
1257 | id id suboptions file_name
1259 define_user_file
($1, $2, &$3, $4);
1260 if
(yychar != YYEMPTY
)
1262 rcparse_discard_strings
();
1266 /* Versioninfo resources. */
1269 id VERSIONINFO fixedverinfo BEG verblocks END
1271 define_versioninfo
($1, language
, $3, $5);
1272 if
(yychar != YYEMPTY
)
1274 rcparse_discard_strings
();
1281 $$
= ((struct fixed_versioninfo
*)
1282 res_alloc
(sizeof
(struct fixed_versioninfo
)));
1283 memset
($$
, 0, sizeof
(struct fixed_versioninfo
));
1285 | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
1287 $1->file_version_ms
= ($3 << 16) |
$4;
1288 $1->file_version_ls
= ($5 << 16) |
$6;
1291 | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
1293 $1->product_version_ms
= ($3 << 16) |
$4;
1294 $1->product_version_ls
= ($5 << 16) |
$6;
1297 | fixedverinfo FILEFLAGSMASK numexpr
1299 $1->file_flags_mask
= $3;
1302 | fixedverinfo FILEFLAGS numexpr
1304 $1->file_flags
= $3;
1307 | fixedverinfo FILEOS numexpr
1312 | fixedverinfo FILETYPE numexpr
1317 | fixedverinfo FILESUBTYPE numexpr
1319 $1->file_subtype
= $3;
1324 /* To handle verblocks successfully, the lexer handles BLOCK
1325 specially. A BLOCK "StringFileInfo" is returned as
1326 BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as
1327 BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK
1328 with the string as the value. */
1335 | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
1337 $$
= append_ver_stringfileinfo
($1, $4, $6);
1339 | verblocks BLOCKVARFILEINFO BEG VALUE QUOTEDSTRING vertrans END
1341 $$
= append_ver_varfileinfo
($1, $5, $6);
1350 | vervals VALUE QUOTEDSTRING
',' QUOTEDSTRING
1352 $$
= append_verval
($1, $3, $5);
1361 | vertrans cnumexpr cnumexpr
1363 $$
= append_vertrans
($1, $2, $3);
1367 /* A resource ID. */
1379 /* It seems that resource ID's are forced to upper case. */
1380 copy
= xstrdup
($1);
1381 for
(s
= copy
; *s
!= '\0'; s
++)
1383 res_string_to_id
(&$$
, copy
);
1388 /* A resource reference. */
1416 /* It seems that resource ID's are forced to upper case. */
1417 copy
= xstrdup
($1);
1418 for
(s
= copy
; *s
!= '\0'; s
++)
1420 res_string_to_id
(&$$
, copy
);
1425 /* Generic suboptions. These may appear before the BEGIN in any
1426 multiline statement. */
1431 memset
(&$$
, 0, sizeof
(struct res_res_info
));
1432 $$.language
= language
;
1433 /* FIXME: Is this the right default? */
1434 $$.memflags
= MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE
;
1436 | suboptions memflag
1439 $$.memflags |
= $2.on
;
1440 $$.memflags
&=~
$2.off
;
1442 | suboptions CHARACTERISTICS numexpr
1445 $$.characteristics
= $3;
1447 | suboptions LANGUAGE numexpr cnumexpr
1450 $$.language
= $3 |
($4 << SUBLANG_SHIFT
);
1452 | suboptions VERSIONK numexpr
1459 /* Memory flags which default to MOVEABLE and DISCARDABLE. */
1461 memflags_move_discard:
1464 memset
(&$$
, 0, sizeof
(struct res_res_info
));
1465 $$.language
= language
;
1466 $$.memflags
= MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE
;
1468 | memflags_move_discard memflag
1471 $$.memflags |
= $2.on
;
1472 $$.memflags
&=~
$2.off
;
1476 /* Memory flags which default to MOVEABLE. */
1481 memset
(&$$
, 0, sizeof
(struct res_res_info
));
1482 $$.language
= language
;
1483 $$.memflags
= MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE
;
1485 | memflags_move memflag
1488 $$.memflags |
= $2.on
;
1489 $$.memflags
&=~
$2.off
;
1493 /* Memory flags. This returns a struct with two integers, because we
1494 sometimes want to set bits and we sometimes want to clear them. */
1499 $$.on
= MEMFLAG_MOVEABLE
;
1505 $$.off
= MEMFLAG_MOVEABLE
;
1509 $$.on
= MEMFLAG_PURE
;
1515 $$.off
= MEMFLAG_PURE
;
1519 $$.on
= MEMFLAG_PRELOAD
;
1525 $$.off
= MEMFLAG_PRELOAD
;
1529 $$.on
= MEMFLAG_DISCARDABLE
;
1547 /* A style expression. This changes the static variable STYLE. We do
1548 it this way because rc appears to permit a style to be set to
1550 WS_GROUP | NOT WS_TABSTOP
1551 to mean that a default of WS_TABSTOP should be removed. Anything
1552 which wants to accept a style must first set STYLE to the default
1553 value. The styleexpr nonterminal will change STYLE as specified by
1554 the user. Note that we do not accept arbitrary expressions here,
1555 just numbers separated by '|'. */
1566 | styleexpr
'|' parennumber
1570 | styleexpr
'|' NOT parennumber
1587 /* An optional expression with a leading comma. */
1600 /* An expression with a leading comma. */
1609 /* A possibly negated numeric expression. */
1618 /* A possibly negated expression with a size. */
1625 |
'(' sizednumexpr
')'
1629 |
'~' sizednumexpr %prec
'~'
1632 $$.dword
= $2.dword
;
1634 |
'-' sizednumexpr %prec NEG
1637 $$.dword
= $2.dword
;
1639 | sizednumexpr
'*' sizednumexpr
1641 $$.val
= $1.val
* $3.val
;
1642 $$.dword
= $1.dword ||
$3.dword
;
1644 | sizednumexpr
'/' sizednumexpr
1646 $$.val
= $1.val
/ $3.val
;
1647 $$.dword
= $1.dword ||
$3.dword
;
1649 | sizednumexpr
'%' sizednumexpr
1651 $$.val
= $1.val %
$3.val
;
1652 $$.dword
= $1.dword ||
$3.dword
;
1654 | sizednumexpr
'+' sizednumexpr
1656 $$.val
= $1.val
+ $3.val
;
1657 $$.dword
= $1.dword ||
$3.dword
;
1659 | sizednumexpr
'-' sizednumexpr
1661 $$.val
= $1.val
- $3.val
;
1662 $$.dword
= $1.dword ||
$3.dword
;
1664 | sizednumexpr
'&' sizednumexpr
1666 $$.val
= $1.val
& $3.val
;
1667 $$.dword
= $1.dword ||
$3.dword
;
1669 | sizednumexpr
'^' sizednumexpr
1671 $$.val
= $1.val ^
$3.val
;
1672 $$.dword
= $1.dword ||
$3.dword
;
1674 | sizednumexpr
'|' sizednumexpr
1676 $$.val
= $1.val |
$3.val
;
1677 $$.dword
= $1.dword ||
$3.dword
;
1681 /* An expression with a leading comma which does not use unary
1691 /* An expression which does not use unary negation. */
1700 /* An expression which does not use unary negation. We separate unary
1701 negation to avoid parsing conflicts when two numeric expressions
1702 appear consecutively. */
1709 |
'(' sizednumexpr
')'
1713 |
'~' sizednumexpr %prec
'~'
1716 $$.dword
= $2.dword
;
1718 | sizedposnumexpr
'*' sizednumexpr
1720 $$.val
= $1.val
* $3.val
;
1721 $$.dword
= $1.dword ||
$3.dword
;
1723 | sizedposnumexpr
'/' sizednumexpr
1725 $$.val
= $1.val
/ $3.val
;
1726 $$.dword
= $1.dword ||
$3.dword
;
1728 | sizedposnumexpr
'%' sizednumexpr
1730 $$.val
= $1.val %
$3.val
;
1731 $$.dword
= $1.dword ||
$3.dword
;
1733 | sizedposnumexpr
'+' sizednumexpr
1735 $$.val
= $1.val
+ $3.val
;
1736 $$.dword
= $1.dword ||
$3.dword
;
1738 | sizedposnumexpr
'-' sizednumexpr
1740 $$.val
= $1.val
- $3.val
;
1741 $$.dword
= $1.dword ||
$3.dword
;
1743 | sizedposnumexpr
'&' sizednumexpr
1745 $$.val
= $1.val
& $3.val
;
1746 $$.dword
= $1.dword ||
$3.dword
;
1748 | sizedposnumexpr
'^' sizednumexpr
1750 $$.val
= $1.val ^
$3.val
;
1751 $$.dword
= $1.dword ||
$3.dword
;
1753 | sizedposnumexpr
'|' sizednumexpr
1755 $$.val
= $1.val |
$3.val
;
1756 $$.dword
= $1.dword ||
$3.dword
;
1762 /* Set the language from the command line. */
1765 rcparse_set_language
(lang
)