1 %{ /* rcparse.y -- parser for Windows rc files
2 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007, 2008,
3 2011 Free Software Foundation, Inc.
4 Written by Ian Lance Taylor, Cygnus Support.
5 Extended by Kai Tietz, Onevision.
7 This file is part of GNU Binutils.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
25 /* This is a parser for Windows rc files. It is based on the parser
26 by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
31 #include "libiberty.h"
33 #include "safe-ctype.h"
35 /* The current language. */
37 static unsigned short language;
39 /* The resource information during a sub statement. */
41 static rc_res_res_info sub_res_info;
43 /* Dialog information. This is built by the nonterminals styles and
46 static rc_dialog dialog;
48 /* This is used when building a style. It is modified by the
49 nonterminal styleexpr. */
51 static unsigned long style;
53 /* These are used when building a control. They are set before using
56 static rc_uint_type base_style;
57 static rc_uint_type default_style;
58 static rc_res_id class;
59 static rc_res_id res_text_field;
60 static unichar null_unichar;
62 /* This is used for COMBOBOX, LISTBOX and EDITTEXT which
63 do not allow resource 'text' field in control definition. */
64 static const rc_res_id res_null_text = { 1, {{0, &null_unichar}}};
72 rc_dialog_control *dialog_control;
73 rc_menuitem *menuitem;
76 rc_rcdata_item *first;
79 rc_rcdata_item *rcdata_item;
80 rc_fixed_versioninfo *fixver;
82 rc_ver_stringtable *verstringtable;
83 rc_ver_stringinfo *verstring;
84 rc_ver_varinfo *vervar;
85 rc_toolbar_item *toobar_item;
87 rc_res_res_info res_info;
96 /* Nonzero if this number was explicitly specified as long. */
116 %token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
119 %token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
120 %token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
121 %token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
122 %token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
123 %token BEDIT HEDIT IEDIT
126 %token ANICURSOR ANIICON DLGINCLUDE DLGINIT FONTDIR HTML MANIFEST PLUGPLAY VXD TOOLBAR BUTTON
127 %token LANGUAGE CHARACTERISTICS VERSIONK
128 %token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
129 %token MENUBARBREAK MENUBREAK
133 %token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
134 %token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
137 %token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
139 %token <uni> QUOTEDUNISTRING
140 %token <s> QUOTEDSTRING STRING
142 %token <suni> SIZEDUNISTRING
143 %token <ss> SIZEDSTRING
146 %type <pacc> acc_entries
147 %type <acc> acc_entry acc_event
148 %type <dialog_control> control control_params
149 %type <menuitem> menuitems menuitem menuexitems menuexitem
150 %type <rcdata> optrcdata_data optrcdata_data_int rcdata_data
151 %type <rcdata_item> opt_control_data
152 %type <fixver> fixedverinfo
153 %type <verinfo> verblocks
154 %type <verstringtable> verstringtables
155 %type <verstring> vervals
156 %type <vervar> vertrans
157 %type <toobar_item> toolbar_data
158 %type <res_info> suboptions memflags_move_discard memflags_move
159 %type <memflags> memflag
160 %type <id> id rcdata_id optresidc resref resid cresid
161 %type <il> exstyle parennumber
162 %type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
163 %type <is> acc_options acc_option menuitem_flags menuitem_flag
165 %type <uni> res_unicode_string resname res_unicode_string_concat
166 %type <ss> sizedstring
167 %type <suni> sizedunistring res_unicode_sizedstring res_unicode_sizedstring_concat
168 %type <i> sizednumexpr sizedposnumexpr
195 | input IGNORED_TOKEN
198 /* Accelerator resources. */
201 id ACCELERATORS suboptions BEG acc_entries END
203 define_accelerator ($1, &$3, $5);
204 if (yychar != YYEMPTY)
206 rcparse_discard_strings ();
215 | acc_entries acc_entry
219 a = (rc_accelerator *) res_alloc (sizeof *a);
227 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
236 acc_event cposnumexpr
241 | acc_event cposnumexpr ',' acc_options
246 if (($$.flags & ACC_VIRTKEY) == 0
247 && ($$.flags & (ACC_SHIFT | ACC_CONTROL)) != 0)
248 rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
265 $$.flags = ACC_CONTROL | ACC_VIRTKEY;
271 rcparse_warning (_("accelerator should only be one character"));
287 | acc_options ',' acc_option
291 /* I've had one report that the comma is optional. */
292 | acc_options acc_option
305 /* This is just the absence of VIRTKEY. */
326 /* Bitmap resources. */
329 id BITMAP memflags_move file_name
331 define_bitmap ($1, &$3, $4);
332 if (yychar != YYEMPTY)
334 rcparse_discard_strings ();
338 /* Cursor resources. */
341 id CURSOR memflags_move_discard file_name
343 define_cursor ($1, &$3, $4);
344 if (yychar != YYEMPTY)
346 rcparse_discard_strings ();
350 /* Dialog resources. */
353 id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
356 memset (&dialog, 0, sizeof dialog);
361 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
363 dialog.menu.named = 1;
364 dialog.class.named = 1;
367 dialog.controls = NULL;
371 styles BEG controls END
373 define_dialog ($1, &sub_res_info, &dialog);
374 if (yychar != YYEMPTY)
376 rcparse_discard_strings ();
378 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
381 memset (&dialog, 0, sizeof dialog);
386 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
388 dialog.menu.named = 1;
389 dialog.class.named = 1;
391 dialog.ex = ((rc_dialog_ex *)
392 res_alloc (sizeof (rc_dialog_ex)));
393 memset (dialog.ex, 0, sizeof (rc_dialog_ex));
394 dialog.controls = NULL;
398 styles BEG controls END
400 define_dialog ($1, &sub_res_info, &dialog);
401 if (yychar != YYEMPTY)
403 rcparse_discard_strings ();
405 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
408 memset (&dialog, 0, sizeof dialog);
413 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
415 dialog.menu.named = 1;
416 dialog.class.named = 1;
418 dialog.ex = ((rc_dialog_ex *)
419 res_alloc (sizeof (rc_dialog_ex)));
420 memset (dialog.ex, 0, sizeof (rc_dialog_ex));
421 dialog.ex->help = $9;
422 dialog.controls = NULL;
426 styles BEG controls END
428 define_dialog ($1, &sub_res_info, &dialog);
429 if (yychar != YYEMPTY)
431 rcparse_discard_strings ();
440 | EXSTYLE '=' numexpr
448 | styles CAPTION res_unicode_string_concat
450 dialog.style |= WS_CAPTION;
461 dialog.style = style;
463 | styles EXSTYLE numexpr
467 | styles CLASS res_unicode_string_concat
469 res_unistring_to_id (& dialog.class, $3);
471 | styles FONT numexpr ',' res_unicode_string_concat
473 dialog.style |= DS_SETFONT;
475 dialog.pointsize = $3;
477 if (dialog.ex != NULL)
479 dialog.ex->weight = 0;
480 dialog.ex->italic = 0;
481 dialog.ex->charset = 1;
484 | styles FONT numexpr ',' res_unicode_string_concat cnumexpr
486 dialog.style |= DS_SETFONT;
488 dialog.pointsize = $3;
490 if (dialog.ex == NULL)
491 rcparse_warning (_("extended FONT requires DIALOGEX"));
494 dialog.ex->weight = $6;
495 dialog.ex->italic = 0;
496 dialog.ex->charset = 1;
499 | styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr
501 dialog.style |= DS_SETFONT;
503 dialog.pointsize = $3;
505 if (dialog.ex == NULL)
506 rcparse_warning (_("extended FONT requires DIALOGEX"));
509 dialog.ex->weight = $6;
510 dialog.ex->italic = $7;
511 dialog.ex->charset = 1;
514 | styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr cnumexpr
516 dialog.style |= DS_SETFONT;
518 dialog.pointsize = $3;
520 if (dialog.ex == NULL)
521 rcparse_warning (_("extended FONT requires DIALOGEX"));
524 dialog.ex->weight = $6;
525 dialog.ex->italic = $7;
526 dialog.ex->charset = $8;
533 | styles CHARACTERISTICS numexpr
535 sub_res_info.characteristics = $3;
537 | styles LANGUAGE numexpr cnumexpr
539 sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT);
541 | styles VERSIONK numexpr
543 sub_res_info.version = $3;
551 rc_dialog_control **pp;
553 for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
562 default_style = BS_AUTO3STATE | WS_TABSTOP;
563 base_style = BS_AUTO3STATE;
565 class.u.id = CTL_BUTTON;
572 | AUTOCHECKBOX optresidc
574 default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
575 base_style = BS_AUTOCHECKBOX;
577 class.u.id = CTL_BUTTON;
584 | AUTORADIOBUTTON optresidc
586 default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
587 base_style = BS_AUTORADIOBUTTON;
589 class.u.id = CTL_BUTTON;
598 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
599 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
601 class.u.id = CTL_EDIT;
607 if (dialog.ex == NULL)
608 rcparse_warning (_("BEDIT requires DIALOGEX"));
609 res_string_to_id (&$$->class, "BEDIT");
613 default_style = BS_CHECKBOX | WS_TABSTOP;
614 base_style = BS_CHECKBOX | WS_TABSTOP;
616 class.u.id = CTL_BUTTON;
625 /* This is as per MSDN documentation. With some (???)
626 versions of MS rc.exe their is no default style. */
627 default_style = CBS_SIMPLE | WS_TABSTOP;
630 class.u.id = CTL_COMBOBOX;
631 res_text_field = res_null_text;
637 | CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
638 cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
640 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
643 if (dialog.ex == NULL)
644 rcparse_warning (_("control data requires DIALOGEX"));
648 | CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
649 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
651 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
652 if (dialog.ex == NULL)
653 rcparse_warning (_("help ID requires DIALOGEX"));
659 default_style = SS_CENTER | WS_GROUP;
660 base_style = SS_CENTER;
662 class.u.id = CTL_STATIC;
669 | DEFPUSHBUTTON optresidc
671 default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
672 base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
674 class.u.id = CTL_BUTTON;
683 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
684 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
686 class.u.id = CTL_EDIT;
687 res_text_field = res_null_text;
695 default_style = BS_GROUPBOX;
696 base_style = BS_GROUPBOX;
698 class.u.id = CTL_BUTTON;
707 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
708 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
710 class.u.id = CTL_EDIT;
716 if (dialog.ex == NULL)
717 rcparse_warning (_("IEDIT requires DIALOGEX"));
718 res_string_to_id (&$$->class, "HEDIT");
720 | ICON resref numexpr cnumexpr cnumexpr opt_control_data
722 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $6,
725 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
728 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $8,
731 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
732 icon_styleexpr optcnumexpr opt_control_data
734 $$ = define_icon_control ($2, $3, $4, $5, style, $9, 0, $10,
737 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
738 icon_styleexpr cnumexpr cnumexpr opt_control_data
740 $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11,
745 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
746 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
748 class.u.id = CTL_EDIT;
754 if (dialog.ex == NULL)
755 rcparse_warning (_("IEDIT requires DIALOGEX"));
756 res_string_to_id (&$$->class, "IEDIT");
760 default_style = LBS_NOTIFY | WS_BORDER;
761 base_style = LBS_NOTIFY | WS_BORDER;
763 class.u.id = CTL_LISTBOX;
764 res_text_field = res_null_text;
772 default_style = SS_LEFT | WS_GROUP;
773 base_style = SS_LEFT;
775 class.u.id = CTL_STATIC;
784 default_style = BS_PUSHBOX | WS_TABSTOP;
785 base_style = BS_PUSHBOX;
787 class.u.id = CTL_BUTTON;
793 | PUSHBUTTON optresidc
795 default_style = BS_PUSHBUTTON | WS_TABSTOP;
796 base_style = BS_PUSHBUTTON | WS_TABSTOP;
798 class.u.id = CTL_BUTTON;
805 | RADIOBUTTON optresidc
807 default_style = BS_RADIOBUTTON | WS_TABSTOP;
808 base_style = BS_RADIOBUTTON;
810 class.u.id = CTL_BUTTON;
819 default_style = SS_RIGHT | WS_GROUP;
820 base_style = SS_RIGHT;
822 class.u.id = CTL_STATIC;
831 default_style = SBS_HORZ;
834 class.u.id = CTL_SCROLLBAR;
835 res_text_field = res_null_text;
843 default_style = BS_3STATE | WS_TABSTOP;
844 base_style = BS_3STATE;
846 class.u.id = CTL_BUTTON;
853 | USERBUTTON resref numexpr ',' numexpr ',' numexpr ','
854 numexpr ',' numexpr ','
855 { style = WS_CHILD | WS_VISIBLE; }
856 styleexpr optcnumexpr
860 cid.u.id = CTL_BUTTON;
861 $$ = define_control ($2, $3, $5, $7, $9, $11, cid,
866 /* Parameters for a control. The static variables DEFAULT_STYLE,
867 BASE_STYLE, and CLASS must be initialized before this nonterminal
868 is used. DEFAULT_STYLE is the style to use if no style expression
869 is specified. BASE_STYLE is the base style to use if a style
870 expression is specified; the style expression modifies the base
871 style. CLASS is the class of the control. */
874 numexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
876 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class,
877 default_style | WS_CHILD | WS_VISIBLE, 0);
880 if (dialog.ex == NULL)
881 rcparse_warning (_("control data requires DIALOGEX"));
885 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
886 control_params_styleexpr optcnumexpr opt_control_data
888 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
891 if (dialog.ex == NULL)
892 rcparse_warning (_("control data requires DIALOGEX"));
896 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
897 control_params_styleexpr cnumexpr cnumexpr opt_control_data
899 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
900 if (dialog.ex == NULL)
901 rcparse_warning (_("help ID requires DIALOGEX"));
911 res_unistring_to_id (&$$, $2.u.n.name);
920 res_string_to_id (&$$, "");
922 | resid ',' { $$=$1; }
931 | res_unicode_string_concat
935 $$.u.n.length = unichar_len ($1);
944 | BEG optrcdata_data END
950 /* These only exist to parse a reduction out of a common case. */
954 { style = WS_CHILD | WS_VISIBLE; }
960 { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
964 control_params_styleexpr:
966 { style = base_style | WS_CHILD | WS_VISIBLE; }
970 /* Font resources. */
973 id FONT memflags_move_discard file_name
975 define_font ($1, &$3, $4);
976 if (yychar != YYEMPTY)
978 rcparse_discard_strings ();
982 /* Icon resources. */
985 id ICON memflags_move_discard file_name
987 define_icon ($1, &$3, $4);
988 if (yychar != YYEMPTY)
990 rcparse_discard_strings ();
994 /* Language command. This changes the static variable language, which
995 affects all subsequent resources. */
998 LANGUAGE numexpr cnumexpr
1000 language = $2 | ($3 << SUBLANG_SHIFT);
1004 /* Menu resources. */
1007 id MENU suboptions BEG menuitems END
1009 define_menu ($1, &$3, $5);
1010 if (yychar != YYEMPTY)
1012 rcparse_discard_strings ();
1021 | menuitems menuitem
1029 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1038 MENUITEM res_unicode_string_concat cnumexpr menuitem_flags
1040 $$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
1042 | MENUITEM SEPARATOR
1044 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1046 | POPUP res_unicode_string_concat menuitem_flags BEG menuitems END
1048 $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
1057 | menuitem_flags ',' menuitem_flag
1061 | menuitem_flags menuitem_flag
1070 $$ = MENUITEM_CHECKED;
1074 $$ = MENUITEM_GRAYED;
1082 $$ = MENUITEM_INACTIVE;
1086 $$ = MENUITEM_MENUBARBREAK;
1090 $$ = MENUITEM_MENUBREAK;
1094 /* Menuex resources. */
1097 id MENUEX suboptions BEG menuexitems END
1099 define_menu ($1, &$3, $5);
1100 if (yychar != YYEMPTY)
1102 rcparse_discard_strings ();
1111 | menuexitems menuexitem
1119 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1128 MENUITEM res_unicode_string_concat
1130 $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
1132 | MENUITEM res_unicode_string_concat cnumexpr
1134 $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
1136 | MENUITEM res_unicode_string_concat cnumexpr cnumexpr optcnumexpr
1138 $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
1140 | MENUITEM SEPARATOR
1142 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1144 | POPUP res_unicode_string_concat BEG menuexitems END
1146 $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
1148 | POPUP res_unicode_string_concat cnumexpr BEG menuexitems END
1150 $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
1152 | POPUP res_unicode_string_concat cnumexpr cnumexpr BEG menuexitems END
1154 $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
1156 | POPUP res_unicode_string_concat cnumexpr cnumexpr cnumexpr optcnumexpr
1159 $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
1163 /* Messagetable resources. */
1166 id MESSAGETABLE memflags_move file_name
1168 define_messagetable ($1, &$3, $4);
1169 if (yychar != YYEMPTY)
1171 rcparse_discard_strings ();
1175 /* We use a different lexing algorithm, because rcdata strings may
1176 contain embedded null bytes, and we need to know the length to use. */
1206 ri = define_rcdata_string ($1.s, $1.length);
1214 ri = define_rcdata_unistring ($1.s, $1.length);
1222 ri = define_rcdata_number ($1.val, $1.dword);
1226 | rcdata_data ',' sizedstring
1230 ri = define_rcdata_string ($3.s, $3.length);
1231 $$.first = $1.first;
1235 | rcdata_data ',' sizedunistring
1239 ri = define_rcdata_unistring ($3.s, $3.length);
1240 $$.first = $1.first;
1244 | rcdata_data ',' sizednumexpr
1248 ri = define_rcdata_number ($3.val, $3.dword);
1249 $$.first = $1.first;
1259 /* Stringtable resources. */
1262 STRINGTABLE suboptions BEG
1263 { sub_res_info = $2; rcparse_rcdata (); }
1264 string_data END { rcparse_normal (); }
1269 | string_data numexpr res_unicode_sizedstring_concat
1271 define_stringtable (&sub_res_info, $2, $3.s, $3.length);
1272 rcparse_discard_strings ();
1274 | string_data numexpr ',' res_unicode_sizedstring_concat
1276 define_stringtable (&sub_res_info, $2, $4.s, $4.length);
1277 rcparse_discard_strings ();
1281 rcparse_warning (_("invalid stringtable resource."));
1299 $$.u.id = RT_RCDATA;
1304 $$.u.id = RT_MANIFEST;
1309 $$.u.id = RT_PLUGPLAY;
1319 $$.u.id = RT_DLGINCLUDE;
1324 $$.u.id = RT_DLGINIT;
1329 $$.u.id = RT_ANICURSOR;
1334 $$.u.id = RT_ANIICON;
1338 /* User defined resources. We accept general suboptions in the
1339 file_name case to keep the parser happy. */
1342 id rcdata_id suboptions BEG optrcdata_data END
1344 define_user_data ($1, $2, &$3, $5.first);
1345 if (yychar != YYEMPTY)
1347 rcparse_discard_strings ();
1349 | id rcdata_id suboptions file_name
1351 define_user_file ($1, $2, &$3, $4);
1352 if (yychar != YYEMPTY)
1354 rcparse_discard_strings ();
1359 id TOOLBAR suboptions numexpr cnumexpr BEG toolbar_data END
1361 define_toolbar ($1, &$3, $4, $5, $7);
1365 toolbar_data: /* empty */ { $$= NULL; }
1366 | toolbar_data BUTTON id
1368 rc_toolbar_item *c,*n;
1370 n= (rc_toolbar_item *)
1371 res_alloc (sizeof (rc_toolbar_item));
1373 while (c->next != NULL)
1385 | toolbar_data SEPARATOR
1387 rc_toolbar_item *c,*n;
1389 n= (rc_toolbar_item *)
1390 res_alloc (sizeof (rc_toolbar_item));
1392 while (c->next != NULL)
1407 /* Versioninfo resources. */
1410 id VERSIONINFO fixedverinfo BEG verblocks END
1412 define_versioninfo ($1, language, $3, $5);
1413 if (yychar != YYEMPTY)
1415 rcparse_discard_strings ();
1422 $$ = ((rc_fixed_versioninfo *)
1423 res_alloc (sizeof (rc_fixed_versioninfo)));
1424 memset ($$, 0, sizeof (rc_fixed_versioninfo));
1426 | fixedverinfo FILEVERSION numexpr optcnumexpr optcnumexpr
1429 $1->file_version_ms = ($3 << 16) | $4;
1430 $1->file_version_ls = ($5 << 16) | $6;
1433 | fixedverinfo PRODUCTVERSION numexpr optcnumexpr optcnumexpr
1436 $1->product_version_ms = ($3 << 16) | $4;
1437 $1->product_version_ls = ($5 << 16) | $6;
1440 | fixedverinfo FILEFLAGSMASK numexpr
1442 $1->file_flags_mask = $3;
1445 | fixedverinfo FILEFLAGS numexpr
1447 $1->file_flags = $3;
1450 | fixedverinfo FILEOS numexpr
1455 | fixedverinfo FILETYPE numexpr
1460 | fixedverinfo FILESUBTYPE numexpr
1462 $1->file_subtype = $3;
1467 /* To handle verblocks successfully, the lexer handles BLOCK
1468 specially. A BLOCK "StringFileInfo" is returned as
1469 BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as
1470 BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK
1471 with the string as the value. */
1478 | verblocks BLOCKSTRINGFILEINFO BEG verstringtables END
1480 $$ = append_ver_stringfileinfo ($1, $4);
1482 | verblocks BLOCKVARFILEINFO BEG VALUE res_unicode_string_concat vertrans END
1484 $$ = append_ver_varfileinfo ($1, $5, $6);
1493 | verstringtables BLOCK BEG vervals END
1495 $$ = append_ver_stringtable ($1, $2, $4);
1504 | vervals VALUE res_unicode_string_concat ',' res_unicode_string_concat
1506 $$ = append_verval ($1, $3, $5);
1515 | vertrans cnumexpr cnumexpr
1517 $$ = append_vertrans ($1, $2, $3);
1521 /* A resource ID. */
1531 res_unistring_to_id (&$$, $1);
1535 /* A resource reference. */
1545 unicode_from_ascii ((rc_uint_type *) NULL, &h, $1);
1559 res_unistring_to_id (&$$, $1);
1563 res_unistring_to_id (&$$, $1);
1567 /* Generic suboptions. These may appear before the BEGIN in any
1568 multiline statement. */
1573 memset (&$$, 0, sizeof (rc_res_res_info));
1574 $$.language = language;
1575 /* FIXME: Is this the right default? */
1576 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1578 | suboptions memflag
1581 $$.memflags |= $2.on;
1582 $$.memflags &=~ $2.off;
1584 | suboptions CHARACTERISTICS numexpr
1587 $$.characteristics = $3;
1589 | suboptions LANGUAGE numexpr cnumexpr
1592 $$.language = $3 | ($4 << SUBLANG_SHIFT);
1594 | suboptions VERSIONK numexpr
1601 /* Memory flags which default to MOVEABLE and DISCARDABLE. */
1603 memflags_move_discard:
1606 memset (&$$, 0, sizeof (rc_res_res_info));
1607 $$.language = language;
1608 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
1610 | memflags_move_discard memflag
1613 $$.memflags |= $2.on;
1614 $$.memflags &=~ $2.off;
1618 /* Memory flags which default to MOVEABLE. */
1623 memset (&$$, 0, sizeof (rc_res_res_info));
1624 $$.language = language;
1625 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1627 | memflags_move memflag
1630 $$.memflags |= $2.on;
1631 $$.memflags &=~ $2.off;
1635 /* Memory flags. This returns a struct with two integers, because we
1636 sometimes want to set bits and we sometimes want to clear them. */
1641 $$.on = MEMFLAG_MOVEABLE;
1647 $$.off = MEMFLAG_MOVEABLE;
1651 $$.on = MEMFLAG_PURE;
1657 $$.off = MEMFLAG_PURE;
1661 $$.on = MEMFLAG_PRELOAD;
1667 $$.off = MEMFLAG_PRELOAD;
1671 $$.on = MEMFLAG_DISCARDABLE;
1690 res_unicode_string_concat:
1696 res_unicode_string_concat res_unicode_string
1698 rc_uint_type l1 = unichar_len ($1);
1699 rc_uint_type l2 = unichar_len ($2);
1700 unichar *h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
1702 memcpy (h, $1, l1 * sizeof (unichar));
1704 memcpy (h + l1, $2, l2 * sizeof (unichar));
1713 $$ = unichar_dup ($1);
1718 unicode_from_ascii ((rc_uint_type *) NULL, &h, $1);
1723 res_unicode_sizedstring:
1732 unicode_from_ascii_len (&l, &h, $1.s, $1.length);
1739 res_unicode_sizedstring_concat:
1740 res_unicode_sizedstring
1745 res_unicode_sizedstring_concat res_unicode_sizedstring
1747 rc_uint_type l1 = $1.length;
1748 rc_uint_type l2 = $2.length;
1749 unichar *h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
1751 memcpy (h, $1.s, l1 * sizeof (unichar));
1753 memcpy (h + l1, $2.s, l2 * sizeof (unichar));
1755 $$.length = l1 + l2;
1765 | sizedstring SIZEDSTRING
1767 rc_uint_type l = $1.length + $2.length;
1768 char *h = (char *) res_alloc (l);
1769 memcpy (h, $1.s, $1.length);
1770 memcpy (h + $1.length, $2.s, $2.length);
1781 | sizedunistring SIZEDUNISTRING
1783 rc_uint_type l = $1.length + $2.length;
1784 unichar *h = (unichar *) res_alloc (l * sizeof (unichar));
1785 memcpy (h, $1.s, $1.length * sizeof (unichar));
1786 memcpy (h + $1.length, $2.s, $2.length * sizeof (unichar));
1792 /* A style expression. This changes the static variable STYLE. We do
1793 it this way because rc appears to permit a style to be set to
1795 WS_GROUP | NOT WS_TABSTOP
1796 to mean that a default of WS_TABSTOP should be removed. Anything
1797 which wants to accept a style must first set STYLE to the default
1798 value. The styleexpr nonterminal will change STYLE as specified by
1799 the user. Note that we do not accept arbitrary expressions here,
1800 just numbers separated by '|'. */
1811 | styleexpr '|' parennumber
1815 | styleexpr '|' NOT parennumber
1832 /* An optional expression with a leading comma. */
1845 /* An expression with a leading comma. */
1854 /* A possibly negated numeric expression. */
1863 /* A possibly negated expression with a size. */
1870 | '(' sizednumexpr ')'
1874 | '~' sizednumexpr %prec '~'
1877 $$.dword = $2.dword;
1879 | '-' sizednumexpr %prec NEG
1882 $$.dword = $2.dword;
1884 | sizednumexpr '*' sizednumexpr
1886 $$.val = $1.val * $3.val;
1887 $$.dword = $1.dword || $3.dword;
1889 | sizednumexpr '/' sizednumexpr
1891 $$.val = $1.val / $3.val;
1892 $$.dword = $1.dword || $3.dword;
1894 | sizednumexpr '%' sizednumexpr
1896 $$.val = $1.val % $3.val;
1897 $$.dword = $1.dword || $3.dword;
1899 | sizednumexpr '+' sizednumexpr
1901 $$.val = $1.val + $3.val;
1902 $$.dword = $1.dword || $3.dword;
1904 | sizednumexpr '-' sizednumexpr
1906 $$.val = $1.val - $3.val;
1907 $$.dword = $1.dword || $3.dword;
1909 | sizednumexpr '&' sizednumexpr
1911 $$.val = $1.val & $3.val;
1912 $$.dword = $1.dword || $3.dword;
1914 | sizednumexpr '^' sizednumexpr
1916 $$.val = $1.val ^ $3.val;
1917 $$.dword = $1.dword || $3.dword;
1919 | sizednumexpr '|' sizednumexpr
1921 $$.val = $1.val | $3.val;
1922 $$.dword = $1.dword || $3.dword;
1926 /* An expression with a leading comma which does not use unary
1936 /* An expression which does not use unary negation. */
1945 /* An expression which does not use unary negation. We separate unary
1946 negation to avoid parsing conflicts when two numeric expressions
1947 appear consecutively. */
1954 | '(' sizednumexpr ')'
1958 | '~' sizednumexpr %prec '~'
1961 $$.dword = $2.dword;
1963 | sizedposnumexpr '*' sizednumexpr
1965 $$.val = $1.val * $3.val;
1966 $$.dword = $1.dword || $3.dword;
1968 | sizedposnumexpr '/' sizednumexpr
1970 $$.val = $1.val / $3.val;
1971 $$.dword = $1.dword || $3.dword;
1973 | sizedposnumexpr '%' sizednumexpr
1975 $$.val = $1.val % $3.val;
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)