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