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