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