Regenerate frv-dis.c in order to fix a compile time warning.
[binutils.git] / binutils / rcparse.y
blob98ad3c8b58b3f2722a9a99ddccc770b70df43fee
1 %{ /* rcparse.y -- parser for Windows rc files
2 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005
3 Free Software Foundation, Inc.
4 Written by Ian Lance Taylor, Cygnus Support.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
23 /* This is a parser for Windows rc files. It is based on the parser
24 by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
26 #include "bfd.h"
27 #include "bucomm.h"
28 #include "libiberty.h"
29 #include "windres.h"
30 #include "safe-ctype.h"
32 /* The current language. */
34 static unsigned short language;
36 /* The resource information during a sub statement. */
38 static struct res_res_info sub_res_info;
40 /* Dialog information. This is built by the nonterminals styles and
41 controls. */
43 static struct dialog dialog;
45 /* This is used when building a style. It is modified by the
46 nonterminal styleexpr. */
48 static unsigned long style;
50 /* These are used when building a control. They are set before using
51 control_params. */
53 static unsigned long base_style;
54 static unsigned long default_style;
55 static unsigned long class;
56 static struct res_id res_text_field;
58 /* This is used for COMBOBOX, LISTBOX and EDITTEXT which
59 do not allow resource 'text' field in control definition. */
60 static const struct res_id res_null_text = { 1, {{0, L""}}};
64 %union
66 struct accelerator acc;
67 struct accelerator *pacc;
68 struct dialog_control *dialog_control;
69 struct menuitem *menuitem;
70 struct
72 struct rcdata_item *first;
73 struct rcdata_item *last;
74 } rcdata;
75 struct rcdata_item *rcdata_item;
76 struct stringtable_data *stringtable;
77 struct fixed_versioninfo *fixver;
78 struct ver_info *verinfo;
79 struct ver_stringinfo *verstring;
80 struct ver_varinfo *vervar;
81 struct res_id id;
82 struct res_res_info res_info;
83 struct
85 unsigned short on;
86 unsigned short off;
87 } memflags;
88 struct
90 unsigned long val;
91 /* Nonzero if this number was explicitly specified as long. */
92 int dword;
93 } i;
94 unsigned long il;
95 unsigned short is;
96 const char *s;
97 struct
99 unsigned long length;
100 const char *s;
101 } ss;
104 %token BEG END
105 %token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
106 %token BITMAP
107 %token CURSOR
108 %token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
109 %token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
110 %token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
111 %token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
112 %token BEDIT HEDIT IEDIT
113 %token FONT
114 %token ICON
115 %token LANGUAGE CHARACTERISTICS VERSIONK
116 %token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
117 %token MENUBARBREAK MENUBREAK
118 %token MESSAGETABLE
119 %token RCDATA
120 %token STRINGTABLE
121 %token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
122 %token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
123 %token VALUE
124 %token <s> BLOCK
125 %token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
126 %token NOT
127 %token <s> QUOTEDSTRING STRING
128 %token <i> NUMBER
129 %token <ss> SIZEDSTRING
130 %token IGNORED_TOKEN
132 %type <pacc> acc_entries
133 %type <acc> acc_entry acc_event
134 %type <dialog_control> control control_params
135 %type <menuitem> menuitems menuitem menuexitems menuexitem
136 %type <rcdata> optrcdata_data optrcdata_data_int rcdata_data
137 %type <rcdata_item> opt_control_data
138 %type <fixver> fixedverinfo
139 %type <verinfo> verblocks
140 %type <verstring> vervals
141 %type <vervar> vertrans
142 %type <res_info> suboptions memflags_move_discard memflags_move
143 %type <memflags> memflag
144 %type <id> id optresidc resref
145 %type <il> exstyle parennumber
146 %type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
147 %type <is> acc_options acc_option menuitem_flags menuitem_flag
148 %type <s> file_name resname
149 %type <i> sizednumexpr sizedposnumexpr
151 %left '|'
152 %left '^'
153 %left '&'
154 %left '+' '-'
155 %left '*' '/' '%'
156 %right '~' NEG
160 input:
161 /* empty */
162 | input accelerator
163 | input bitmap
164 | input cursor
165 | input dialog
166 | input font
167 | input icon
168 | input language
169 | input menu
170 | input menuex
171 | input messagetable
172 | input rcdata
173 | input stringtable
174 | input user
175 | input versioninfo
176 | input IGNORED_TOKEN
179 /* Accelerator resources. */
181 accelerator:
182 id ACCELERATORS suboptions BEG acc_entries END
184 define_accelerator ($1, &$3, $5);
185 if (yychar != YYEMPTY)
186 YYERROR;
187 rcparse_discard_strings ();
191 acc_entries:
192 /* empty */
194 $$ = NULL;
196 | acc_entries acc_entry
198 struct accelerator *a;
200 a = (struct accelerator *) res_alloc (sizeof *a);
201 *a = $2;
202 if ($1 == NULL)
203 $$ = a;
204 else
206 struct accelerator **pp;
208 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
210 *pp = a;
211 $$ = $1;
216 acc_entry:
217 acc_event cposnumexpr
219 $$ = $1;
220 $$.id = $2;
222 | acc_event cposnumexpr ',' acc_options
224 $$ = $1;
225 $$.id = $2;
226 $$.flags |= $4;
227 if (($$.flags & ACC_VIRTKEY) == 0
228 && ($$.flags & (ACC_SHIFT | ACC_CONTROL)) != 0)
229 rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
233 acc_event:
234 QUOTEDSTRING
236 const char *s = $1;
237 char ch;
239 $$.next = NULL;
240 $$.id = 0;
241 ch = *s;
242 if (ch != '^')
243 $$.flags = 0;
244 else
246 $$.flags = ACC_CONTROL | ACC_VIRTKEY;
247 ++s;
248 ch = *s;
249 ch = TOUPPER (ch);
251 $$.key = ch;
252 if (s[1] != '\0')
253 rcparse_warning (_("accelerator should only be one character"));
255 | posnumexpr
257 $$.next = NULL;
258 $$.flags = 0;
259 $$.id = 0;
260 $$.key = $1;
264 acc_options:
265 acc_option
267 $$ = $1;
269 | acc_options ',' acc_option
271 $$ = $1 | $3;
273 /* I've had one report that the comma is optional. */
274 | acc_options acc_option
276 $$ = $1 | $2;
280 acc_option:
281 VIRTKEY
283 $$ = ACC_VIRTKEY;
285 | ASCII
287 /* This is just the absence of VIRTKEY. */
288 $$ = 0;
290 | NOINVERT
292 $$ = ACC_NOINVERT;
294 | SHIFT
296 $$ = ACC_SHIFT;
298 | CONTROL
300 $$ = ACC_CONTROL;
302 | ALT
304 $$ = ACC_ALT;
308 /* Bitmap resources. */
310 bitmap:
311 id BITMAP memflags_move file_name
313 define_bitmap ($1, &$3, $4);
314 if (yychar != YYEMPTY)
315 YYERROR;
316 rcparse_discard_strings ();
320 /* Cursor resources. */
322 cursor:
323 id CURSOR memflags_move_discard file_name
325 define_cursor ($1, &$3, $4);
326 if (yychar != YYEMPTY)
327 YYERROR;
328 rcparse_discard_strings ();
332 /* Dialog resources. */
334 dialog:
335 id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
336 cnumexpr
338 memset (&dialog, 0, sizeof dialog);
339 dialog.x = $5;
340 dialog.y = $6;
341 dialog.width = $7;
342 dialog.height = $8;
343 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
344 dialog.exstyle = $4;
345 dialog.menu.named = 1;
346 dialog.class.named = 1;
347 dialog.font = NULL;
348 dialog.ex = NULL;
349 dialog.controls = NULL;
350 sub_res_info = $3;
351 style = 0;
353 styles BEG controls END
355 define_dialog ($1, &sub_res_info, &dialog);
356 if (yychar != YYEMPTY)
357 YYERROR;
358 rcparse_discard_strings ();
360 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
361 cnumexpr
363 memset (&dialog, 0, sizeof dialog);
364 dialog.x = $5;
365 dialog.y = $6;
366 dialog.width = $7;
367 dialog.height = $8;
368 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
369 dialog.exstyle = $4;
370 dialog.menu.named = 1;
371 dialog.class.named = 1;
372 dialog.font = NULL;
373 dialog.ex = ((struct dialog_ex *)
374 res_alloc (sizeof (struct dialog_ex)));
375 memset (dialog.ex, 0, sizeof (struct dialog_ex));
376 dialog.controls = NULL;
377 sub_res_info = $3;
378 style = 0;
380 styles BEG controls END
382 define_dialog ($1, &sub_res_info, &dialog);
383 if (yychar != YYEMPTY)
384 YYERROR;
385 rcparse_discard_strings ();
387 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
388 cnumexpr cnumexpr
390 memset (&dialog, 0, sizeof dialog);
391 dialog.x = $5;
392 dialog.y = $6;
393 dialog.width = $7;
394 dialog.height = $8;
395 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
396 dialog.exstyle = $4;
397 dialog.menu.named = 1;
398 dialog.class.named = 1;
399 dialog.font = NULL;
400 dialog.ex = ((struct dialog_ex *)
401 res_alloc (sizeof (struct dialog_ex)));
402 memset (dialog.ex, 0, sizeof (struct dialog_ex));
403 dialog.ex->help = $9;
404 dialog.controls = NULL;
405 sub_res_info = $3;
406 style = 0;
408 styles BEG controls END
410 define_dialog ($1, &sub_res_info, &dialog);
411 if (yychar != YYEMPTY)
412 YYERROR;
413 rcparse_discard_strings ();
417 exstyle:
418 /* empty */
420 $$ = 0;
422 | EXSTYLE '=' numexpr
424 $$ = $3;
428 styles:
429 /* empty */
430 | styles CAPTION QUOTEDSTRING
432 dialog.style |= WS_CAPTION;
433 style |= WS_CAPTION;
434 unicode_from_ascii ((int *) NULL, &dialog.caption, $3);
436 | styles CLASS id
438 dialog.class = $3;
440 | styles STYLE
441 styleexpr
443 dialog.style = style;
445 | styles EXSTYLE numexpr
447 dialog.exstyle = $3;
449 | styles CLASS QUOTEDSTRING
451 res_string_to_id (& dialog.class, $3);
453 | styles FONT numexpr ',' QUOTEDSTRING
455 dialog.style |= DS_SETFONT;
456 style |= DS_SETFONT;
457 dialog.pointsize = $3;
458 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
459 if (dialog.ex != NULL)
461 dialog.ex->weight = 0;
462 dialog.ex->italic = 0;
463 dialog.ex->charset = 1;
466 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr
468 dialog.style |= DS_SETFONT;
469 style |= DS_SETFONT;
470 dialog.pointsize = $3;
471 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
472 if (dialog.ex == NULL)
473 rcparse_warning (_("extended FONT requires DIALOGEX"));
474 else
476 dialog.ex->weight = $6;
477 dialog.ex->italic = 0;
478 dialog.ex->charset = 1;
481 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr
483 dialog.style |= DS_SETFONT;
484 style |= DS_SETFONT;
485 dialog.pointsize = $3;
486 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
487 if (dialog.ex == NULL)
488 rcparse_warning (_("extended FONT requires DIALOGEX"));
489 else
491 dialog.ex->weight = $6;
492 dialog.ex->italic = $7;
493 dialog.ex->charset = 1;
496 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr cnumexpr
498 dialog.style |= DS_SETFONT;
499 style |= DS_SETFONT;
500 dialog.pointsize = $3;
501 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
502 if (dialog.ex == NULL)
503 rcparse_warning (_("extended FONT requires DIALOGEX"));
504 else
506 dialog.ex->weight = $6;
507 dialog.ex->italic = $7;
508 dialog.ex->charset = $8;
511 | styles MENU id
513 dialog.menu = $3;
515 | styles CHARACTERISTICS numexpr
517 sub_res_info.characteristics = $3;
519 | styles LANGUAGE numexpr cnumexpr
521 sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT);
523 | styles VERSIONK numexpr
525 sub_res_info.version = $3;
529 controls:
530 /* empty */
531 | controls control
533 struct dialog_control **pp;
535 for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
537 *pp = $2;
541 control:
542 AUTO3STATE optresidc
544 default_style = BS_AUTO3STATE | WS_TABSTOP;
545 base_style = BS_AUTO3STATE;
546 class = CTL_BUTTON;
547 res_text_field = $2;
549 control_params
551 $$ = $4;
553 | AUTOCHECKBOX optresidc
555 default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
556 base_style = BS_AUTOCHECKBOX;
557 class = CTL_BUTTON;
558 res_text_field = $2;
560 control_params
562 $$ = $4;
564 | AUTORADIOBUTTON optresidc
566 default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
567 base_style = BS_AUTORADIOBUTTON;
568 class = CTL_BUTTON;
569 res_text_field = $2;
571 control_params
573 $$ = $4;
575 | BEDIT optresidc
577 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
578 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
579 class = CTL_EDIT;
580 res_text_field = $2;
582 control_params
584 $$ = $4;
585 if (dialog.ex == NULL)
586 rcparse_warning (_("BEDIT requires DIALOGEX"));
587 res_string_to_id (&$$->class, "BEDIT");
589 | CHECKBOX optresidc
591 default_style = BS_CHECKBOX | WS_TABSTOP;
592 base_style = BS_CHECKBOX | WS_TABSTOP;
593 class = CTL_BUTTON;
594 res_text_field = $2;
596 control_params
598 $$ = $4;
600 | COMBOBOX
602 /* This is as per MSDN documentation. With some (???)
603 versions of MS rc.exe their is no default style. */
604 default_style = CBS_SIMPLE | WS_TABSTOP;
605 base_style = 0;
606 class = CTL_COMBOBOX;
607 res_text_field = res_null_text;
609 control_params
611 $$ = $3;
613 | CONTROL optresidc numexpr cnumexpr control_styleexpr cnumexpr
614 cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
616 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
617 if ($11 != NULL)
619 if (dialog.ex == NULL)
620 rcparse_warning (_("control data requires DIALOGEX"));
621 $$->data = $11;
624 | CONTROL optresidc numexpr cnumexpr control_styleexpr cnumexpr
625 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
627 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
628 if (dialog.ex == NULL)
629 rcparse_warning (_("help ID requires DIALOGEX"));
630 $$->help = $11;
631 $$->data = $12;
633 | CONTROL optresidc numexpr ',' QUOTEDSTRING control_styleexpr
634 cnumexpr cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
636 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
637 if ($12 != NULL)
639 if (dialog.ex == NULL)
640 rcparse_warning ("control data requires DIALOGEX");
641 $$->data = $12;
643 $$->class.named = 1;
644 unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5);
646 | CONTROL optresidc numexpr ',' QUOTEDSTRING control_styleexpr
647 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
649 $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
650 if (dialog.ex == NULL)
651 rcparse_warning ("help ID requires DIALOGEX");
652 $$->help = $12;
653 $$->data = $13;
654 $$->class.named = 1;
655 unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5);
657 | CTEXT optresidc
659 default_style = SS_CENTER | WS_GROUP;
660 base_style = SS_CENTER;
661 class = CTL_STATIC;
662 res_text_field = $2;
664 control_params
666 $$ = $4;
668 | DEFPUSHBUTTON optresidc
670 default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
671 base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
672 class = CTL_BUTTON;
673 res_text_field = $2;
675 control_params
677 $$ = $4;
679 | EDITTEXT
681 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
682 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
683 class = CTL_EDIT;
684 res_text_field = res_null_text;
686 control_params
688 $$ = $3;
690 | GROUPBOX optresidc
692 default_style = BS_GROUPBOX;
693 base_style = BS_GROUPBOX;
694 class = CTL_BUTTON;
695 res_text_field = $2;
697 control_params
699 $$ = $4;
701 | HEDIT optresidc
703 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
704 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
705 class = CTL_EDIT;
706 res_text_field = $2;
708 control_params
710 $$ = $4;
711 if (dialog.ex == NULL)
712 rcparse_warning (_("IEDIT requires DIALOGEX"));
713 res_string_to_id (&$$->class, "HEDIT");
715 | ICON resref numexpr cnumexpr cnumexpr opt_control_data
717 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $6,
718 dialog.ex);
720 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
721 opt_control_data
723 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $8,
724 dialog.ex);
726 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
727 icon_styleexpr optcnumexpr opt_control_data
729 $$ = define_icon_control ($2, $3, $4, $5, style, $9, 0, $10,
730 dialog.ex);
732 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
733 icon_styleexpr cnumexpr cnumexpr opt_control_data
735 $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11,
736 dialog.ex);
738 | IEDIT optresidc
740 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
741 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
742 class = CTL_EDIT;
743 res_text_field = $2;
745 control_params
747 $$ = $4;
748 if (dialog.ex == NULL)
749 rcparse_warning (_("IEDIT requires DIALOGEX"));
750 res_string_to_id (&$$->class, "IEDIT");
752 | LISTBOX
754 default_style = LBS_NOTIFY | WS_BORDER;
755 base_style = LBS_NOTIFY | WS_BORDER;
756 class = CTL_LISTBOX;
757 res_text_field = res_null_text;
759 control_params
761 $$ = $3;
763 | LTEXT optresidc
765 default_style = SS_LEFT | WS_GROUP;
766 base_style = SS_LEFT;
767 class = CTL_STATIC;
768 res_text_field = $2;
770 control_params
772 $$ = $4;
774 | PUSHBOX optresidc
776 default_style = BS_PUSHBOX | WS_TABSTOP;
777 base_style = BS_PUSHBOX;
778 class = CTL_BUTTON;
780 control_params
782 $$ = $4;
784 | PUSHBUTTON optresidc
786 default_style = BS_PUSHBUTTON | WS_TABSTOP;
787 base_style = BS_PUSHBUTTON | WS_TABSTOP;
788 class = CTL_BUTTON;
789 res_text_field = $2;
791 control_params
793 $$ = $4;
795 | RADIOBUTTON optresidc
797 default_style = BS_RADIOBUTTON | WS_TABSTOP;
798 base_style = BS_RADIOBUTTON;
799 class = CTL_BUTTON;
800 res_text_field = $2;
802 control_params
804 $$ = $4;
806 | RTEXT optresidc
808 default_style = SS_RIGHT | WS_GROUP;
809 base_style = SS_RIGHT;
810 class = CTL_STATIC;
811 res_text_field = $2;
813 control_params
815 $$ = $4;
817 | SCROLLBAR
819 default_style = SBS_HORZ;
820 base_style = 0;
821 class = CTL_SCROLLBAR;
822 res_text_field = res_null_text;
824 control_params
826 $$ = $3;
828 | STATE3 optresidc
830 default_style = BS_3STATE | WS_TABSTOP;
831 base_style = BS_3STATE;
832 class = CTL_BUTTON;
833 res_text_field = $2;
835 control_params
837 $$ = $4;
839 | USERBUTTON resref numexpr ',' numexpr ',' numexpr ','
840 numexpr ',' numexpr ','
841 { style = WS_CHILD | WS_VISIBLE; }
842 styleexpr optcnumexpr
844 $$ = define_control ($2, $3, $5, $7, $9, $11, CTL_BUTTON,
845 style, $15);
849 /* Parameters for a control. The static variables DEFAULT_STYLE,
850 BASE_STYLE, and CLASS must be initialized before this nonterminal
851 is used. DEFAULT_STYLE is the style to use if no style expression
852 is specified. BASE_STYLE is the base style to use if a style
853 expression is specified; the style expression modifies the base
854 style. CLASS is the class of the control. */
856 control_params:
857 numexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
859 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class,
860 default_style | WS_CHILD | WS_VISIBLE, 0);
861 if ($6 != NULL)
863 if (dialog.ex == NULL)
864 rcparse_warning (_("control data requires DIALOGEX"));
865 $$->data = $6;
868 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
869 control_params_styleexpr optcnumexpr opt_control_data
871 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
872 if ($8 != NULL)
874 if (dialog.ex == NULL)
875 rcparse_warning (_("control data requires DIALOGEX"));
876 $$->data = $8;
879 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
880 control_params_styleexpr cnumexpr cnumexpr opt_control_data
882 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
883 if (dialog.ex == NULL)
884 rcparse_warning (_("help ID requires DIALOGEX"));
885 $$->help = $8;
886 $$->data = $9;
890 optresidc:
891 /* empty */
893 res_string_to_id (&$$, "");
895 | posnumexpr ','
897 $$.named = 0;
898 $$.u.id = $1;
900 | QUOTEDSTRING
902 res_string_to_id (&$$, $1);
904 | QUOTEDSTRING ','
906 res_string_to_id (&$$, $1);
910 opt_control_data:
911 /* empty */
913 $$ = NULL;
915 | BEG optrcdata_data END
917 $$ = $2.first;
921 /* These only exist to parse a reduction out of a common case. */
923 control_styleexpr:
925 { style = WS_CHILD | WS_VISIBLE; }
926 styleexpr
929 icon_styleexpr:
931 { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
932 styleexpr
935 control_params_styleexpr:
937 { style = base_style | WS_CHILD | WS_VISIBLE; }
938 styleexpr
941 /* Font resources. */
943 font:
944 id FONT memflags_move_discard file_name
946 define_font ($1, &$3, $4);
947 if (yychar != YYEMPTY)
948 YYERROR;
949 rcparse_discard_strings ();
953 /* Icon resources. */
955 icon:
956 id ICON memflags_move_discard file_name
958 define_icon ($1, &$3, $4);
959 if (yychar != YYEMPTY)
960 YYERROR;
961 rcparse_discard_strings ();
965 /* Language command. This changes the static variable language, which
966 affects all subsequent resources. */
968 language:
969 LANGUAGE numexpr cnumexpr
971 language = $2 | ($3 << SUBLANG_SHIFT);
975 /* Menu resources. */
977 menu:
978 id MENU suboptions BEG menuitems END
980 define_menu ($1, &$3, $5);
981 if (yychar != YYEMPTY)
982 YYERROR;
983 rcparse_discard_strings ();
987 menuitems:
988 /* empty */
990 $$ = NULL;
992 | menuitems menuitem
994 if ($1 == NULL)
995 $$ = $2;
996 else
998 struct menuitem **pp;
1000 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1002 *pp = $2;
1003 $$ = $1;
1008 menuitem:
1009 MENUITEM QUOTEDSTRING cnumexpr menuitem_flags
1011 $$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
1013 | MENUITEM SEPARATOR
1015 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1017 | POPUP QUOTEDSTRING menuitem_flags BEG menuitems END
1019 $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
1023 menuitem_flags:
1024 /* empty */
1026 $$ = 0;
1028 | menuitem_flags ',' menuitem_flag
1030 $$ = $1 | $3;
1032 | menuitem_flags menuitem_flag
1034 $$ = $1 | $2;
1038 menuitem_flag:
1039 CHECKED
1041 $$ = MENUITEM_CHECKED;
1043 | GRAYED
1045 $$ = MENUITEM_GRAYED;
1047 | HELP
1049 $$ = MENUITEM_HELP;
1051 | INACTIVE
1053 $$ = MENUITEM_INACTIVE;
1055 | MENUBARBREAK
1057 $$ = MENUITEM_MENUBARBREAK;
1059 | MENUBREAK
1061 $$ = MENUITEM_MENUBREAK;
1065 /* Menuex resources. */
1067 menuex:
1068 id MENUEX suboptions BEG menuexitems END
1070 define_menu ($1, &$3, $5);
1071 if (yychar != YYEMPTY)
1072 YYERROR;
1073 rcparse_discard_strings ();
1077 menuexitems:
1078 /* empty */
1080 $$ = NULL;
1082 | menuexitems menuexitem
1084 if ($1 == NULL)
1085 $$ = $2;
1086 else
1088 struct menuitem **pp;
1090 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1092 *pp = $2;
1093 $$ = $1;
1098 menuexitem:
1099 MENUITEM QUOTEDSTRING
1101 $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
1103 | MENUITEM QUOTEDSTRING cnumexpr
1105 $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
1107 | MENUITEM QUOTEDSTRING cnumexpr cnumexpr optcnumexpr
1109 $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
1111 | MENUITEM SEPARATOR
1113 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
1115 | POPUP QUOTEDSTRING BEG menuexitems END
1117 $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
1119 | POPUP QUOTEDSTRING cnumexpr BEG menuexitems END
1121 $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
1123 | POPUP QUOTEDSTRING cnumexpr cnumexpr BEG menuexitems END
1125 $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
1127 | POPUP QUOTEDSTRING cnumexpr cnumexpr cnumexpr optcnumexpr
1128 BEG menuexitems END
1130 $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
1134 /* Messagetable resources. */
1136 messagetable:
1137 id MESSAGETABLE memflags_move file_name
1139 define_messagetable ($1, &$3, $4);
1140 if (yychar != YYEMPTY)
1141 YYERROR;
1142 rcparse_discard_strings ();
1146 /* Rcdata resources. */
1148 rcdata:
1149 id RCDATA suboptions BEG optrcdata_data END
1151 define_rcdata ($1, &$3, $5.first);
1152 if (yychar != YYEMPTY)
1153 YYERROR;
1154 rcparse_discard_strings ();
1156 | id RCDATA suboptions file_name
1158 define_rcdata_file ($1, &$3, $4);
1159 if (yychar != YYEMPTY)
1160 YYERROR;
1161 rcparse_discard_strings ();
1165 /* We use a different lexing algorithm, because rcdata strings may
1166 contain embedded null bytes, and we need to know the length to use. */
1168 optrcdata_data:
1170 rcparse_rcdata ();
1172 optrcdata_data_int
1174 rcparse_normal ();
1175 $$ = $2;
1179 optrcdata_data_int:
1180 /* empty */
1182 $$.first = NULL;
1183 $$.last = NULL;
1185 | rcdata_data
1187 $$ = $1;
1191 rcdata_data:
1192 SIZEDSTRING
1194 struct rcdata_item *ri;
1196 ri = define_rcdata_string ($1.s, $1.length);
1197 $$.first = ri;
1198 $$.last = ri;
1200 | sizednumexpr
1202 struct rcdata_item *ri;
1204 ri = define_rcdata_number ($1.val, $1.dword);
1205 $$.first = ri;
1206 $$.last = ri;
1208 | rcdata_data ',' SIZEDSTRING
1210 struct rcdata_item *ri;
1212 ri = define_rcdata_string ($3.s, $3.length);
1213 $$.first = $1.first;
1214 $1.last->next = ri;
1215 $$.last = ri;
1217 | rcdata_data ',' sizednumexpr
1219 struct rcdata_item *ri;
1221 ri = define_rcdata_number ($3.val, $3.dword);
1222 $$.first = $1.first;
1223 $1.last->next = ri;
1224 $$.last = ri;
1228 /* Stringtable resources. */
1230 stringtable:
1231 STRINGTABLE suboptions BEG
1232 { sub_res_info = $2; }
1233 string_data END
1236 string_data:
1237 /* empty */
1238 | string_data numexpr QUOTEDSTRING
1240 define_stringtable (&sub_res_info, $2, $3);
1241 if (yychar != YYEMPTY)
1242 YYERROR;
1243 rcparse_discard_strings ();
1245 | string_data numexpr ',' QUOTEDSTRING
1247 define_stringtable (&sub_res_info, $2, $4);
1248 if (yychar != YYEMPTY)
1249 YYERROR;
1250 rcparse_discard_strings ();
1254 /* User defined resources. We accept general suboptions in the
1255 file_name case to keep the parser happy. */
1257 user:
1258 id id suboptions BEG optrcdata_data END
1260 define_user_data ($1, $2, &$3, $5.first);
1261 if (yychar != YYEMPTY)
1262 YYERROR;
1263 rcparse_discard_strings ();
1265 | id id suboptions file_name
1267 define_user_file ($1, $2, &$3, $4);
1268 if (yychar != YYEMPTY)
1269 YYERROR;
1270 rcparse_discard_strings ();
1274 /* Versioninfo resources. */
1276 versioninfo:
1277 id VERSIONINFO fixedverinfo BEG verblocks END
1279 define_versioninfo ($1, language, $3, $5);
1280 if (yychar != YYEMPTY)
1281 YYERROR;
1282 rcparse_discard_strings ();
1286 fixedverinfo:
1287 /* empty */
1289 $$ = ((struct fixed_versioninfo *)
1290 res_alloc (sizeof (struct fixed_versioninfo)));
1291 memset ($$, 0, sizeof (struct fixed_versioninfo));
1293 | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
1295 $1->file_version_ms = ($3 << 16) | $4;
1296 $1->file_version_ls = ($5 << 16) | $6;
1297 $$ = $1;
1299 | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
1301 $1->product_version_ms = ($3 << 16) | $4;
1302 $1->product_version_ls = ($5 << 16) | $6;
1303 $$ = $1;
1305 | fixedverinfo FILEFLAGSMASK numexpr
1307 $1->file_flags_mask = $3;
1308 $$ = $1;
1310 | fixedverinfo FILEFLAGS numexpr
1312 $1->file_flags = $3;
1313 $$ = $1;
1315 | fixedverinfo FILEOS numexpr
1317 $1->file_os = $3;
1318 $$ = $1;
1320 | fixedverinfo FILETYPE numexpr
1322 $1->file_type = $3;
1323 $$ = $1;
1325 | fixedverinfo FILESUBTYPE numexpr
1327 $1->file_subtype = $3;
1328 $$ = $1;
1332 /* To handle verblocks successfully, the lexer handles BLOCK
1333 specially. A BLOCK "StringFileInfo" is returned as
1334 BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as
1335 BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK
1336 with the string as the value. */
1338 verblocks:
1339 /* empty */
1341 $$ = NULL;
1343 | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
1345 $$ = append_ver_stringfileinfo ($1, $4, $6);
1347 | verblocks BLOCKVARFILEINFO BEG VALUE QUOTEDSTRING vertrans END
1349 $$ = append_ver_varfileinfo ($1, $5, $6);
1353 vervals:
1354 /* empty */
1356 $$ = NULL;
1358 | vervals VALUE QUOTEDSTRING ',' QUOTEDSTRING
1360 $$ = append_verval ($1, $3, $5);
1364 vertrans:
1365 /* empty */
1367 $$ = NULL;
1369 | vertrans cnumexpr cnumexpr
1371 $$ = append_vertrans ($1, $2, $3);
1375 /* A resource ID. */
1378 posnumexpr
1380 $$.named = 0;
1381 $$.u.id = $1;
1383 | STRING
1385 char *copy, *s;
1387 /* It seems that resource ID's are forced to upper case. */
1388 copy = xstrdup ($1);
1389 for (s = copy; *s != '\0'; s++)
1390 *s = TOUPPER (*s);
1391 res_string_to_id (&$$, copy);
1392 free (copy);
1396 /* A resource reference. */
1398 resname:
1399 QUOTEDSTRING
1401 $$ = $1;
1403 | QUOTEDSTRING ','
1405 $$ = $1;
1407 | STRING ','
1409 $$ = $1;
1414 resref:
1415 posnumexpr ','
1417 $$.named = 0;
1418 $$.u.id = $1;
1420 | resname
1422 char *copy, *s;
1424 /* It seems that resource ID's are forced to upper case. */
1425 copy = xstrdup ($1);
1426 for (s = copy; *s != '\0'; s++)
1427 *s = TOUPPER (*s);
1428 res_string_to_id (&$$, copy);
1429 free (copy);
1433 /* Generic suboptions. These may appear before the BEGIN in any
1434 multiline statement. */
1436 suboptions:
1437 /* empty */
1439 memset (&$$, 0, sizeof (struct res_res_info));
1440 $$.language = language;
1441 /* FIXME: Is this the right default? */
1442 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1444 | suboptions memflag
1446 $$ = $1;
1447 $$.memflags |= $2.on;
1448 $$.memflags &=~ $2.off;
1450 | suboptions CHARACTERISTICS numexpr
1452 $$ = $1;
1453 $$.characteristics = $3;
1455 | suboptions LANGUAGE numexpr cnumexpr
1457 $$ = $1;
1458 $$.language = $3 | ($4 << SUBLANG_SHIFT);
1460 | suboptions VERSIONK numexpr
1462 $$ = $1;
1463 $$.version = $3;
1467 /* Memory flags which default to MOVEABLE and DISCARDABLE. */
1469 memflags_move_discard:
1470 /* empty */
1472 memset (&$$, 0, sizeof (struct res_res_info));
1473 $$.language = language;
1474 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
1476 | memflags_move_discard memflag
1478 $$ = $1;
1479 $$.memflags |= $2.on;
1480 $$.memflags &=~ $2.off;
1484 /* Memory flags which default to MOVEABLE. */
1486 memflags_move:
1487 /* empty */
1489 memset (&$$, 0, sizeof (struct res_res_info));
1490 $$.language = language;
1491 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1493 | memflags_move memflag
1495 $$ = $1;
1496 $$.memflags |= $2.on;
1497 $$.memflags &=~ $2.off;
1501 /* Memory flags. This returns a struct with two integers, because we
1502 sometimes want to set bits and we sometimes want to clear them. */
1504 memflag:
1505 MOVEABLE
1507 $$.on = MEMFLAG_MOVEABLE;
1508 $$.off = 0;
1510 | FIXED
1512 $$.on = 0;
1513 $$.off = MEMFLAG_MOVEABLE;
1515 | PURE
1517 $$.on = MEMFLAG_PURE;
1518 $$.off = 0;
1520 | IMPURE
1522 $$.on = 0;
1523 $$.off = MEMFLAG_PURE;
1525 | PRELOAD
1527 $$.on = MEMFLAG_PRELOAD;
1528 $$.off = 0;
1530 | LOADONCALL
1532 $$.on = 0;
1533 $$.off = MEMFLAG_PRELOAD;
1535 | DISCARDABLE
1537 $$.on = MEMFLAG_DISCARDABLE;
1538 $$.off = 0;
1542 /* A file name. */
1544 file_name:
1545 QUOTEDSTRING
1547 $$ = $1;
1549 | STRING
1551 $$ = $1;
1555 /* A style expression. This changes the static variable STYLE. We do
1556 it this way because rc appears to permit a style to be set to
1557 something like
1558 WS_GROUP | NOT WS_TABSTOP
1559 to mean that a default of WS_TABSTOP should be removed. Anything
1560 which wants to accept a style must first set STYLE to the default
1561 value. The styleexpr nonterminal will change STYLE as specified by
1562 the user. Note that we do not accept arbitrary expressions here,
1563 just numbers separated by '|'. */
1565 styleexpr:
1566 parennumber
1568 style |= $1;
1570 | NOT parennumber
1572 style &=~ $2;
1574 | styleexpr '|' parennumber
1576 style |= $3;
1578 | styleexpr '|' NOT parennumber
1580 style &=~ $4;
1584 parennumber:
1585 NUMBER
1587 $$ = $1.val;
1589 | '(' numexpr ')'
1591 $$ = $2;
1595 /* An optional expression with a leading comma. */
1597 optcnumexpr:
1598 /* empty */
1600 $$ = 0;
1602 | cnumexpr
1604 $$ = $1;
1608 /* An expression with a leading comma. */
1610 cnumexpr:
1611 ',' numexpr
1613 $$ = $2;
1617 /* A possibly negated numeric expression. */
1619 numexpr:
1620 sizednumexpr
1622 $$ = $1.val;
1626 /* A possibly negated expression with a size. */
1628 sizednumexpr:
1629 NUMBER
1631 $$ = $1;
1633 | '(' sizednumexpr ')'
1635 $$ = $2;
1637 | '~' sizednumexpr %prec '~'
1639 $$.val = ~ $2.val;
1640 $$.dword = $2.dword;
1642 | '-' sizednumexpr %prec NEG
1644 $$.val = - $2.val;
1645 $$.dword = $2.dword;
1647 | sizednumexpr '*' sizednumexpr
1649 $$.val = $1.val * $3.val;
1650 $$.dword = $1.dword || $3.dword;
1652 | sizednumexpr '/' sizednumexpr
1654 $$.val = $1.val / $3.val;
1655 $$.dword = $1.dword || $3.dword;
1657 | sizednumexpr '%' sizednumexpr
1659 $$.val = $1.val % $3.val;
1660 $$.dword = $1.dword || $3.dword;
1662 | sizednumexpr '+' sizednumexpr
1664 $$.val = $1.val + $3.val;
1665 $$.dword = $1.dword || $3.dword;
1667 | sizednumexpr '-' sizednumexpr
1669 $$.val = $1.val - $3.val;
1670 $$.dword = $1.dword || $3.dword;
1672 | sizednumexpr '&' sizednumexpr
1674 $$.val = $1.val & $3.val;
1675 $$.dword = $1.dword || $3.dword;
1677 | sizednumexpr '^' sizednumexpr
1679 $$.val = $1.val ^ $3.val;
1680 $$.dword = $1.dword || $3.dword;
1682 | sizednumexpr '|' sizednumexpr
1684 $$.val = $1.val | $3.val;
1685 $$.dword = $1.dword || $3.dword;
1689 /* An expression with a leading comma which does not use unary
1690 negation. */
1692 cposnumexpr:
1693 ',' posnumexpr
1695 $$ = $2;
1699 /* An expression which does not use unary negation. */
1701 posnumexpr:
1702 sizedposnumexpr
1704 $$ = $1.val;
1708 /* An expression which does not use unary negation. We separate unary
1709 negation to avoid parsing conflicts when two numeric expressions
1710 appear consecutively. */
1712 sizedposnumexpr:
1713 NUMBER
1715 $$ = $1;
1717 | '(' sizednumexpr ')'
1719 $$ = $2;
1721 | '~' sizednumexpr %prec '~'
1723 $$.val = ~ $2.val;
1724 $$.dword = $2.dword;
1726 | sizedposnumexpr '*' sizednumexpr
1728 $$.val = $1.val * $3.val;
1729 $$.dword = $1.dword || $3.dword;
1731 | sizedposnumexpr '/' sizednumexpr
1733 $$.val = $1.val / $3.val;
1734 $$.dword = $1.dword || $3.dword;
1736 | sizedposnumexpr '%' sizednumexpr
1738 $$.val = $1.val % $3.val;
1739 $$.dword = $1.dword || $3.dword;
1741 | sizedposnumexpr '+' sizednumexpr
1743 $$.val = $1.val + $3.val;
1744 $$.dword = $1.dword || $3.dword;
1746 | sizedposnumexpr '-' sizednumexpr
1748 $$.val = $1.val - $3.val;
1749 $$.dword = $1.dword || $3.dword;
1751 | sizedposnumexpr '&' sizednumexpr
1753 $$.val = $1.val & $3.val;
1754 $$.dword = $1.dword || $3.dword;
1756 | sizedposnumexpr '^' sizednumexpr
1758 $$.val = $1.val ^ $3.val;
1759 $$.dword = $1.dword || $3.dword;
1761 | sizedposnumexpr '|' sizednumexpr
1763 $$.val = $1.val | $3.val;
1764 $$.dword = $1.dword || $3.dword;
1770 /* Set the language from the command line. */
1772 void
1773 rcparse_set_language (int lang)
1775 language = lang;