Add new function: non_fatal().
[deliverable/binutils-gdb.git] / binutils / rcparse.y
CommitLineData
1d371d35
ILT
1%{ /* rcparse.y -- parser for Windows rc files
2 Copyright 1997 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support.
4
5 This file is part of GNU Binutils.
6
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.
11
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.
16
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. */
21
22/* This is a parser for Windows rc files. It is based on the parser
23 by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */
24
25#include "bfd.h"
26#include "bucomm.h"
27#include "libiberty.h"
28#include "windres.h"
29
662cc41e 30#include <ctype.h>
1d371d35 31
662cc41e
ILT
32/* The current language. */
33
34static unsigned short language;
1d371d35
ILT
35
36/* The resource information during a sub statement. */
37
38static struct res_res_info sub_res_info;
39
40/* Dialog information. This is built by the nonterminals styles and
41 controls. */
42
43static struct dialog dialog;
44
45/* This is used when building a style. It is modified by the
46 nonterminal styleexpr. */
47
48static unsigned long style;
49
50/* These are used when building a control. They are set before using
51 control_params. */
52
53static unsigned long base_style;
54static unsigned long default_style;
55static unsigned long class;
56
57%}
58
59%union
60{
61 struct accelerator acc;
62 struct accelerator *pacc;
63 struct dialog_control *dialog_control;
64 struct menuitem *menuitem;
662cc41e
ILT
65 struct
66 {
67 struct rcdata_item *first;
68 struct rcdata_item *last;
69 } rcdata;
70 struct rcdata_item *rcdata_item;
1d371d35
ILT
71 struct stringtable_data *stringtable;
72 struct fixed_versioninfo *fixver;
73 struct ver_info *verinfo;
74 struct ver_stringinfo *verstring;
75 struct ver_varinfo *vervar;
76 struct res_id id;
77 struct res_res_info res_info;
78 struct
79 {
80 unsigned short on;
81 unsigned short off;
82 } memflags;
83 struct
84 {
85 unsigned long val;
86 /* Nonzero if this number was explicitly specified as long. */
87 int dword;
88 } i;
89 unsigned long il;
90 unsigned short is;
662cc41e
ILT
91 const char *s;
92 struct
93 {
94 unsigned long length;
95 const char *s;
96 } ss;
1d371d35
ILT
97};
98
99%token BEG END
100%token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
101%token BITMAP
102%token CURSOR
103%token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
104%token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
105%token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
106%token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
107%token BEDIT HEDIT IEDIT
108%token FONT
109%token ICON
110%token LANGUAGE CHARACTERISTICS VERSION
111%token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
112%token MENUBARBREAK MENUBREAK
113%token MESSAGETABLE
114%token RCDATA
115%token STRINGTABLE
116%token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
117%token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
118%token VALUE
119%token <s> BLOCK
120%token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
121%token NOT
122%token <s> QUOTEDSTRING STRING
123%token <i> NUMBER
662cc41e 124%token <ss> SIZEDSTRING
1d371d35
ILT
125
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
662cc41e
ILT
130%type <rcdata> optrcdata_data optrcdata_data_int rcdata_data
131%type <rcdata_item> opt_control_data
1d371d35
ILT
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
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
143%type <i> sizednumexpr sizedposnumexpr
144
145%left '|'
146%left '^'
147%left '&'
148%left '+' '-'
149%left '*' '/' '%'
150%right '~' NEG
151
152%%
153
154input:
155 /* empty */
662cc41e
ILT
156 | input newcmd accelerator
157 | input newcmd bitmap
158 | input newcmd cursor
159 | input newcmd dialog
160 | input newcmd font
161 | input newcmd icon
162 | input newcmd language
163 | input newcmd menu
164 | input newcmd menuex
165 | input newcmd messagetable
166 | input newcmd rcdata
167 | input newcmd stringtable
168 | input newcmd user
169 | input newcmd versioninfo
170 ;
171
172newcmd:
173 /* empty */
174 {
175 rcparse_discard_strings ();
176 }
1d371d35
ILT
177 ;
178
179/* Accelerator resources. */
180
181accelerator:
182 id ACCELERATORS suboptions BEG acc_entries END
183 {
184 define_accelerator ($1, &$3, $5);
185 }
186 ;
187
188acc_entries:
189 /* empty */
190 {
191 $$ = NULL;
192 }
193 | acc_entries acc_entry
194 {
195 struct accelerator *a;
196
662cc41e 197 a = (struct accelerator *) res_alloc (sizeof *a);
1d371d35
ILT
198 *a = $2;
199 if ($1 == NULL)
200 $$ = a;
201 else
202 {
203 struct accelerator **pp;
204
205 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
206 ;
207 *pp = a;
208 $$ = $1;
209 }
210 }
211 ;
212
213acc_entry:
214 acc_event cposnumexpr
215 {
216 $$ = $1;
217 $$.id = $2;
218 }
219 | acc_event cposnumexpr ',' acc_options
220 {
221 $$ = $1;
222 $$.id = $2;
223 $$.flags |= $4;
224 }
225 ;
226
227acc_event:
228 QUOTEDSTRING
229 {
662cc41e 230 const char *s = $1;
1d371d35
ILT
231
232 $$.id = 0;
233 if (*s != '^')
234 $$.flags = 0;
235 else
236 {
237 $$.flags = ACC_CONTROL;
238 ++s;
239 }
240 $$.key = *s;
241 if (s[1] != '\0')
242 rcparse_warning ("accelerator should only be one character");
1d371d35
ILT
243 }
244 | posnumexpr
245 {
246 $$.flags = 0;
247 $$.id = 0;
248 $$.key = $1;
249 }
250 ;
251
252acc_options:
253 acc_option
254 {
255 $$ = $1;
256 }
257 | acc_options ',' acc_option
258 {
259 $$ = $1 | $3;
260 }
261 ;
262
263acc_option:
264 VIRTKEY
265 {
266 $$ = ACC_VIRTKEY;
267 }
268 | ASCII
269 {
270 /* This is just the absence of VIRTKEY. */
271 $$ = 0;
272 }
273 | NOINVERT
274 {
275 $$ = ACC_NOINVERT;
276 }
277 | SHIFT
278 {
279 $$ = ACC_SHIFT;
280 }
281 | CONTROL
282 {
283 $$ = ACC_CONTROL;
284 }
285 | ALT
286 {
287 $$ = ACC_ALT;
288 }
289 ;
290
291/* Bitmap resources. */
292
293bitmap:
294 id BITMAP memflags_move file_name
295 {
296 define_bitmap ($1, &$3, $4);
1d371d35
ILT
297 }
298 ;
299
300/* Cursor resources. */
301
302cursor:
303 id CURSOR memflags_move_discard file_name
304 {
305 define_cursor ($1, &$3, $4);
1d371d35
ILT
306 }
307 ;
308
309/* Dialog resources. */
310
311dialog:
312 id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
313 cnumexpr
314 {
315 memset (&dialog, 0, sizeof dialog);
316 dialog.x = $5;
317 dialog.y = $6;
318 dialog.width = $7;
319 dialog.height = $8;
320 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
321 dialog.exstyle = $4;
e42872a2
ILT
322 dialog.menu.named = 1;
323 dialog.class.named = 1;
1d371d35
ILT
324 dialog.font = NULL;
325 dialog.ex = NULL;
326 dialog.controls = NULL;
327 sub_res_info = $3;
328 }
329 styles BEG controls END
330 {
331 define_dialog ($1, &sub_res_info, &dialog);
332 }
333 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
334 cnumexpr
335 {
336 memset (&dialog, 0, sizeof dialog);
337 dialog.x = $5;
338 dialog.y = $6;
339 dialog.width = $7;
340 dialog.height = $8;
341 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
342 dialog.exstyle = $4;
e42872a2
ILT
343 dialog.menu.named = 1;
344 dialog.class.named = 1;
1d371d35
ILT
345 dialog.font = NULL;
346 dialog.ex = ((struct dialog_ex *)
662cc41e 347 res_alloc (sizeof (struct dialog_ex)));
1d371d35
ILT
348 memset (dialog.ex, 0, sizeof (struct dialog_ex));
349 dialog.controls = NULL;
350 sub_res_info = $3;
351 }
352 styles BEG controls END
353 {
354 define_dialog ($1, &sub_res_info, &dialog);
355 }
356 | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
357 cnumexpr cnumexpr
358 {
359 memset (&dialog, 0, sizeof dialog);
360 dialog.x = $5;
361 dialog.y = $6;
362 dialog.width = $7;
363 dialog.height = $8;
364 dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
365 dialog.exstyle = $4;
e42872a2
ILT
366 dialog.menu.named = 1;
367 dialog.class.named = 1;
1d371d35
ILT
368 dialog.font = NULL;
369 dialog.ex = ((struct dialog_ex *)
662cc41e 370 res_alloc (sizeof (struct dialog_ex)));
1d371d35
ILT
371 memset (dialog.ex, 0, sizeof (struct dialog_ex));
372 dialog.ex->help = $9;
373 dialog.controls = NULL;
374 sub_res_info = $3;
375 }
376 styles BEG controls END
377 {
378 define_dialog ($1, &sub_res_info, &dialog);
379 }
380 ;
381
382exstyle:
383 /* empty */
384 {
385 $$ = 0;
386 }
387 | EXSTYLE '=' numexpr
388 {
389 $$ = $3;
390 }
391 ;
392
393styles:
394 /* empty */
395 | styles CAPTION QUOTEDSTRING
396 {
662cc41e 397 unicode_from_ascii ((int *) NULL, &dialog.caption, $3);
1d371d35
ILT
398 }
399 | styles CLASS id
400 {
401 dialog.class = $3;
402 }
403 | styles STYLE
a89c9be0 404 { style = dialog.style; }
1d371d35
ILT
405 styleexpr
406 {
407 dialog.style = style;
408 }
409 | styles EXSTYLE numexpr
410 {
411 dialog.exstyle = $3;
412 }
413 | styles FONT numexpr ',' QUOTEDSTRING
414 {
e42872a2 415 dialog.style |= DS_SETFONT;
1d371d35 416 dialog.pointsize = $3;
662cc41e 417 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
1d371d35
ILT
418 }
419 | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr
420 {
e42872a2 421 dialog.style |= DS_SETFONT;
1d371d35 422 dialog.pointsize = $3;
662cc41e 423 unicode_from_ascii ((int *) NULL, &dialog.font, $5);
1d371d35
ILT
424 if (dialog.ex == NULL)
425 rcparse_warning ("extended FONT requires DIALOGEX");
426 else
427 {
428 dialog.ex->weight = $6;
429 dialog.ex->italic = $7;
430 }
431 }
432 | styles MENU id
433 {
434 dialog.menu = $3;
435 }
436 | styles CHARACTERISTICS numexpr
437 {
438 sub_res_info.characteristics = $3;
439 }
440 | styles LANGUAGE numexpr cnumexpr
441 {
442 sub_res_info.language = $3 | ($4 << 8);
443 }
444 | styles VERSION numexpr
445 {
446 sub_res_info.version = $3;
447 }
448 ;
449
450controls:
451 /* empty */
452 | controls control
453 {
454 struct dialog_control **pp;
455
456 for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
457 ;
458 *pp = $2;
459 }
460 ;
461
462control:
463 AUTO3STATE
464 {
465 default_style = BS_AUTO3STATE | WS_TABSTOP;
466 base_style = BS_AUTO3STATE;
467 class = CTL_BUTTON;
468 }
469 control_params
470 {
471 $$ = $3;
472 }
473 | AUTOCHECKBOX
474 {
475 default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
476 base_style = BS_AUTOCHECKBOX;
477 class = CTL_BUTTON;
478 }
479 control_params
480 {
481 $$ = $3;
482 }
483 | AUTORADIOBUTTON
484 {
485 default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
486 base_style = BS_AUTORADIOBUTTON;
487 class = CTL_BUTTON;
488 }
489 control_params
490 {
491 $$ = $3;
492 }
493 | BEDIT
494 {
495 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
496 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
497 class = CTL_EDIT;
498 }
499 control_params
500 {
501 $$ = $3;
502 if (dialog.ex == NULL)
503 rcparse_warning ("IEDIT requires DIALOGEX");
504 res_string_to_id (&$$->class, "BEDIT");
505 }
506 | CHECKBOX
507 {
508 default_style = BS_CHECKBOX | WS_TABSTOP;
509 base_style = BS_CHECKBOX | WS_TABSTOP;
510 class = CTL_BUTTON;
511 }
512 control_params
513 {
514 $$ = $3;
515 }
516 | COMBOBOX
517 {
518 default_style = CBS_SIMPLE | WS_TABSTOP;
519 base_style = 0;
520 class = CTL_COMBOBOX;
521 }
522 control_params
523 {
524 $$ = $3;
525 }
526 | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
527 cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
528 {
529 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
530 if ($11 != NULL)
531 {
532 if (dialog.ex == NULL)
533 rcparse_warning ("control data requires DIALOGEX");
534 $$->data = $11;
535 }
536 }
537 | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
538 cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
539 {
540 $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
541 if (dialog.ex == NULL)
542 rcparse_warning ("help ID requires DIALOGEX");
543 $$->help = $11;
544 $$->data = $12;
545 }
546 | CTEXT
547 {
548 default_style = SS_CENTER | WS_GROUP;
549 base_style = SS_CENTER;
550 class = CTL_STATIC;
551 }
552 control_params
553 {
554 $$ = $3;
555 }
556 | DEFPUSHBUTTON
557 {
558 default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
559 base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
560 class = CTL_BUTTON;
561 }
562 control_params
563 {
564 $$ = $3;
565 }
566 | EDITTEXT
567 {
568 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
569 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
570 class = CTL_EDIT;
571 }
572 control_params
573 {
574 $$ = $3;
575 }
576 | GROUPBOX
577 {
578 default_style = BS_GROUPBOX;
579 base_style = BS_GROUPBOX;
580 class = CTL_BUTTON;
581 }
582 control_params
583 {
584 $$ = $3;
585 }
586 | HEDIT
587 {
588 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
589 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
590 class = CTL_EDIT;
591 }
592 control_params
593 {
594 $$ = $3;
595 if (dialog.ex == NULL)
596 rcparse_warning ("IEDIT requires DIALOGEX");
597 res_string_to_id (&$$->class, "HEDIT");
598 }
599 | ICON optstringc numexpr cnumexpr cnumexpr opt_control_data
600 {
601 $$ = define_control ($2, $3, $4, $5, 0, 0, CTL_STATIC,
602 SS_ICON | WS_CHILD | WS_VISIBLE, 0);
603 if ($6 != NULL)
604 {
605 if (dialog.ex == NULL)
606 rcparse_warning ("control data requires DIALOGEX");
607 $$->data = $6;
608 }
609 }
610 | ICON optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
611 icon_styleexpr optcnumexpr opt_control_data
612 {
613 $$ = define_control ($2, $3, $4, $5, $6, $7, CTL_STATIC,
614 style, $9);
615 if ($10 != NULL)
616 {
617 if (dialog.ex == NULL)
618 rcparse_warning ("control data requires DIALOGEX");
619 $$->data = $10;
620 }
621 }
622 | ICON optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
623 icon_styleexpr cnumexpr cnumexpr opt_control_data
624 {
625 $$ = define_control ($2, $3, $4, $5, $6, $7, CTL_STATIC,
626 style, $9);
627 if (dialog.ex == NULL)
628 rcparse_warning ("help ID requires DIALOGEX");
629 $$->help = $10;
630 $$->data = $11;
631 }
632 | IEDIT
633 {
634 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
635 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
636 class = CTL_EDIT;
637 }
638 control_params
639 {
640 $$ = $3;
641 if (dialog.ex == NULL)
642 rcparse_warning ("IEDIT requires DIALOGEX");
643 res_string_to_id (&$$->class, "IEDIT");
644 }
645 | LISTBOX
646 {
647 default_style = LBS_NOTIFY | WS_BORDER;
648 base_style = LBS_NOTIFY | WS_BORDER;
649 class = CTL_LISTBOX;
650 }
651 control_params
652 {
653 $$ = $3;
654 }
655 | LTEXT
656 {
657 default_style = SS_LEFT | WS_GROUP;
658 base_style = SS_LEFT;
659 class = CTL_STATIC;
660 }
661 control_params
662 {
663 $$ = $3;
664 }
665 | PUSHBOX
666 {
667 default_style = BS_PUSHBOX | WS_TABSTOP;
668 base_style = BS_PUSHBOX;
669 class = CTL_BUTTON;
670 }
671 control_params
672 {
673 $$ = $3;
674 }
675 | PUSHBUTTON
676 {
677 default_style = BS_PUSHBUTTON | WS_TABSTOP;
678 base_style = BS_PUSHBUTTON | WS_TABSTOP;
679 class = CTL_BUTTON;
680 }
681 control_params
682 {
683 $$ = $3;
684 }
685 | RADIOBUTTON
686 {
687 default_style = BS_RADIOBUTTON | WS_TABSTOP;
688 base_style = BS_RADIOBUTTON;
689 class = CTL_BUTTON;
690 }
691 control_params
692 {
693 $$ = $3;
694 }
695 | RTEXT
696 {
697 default_style = SS_RIGHT | WS_GROUP;
698 base_style = SS_RIGHT;
699 class = CTL_STATIC;
700 }
701 control_params
702 {
703 $$ = $3;
704 }
705 | SCROLLBAR
706 {
707 default_style = SBS_HORZ;
708 base_style = 0;
709 class = CTL_SCROLLBAR;
710 }
711 control_params
712 {
713 $$ = $3;
714 }
715 | STATE3
716 {
717 default_style = BS_3STATE | WS_TABSTOP;
718 base_style = BS_3STATE;
719 class = CTL_BUTTON;
720 }
721 control_params
722 {
723 $$ = $3;
724 }
725 | USERBUTTON QUOTEDSTRING ',' numexpr ',' numexpr ',' numexpr ','
726 numexpr ',' numexpr ','
a89c9be0 727 { style = WS_CHILD | WS_VISIBLE; }
1d371d35
ILT
728 styleexpr optcnumexpr
729 {
730 $$ = define_control ($2, $4, $6, $8, $10, $12, CTL_BUTTON,
731 style, $16);
732 }
733 ;
734
735/* Parameters for a control. The static variables DEFAULT_STYLE,
736 BASE_STYLE, and CLASS must be initialized before this nonterminal
737 is used. DEFAULT_STYLE is the style to use if no style expression
738 is specified. BASE_STYLE is the base style to use if a style
739 expression is specified; the style expression modifies the base
740 style. CLASS is the class of the control. */
741
742control_params:
743 optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
744 opt_control_data
745 {
746 $$ = define_control ($1, $2, $3, $4, $5, $6, class,
747 default_style | WS_CHILD | WS_VISIBLE, 0);
748 if ($7 != NULL)
749 {
750 if (dialog.ex == NULL)
751 rcparse_warning ("control data requires DIALOGEX");
752 $$->data = $7;
753 }
754 }
755 | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
756 control_params_styleexpr optcnumexpr opt_control_data
757 {
758 $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
759 if ($9 != NULL)
760 {
761 if (dialog.ex == NULL)
762 rcparse_warning ("control data requires DIALOGEX");
763 $$->data = $9;
764 }
765 }
766 | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
767 control_params_styleexpr cnumexpr cnumexpr opt_control_data
768 {
769 $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
770 if (dialog.ex == NULL)
771 rcparse_warning ("help ID requires DIALOGEX");
772 $$->help = $9;
773 $$->data = $10;
774 }
775 ;
776
777optstringc:
778 /* empty */
779 {
780 $$ = NULL;
781 }
782 | QUOTEDSTRING ','
783 {
784 $$ = $1;
785 }
786 ;
787
788opt_control_data:
789 /* empty */
790 {
791 $$ = NULL;
792 }
793 | BEG optrcdata_data END
794 {
662cc41e 795 $$ = $2.first;
1d371d35
ILT
796 }
797 ;
798
799/* These only exist to parse a reduction out of a common case. */
800
801control_styleexpr:
802 ','
803 { style = WS_CHILD | WS_VISIBLE; }
804 styleexpr
805 ;
806
807icon_styleexpr:
808 ','
809 { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
810 styleexpr
811 ;
812
813control_params_styleexpr:
814 ','
815 { style = base_style | WS_CHILD | WS_VISIBLE; }
816 styleexpr
817 ;
818
819/* Font resources. */
820
821font:
822 id FONT memflags_move_discard file_name
823 {
824 define_font ($1, &$3, $4);
1d371d35
ILT
825 }
826 ;
827
828/* Icon resources. */
829
830icon:
831 id ICON memflags_move_discard file_name
832 {
833 define_icon ($1, &$3, $4);
1d371d35
ILT
834 }
835 ;
836
837/* Language command. This changes the static variable language, which
838 affects all subsequent resources. */
839
840language:
841 LANGUAGE numexpr cnumexpr
842 {
843 language = $2 | ($3 << 8);
844 }
845 ;
846
847/* Menu resources. */
848
849menu:
850 id MENU suboptions BEG menuitems END
851 {
852 define_menu ($1, &$3, $5);
853 }
854 ;
855
856menuitems:
857 /* empty */
858 {
859 $$ = NULL;
860 }
861 | menuitems menuitem
862 {
863 if ($1 == NULL)
864 $$ = $2;
865 else
866 {
867 struct menuitem **pp;
868
869 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
870 ;
871 *pp = $2;
872 $$ = $1;
873 }
874 }
875 ;
876
877menuitem:
878 MENUITEM QUOTEDSTRING cnumexpr menuitem_flags
879 {
880 $$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
881 }
882 | MENUITEM SEPARATOR
883 {
884 $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
885 }
886 | POPUP QUOTEDSTRING menuitem_flags BEG menuitems END
887 {
888 $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
889 }
890 ;
891
892menuitem_flags:
893 /* empty */
894 {
895 $$ = 0;
896 }
897 | menuitem_flags ',' menuitem_flag
898 {
899 $$ = $1 | $3;
900 }
901 | menuitem_flags menuitem_flag
902 {
903 $$ = $1 | $2;
904 }
905 ;
906
907menuitem_flag:
908 CHECKED
909 {
910 $$ = MENUITEM_CHECKED;
911 }
912 | GRAYED
913 {
914 $$ = MENUITEM_GRAYED;
915 }
916 | HELP
917 {
918 $$ = MENUITEM_HELP;
919 }
920 | INACTIVE
921 {
922 $$ = MENUITEM_INACTIVE;
923 }
924 | MENUBARBREAK
925 {
926 $$ = MENUITEM_MENUBARBREAK;
927 }
928 | MENUBREAK
929 {
930 $$ = MENUITEM_MENUBREAK;
931 }
932 ;
933
934/* Menuex resources. */
935
936menuex:
937 id MENUEX suboptions BEG menuexitems END
938 {
939 define_menu ($1, &$3, $5);
940 }
941 ;
942
943menuexitems:
944 /* empty */
945 {
946 $$ = NULL;
947 }
948 | menuexitems menuexitem
949 {
950 if ($1 == NULL)
951 $$ = $2;
952 else
953 {
954 struct menuitem **pp;
955
956 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
957 ;
958 *pp = $2;
959 $$ = $1;
960 }
961 }
962 ;
963
964menuexitem:
965 MENUITEM QUOTEDSTRING
966 {
967 $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
968 }
969 | MENUITEM QUOTEDSTRING cnumexpr
970 {
971 $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
972 }
973 | MENUITEM QUOTEDSTRING cnumexpr cnumexpr optcnumexpr
974 {
975 $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
976 }
977 | POPUP QUOTEDSTRING BEG menuexitems END
978 {
979 $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
980 }
981 | POPUP QUOTEDSTRING cnumexpr BEG menuexitems END
982 {
983 $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
984 }
985 | POPUP QUOTEDSTRING cnumexpr cnumexpr BEG menuexitems END
986 {
987 $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
988 }
989 | POPUP QUOTEDSTRING cnumexpr cnumexpr cnumexpr optcnumexpr
990 BEG menuexitems END
991 {
992 $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
993 }
994 ;
995
996/* Messagetable resources. */
997
998messagetable:
999 id MESSAGETABLE memflags_move file_name
1000 {
1001 define_messagetable ($1, &$3, $4);
1d371d35
ILT
1002 }
1003 ;
1004
1005/* Rcdata resources. */
1006
1007rcdata:
1008 id RCDATA suboptions BEG optrcdata_data END
1009 {
662cc41e 1010 define_rcdata ($1, &$3, $5.first);
1d371d35
ILT
1011 }
1012 ;
1013
662cc41e
ILT
1014/* We use a different lexing algorithm, because rcdata strings may
1015 contain embedded null bytes, and we need to know the length to use. */
1016
1d371d35 1017optrcdata_data:
662cc41e
ILT
1018 {
1019 rcparse_rcdata ();
1020 }
1021 optrcdata_data_int
1022 {
1023 rcparse_normal ();
1024 $$ = $2;
1025 }
1026 ;
1027
1028optrcdata_data_int:
1d371d35
ILT
1029 /* empty */
1030 {
662cc41e
ILT
1031 $$.first = NULL;
1032 $$.last = NULL;
1d371d35
ILT
1033 }
1034 | rcdata_data
1035 {
1036 $$ = $1;
1037 }
1038 ;
1039
1040rcdata_data:
662cc41e 1041 SIZEDSTRING
1d371d35 1042 {
662cc41e
ILT
1043 struct rcdata_item *ri;
1044
1045 ri = define_rcdata_string ($1.s, $1.length);
1046 $$.first = ri;
1047 $$.last = ri;
1d371d35
ILT
1048 }
1049 | sizednumexpr
1050 {
662cc41e
ILT
1051 struct rcdata_item *ri;
1052
1053 ri = define_rcdata_number ($1.val, $1.dword);
1054 $$.first = ri;
1055 $$.last = ri;
1d371d35 1056 }
662cc41e 1057 | rcdata_data ',' SIZEDSTRING
1d371d35 1058 {
662cc41e
ILT
1059 struct rcdata_item *ri;
1060
1061 ri = define_rcdata_string ($3.s, $3.length);
1062 $$.first = $1.first;
1063 $1.last->next = ri;
1064 $$.last = ri;
1d371d35
ILT
1065 }
1066 | rcdata_data ',' sizednumexpr
1067 {
662cc41e
ILT
1068 struct rcdata_item *ri;
1069
1070 ri = define_rcdata_number ($3.val, $3.dword);
1071 $$.first = $1.first;
1072 $1.last->next = ri;
1073 $$.last = ri;
1d371d35
ILT
1074 }
1075 ;
1076
1077/* Stringtable resources. */
1078
1079stringtable:
1080 STRINGTABLE suboptions BEG
1081 { sub_res_info = $2; }
1082 string_data END
1083 ;
1084
1085string_data:
1086 /* empty */
1087 | string_data numexpr QUOTEDSTRING
1088 {
1089 define_stringtable (&sub_res_info, $2, $3);
1090 }
1091 | string_data numexpr ',' QUOTEDSTRING
1092 {
1093 define_stringtable (&sub_res_info, $2, $4);
1094 }
1095 ;
1096
1097/* User defined resources. We accept general suboptions in the
1098 file_name case to keep the parser happy. */
1099
1100user:
662cc41e 1101 id id suboptions BEG optrcdata_data END
1d371d35 1102 {
662cc41e 1103 define_user_data ($1, $2, &$3, $5.first);
1d371d35
ILT
1104 }
1105 | id id suboptions file_name
1106 {
1107 define_user_file ($1, $2, &$3, $4);
1d371d35
ILT
1108 }
1109 ;
1110
1111/* Versioninfo resources. */
1112
1113versioninfo:
1114 id VERSIONINFO fixedverinfo BEG verblocks END
1115 {
1116 define_versioninfo ($1, language, $3, $5);
1117 }
1118 ;
1119
1120fixedverinfo:
1121 /* empty */
1122 {
1123 $$ = ((struct fixed_versioninfo *)
662cc41e 1124 res_alloc (sizeof (struct fixed_versioninfo)));
1d371d35
ILT
1125 memset ($$, 0, sizeof (struct fixed_versioninfo));
1126 }
1127 | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
1128 {
1129 $1->file_version_ms = ($3 << 16) | $4;
1130 $1->file_version_ls = ($5 << 16) | $6;
1131 $$ = $1;
1132 }
1133 | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
1134 {
1135 $1->product_version_ms = ($3 << 16) | $4;
1136 $1->product_version_ls = ($5 << 16) | $6;
1137 $$ = $1;
1138 }
1139 | fixedverinfo FILEFLAGSMASK numexpr
1140 {
1141 $1->file_flags_mask = $3;
1142 $$ = $1;
1143 }
1144 | fixedverinfo FILEFLAGS numexpr
1145 {
1146 $1->file_flags = $3;
1147 $$ = $1;
1148 }
1149 | fixedverinfo FILEOS numexpr
1150 {
1151 $1->file_os = $3;
1152 $$ = $1;
1153 }
1154 | fixedverinfo FILETYPE numexpr
1155 {
1156 $1->file_type = $3;
1157 $$ = $1;
1158 }
1159 | fixedverinfo FILESUBTYPE numexpr
1160 {
1161 $1->file_subtype = $3;
1162 $$ = $1;
1163 }
1164 ;
1165
1166/* To handle verblocks successfully, the lexer handles BLOCK
1167 specially. A BLOCK "StringFileInfo" is returned as
1168 BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as
1169 BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK
1170 with the string as the value. */
1171
1172verblocks:
1173 /* empty */
1174 {
1175 $$ = NULL;
1176 }
1177 | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
1178 {
1179 $$ = append_ver_stringfileinfo ($1, $4, $6);
1180 }
1181 | verblocks BLOCKVARFILEINFO BEG VALUE QUOTEDSTRING vertrans END
1182 {
1183 $$ = append_ver_varfileinfo ($1, $5, $6);
1184 }
1185 ;
1186
1187vervals:
1188 /* empty */
1189 {
1190 $$ = NULL;
1191 }
1192 | vervals VALUE QUOTEDSTRING ',' QUOTEDSTRING
1193 {
1194 $$ = append_verval ($1, $3, $5);
1195 }
1196 ;
1197
1198vertrans:
1199 /* empty */
1200 {
1201 $$ = NULL;
1202 }
1203 | vertrans cnumexpr cnumexpr
1204 {
1205 $$ = append_vertrans ($1, $2, $3);
1206 }
1207 ;
1208
1209/* A resource ID. */
1210
1211id:
1212 posnumexpr
1213 {
1214 $$.named = 0;
1215 $$.u.id = $1;
1216 }
1217 | STRING
1218 {
662cc41e
ILT
1219 char *copy, *s;
1220
1221 /* It seems that resource ID's are forced to upper case. */
1222 copy = xstrdup ($1);
1223 for (s = copy; *s != '\0'; s++)
1224 if (islower (*s))
1225 *s = toupper (*s);
1226 res_string_to_id (&$$, copy);
1227 free (copy);
1d371d35
ILT
1228 }
1229 ;
1230
1231/* Generic suboptions. These may appear before the BEGIN in any
1232 multiline statement. */
1233
1234suboptions:
1235 /* empty */
1236 {
1237 memset (&$$, 0, sizeof (struct res_res_info));
1238 $$.language = language;
1239 /* FIXME: Is this the right default? */
1240 $$.memflags = MEMFLAG_MOVEABLE;
1241 }
1242 | suboptions memflag
1243 {
1244 $$ = $1;
1245 $$.memflags |= $2.on;
1246 $$.memflags &=~ $2.off;
1247 }
1248 | suboptions CHARACTERISTICS numexpr
1249 {
1250 $$ = $1;
1251 $$.characteristics = $3;
1252 }
1253 | suboptions LANGUAGE numexpr cnumexpr
1254 {
1255 $$ = $1;
1256 $$.language = $3 | ($4 << 8);
1257 }
1258 | suboptions VERSION numexpr
1259 {
1260 $$ = $1;
1261 $$.version = $3;
1262 }
1263 ;
1264
1265/* Memory flags which default to MOVEABLE and DISCARDABLE. */
1266
1267memflags_move_discard:
1268 /* empty */
1269 {
1270 memset (&$$, 0, sizeof (struct res_res_info));
1271 $$.language = language;
1272 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
1273 }
1274 | memflags_move_discard memflag
1275 {
1276 $$ = $1;
1277 $$.memflags |= $2.on;
1278 $$.memflags &=~ $2.off;
1279 }
1280 ;
1281
1282/* Memory flags which default to MOVEABLE. */
1283
1284memflags_move:
1285 /* empty */
1286 {
1287 memset (&$$, 0, sizeof (struct res_res_info));
1288 $$.language = language;
1289 $$.memflags = MEMFLAG_MOVEABLE;
1290 }
1291 | memflags_move_discard memflag
1292 {
1293 $$ = $1;
1294 $$.memflags |= $2.on;
1295 $$.memflags &=~ $2.off;
1296 }
1297 ;
1298
1299/* Memory flags. This returns a struct with two integers, because we
1300 sometimes want to set bits and we sometimes want to clear them. */
1301
1302memflag:
1303 MOVEABLE
1304 {
1305 $$.on = MEMFLAG_MOVEABLE;
1306 $$.off = 0;
1307 }
1308 | FIXED
1309 {
1310 $$.on = 0;
1311 $$.off = MEMFLAG_MOVEABLE;
1312 }
1313 | PURE
1314 {
1315 $$.on = MEMFLAG_PURE;
1316 $$.off = 0;
1317 }
1318 | IMPURE
1319 {
1320 $$.on = 0;
1321 $$.off = MEMFLAG_PURE;
1322 }
1323 | PRELOAD
1324 {
1325 $$.on = MEMFLAG_PRELOAD;
1326 $$.off = 0;
1327 }
1328 | LOADONCALL
1329 {
1330 $$.on = 0;
1331 $$.off = MEMFLAG_PRELOAD;
1332 }
1333 | DISCARDABLE
1334 {
1335 $$.on = MEMFLAG_DISCARDABLE;
1336 $$.off = 0;
1337 }
1338 ;
1339
1340/* A file name. */
1341
1342file_name:
1343 QUOTEDSTRING
1344 {
1345 $$ = $1;
1346 }
1347 | STRING
1348 {
1349 $$ = $1;
1350 }
1351 ;
1352
1353/* A style expression. This changes the static variable STYLE. We do
1354 it this way because rc appears to permit a style to be set to
1355 something like
1356 WS_GROUP | NOT WS_TABSTOP
1357 to mean that a default of WS_TABSTOP should be removed. Anything
1358 which wants to accept a style must first set STYLE to the default
1359 value. The styleexpr nonterminal will change STYLE as specified by
1360 the user. Note that we do not accept arbitrary expressions here,
1361 just numbers separated by '|'. */
1362
1363styleexpr:
1364 parennumber
1365 {
1366 style |= $1;
1367 }
1368 | NOT parennumber
1369 {
1370 style &=~ $2;
1371 }
1372 | styleexpr '|' parennumber
1373 {
1374 style |= $3;
1375 }
1376 | styleexpr '|' NOT parennumber
1377 {
1378 style &=~ $4;
1379 }
1380 ;
1381
1382parennumber:
1383 NUMBER
1384 {
1385 $$ = $1.val;
1386 }
1387 | '(' numexpr ')'
1388 {
1389 $$ = $2;
1390 }
1391 ;
1392
1393/* An optional expression with a leading comma. */
1394
1395optcnumexpr:
1396 /* empty */
1397 {
1398 $$ = 0;
1399 }
1400 | cnumexpr
1401 {
1402 $$ = $1;
1403 }
1404 ;
1405
1406/* An expression with a leading comma. */
1407
1408cnumexpr:
1409 ',' numexpr
1410 {
1411 $$ = $2;
1412 }
1413 ;
1414
1415/* A possibly negated numeric expression. */
1416
1417numexpr:
1418 sizednumexpr
1419 {
1420 $$ = $1.val;
1421 }
1422 ;
1423
1424/* A possibly negated expression with a size. */
1425
1426sizednumexpr:
1427 NUMBER
1428 {
1429 $$ = $1;
1430 }
1431 | '(' sizednumexpr ')'
1432 {
1433 $$ = $2;
1434 }
1435 | '~' sizednumexpr %prec '~'
1436 {
1437 $$.val = ~ $2.val;
1438 $$.dword = $2.dword;
1439 }
1440 | '-' sizednumexpr %prec NEG
1441 {
1442 $$.val = - $2.val;
1443 $$.dword = $2.dword;
1444 }
1445 | sizednumexpr '*' sizednumexpr
1446 {
1447 $$.val = $1.val * $3.val;
1448 $$.dword = $1.dword || $3.dword;
1449 }
1450 | sizednumexpr '/' sizednumexpr
1451 {
1452 $$.val = $1.val / $3.val;
1453 $$.dword = $1.dword || $3.dword;
1454 }
1455 | sizednumexpr '%' sizednumexpr
1456 {
1457 $$.val = $1.val % $3.val;
1458 $$.dword = $1.dword || $3.dword;
1459 }
1460 | sizednumexpr '+' sizednumexpr
1461 {
1462 $$.val = $1.val + $3.val;
1463 $$.dword = $1.dword || $3.dword;
1464 }
1465 | sizednumexpr '-' sizednumexpr
1466 {
1467 $$.val = $1.val - $3.val;
1468 $$.dword = $1.dword || $3.dword;
1469 }
1470 | sizednumexpr '&' sizednumexpr
1471 {
1472 $$.val = $1.val & $3.val;
1473 $$.dword = $1.dword || $3.dword;
1474 }
1475 | sizednumexpr '^' sizednumexpr
1476 {
1477 $$.val = $1.val ^ $3.val;
1478 $$.dword = $1.dword || $3.dword;
1479 }
1480 | sizednumexpr '|' sizednumexpr
1481 {
1482 $$.val = $1.val | $3.val;
1483 $$.dword = $1.dword || $3.dword;
1484 }
1485 ;
1486
1487/* An expression with a leading comma which does not use unary
1488 negation. */
1489
1490cposnumexpr:
1491 ',' posnumexpr
1492 {
1493 $$ = $2;
1494 }
1495 ;
1496
1497/* An expression which does not use unary negation. */
1498
1499posnumexpr:
1500 sizedposnumexpr
1501 {
1502 $$ = $1.val;
1503 }
1504 ;
1505
1506/* An expression which does not use unary negation. We separate unary
1507 negation to avoid parsing conflicts when two numeric expressions
1508 appear consecutively. */
1509
1510sizedposnumexpr:
1511 NUMBER
1512 {
1513 $$ = $1;
1514 }
1515 | '(' sizednumexpr ')'
1516 {
1517 $$ = $2;
1518 }
1519 | '~' sizednumexpr %prec '~'
1520 {
1521 $$.val = ~ $2.val;
1522 $$.dword = $2.dword;
1523 }
1524 | sizedposnumexpr '*' sizednumexpr
1525 {
1526 $$.val = $1.val * $3.val;
1527 $$.dword = $1.dword || $3.dword;
1528 }
1529 | sizedposnumexpr '/' sizednumexpr
1530 {
1531 $$.val = $1.val / $3.val;
1532 $$.dword = $1.dword || $3.dword;
1533 }
1534 | sizedposnumexpr '%' sizednumexpr
1535 {
1536 $$.val = $1.val % $3.val;
1537 $$.dword = $1.dword || $3.dword;
1538 }
1539 | sizedposnumexpr '+' sizednumexpr
1540 {
1541 $$.val = $1.val + $3.val;
1542 $$.dword = $1.dword || $3.dword;
1543 }
1544 | sizedposnumexpr '-' sizednumexpr
1545 {
1546 $$.val = $1.val - $3.val;
1547 $$.dword = $1.dword || $3.dword;
1548 }
1549 | sizedposnumexpr '&' sizednumexpr
1550 {
1551 $$.val = $1.val & $3.val;
1552 $$.dword = $1.dword || $3.dword;
1553 }
1554 | sizedposnumexpr '^' sizednumexpr
1555 {
1556 $$.val = $1.val ^ $3.val;
1557 $$.dword = $1.dword || $3.dword;
1558 }
1559 | sizedposnumexpr '|' sizednumexpr
1560 {
1561 $$.val = $1.val | $3.val;
1562 $$.dword = $1.dword || $3.dword;
1563 }
1564 ;
1565
1566%%
1567
1568/* Set the language from the command line. */
1569
1570void
1571rcparse_set_language (lang)
1572 int lang;
1573{
1574 language = lang;
1575}
This page took 0.187058 seconds and 4 git commands to generate.