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