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