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