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