003-02-12 Dave Brolley <brolley@redhat.com>
[binutils.git] / binutils / rcparse.y
blob1f10da7eaf3e23bb258ac04b017e145956cf8738
1 %{ /* rcparse.y -- parser for Windows rc files
2 Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
22 /* This is a parser for Windows rc files. It is based on the parser
23 by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
25 #include "bfd.h"
26 #include "bucomm.h"
27 #include "libiberty.h"
28 #include "windres.h"
29 #include "safe-ctype.h"
31 /* The current language. */
33 static unsigned short language;
35 /* The resource information during a sub statement. */
37 static struct res_res_info sub_res_info;
39 /* Dialog information. This is built by the nonterminals styles and
40 controls. */
42 static struct dialog dialog;
44 /* This is used when building a style. It is modified by the
45 nonterminal styleexpr. */
47 static unsigned long style;
49 /* These are used when building a control. They are set before using
50 control_params. */
52 static unsigned long base_style;
53 static unsigned long default_style;
54 static unsigned long class;
58 %union
60 struct accelerator acc;
61 struct accelerator *pacc;
62 struct dialog_control *dialog_control;
63 struct menuitem *menuitem;
64 struct
66 struct rcdata_item *first;
67 struct rcdata_item *last;
68 } rcdata;
69 struct rcdata_item *rcdata_item;
70 struct stringtable_data *stringtable;
71 struct fixed_versioninfo *fixver;
72 struct ver_info *verinfo;
73 struct ver_stringinfo *verstring;
74 struct ver_varinfo *vervar;
75 struct res_id id;
76 struct res_res_info res_info;
77 struct
79 unsigned short on;
80 unsigned short off;
81 } memflags;
82 struct
84 unsigned long val;
85 /* Nonzero if this number was explicitly specified as long. */
86 int dword;
87 } i;
88 unsigned long il;
89 unsigned short is;
90 const char *s;
91 struct
93 unsigned long length;
94 const char *s;
95 } ss;
98 %token BEG END
99 %token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
100 %token BITMAP
101 %token CURSOR
102 %token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
103 %token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
104 %token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
105 %token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
106 %token BEDIT HEDIT IEDIT
107 %token FONT
108 %token ICON
109 %token LANGUAGE CHARACTERISTICS VERSIONK
110 %token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
111 %token MENUBARBREAK MENUBREAK
112 %token MESSAGETABLE
113 %token RCDATA
114 %token STRINGTABLE
115 %token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
116 %token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
117 %token VALUE
118 %token <s> BLOCK
119 %token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
120 %token NOT
121 %token <s> QUOTEDSTRING STRING
122 %token <i> NUMBER
123 %token <ss> SIZEDSTRING
124 %token IGNORED_TOKEN
126 %type <pacc> acc_entries
127 %type <acc> acc_entry acc_event
128 %type <dialog_control> control control_params
129 %type <menuitem> menuitems menuitem menuexitems menuexitem
130 %type <rcdata> optrcdata_data optrcdata_data_int rcdata_data
131 %type <rcdata_item> opt_control_data
132 %type <fixver> fixedverinfo
133 %type <verinfo> verblocks
134 %type <verstring> vervals
135 %type <vervar> vertrans
136 %type <res_info> suboptions memflags_move_discard memflags_move
137 %type <memflags> memflag
138 %type <id> id resref
139 %type <il> exstyle parennumber
140 %type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
141 %type <is> acc_options acc_option menuitem_flags menuitem_flag
142 %type <s> optstringc file_name resname
143 %type <i> sizednumexpr sizedposnumexpr
145 %left '|'
146 %left '^'
147 %left '&'
148 %left '+' '-'
149 %left '*' '/' '%'
150 %right '~' NEG
154 input:
155 /* empty */
156 | input accelerator
157 | input bitmap
158 | input cursor
159 | input dialog
160 | input font
161 | input icon
162 | input language
163 | input menu
164 | input menuex
165 | input messagetable
166 | input rcdata
167 | input stringtable
168 | input user
169 | input versioninfo
170 | input IGNORED_TOKEN
173 /* Accelerator resources. */
175 accelerator:
176 id ACCELERATORS suboptions BEG acc_entries END
178 define_accelerator ($1, &$3, $5);
179 if (yychar != YYEMPTY)
180 YYERROR;
181 rcparse_discard_strings ();
185 acc_entries:
186 /* empty */
188 $$ = NULL;
190 | acc_entries acc_entry
192 struct accelerator *a;
194 a = (struct accelerator *) res_alloc (sizeof *a);
195 *a = $2;
196 if ($1 == NULL)
197 $$ = a;
198 else
200 struct accelerator **pp;
202 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
204 *pp = a;
205 $$ = $1;
210 acc_entry:
211 acc_event cposnumexpr
213 $$ = $1;
214 $$.id = $2;
216 | acc_event cposnumexpr ',' acc_options
218 $$ = $1;
219 $$.id = $2;
220 $$.flags |= $4;
221 if (($$.flags & ACC_VIRTKEY) == 0
222 && ($$.flags & (ACC_SHIFT | ACC_CONTROL)) != 0)
223 rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
227 acc_event:
228 QUOTEDSTRING
230 const char *s = $1;
231 char ch;
233 $$.next = NULL;
234 $$.id = 0;
235 ch = *s;
236 if (ch != '^')
237 $$.flags = 0;
238 else
240 $$.flags = ACC_CONTROL | ACC_VIRTKEY;
241 ++s;
242 ch = *s;
243 ch = TOUPPER (ch);
245 $$.key = ch;
246 if (s[1] != '\0')
247 rcparse_warning (_("accelerator should only be one character"));
249 | posnumexpr
251 $$.next = NULL;
252 $$.flags = 0;
253 $$.id = 0;
254 $$.key = $1;
258 acc_options:
259 acc_option
261 $$ = $1;
263 | acc_options ',' acc_option
265 $$ = $1 | $3;
267 /* I've had one report that the comma is optional. */
268 | acc_options acc_option
270 $$ = $1 | $2;
274 acc_option:
275 VIRTKEY
277 $$ = ACC_VIRTKEY;
279 | ASCII
281 /* This is just the absence of VIRTKEY. */
282 $$ = 0;
284 | NOINVERT
286 $$ = ACC_NOINVERT;
288 | SHIFT
290 $$ = ACC_SHIFT;
292 | CONTROL
294 $$ = ACC_CONTROL;
296 | ALT
298 $$ = ACC_ALT;
302 /* Bitmap resources. */
304 bitmap:
305 id BITMAP memflags_move file_name
307 define_bitmap ($1, &$3, $4);
308 if (yychar != YYEMPTY)
309 YYERROR;
310 rcparse_discard_strings ();
314 /* Cursor resources. */
316 cursor:
317 id CURSOR memflags_move_discard file_name
319 define_cursor ($1, &$3, $4);
320 if (yychar != YYEMPTY)
321 YYERROR;
322 rcparse_discard_strings ();
326 /* Dialog resources. */
328 dialog:
329 id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
330 cnumexpr
332 memset (&dialog, 0, sizeof dialog);
333 dialog.x = $5;
334 dialog.y = $6;
335 dialog.width = $7;
336 dialog.height = $8;
337 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
338 dialog.exstyle = $4;
339 dialog.menu.named = 1;
340 dialog.class.named = 1;
341 dialog.font = NULL;
342 dialog.ex = NULL;
343 dialog.controls = NULL;
344 sub_res_info = $3;
345 style = 0;
347 styles BEG controls END
349 define_dialog ($1, &sub_res_info, &dialog);
350 if (yychar != YYEMPTY)
351 YYERROR;
352 rcparse_discard_strings ();
354 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
355 cnumexpr
357 memset (&dialog, 0, sizeof dialog);
358 dialog.x = $5;
359 dialog.y = $6;
360 dialog.width = $7;
361 dialog.height = $8;
362 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
363 dialog.exstyle = $4;
364 dialog.menu.named = 1;
365 dialog.class.named = 1;
366 dialog.font = NULL;
367 dialog.ex = ((struct dialog_ex *)
368 res_alloc (sizeof (struct dialog_ex)));
369 memset (dialog.ex, 0, sizeof (struct dialog_ex));
370 dialog.controls = NULL;
371 sub_res_info = $3;
372 style = 0;
374 styles BEG controls END
376 define_dialog ($1, &sub_res_info, &dialog);
377 if (yychar != YYEMPTY)
378 YYERROR;
379 rcparse_discard_strings ();
381 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
382 cnumexpr cnumexpr
384 memset (&dialog, 0, sizeof dialog);
385 dialog.x = $5;
386 dialog.y = $6;
387 dialog.width = $7;
388 dialog.height = $8;
389 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
390 dialog.exstyle = $4;
391 dialog.menu.named = 1;
392 dialog.class.named = 1;
393 dialog.font = NULL;
394 dialog.ex = ((struct dialog_ex *)
395 res_alloc (sizeof (struct dialog_ex)));
396 memset (dialog.ex, 0, sizeof (struct dialog_ex));
397 dialog.ex->help = $9;
398 dialog.controls = NULL;
399 sub_res_info = $3;
400 style = 0;
402 styles BEG controls END
404 define_dialog ($1, &sub_res_info, &dialog);
405 if (yychar != YYEMPTY)
406 YYERROR;
407 rcparse_discard_strings ();
411 exstyle:
412 /* empty */
414 $$ = 0;
416 | EXSTYLE '=' numexpr
418 $$ = $3;
422 styles:
423 /* empty */
424 | styles CAPTION QUOTEDSTRING
426 dialog.style |= WS_CAPTION;
427 style |= WS_CAPTION;
428 unicode_from_ascii ((int *) NULL, &dialog.caption, $3);
430 | styles CLASS id
432 dialog.class = $3;
434 | styles STYLE
435 styleexpr
437 dialog.style = style;
439 | styles EXSTYLE numexpr
441 dialog.exstyle = $3;
443 | styles CLASS QUOTEDSTRING
445 res_string_to_id (& dialog.class, $3);
447 | styles FONT numexpr ',' QUOTEDSTRING
449 dialog.style |= DS_SETFONT;
450 style |= DS_SETFONT;
451 dialog.pointsize = $3;
452 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
453 if (dialog.ex != NULL)
455 dialog.ex->weight = 0;
456 dialog.ex->italic = 0;
457 dialog.ex->charset = 1;
460 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr
462 dialog.style |= DS_SETFONT;
463 style |= DS_SETFONT;
464 dialog.pointsize = $3;
465 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
466 if (dialog.ex == NULL)
467 rcparse_warning (_("extended FONT requires DIALOGEX"));
468 else
470 dialog.ex->weight = $6;
471 dialog.ex->italic = 0;
472 dialog.ex->charset = 1;
475 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr
477 dialog.style |= DS_SETFONT;
478 style |= DS_SETFONT;
479 dialog.pointsize = $3;
480 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
481 if (dialog.ex == NULL)
482 rcparse_warning (_("extended FONT requires DIALOGEX"));
483 else
485 dialog.ex->weight = $6;
486 dialog.ex->italic = $7;
487 dialog.ex->charset = 1;
490 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr cnumexpr
492 dialog.style |= DS_SETFONT;
493 style |= DS_SETFONT;
494 dialog.pointsize = $3;
495 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
496 if (dialog.ex == NULL)
497 rcparse_warning (_("extended FONT requires DIALOGEX"));
498 else
500 dialog.ex->weight = $6;
501 dialog.ex->italic = $7;
502 dialog.ex->charset = $8;
505 | styles MENU id
507 dialog.menu = $3;
509 | styles CHARACTERISTICS numexpr
511 sub_res_info.characteristics = $3;
513 | styles LANGUAGE numexpr cnumexpr
515 sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT);
517 | styles VERSIONK numexpr
519 sub_res_info.version = $3;
523 controls:
524 /* empty */
525 | controls control
527 struct dialog_control **pp;
529 for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
531 *pp = $2;
535 control:
536 AUTO3STATE
538 default_style = BS_AUTO3STATE | WS_TABSTOP;
539 base_style = BS_AUTO3STATE;
540 class = CTL_BUTTON;
542 control_params
544 $$ = $3;
546 | AUTOCHECKBOX
548 default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
549 base_style = BS_AUTOCHECKBOX;
550 class = CTL_BUTTON;
552 control_params
554 $$ = $3;
556 | AUTORADIOBUTTON
558 default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
559 base_style = BS_AUTORADIOBUTTON;
560 class = CTL_BUTTON;
562 control_params
564 $$ = $3;
566 | BEDIT
568 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
569 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
570 class = CTL_EDIT;
572 control_params
574 $$ = $3;
575 if (dialog.ex == NULL)
576 rcparse_warning (_("BEDIT requires DIALOGEX"));
577 res_string_to_id (&$$->class, "BEDIT");
579 | CHECKBOX
581 default_style = BS_CHECKBOX | WS_TABSTOP;
582 base_style = BS_CHECKBOX | WS_TABSTOP;
583 class = CTL_BUTTON;
585 control_params
587 $$ = $3;
589 | COMBOBOX
591 default_style = CBS_SIMPLE | WS_TABSTOP;
592 base_style = 0;
593 class = CTL_COMBOBOX;
595 control_params
597 $$ = $3;
599 | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
600 cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
602 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
603 if ($11 != NULL)
605 if (dialog.ex == NULL)
606 rcparse_warning (_("control data requires DIALOGEX"));
607 $$->data = $11;
610 | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
611 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
613 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
614 if (dialog.ex == NULL)
615 rcparse_warning (_("help ID requires DIALOGEX"));
616 $$->help = $11;
617 $$->data = $12;
619 | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr
620 cnumexpr cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
622 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
623 if ($12 != NULL)
625 if (dialog.ex == NULL)
626 rcparse_warning ("control data requires DIALOGEX");
627 $$->data = $12;
629 $$->class.named = 1;
630 unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5);
632 | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr
633 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
635 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
636 if (dialog.ex == NULL)
637 rcparse_warning ("help ID requires DIALOGEX");
638 $$->help = $12;
639 $$->data = $13;
640 $$->class.named = 1;
641 unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5);
643 | CTEXT
645 default_style = SS_CENTER | WS_GROUP;
646 base_style = SS_CENTER;
647 class = CTL_STATIC;
649 control_params
651 $$ = $3;
653 | DEFPUSHBUTTON
655 default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
656 base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
657 class = CTL_BUTTON;
659 control_params
661 $$ = $3;
663 | EDITTEXT
665 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
666 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
667 class = CTL_EDIT;
669 control_params
671 $$ = $3;
673 | GROUPBOX
675 default_style = BS_GROUPBOX;
676 base_style = BS_GROUPBOX;
677 class = CTL_BUTTON;
679 control_params
681 $$ = $3;
683 | HEDIT
685 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
686 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
687 class = CTL_EDIT;
689 control_params
691 $$ = $3;
692 if (dialog.ex == NULL)
693 rcparse_warning (_("IEDIT requires DIALOGEX"));
694 res_string_to_id (&$$->class, "HEDIT");
696 | ICON resref numexpr cnumexpr cnumexpr opt_control_data
698 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $6,
699 dialog.ex);
701 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
702 opt_control_data
704 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $8,
705 dialog.ex);
707 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
708 icon_styleexpr optcnumexpr opt_control_data
710 $$ = define_icon_control ($2, $3, $4, $5, style, $9, 0, $10,
711 dialog.ex);
713 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
714 icon_styleexpr cnumexpr cnumexpr opt_control_data
716 $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11,
717 dialog.ex);
719 | IEDIT
721 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
722 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
723 class = CTL_EDIT;
725 control_params
727 $$ = $3;
728 if (dialog.ex == NULL)
729 rcparse_warning (_("IEDIT requires DIALOGEX"));
730 res_string_to_id (&$$->class, "IEDIT");
732 | LISTBOX
734 default_style = LBS_NOTIFY | WS_BORDER;
735 base_style = LBS_NOTIFY | WS_BORDER;
736 class = CTL_LISTBOX;
738 control_params
740 $$ = $3;
742 | LTEXT
744 default_style = SS_LEFT | WS_GROUP;
745 base_style = SS_LEFT;
746 class = CTL_STATIC;
748 control_params
750 $$ = $3;
752 | PUSHBOX
754 default_style = BS_PUSHBOX | WS_TABSTOP;
755 base_style = BS_PUSHBOX;
756 class = CTL_BUTTON;
758 control_params
760 $$ = $3;
762 | PUSHBUTTON
764 default_style = BS_PUSHBUTTON | WS_TABSTOP;
765 base_style = BS_PUSHBUTTON | WS_TABSTOP;
766 class = CTL_BUTTON;
768 control_params
770 $$ = $3;
772 | RADIOBUTTON
774 default_style = BS_RADIOBUTTON | WS_TABSTOP;
775 base_style = BS_RADIOBUTTON;
776 class = CTL_BUTTON;
778 control_params
780 $$ = $3;
782 | RTEXT
784 default_style = SS_RIGHT | WS_GROUP;
785 base_style = SS_RIGHT;
786 class = CTL_STATIC;
788 control_params
790 $$ = $3;
792 | SCROLLBAR
794 default_style = SBS_HORZ;
795 base_style = 0;
796 class = CTL_SCROLLBAR;
798 control_params
800 $$ = $3;
802 | STATE3
804 default_style = BS_3STATE | WS_TABSTOP;
805 base_style = BS_3STATE;
806 class = CTL_BUTTON;
808 control_params
810 $$ = $3;
812 | USERBUTTON QUOTEDSTRING ',' numexpr ',' numexpr ',' numexpr ','
813 numexpr ',' numexpr ','
814 { style = WS_CHILD | WS_VISIBLE; }
815 styleexpr optcnumexpr
817 $$ = define_control ($2, $4, $6, $8, $10, $12, CTL_BUTTON,
818 style, $16);
822 /* Parameters for a control. The static variables DEFAULT_STYLE,
823 BASE_STYLE, and CLASS must be initialized before this nonterminal
824 is used. DEFAULT_STYLE is the style to use if no style expression
825 is specified. BASE_STYLE is the base style to use if a style
826 expression is specified; the style expression modifies the base
827 style. CLASS is the class of the control. */
829 control_params:
830 optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
831 opt_control_data
833 $$ = define_control ($1, $2, $3, $4, $5, $6, class,
834 default_style | WS_CHILD | WS_VISIBLE, 0);
835 if ($7 != NULL)
837 if (dialog.ex == NULL)
838 rcparse_warning (_("control data requires DIALOGEX"));
839 $$->data = $7;
842 | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
843 control_params_styleexpr optcnumexpr opt_control_data
845 $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
846 if ($9 != NULL)
848 if (dialog.ex == NULL)
849 rcparse_warning (_("control data requires DIALOGEX"));
850 $$->data = $9;
853 | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
854 control_params_styleexpr cnumexpr cnumexpr opt_control_data
856 $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
857 if (dialog.ex == NULL)
858 rcparse_warning (_("help ID requires DIALOGEX"));
859 $$->help = $9;
860 $$->data = $10;
864 optstringc:
865 /* empty */
867 $$ = NULL;
869 | QUOTEDSTRING
871 $$ = $1;
873 | QUOTEDSTRING ','
875 $$ = $1;
879 opt_control_data:
880 /* empty */
882 $$ = NULL;
884 | BEG optrcdata_data END
886 $$ = $2.first;
890 /* These only exist to parse a reduction out of a common case. */
892 control_styleexpr:
894 { style = WS_CHILD | WS_VISIBLE; }
895 styleexpr
898 icon_styleexpr:
900 { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
901 styleexpr
904 control_params_styleexpr:
906 { style = base_style | WS_CHILD | WS_VISIBLE; }
907 styleexpr
910 /* Font resources. */
912 font:
913 id FONT memflags_move_discard file_name
915 define_font ($1, &$3, $4);
916 if (yychar != YYEMPTY)
917 YYERROR;
918 rcparse_discard_strings ();
922 /* Icon resources. */
924 icon:
925 id ICON memflags_move_discard file_name
927 define_icon ($1, &$3, $4);
928 if (yychar != YYEMPTY)
929 YYERROR;
930 rcparse_discard_strings ();
934 /* Language command. This changes the static variable language, which
935 affects all subsequent resources. */
937 language:
938 LANGUAGE numexpr cnumexpr
940 language = $2 | ($3 << SUBLANG_SHIFT);
944 /* Menu resources. */
946 menu:
947 id MENU suboptions BEG menuitems END
949 define_menu ($1, &$3, $5);
950 if (yychar != YYEMPTY)
951 YYERROR;
952 rcparse_discard_strings ();
956 menuitems:
957 /* empty */
959 $$ = NULL;
961 | menuitems menuitem
963 if ($1 == NULL)
964 $$ = $2;
965 else
967 struct menuitem **pp;
969 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
971 *pp = $2;
972 $$ = $1;
977 menuitem:
978 MENUITEM QUOTEDSTRING cnumexpr menuitem_flags
980 $$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
982 | MENUITEM SEPARATOR
984 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
986 | POPUP QUOTEDSTRING menuitem_flags BEG menuitems END
988 $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
992 menuitem_flags:
993 /* empty */
995 $$ = 0;
997 | menuitem_flags ',' menuitem_flag
999 $$ = $1 | $3;
1001 | menuitem_flags menuitem_flag
1003 $$ = $1 | $2;
1007 menuitem_flag:
1008 CHECKED
1010 $$ = MENUITEM_CHECKED;
1012 | GRAYED
1014 $$ = MENUITEM_GRAYED;
1016 | HELP
1018 $$ = MENUITEM_HELP;
1020 | INACTIVE
1022 $$ = MENUITEM_INACTIVE;
1024 | MENUBARBREAK
1026 $$ = MENUITEM_MENUBARBREAK;
1028 | MENUBREAK
1030 $$ = MENUITEM_MENUBREAK;
1034 /* Menuex resources. */
1036 menuex:
1037 id MENUEX suboptions BEG menuexitems END
1039 define_menu ($1, &$3, $5);
1040 if (yychar != YYEMPTY)
1041 YYERROR;
1042 rcparse_discard_strings ();
1046 menuexitems:
1047 /* empty */
1049 $$ = NULL;
1051 | menuexitems menuexitem
1053 if ($1 == NULL)
1054 $$ = $2;
1055 else
1057 struct menuitem **pp;
1059 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1061 *pp = $2;
1062 $$ = $1;
1067 menuexitem:
1068 MENUITEM QUOTEDSTRING
1070 $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
1072 | MENUITEM QUOTEDSTRING cnumexpr
1074 $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
1076 | MENUITEM QUOTEDSTRING cnumexpr cnumexpr optcnumexpr
1078 $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
1080 | MENUITEM SEPARATOR
1082 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1084 | POPUP QUOTEDSTRING BEG menuexitems END
1086 $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
1088 | POPUP QUOTEDSTRING cnumexpr BEG menuexitems END
1090 $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
1092 | POPUP QUOTEDSTRING cnumexpr cnumexpr BEG menuexitems END
1094 $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
1096 | POPUP QUOTEDSTRING cnumexpr cnumexpr cnumexpr optcnumexpr
1097 BEG menuexitems END
1099 $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
1103 /* Messagetable resources. */
1105 messagetable:
1106 id MESSAGETABLE memflags_move file_name
1108 define_messagetable ($1, &$3, $4);
1109 if (yychar != YYEMPTY)
1110 YYERROR;
1111 rcparse_discard_strings ();
1115 /* Rcdata resources. */
1117 rcdata:
1118 id RCDATA suboptions BEG optrcdata_data END
1120 define_rcdata ($1, &$3, $5.first);
1121 if (yychar != YYEMPTY)
1122 YYERROR;
1123 rcparse_discard_strings ();
1127 /* We use a different lexing algorithm, because rcdata strings may
1128 contain embedded null bytes, and we need to know the length to use. */
1130 optrcdata_data:
1132 rcparse_rcdata ();
1134 optrcdata_data_int
1136 rcparse_normal ();
1137 $$ = $2;
1141 optrcdata_data_int:
1142 /* empty */
1144 $$.first = NULL;
1145 $$.last = NULL;
1147 | rcdata_data
1149 $$ = $1;
1153 rcdata_data:
1154 SIZEDSTRING
1156 struct rcdata_item *ri;
1158 ri = define_rcdata_string ($1.s, $1.length);
1159 $$.first = ri;
1160 $$.last = ri;
1162 | sizednumexpr
1164 struct rcdata_item *ri;
1166 ri = define_rcdata_number ($1.val, $1.dword);
1167 $$.first = ri;
1168 $$.last = ri;
1170 | rcdata_data ',' SIZEDSTRING
1172 struct rcdata_item *ri;
1174 ri = define_rcdata_string ($3.s, $3.length);
1175 $$.first = $1.first;
1176 $1.last->next = ri;
1177 $$.last = ri;
1179 | rcdata_data ',' sizednumexpr
1181 struct rcdata_item *ri;
1183 ri = define_rcdata_number ($3.val, $3.dword);
1184 $$.first = $1.first;
1185 $1.last->next = ri;
1186 $$.last = ri;
1190 /* Stringtable resources. */
1192 stringtable:
1193 STRINGTABLE suboptions BEG
1194 { sub_res_info = $2; }
1195 string_data END
1198 string_data:
1199 /* empty */
1200 | string_data numexpr QUOTEDSTRING
1202 define_stringtable (&sub_res_info, $2, $3);
1203 if (yychar != YYEMPTY)
1204 YYERROR;
1205 rcparse_discard_strings ();
1207 | string_data numexpr ',' QUOTEDSTRING
1209 define_stringtable (&sub_res_info, $2, $4);
1210 if (yychar != YYEMPTY)
1211 YYERROR;
1212 rcparse_discard_strings ();
1216 /* User defined resources. We accept general suboptions in the
1217 file_name case to keep the parser happy. */
1219 user:
1220 id id suboptions BEG optrcdata_data END
1222 define_user_data ($1, $2, &$3, $5.first);
1223 if (yychar != YYEMPTY)
1224 YYERROR;
1225 rcparse_discard_strings ();
1227 | id id suboptions file_name
1229 define_user_file ($1, $2, &$3, $4);
1230 if (yychar != YYEMPTY)
1231 YYERROR;
1232 rcparse_discard_strings ();
1236 /* Versioninfo resources. */
1238 versioninfo:
1239 id VERSIONINFO fixedverinfo BEG verblocks END
1241 define_versioninfo ($1, language, $3, $5);
1242 if (yychar != YYEMPTY)
1243 YYERROR;
1244 rcparse_discard_strings ();
1248 fixedverinfo:
1249 /* empty */
1251 $$ = ((struct fixed_versioninfo *)
1252 res_alloc (sizeof (struct fixed_versioninfo)));
1253 memset ($$, 0, sizeof (struct fixed_versioninfo));
1255 | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
1257 $1->file_version_ms = ($3 << 16) | $4;
1258 $1->file_version_ls = ($5 << 16) | $6;
1259 $$ = $1;
1261 | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
1263 $1->product_version_ms = ($3 << 16) | $4;
1264 $1->product_version_ls = ($5 << 16) | $6;
1265 $$ = $1;
1267 | fixedverinfo FILEFLAGSMASK numexpr
1269 $1->file_flags_mask = $3;
1270 $$ = $1;
1272 | fixedverinfo FILEFLAGS numexpr
1274 $1->file_flags = $3;
1275 $$ = $1;
1277 | fixedverinfo FILEOS numexpr
1279 $1->file_os = $3;
1280 $$ = $1;
1282 | fixedverinfo FILETYPE numexpr
1284 $1->file_type = $3;
1285 $$ = $1;
1287 | fixedverinfo FILESUBTYPE numexpr
1289 $1->file_subtype = $3;
1290 $$ = $1;
1294 /* To handle verblocks successfully, the lexer handles BLOCK
1295 specially. A BLOCK "StringFileInfo" is returned as
1296 BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as
1297 BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK
1298 with the string as the value. */
1300 verblocks:
1301 /* empty */
1303 $$ = NULL;
1305 | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
1307 $$ = append_ver_stringfileinfo ($1, $4, $6);
1309 | verblocks BLOCKVARFILEINFO BEG VALUE QUOTEDSTRING vertrans END
1311 $$ = append_ver_varfileinfo ($1, $5, $6);
1315 vervals:
1316 /* empty */
1318 $$ = NULL;
1320 | vervals VALUE QUOTEDSTRING ',' QUOTEDSTRING
1322 $$ = append_verval ($1, $3, $5);
1326 vertrans:
1327 /* empty */
1329 $$ = NULL;
1331 | vertrans cnumexpr cnumexpr
1333 $$ = append_vertrans ($1, $2, $3);
1337 /* A resource ID. */
1340 posnumexpr
1342 $$.named = 0;
1343 $$.u.id = $1;
1345 | STRING
1347 char *copy, *s;
1349 /* It seems that resource ID's are forced to upper case. */
1350 copy = xstrdup ($1);
1351 for (s = copy; *s != '\0'; s++)
1352 *s = TOUPPER (*s);
1353 res_string_to_id (&$$, copy);
1354 free (copy);
1358 /* A resource reference. */
1360 resname:
1361 QUOTEDSTRING
1363 $$ = $1;
1365 | QUOTEDSTRING ','
1367 $$ = $1;
1369 | STRING ','
1371 $$ = $1;
1376 resref:
1377 posnumexpr ','
1379 $$.named = 0;
1380 $$.u.id = $1;
1382 | resname
1384 char *copy, *s;
1386 /* It seems that resource ID's are forced to upper case. */
1387 copy = xstrdup ($1);
1388 for (s = copy; *s != '\0'; s++)
1389 *s = TOUPPER (*s);
1390 res_string_to_id (&$$, copy);
1391 free (copy);
1395 /* Generic suboptions. These may appear before the BEGIN in any
1396 multiline statement. */
1398 suboptions:
1399 /* empty */
1401 memset (&$$, 0, sizeof (struct res_res_info));
1402 $$.language = language;
1403 /* FIXME: Is this the right default? */
1404 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1406 | suboptions memflag
1408 $$ = $1;
1409 $$.memflags |= $2.on;
1410 $$.memflags &=~ $2.off;
1412 | suboptions CHARACTERISTICS numexpr
1414 $$ = $1;
1415 $$.characteristics = $3;
1417 | suboptions LANGUAGE numexpr cnumexpr
1419 $$ = $1;
1420 $$.language = $3 | ($4 << SUBLANG_SHIFT);
1422 | suboptions VERSIONK numexpr
1424 $$ = $1;
1425 $$.version = $3;
1429 /* Memory flags which default to MOVEABLE and DISCARDABLE. */
1431 memflags_move_discard:
1432 /* empty */
1434 memset (&$$, 0, sizeof (struct res_res_info));
1435 $$.language = language;
1436 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
1438 | memflags_move_discard memflag
1440 $$ = $1;
1441 $$.memflags |= $2.on;
1442 $$.memflags &=~ $2.off;
1446 /* Memory flags which default to MOVEABLE. */
1448 memflags_move:
1449 /* empty */
1451 memset (&$$, 0, sizeof (struct res_res_info));
1452 $$.language = language;
1453 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1455 | memflags_move memflag
1457 $$ = $1;
1458 $$.memflags |= $2.on;
1459 $$.memflags &=~ $2.off;
1463 /* Memory flags. This returns a struct with two integers, because we
1464 sometimes want to set bits and we sometimes want to clear them. */
1466 memflag:
1467 MOVEABLE
1469 $$.on = MEMFLAG_MOVEABLE;
1470 $$.off = 0;
1472 | FIXED
1474 $$.on = 0;
1475 $$.off = MEMFLAG_MOVEABLE;
1477 | PURE
1479 $$.on = MEMFLAG_PURE;
1480 $$.off = 0;
1482 | IMPURE
1484 $$.on = 0;
1485 $$.off = MEMFLAG_PURE;
1487 | PRELOAD
1489 $$.on = MEMFLAG_PRELOAD;
1490 $$.off = 0;
1492 | LOADONCALL
1494 $$.on = 0;
1495 $$.off = MEMFLAG_PRELOAD;
1497 | DISCARDABLE
1499 $$.on = MEMFLAG_DISCARDABLE;
1500 $$.off = 0;
1504 /* A file name. */
1506 file_name:
1507 QUOTEDSTRING
1509 $$ = $1;
1511 | STRING
1513 $$ = $1;
1517 /* A style expression. This changes the static variable STYLE. We do
1518 it this way because rc appears to permit a style to be set to
1519 something like
1520 WS_GROUP | NOT WS_TABSTOP
1521 to mean that a default of WS_TABSTOP should be removed. Anything
1522 which wants to accept a style must first set STYLE to the default
1523 value. The styleexpr nonterminal will change STYLE as specified by
1524 the user. Note that we do not accept arbitrary expressions here,
1525 just numbers separated by '|'. */
1527 styleexpr:
1528 parennumber
1530 style |= $1;
1532 | NOT parennumber
1534 style &=~ $2;
1536 | styleexpr '|' parennumber
1538 style |= $3;
1540 | styleexpr '|' NOT parennumber
1542 style &=~ $4;
1546 parennumber:
1547 NUMBER
1549 $$ = $1.val;
1551 | '(' numexpr ')'
1553 $$ = $2;
1557 /* An optional expression with a leading comma. */
1559 optcnumexpr:
1560 /* empty */
1562 $$ = 0;
1564 | cnumexpr
1566 $$ = $1;
1570 /* An expression with a leading comma. */
1572 cnumexpr:
1573 ',' numexpr
1575 $$ = $2;
1579 /* A possibly negated numeric expression. */
1581 numexpr:
1582 sizednumexpr
1584 $$ = $1.val;
1588 /* A possibly negated expression with a size. */
1590 sizednumexpr:
1591 NUMBER
1593 $$ = $1;
1595 | '(' sizednumexpr ')'
1597 $$ = $2;
1599 | '~' sizednumexpr %prec '~'
1601 $$.val = ~ $2.val;
1602 $$.dword = $2.dword;
1604 | '-' sizednumexpr %prec NEG
1606 $$.val = - $2.val;
1607 $$.dword = $2.dword;
1609 | sizednumexpr '*' sizednumexpr
1611 $$.val = $1.val * $3.val;
1612 $$.dword = $1.dword || $3.dword;
1614 | sizednumexpr '/' sizednumexpr
1616 $$.val = $1.val / $3.val;
1617 $$.dword = $1.dword || $3.dword;
1619 | sizednumexpr '%' sizednumexpr
1621 $$.val = $1.val % $3.val;
1622 $$.dword = $1.dword || $3.dword;
1624 | sizednumexpr '+' sizednumexpr
1626 $$.val = $1.val + $3.val;
1627 $$.dword = $1.dword || $3.dword;
1629 | sizednumexpr '-' sizednumexpr
1631 $$.val = $1.val - $3.val;
1632 $$.dword = $1.dword || $3.dword;
1634 | sizednumexpr '&' sizednumexpr
1636 $$.val = $1.val & $3.val;
1637 $$.dword = $1.dword || $3.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;
1651 /* An expression with a leading comma which does not use unary
1652 negation. */
1654 cposnumexpr:
1655 ',' posnumexpr
1657 $$ = $2;
1661 /* An expression which does not use unary negation. */
1663 posnumexpr:
1664 sizedposnumexpr
1666 $$ = $1.val;
1670 /* An expression which does not use unary negation. We separate unary
1671 negation to avoid parsing conflicts when two numeric expressions
1672 appear consecutively. */
1674 sizedposnumexpr:
1675 NUMBER
1677 $$ = $1;
1679 | '(' sizednumexpr ')'
1681 $$ = $2;
1683 | '~' sizednumexpr %prec '~'
1685 $$.val = ~ $2.val;
1686 $$.dword = $2.dword;
1688 | sizedposnumexpr '*' sizednumexpr
1690 $$.val = $1.val * $3.val;
1691 $$.dword = $1.dword || $3.dword;
1693 | sizedposnumexpr '/' sizednumexpr
1695 $$.val = $1.val / $3.val;
1696 $$.dword = $1.dword || $3.dword;
1698 | sizedposnumexpr '%' sizednumexpr
1700 $$.val = $1.val % $3.val;
1701 $$.dword = $1.dword || $3.dword;
1703 | sizedposnumexpr '+' sizednumexpr
1705 $$.val = $1.val + $3.val;
1706 $$.dword = $1.dword || $3.dword;
1708 | sizedposnumexpr '-' sizednumexpr
1710 $$.val = $1.val - $3.val;
1711 $$.dword = $1.dword || $3.dword;
1713 | sizedposnumexpr '&' sizednumexpr
1715 $$.val = $1.val & $3.val;
1716 $$.dword = $1.dword || $3.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;
1732 /* Set the language from the command line. */
1734 void
1735 rcparse_set_language (lang)
1736 int lang;
1738 language = lang;