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