1 %
{ /* rcparse.y -- parser for Windows rc files
2 Copyright (C) 1997-2017 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support.
4 Extended by Kai Tietz, Onevision.
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 3 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., 51 Franklin Street - Fifth Floor, Boston, MA
24 /* This is a parser for Windows rc files. It is based on the parser
25 by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
30 #include "libiberty.h"
32 #include "safe-ctype.h"
34 /* The current language. */
36 static unsigned short language
;
38 /* The resource information during a sub statement. */
40 static rc_res_res_info sub_res_info
;
42 /* Dialog information. This is built by the nonterminals styles and
45 static rc_dialog dialog
;
47 /* This is used when building a style. It is modified by the
48 nonterminal styleexpr. */
50 static unsigned long style
;
52 /* These are used when building a control. They are set before using
55 static rc_uint_type base_style
;
56 static rc_uint_type default_style
;
57 static rc_res_id class
;
58 static rc_res_id res_text_field
;
59 static unichar null_unichar
;
61 /* This is used for COMBOBOX, LISTBOX and EDITTEXT which
62 do not allow resource 'text' field in control definition. */
63 static const rc_res_id res_null_text
= { 1, {{0, &null_unichar
}}};
71 rc_dialog_control
*dialog_control
;
72 rc_menuitem
*menuitem
;
75 rc_rcdata_item
*first
;
78 rc_rcdata_item
*rcdata_item
;
79 rc_fixed_versioninfo
*fixver
;
81 rc_ver_stringtable
*verstringtable
;
82 rc_ver_stringinfo
*verstring
;
83 rc_ver_varinfo
*vervar
;
84 rc_toolbar_item
*toobar_item
;
86 rc_res_res_info res_info
;
95 /* Nonzero if this number was explicitly specified as long. */
115 %token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
118 %token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
119 %token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
120 %token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
121 %token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
122 %token BEDIT HEDIT IEDIT
125 %token ANICURSOR ANIICON DLGINCLUDE DLGINIT FONTDIR HTML MANIFEST PLUGPLAY VXD TOOLBAR BUTTON
126 %token LANGUAGE CHARACTERISTICS VERSIONK
127 %token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
128 %token MENUBARBREAK MENUBREAK
132 %token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
133 %token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
136 %token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
138 %token
<uni
> QUOTEDUNISTRING
139 %token
<s
> QUOTEDSTRING STRING
141 %token
<suni
> SIZEDUNISTRING
142 %token
<ss
> SIZEDSTRING
145 %type
<pacc
> acc_entries
146 %type
<acc
> acc_entry acc_event
147 %type
<dialog_control
> control control_params
148 %type
<menuitem
> menuitems menuitem menuexitems menuexitem
149 %type
<rcdata
> optrcdata_data optrcdata_data_int rcdata_data
150 %type
<rcdata_item
> opt_control_data
151 %type
<fixver
> fixedverinfo
152 %type
<verinfo
> verblocks
153 %type
<verstringtable
> verstringtables
154 %type
<verstring
> vervals
155 %type
<vervar
> vertrans
156 %type
<toobar_item
> toolbar_data
157 %type
<res_info
> suboptions memflags_move_discard memflags_move
158 %type
<memflags
> memflag
159 %type
<id
> id rcdata_id optresidc resref resid cresid
160 %type
<il
> exstyle parennumber
161 %type
<il
> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
162 %type
<is
> acc_options acc_option menuitem_flags menuitem_flag
164 %type
<uni
> res_unicode_string resname res_unicode_string_concat
165 %type
<ss
> sizedstring
166 %type
<suni
> sizedunistring res_unicode_sizedstring res_unicode_sizedstring_concat
167 %type
<i
> sizednumexpr sizedposnumexpr
194 | input IGNORED_TOKEN
197 /* Accelerator resources. */
200 id ACCELERATORS suboptions BEG acc_entries END
202 define_accelerator
($1, &$3, $5);
203 if
(yychar != YYEMPTY
)
205 rcparse_discard_strings
();
214 | acc_entries acc_entry
218 a
= (rc_accelerator
*) res_alloc
(sizeof
*a
);
226 for
(pp
= &$1->next
; *pp
!= NULL
; pp
= &(*pp
)->next
)
235 acc_event cposnumexpr
240 | acc_event cposnumexpr
',' acc_options
245 if
(($$.flags
& ACC_VIRTKEY
) == 0
246 && ($$.flags
& (ACC_SHIFT | ACC_CONTROL
)) != 0)
247 rcparse_warning
(_
("inappropriate modifiers for non-VIRTKEY"));
264 $$.flags
= ACC_CONTROL | ACC_VIRTKEY
;
270 rcparse_warning
(_
("accelerator should only be one character"));
286 | acc_options
',' acc_option
290 /* I've had one report that the comma is optional. */
291 | acc_options acc_option
304 /* This is just the absence of VIRTKEY. */
325 /* Bitmap resources. */
328 id BITMAP memflags_move file_name
330 define_bitmap
($1, &$3, $4);
331 if
(yychar != YYEMPTY
)
333 rcparse_discard_strings
();
337 /* Cursor resources. */
340 id CURSOR memflags_move_discard file_name
342 define_cursor
($1, &$3, $4);
343 if
(yychar != YYEMPTY
)
345 rcparse_discard_strings
();
349 /* Dialog resources. */
352 id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
355 memset
(&dialog
, 0, sizeof dialog
);
360 dialog.style
= WS_POPUP | WS_BORDER | WS_SYSMENU
;
362 dialog.menu.named
= 1;
363 dialog.class.named
= 1;
366 dialog.controls
= NULL
;
370 styles BEG controls END
372 define_dialog
($1, &sub_res_info
, &dialog
);
373 if
(yychar != YYEMPTY
)
375 rcparse_discard_strings
();
377 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
380 memset
(&dialog
, 0, sizeof dialog
);
385 dialog.style
= WS_POPUP | WS_BORDER | WS_SYSMENU
;
387 dialog.menu.named
= 1;
388 dialog.class.named
= 1;
390 dialog.ex
= ((rc_dialog_ex
*)
391 res_alloc
(sizeof
(rc_dialog_ex
)));
392 memset
(dialog.ex
, 0, sizeof
(rc_dialog_ex
));
393 dialog.controls
= NULL
;
397 styles BEG controls END
399 define_dialog
($1, &sub_res_info
, &dialog
);
400 if
(yychar != YYEMPTY
)
402 rcparse_discard_strings
();
404 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
407 memset
(&dialog
, 0, sizeof dialog
);
412 dialog.style
= WS_POPUP | WS_BORDER | WS_SYSMENU
;
414 dialog.menu.named
= 1;
415 dialog.class.named
= 1;
417 dialog.ex
= ((rc_dialog_ex
*)
418 res_alloc
(sizeof
(rc_dialog_ex
)));
419 memset
(dialog.ex
, 0, sizeof
(rc_dialog_ex
));
420 dialog.ex
->help
= $9;
421 dialog.controls
= NULL
;
425 styles BEG controls END
427 define_dialog
($1, &sub_res_info
, &dialog
);
428 if
(yychar != YYEMPTY
)
430 rcparse_discard_strings
();
439 | EXSTYLE
'=' numexpr
447 | styles CAPTION res_unicode_string_concat
449 dialog.style |
= WS_CAPTION
;
460 dialog.style
= style
;
462 | styles EXSTYLE numexpr
466 | styles CLASS res_unicode_string_concat
468 res_unistring_to_id
(& dialog.class
, $3);
470 | styles FONT numexpr
',' res_unicode_string_concat
472 dialog.style |
= DS_SETFONT
;
474 dialog.pointsize
= $3;
476 if
(dialog.ex
!= NULL
)
478 dialog.ex
->weight
= 0;
479 dialog.ex
->italic
= 0;
480 dialog.ex
->charset
= 1;
483 | styles FONT numexpr
',' res_unicode_string_concat cnumexpr
485 dialog.style |
= DS_SETFONT
;
487 dialog.pointsize
= $3;
489 if
(dialog.ex
== NULL
)
490 rcparse_warning
(_
("extended FONT requires DIALOGEX"));
493 dialog.ex
->weight
= $6;
494 dialog.ex
->italic
= 0;
495 dialog.ex
->charset
= 1;
498 | styles FONT numexpr
',' res_unicode_string_concat cnumexpr cnumexpr
500 dialog.style |
= DS_SETFONT
;
502 dialog.pointsize
= $3;
504 if
(dialog.ex
== NULL
)
505 rcparse_warning
(_
("extended FONT requires DIALOGEX"));
508 dialog.ex
->weight
= $6;
509 dialog.ex
->italic
= $7;
510 dialog.ex
->charset
= 1;
513 | styles FONT numexpr
',' res_unicode_string_concat cnumexpr cnumexpr cnumexpr
515 dialog.style |
= DS_SETFONT
;
517 dialog.pointsize
= $3;
519 if
(dialog.ex
== NULL
)
520 rcparse_warning
(_
("extended FONT requires DIALOGEX"));
523 dialog.ex
->weight
= $6;
524 dialog.ex
->italic
= $7;
525 dialog.ex
->charset
= $8;
532 | styles CHARACTERISTICS numexpr
534 sub_res_info.characteristics
= $3;
536 | styles LANGUAGE numexpr cnumexpr
538 sub_res_info.language
= $3 |
($4 << SUBLANG_SHIFT
);
540 | styles VERSIONK numexpr
542 sub_res_info.version
= $3;
550 rc_dialog_control
**pp
;
552 for
(pp
= &dialog.controls
; *pp
!= NULL
; pp
= &(*pp
)->next
)
561 default_style
= BS_AUTO3STATE | WS_TABSTOP
;
562 base_style
= BS_AUTO3STATE
;
564 class.u.id
= CTL_BUTTON
;
571 | AUTOCHECKBOX optresidc
573 default_style
= BS_AUTOCHECKBOX | WS_TABSTOP
;
574 base_style
= BS_AUTOCHECKBOX
;
576 class.u.id
= CTL_BUTTON
;
583 | AUTORADIOBUTTON optresidc
585 default_style
= BS_AUTORADIOBUTTON | WS_TABSTOP
;
586 base_style
= BS_AUTORADIOBUTTON
;
588 class.u.id
= CTL_BUTTON
;
597 default_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
598 base_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
600 class.u.id
= CTL_EDIT
;
606 if
(dialog.ex
== NULL
)
607 rcparse_warning
(_
("BEDIT requires DIALOGEX"));
608 res_string_to_id
(&$$
->class
, "BEDIT");
612 default_style
= BS_CHECKBOX | WS_TABSTOP
;
613 base_style
= BS_CHECKBOX | WS_TABSTOP
;
615 class.u.id
= CTL_BUTTON
;
624 /* This is as per MSDN documentation. With some (???)
625 versions of MS rc.exe their is no default style. */
626 default_style
= CBS_SIMPLE | WS_TABSTOP
;
629 class.u.id
= CTL_COMBOBOX
;
630 res_text_field
= res_null_text
;
636 | CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
637 cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
639 $$
= define_control
($2, $3, $6, $7, $8, $9, $4, style
, $10);
642 if
(dialog.ex
== NULL
)
643 rcparse_warning
(_
("control data requires DIALOGEX"));
647 | CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
648 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
650 $$
= define_control
($2, $3, $6, $7, $8, $9, $4, style
, $10);
651 if
(dialog.ex
== NULL
)
652 rcparse_warning
(_
("help ID requires DIALOGEX"));
658 default_style
= SS_CENTER | WS_GROUP
;
659 base_style
= SS_CENTER
;
661 class.u.id
= CTL_STATIC
;
668 | DEFPUSHBUTTON optresidc
670 default_style
= BS_DEFPUSHBUTTON | WS_TABSTOP
;
671 base_style
= BS_DEFPUSHBUTTON | WS_TABSTOP
;
673 class.u.id
= CTL_BUTTON
;
682 default_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
683 base_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
685 class.u.id
= CTL_EDIT
;
686 res_text_field
= res_null_text
;
694 default_style
= BS_GROUPBOX
;
695 base_style
= BS_GROUPBOX
;
697 class.u.id
= CTL_BUTTON
;
706 default_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
707 base_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
709 class.u.id
= CTL_EDIT
;
715 if
(dialog.ex
== NULL
)
716 rcparse_warning
(_
("IEDIT requires DIALOGEX"));
717 res_string_to_id
(&$$
->class
, "HEDIT");
719 | ICON resref numexpr cnumexpr cnumexpr opt_control_data
721 $$
= define_icon_control
($2, $3, $4, $5, 0, 0, 0, $6,
724 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
727 $$
= define_icon_control
($2, $3, $4, $5, 0, 0, 0, $8,
730 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
731 icon_styleexpr optcnumexpr opt_control_data
733 $$
= define_icon_control
($2, $3, $4, $5, style
, $9, 0, $10,
736 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
737 icon_styleexpr cnumexpr cnumexpr opt_control_data
739 $$
= define_icon_control
($2, $3, $4, $5, style
, $9, $10, $11,
744 default_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
745 base_style
= ES_LEFT | WS_BORDER | WS_TABSTOP
;
747 class.u.id
= CTL_EDIT
;
753 if
(dialog.ex
== NULL
)
754 rcparse_warning
(_
("IEDIT requires DIALOGEX"));
755 res_string_to_id
(&$$
->class
, "IEDIT");
759 default_style
= LBS_NOTIFY | WS_BORDER
;
760 base_style
= LBS_NOTIFY | WS_BORDER
;
762 class.u.id
= CTL_LISTBOX
;
763 res_text_field
= res_null_text
;
771 default_style
= SS_LEFT | WS_GROUP
;
772 base_style
= SS_LEFT
;
774 class.u.id
= CTL_STATIC
;
783 default_style
= BS_PUSHBOX | WS_TABSTOP
;
784 base_style
= BS_PUSHBOX
;
786 class.u.id
= CTL_BUTTON
;
792 | PUSHBUTTON optresidc
794 default_style
= BS_PUSHBUTTON | WS_TABSTOP
;
795 base_style
= BS_PUSHBUTTON | WS_TABSTOP
;
797 class.u.id
= CTL_BUTTON
;
804 | RADIOBUTTON optresidc
806 default_style
= BS_RADIOBUTTON | WS_TABSTOP
;
807 base_style
= BS_RADIOBUTTON
;
809 class.u.id
= CTL_BUTTON
;
818 default_style
= SS_RIGHT | WS_GROUP
;
819 base_style
= SS_RIGHT
;
821 class.u.id
= CTL_STATIC
;
830 default_style
= SBS_HORZ
;
833 class.u.id
= CTL_SCROLLBAR
;
834 res_text_field
= res_null_text
;
842 default_style
= BS_3STATE | WS_TABSTOP
;
843 base_style
= BS_3STATE
;
845 class.u.id
= CTL_BUTTON
;
852 | USERBUTTON resref numexpr
',' numexpr
',' numexpr
','
853 numexpr
',' numexpr
','
854 { style
= WS_CHILD | WS_VISIBLE
; }
855 styleexpr optcnumexpr
859 cid.u.id
= CTL_BUTTON
;
860 $$
= define_control
($2, $3, $5, $7, $9, $11, cid
,
865 /* Parameters for a control. The static variables DEFAULT_STYLE,
866 BASE_STYLE, and CLASS must be initialized before this nonterminal
867 is used. DEFAULT_STYLE is the style to use if no style expression
868 is specified. BASE_STYLE is the base style to use if a style
869 expression is specified; the style expression modifies the base
870 style. CLASS is the class of the control. */
873 numexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
875 $$
= define_control
(res_text_field
, $1, $2, $3, $4, $5, class
,
876 default_style | WS_CHILD | WS_VISIBLE
, 0);
879 if
(dialog.ex
== NULL
)
880 rcparse_warning
(_
("control data requires DIALOGEX"));
884 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
885 control_params_styleexpr optcnumexpr opt_control_data
887 $$
= define_control
(res_text_field
, $1, $2, $3, $4, $5, class
, style
, $7);
890 if
(dialog.ex
== NULL
)
891 rcparse_warning
(_
("control data requires DIALOGEX"));
895 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
896 control_params_styleexpr cnumexpr cnumexpr opt_control_data
898 $$
= define_control
(res_text_field
, $1, $2, $3, $4, $5, class
, style
, $7);
899 if
(dialog.ex
== NULL
)
900 rcparse_warning
(_
("help ID requires DIALOGEX"));
910 res_unistring_to_id
(&$$
, $2.u.n.name
);
919 res_string_to_id
(&$$
, "");
921 | resid
',' { $$
=$1; }
930 | res_unicode_string_concat
934 $$.u.n.length
= unichar_len
($1);
943 | BEG optrcdata_data END
949 /* These only exist to parse a reduction out of a common case. */
953 { style
= WS_CHILD | WS_VISIBLE
; }
959 { style
= SS_ICON | WS_CHILD | WS_VISIBLE
; }
963 control_params_styleexpr:
965 { style
= base_style | WS_CHILD | WS_VISIBLE
; }
969 /* Font resources. */
972 id FONT memflags_move_discard file_name
974 define_font
($1, &$3, $4);
975 if
(yychar != YYEMPTY
)
977 rcparse_discard_strings
();
981 /* Icon resources. */
984 id ICON memflags_move_discard file_name
986 define_icon
($1, &$3, $4);
987 if
(yychar != YYEMPTY
)
989 rcparse_discard_strings
();
993 /* Language command. This changes the static variable language, which
994 affects all subsequent resources. */
997 LANGUAGE numexpr cnumexpr
999 language
= $2 |
($3 << SUBLANG_SHIFT
);
1003 /* Menu resources. */
1006 id MENU suboptions BEG menuitems END
1008 define_menu
($1, &$3, $5);
1009 if
(yychar != YYEMPTY
)
1011 rcparse_discard_strings
();
1020 | menuitems menuitem
1028 for
(pp
= &$1->next
; *pp
!= NULL
; pp
= &(*pp
)->next
)
1037 MENUITEM res_unicode_string_concat cnumexpr menuitem_flags
1039 $$
= define_menuitem
($2, $3, $4, 0, 0, NULL
);
1041 | MENUITEM SEPARATOR
1043 $$
= define_menuitem
(NULL
, 0, 0, 0, 0, NULL
);
1045 | POPUP res_unicode_string_concat menuitem_flags BEG menuitems END
1047 $$
= define_menuitem
($2, 0, $3, 0, 0, $5);
1056 | menuitem_flags
',' menuitem_flag
1060 | menuitem_flags menuitem_flag
1069 $$
= MENUITEM_CHECKED
;
1073 $$
= MENUITEM_GRAYED
;
1081 $$
= MENUITEM_INACTIVE
;
1085 $$
= MENUITEM_MENUBARBREAK
;
1089 $$
= MENUITEM_MENUBREAK
;
1093 /* Menuex resources. */
1096 id MENUEX suboptions BEG menuexitems END
1098 define_menu
($1, &$3, $5);
1099 if
(yychar != YYEMPTY
)
1101 rcparse_discard_strings
();
1110 | menuexitems menuexitem
1118 for
(pp
= &$1->next
; *pp
!= NULL
; pp
= &(*pp
)->next
)
1127 MENUITEM res_unicode_string_concat
1129 $$
= define_menuitem
($2, 0, 0, 0, 0, NULL
);
1131 | MENUITEM res_unicode_string_concat cnumexpr
1133 $$
= define_menuitem
($2, $3, 0, 0, 0, NULL
);
1135 | MENUITEM res_unicode_string_concat cnumexpr cnumexpr optcnumexpr
1137 $$
= define_menuitem
($2, $3, $4, $5, 0, NULL
);
1139 | MENUITEM SEPARATOR
1141 $$
= define_menuitem
(NULL
, 0, 0, 0, 0, NULL
);
1143 | POPUP res_unicode_string_concat BEG menuexitems END
1145 $$
= define_menuitem
($2, 0, 0, 0, 0, $4);
1147 | POPUP res_unicode_string_concat cnumexpr BEG menuexitems END
1149 $$
= define_menuitem
($2, $3, 0, 0, 0, $5);
1151 | POPUP res_unicode_string_concat cnumexpr cnumexpr BEG menuexitems END
1153 $$
= define_menuitem
($2, $3, $4, 0, 0, $6);
1155 | POPUP res_unicode_string_concat cnumexpr cnumexpr cnumexpr optcnumexpr
1158 $$
= define_menuitem
($2, $3, $4, $5, $6, $8);
1162 /* Messagetable resources. */
1165 id MESSAGETABLE memflags_move file_name
1167 define_messagetable
($1, &$3, $4);
1168 if
(yychar != YYEMPTY
)
1170 rcparse_discard_strings
();
1174 /* We use a different lexing algorithm, because rcdata strings may
1175 contain embedded null bytes, and we need to know the length to use. */
1205 ri
= define_rcdata_string
($1.s
, $1.length
);
1213 ri
= define_rcdata_unistring
($1.s
, $1.length
);
1221 ri
= define_rcdata_number
($1.val
, $1.dword
);
1225 | rcdata_data
',' sizedstring
1229 ri
= define_rcdata_string
($3.s
, $3.length
);
1230 $$.first
= $1.first
;
1234 | rcdata_data
',' sizedunistring
1238 ri
= define_rcdata_unistring
($3.s
, $3.length
);
1239 $$.first
= $1.first
;
1243 | rcdata_data
',' sizednumexpr
1247 ri
= define_rcdata_number
($3.val
, $3.dword
);
1248 $$.first
= $1.first
;
1258 /* Stringtable resources. */
1261 STRINGTABLE suboptions BEG
1262 { sub_res_info
= $2; rcparse_rcdata
(); }
1263 string_data END
{ rcparse_normal
(); }
1268 | string_data numexpr res_unicode_sizedstring_concat
1270 define_stringtable
(&sub_res_info
, $2, $3.s
, $3.length
);
1271 rcparse_discard_strings
();
1273 | string_data numexpr
',' res_unicode_sizedstring_concat
1275 define_stringtable
(&sub_res_info
, $2, $4.s
, $4.length
);
1276 rcparse_discard_strings
();
1280 rcparse_warning
(_
("invalid stringtable resource."));
1298 $$.u.id
= RT_RCDATA
;
1303 $$.u.id
= RT_MANIFEST
;
1308 $$.u.id
= RT_PLUGPLAY
;
1318 $$.u.id
= RT_DLGINCLUDE
;
1323 $$.u.id
= RT_DLGINIT
;
1328 $$.u.id
= RT_ANICURSOR
;
1333 $$.u.id
= RT_ANIICON
;
1337 /* User defined resources. We accept general suboptions in the
1338 file_name case to keep the parser happy. */
1341 id rcdata_id suboptions BEG optrcdata_data END
1343 define_user_data
($1, $2, &$3, $5.first
);
1344 if
(yychar != YYEMPTY
)
1346 rcparse_discard_strings
();
1348 | id rcdata_id suboptions file_name
1350 define_user_file
($1, $2, &$3, $4);
1351 if
(yychar != YYEMPTY
)
1353 rcparse_discard_strings
();
1358 id TOOLBAR suboptions numexpr cnumexpr BEG toolbar_data END
1360 define_toolbar
($1, &$3, $4, $5, $7);
1364 toolbar_data: /* empty */ { $$
= NULL
; }
1365 | toolbar_data BUTTON id
1367 rc_toolbar_item
*c
,*n
;
1369 n
= (rc_toolbar_item
*)
1370 res_alloc
(sizeof
(rc_toolbar_item
));
1372 while
(c
->next
!= NULL
)
1384 | toolbar_data SEPARATOR
1386 rc_toolbar_item
*c
,*n
;
1388 n
= (rc_toolbar_item
*)
1389 res_alloc
(sizeof
(rc_toolbar_item
));
1391 while
(c
->next
!= NULL
)
1406 /* Versioninfo resources. */
1409 id VERSIONINFO fixedverinfo BEG verblocks END
1411 define_versioninfo
($1, language
, $3, $5);
1412 if
(yychar != YYEMPTY
)
1414 rcparse_discard_strings
();
1421 $$
= ((rc_fixed_versioninfo
*)
1422 res_alloc
(sizeof
(rc_fixed_versioninfo
)));
1423 memset
($$
, 0, sizeof
(rc_fixed_versioninfo
));
1425 | fixedverinfo FILEVERSION numexpr optcnumexpr optcnumexpr
1428 $1->file_version_ms
= ($3 << 16) |
($4 & 0xffff);
1429 $1->file_version_ls
= ($5 << 16) |
($6 & 0xffff);
1432 | fixedverinfo PRODUCTVERSION numexpr optcnumexpr optcnumexpr
1435 $1->product_version_ms
= ($3 << 16) |
($4 & 0xffff);
1436 $1->product_version_ls
= ($5 << 16) |
($6 & 0xffff);
1439 | fixedverinfo FILEFLAGSMASK numexpr
1441 $1->file_flags_mask
= $3;
1444 | fixedverinfo FILEFLAGS numexpr
1446 $1->file_flags
= $3;
1449 | fixedverinfo FILEOS numexpr
1454 | fixedverinfo FILETYPE numexpr
1459 | fixedverinfo FILESUBTYPE numexpr
1461 $1->file_subtype
= $3;
1466 /* To handle verblocks successfully, the lexer handles BLOCK
1467 specially. A BLOCK "StringFileInfo" is returned as
1468 BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as
1469 BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK
1470 with the string as the value. */
1477 | verblocks BLOCKSTRINGFILEINFO BEG verstringtables END
1479 $$
= append_ver_stringfileinfo
($1, $4);
1481 | verblocks BLOCKVARFILEINFO BEG VALUE res_unicode_string_concat vertrans END
1483 $$
= append_ver_varfileinfo
($1, $5, $6);
1492 | verstringtables BLOCK BEG vervals END
1494 $$
= append_ver_stringtable
($1, $2, $4);
1503 | vervals VALUE res_unicode_string_concat
',' res_unicode_string_concat
1505 $$
= append_verval
($1, $3, $5);
1514 | vertrans cnumexpr cnumexpr
1516 $$
= append_vertrans
($1, $2, $3);
1520 /* A resource ID. */
1530 res_unistring_to_id
(&$$
, $1);
1534 /* A resource reference. */
1544 unicode_from_ascii
((rc_uint_type
*) NULL
, &h
, $1);
1558 res_unistring_to_id
(&$$
, $1);
1562 res_unistring_to_id
(&$$
, $1);
1566 /* Generic suboptions. These may appear before the BEGIN in any
1567 multiline statement. */
1572 memset
(&$$
, 0, sizeof
(rc_res_res_info
));
1573 $$.language
= language
;
1574 /* FIXME: Is this the right default? */
1575 $$.memflags
= MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE
;
1577 | suboptions memflag
1580 $$.memflags |
= $2.on
;
1581 $$.memflags
&=~
$2.off
;
1583 | suboptions CHARACTERISTICS numexpr
1586 $$.characteristics
= $3;
1588 | suboptions LANGUAGE numexpr cnumexpr
1591 $$.language
= $3 |
($4 << SUBLANG_SHIFT
);
1593 | suboptions VERSIONK numexpr
1600 /* Memory flags which default to MOVEABLE and DISCARDABLE. */
1602 memflags_move_discard:
1605 memset
(&$$
, 0, sizeof
(rc_res_res_info
));
1606 $$.language
= language
;
1607 $$.memflags
= MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE
;
1609 | memflags_move_discard memflag
1612 $$.memflags |
= $2.on
;
1613 $$.memflags
&=~
$2.off
;
1617 /* Memory flags which default to MOVEABLE. */
1622 memset
(&$$
, 0, sizeof
(rc_res_res_info
));
1623 $$.language
= language
;
1624 $$.memflags
= MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE
;
1626 | memflags_move memflag
1629 $$.memflags |
= $2.on
;
1630 $$.memflags
&=~
$2.off
;
1634 /* Memory flags. This returns a struct with two integers, because we
1635 sometimes want to set bits and we sometimes want to clear them. */
1640 $$.on
= MEMFLAG_MOVEABLE
;
1646 $$.off
= MEMFLAG_MOVEABLE
;
1650 $$.on
= MEMFLAG_PURE
;
1656 $$.off
= MEMFLAG_PURE
;
1660 $$.on
= MEMFLAG_PRELOAD
;
1666 $$.off
= MEMFLAG_PRELOAD
;
1670 $$.on
= MEMFLAG_DISCARDABLE
;
1689 res_unicode_string_concat:
1695 res_unicode_string_concat res_unicode_string
1697 rc_uint_type l1
= unichar_len
($1);
1698 rc_uint_type l2
= unichar_len
($2);
1699 unichar
*h
= (unichar
*) res_alloc
((l1
+ l2
+ 1) * sizeof
(unichar
));
1701 memcpy
(h
, $1, l1
* sizeof
(unichar
));
1703 memcpy
(h
+ l1
, $2, l2
* sizeof
(unichar
));
1712 $$
= unichar_dup
($1);
1717 unicode_from_ascii
((rc_uint_type
*) NULL
, &h
, $1);
1722 res_unicode_sizedstring:
1731 unicode_from_ascii_len
(&l
, &h
, $1.s
, $1.length
);
1738 res_unicode_sizedstring_concat:
1739 res_unicode_sizedstring
1744 res_unicode_sizedstring_concat res_unicode_sizedstring
1746 rc_uint_type l1
= $1.length
;
1747 rc_uint_type l2
= $2.length
;
1748 unichar
*h
= (unichar
*) res_alloc
((l1
+ l2
+ 1) * sizeof
(unichar
));
1750 memcpy
(h
, $1.s
, l1
* sizeof
(unichar
));
1752 memcpy
(h
+ l1
, $2.s
, l2
* sizeof
(unichar
));
1754 $$.length
= l1
+ l2
;
1764 | sizedstring SIZEDSTRING
1766 rc_uint_type l
= $1.length
+ $2.length
;
1767 char *h
= (char *) res_alloc
(l
);
1768 memcpy
(h
, $1.s
, $1.length
);
1769 memcpy
(h
+ $1.length
, $2.s
, $2.length
);
1780 | sizedunistring SIZEDUNISTRING
1782 rc_uint_type l
= $1.length
+ $2.length
;
1783 unichar
*h
= (unichar
*) res_alloc
(l
* sizeof
(unichar
));
1784 memcpy
(h
, $1.s
, $1.length
* sizeof
(unichar
));
1785 memcpy
(h
+ $1.length
, $2.s
, $2.length
* sizeof
(unichar
));
1791 /* A style expression. This changes the static variable STYLE. We do
1792 it this way because rc appears to permit a style to be set to
1794 WS_GROUP | NOT WS_TABSTOP
1795 to mean that a default of WS_TABSTOP should be removed. Anything
1796 which wants to accept a style must first set STYLE to the default
1797 value. The styleexpr nonterminal will change STYLE as specified by
1798 the user. Note that we do not accept arbitrary expressions here,
1799 just numbers separated by '|'. */
1810 | styleexpr
'|' parennumber
1814 | styleexpr
'|' NOT parennumber
1831 /* An optional expression with a leading comma. */
1844 /* An expression with a leading comma. */
1853 /* A possibly negated numeric expression. */
1862 /* A possibly negated expression with a size. */
1869 |
'(' sizednumexpr
')'
1873 |
'~' sizednumexpr %prec
'~'
1876 $$.dword
= $2.dword
;
1878 |
'-' sizednumexpr %prec NEG
1881 $$.dword
= $2.dword
;
1883 | sizednumexpr
'*' sizednumexpr
1885 $$.val
= $1.val
* $3.val
;
1886 $$.dword
= $1.dword ||
$3.dword
;
1888 | sizednumexpr
'/' sizednumexpr
1890 $$.val
= $1.val
/ ($3.val ?
$3.val
: 1);
1891 $$.dword
= $1.dword ||
$3.dword
;
1893 | sizednumexpr
'%' sizednumexpr
1895 $$.val
= $1.val %
($3.val ?
$3.val
: 1);
1896 $$.dword
= $1.dword ||
$3.dword
;
1898 | sizednumexpr
'+' sizednumexpr
1900 $$.val
= $1.val
+ $3.val
;
1901 $$.dword
= $1.dword ||
$3.dword
;
1903 | sizednumexpr
'-' sizednumexpr
1905 $$.val
= $1.val
- $3.val
;
1906 $$.dword
= $1.dword ||
$3.dword
;
1908 | sizednumexpr
'&' sizednumexpr
1910 $$.val
= $1.val
& $3.val
;
1911 $$.dword
= $1.dword ||
$3.dword
;
1913 | sizednumexpr
'^' sizednumexpr
1915 $$.val
= $1.val ^
$3.val
;
1916 $$.dword
= $1.dword ||
$3.dword
;
1918 | sizednumexpr
'|' sizednumexpr
1920 $$.val
= $1.val |
$3.val
;
1921 $$.dword
= $1.dword ||
$3.dword
;
1925 /* An expression with a leading comma which does not use unary
1935 /* An expression which does not use unary negation. */
1944 /* An expression which does not use unary negation. We separate unary
1945 negation to avoid parsing conflicts when two numeric expressions
1946 appear consecutively. */
1953 |
'(' sizednumexpr
')'
1957 |
'~' sizednumexpr %prec
'~'
1960 $$.dword
= $2.dword
;
1962 | sizedposnumexpr
'*' sizednumexpr
1964 $$.val
= $1.val
* $3.val
;
1965 $$.dword
= $1.dword ||
$3.dword
;
1967 | sizedposnumexpr
'/' sizednumexpr
1969 $$.val
= $1.val
/ ($3.val ?
$3.val
: 1);
1970 $$.dword
= $1.dword ||
$3.dword
;
1972 | sizedposnumexpr
'%' sizednumexpr
1974 /* PR 17512: file: 89105a25. */
1975 $$.val
= $1.val %
($3.val ?
$3.val
: 1);
1976 $$.dword
= $1.dword ||
$3.dword
;
1978 | sizedposnumexpr
'+' sizednumexpr
1980 $$.val
= $1.val
+ $3.val
;
1981 $$.dword
= $1.dword ||
$3.dword
;
1983 | sizedposnumexpr
'-' sizednumexpr
1985 $$.val
= $1.val
- $3.val
;
1986 $$.dword
= $1.dword ||
$3.dword
;
1988 | sizedposnumexpr
'&' sizednumexpr
1990 $$.val
= $1.val
& $3.val
;
1991 $$.dword
= $1.dword ||
$3.dword
;
1993 | sizedposnumexpr
'^' sizednumexpr
1995 $$.val
= $1.val ^
$3.val
;
1996 $$.dword
= $1.dword ||
$3.dword
;
1998 | sizedposnumexpr
'|' sizednumexpr
2000 $$.val
= $1.val |
$3.val
;
2001 $$.dword
= $1.dword ||
$3.dword
;
2007 /* Set the language from the command line. */
2010 rcparse_set_language
(int lang
)