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