* embedspu.sh (relas): Correct sh_info parsing.
[deliverable/binutils-gdb.git] / binutils / rcparse.y
1 %{ /* rcparse.y -- parser for Windows rc files
2 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
3 Free Software Foundation, Inc.
4 Written by Ian Lance Taylor, Cygnus Support.
5 Extended by Kai Tietz, Onevision.
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
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
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
27 #include "sysdep.h"
28 #include "bfd.h"
29 #include "bucomm.h"
30 #include "libiberty.h"
31 #include "windres.h"
32 #include "safe-ctype.h"
33
34 /* The current language. */
35
36 static unsigned short language;
37
38 /* The resource information during a sub statement. */
39
40 static rc_res_res_info sub_res_info;
41
42 /* Dialog information. This is built by the nonterminals styles and
43 controls. */
44
45 static rc_dialog dialog;
46
47 /* This is used when building a style. It is modified by the
48 nonterminal styleexpr. */
49
50 static unsigned long style;
51
52 /* These are used when building a control. They are set before using
53 control_params. */
54
55 static rc_uint_type base_style;
56 static rc_uint_type default_style;
57 static rc_res_id class;
58 static rc_res_id res_text_field;
59 static unichar null_unichar;
60
61 /* This is used for COMBOBOX, LISTBOX and EDITTEXT which
62 do not allow resource 'text' field in control definition. */
63 static const rc_res_id res_null_text = { 1, {{0, &null_unichar}}};
64
65 %}
66
67 %union
68 {
69 rc_accelerator acc;
70 rc_accelerator *pacc;
71 rc_dialog_control *dialog_control;
72 rc_menuitem *menuitem;
73 struct
74 {
75 rc_rcdata_item *first;
76 rc_rcdata_item *last;
77 } rcdata;
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;
86 struct
87 {
88 rc_uint_type on;
89 rc_uint_type off;
90 } memflags;
91 struct
92 {
93 rc_uint_type val;
94 /* Nonzero if this number was explicitly specified as long. */
95 int dword;
96 } i;
97 rc_uint_type il;
98 rc_uint_type is;
99 const char *s;
100 struct
101 {
102 rc_uint_type length;
103 const char *s;
104 } ss;
105 unichar *uni;
106 struct
107 {
108 rc_uint_type length;
109 const unichar *s;
110 } suni;
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
124 %token ANICURSOR ANIICON DLGINCLUDE DLGINIT FONTDIR HTML MANIFEST PLUGPLAY VXD TOOLBAR BUTTON
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
137 %token <uni> QUOTEDUNISTRING
138 %token <s> QUOTEDSTRING STRING
139 %token <i> NUMBER
140 %token <suni> SIZEDUNISTRING
141 %token <ss> SIZEDSTRING
142 %token IGNORED_TOKEN
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
154 %type <toobar_item> toolbar_data
155 %type <res_info> suboptions memflags_move_discard memflags_move
156 %type <memflags> memflag
157 %type <id> id rcdata_id optresidc resref resid cresid
158 %type <il> exstyle parennumber
159 %type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
160 %type <is> acc_options acc_option menuitem_flags menuitem_flag
161 %type <s> file_name
162 %type <uni> res_unicode_string resname res_unicode_string_concat
163 %type <ss> sizedstring
164 %type <suni> sizedunistring
165 %type <i> sizednumexpr sizedposnumexpr
166
167 %left '|'
168 %left '^'
169 %left '&'
170 %left '+' '-'
171 %left '*' '/' '%'
172 %right '~' NEG
173
174 %%
175
176 input:
177 /* empty */
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
188 | input stringtable
189 | input toolbar
190 | input user
191 | input versioninfo
192 | input IGNORED_TOKEN
193 ;
194
195 /* Accelerator resources. */
196
197 accelerator:
198 id ACCELERATORS suboptions BEG acc_entries END
199 {
200 define_accelerator ($1, &$3, $5);
201 if (yychar != YYEMPTY)
202 YYERROR;
203 rcparse_discard_strings ();
204 }
205 ;
206
207 acc_entries:
208 /* empty */
209 {
210 $$ = NULL;
211 }
212 | acc_entries acc_entry
213 {
214 rc_accelerator *a;
215
216 a = (rc_accelerator *) res_alloc (sizeof *a);
217 *a = $2;
218 if ($1 == NULL)
219 $$ = a;
220 else
221 {
222 rc_accelerator **pp;
223
224 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
225 ;
226 *pp = a;
227 $$ = $1;
228 }
229 }
230 ;
231
232 acc_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
244 && ($$.flags & (ACC_SHIFT | ACC_CONTROL)) != 0)
245 rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
246 }
247 ;
248
249 acc_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;
264 ch = TOUPPER (s[0]);
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
279 acc_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
295 acc_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
325 bitmap:
326 id BITMAP memflags_move file_name
327 {
328 define_bitmap ($1, &$3, $4);
329 if (yychar != YYEMPTY)
330 YYERROR;
331 rcparse_discard_strings ();
332 }
333 ;
334
335 /* Cursor resources. */
336
337 cursor:
338 id CURSOR memflags_move_discard file_name
339 {
340 define_cursor ($1, &$3, $4);
341 if (yychar != YYEMPTY)
342 YYERROR;
343 rcparse_discard_strings ();
344 }
345 ;
346
347 /* Dialog resources. */
348
349 dialog:
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;
366 style = 0;
367 }
368 styles BEG controls END
369 {
370 define_dialog ($1, &sub_res_info, &dialog);
371 if (yychar != YYEMPTY)
372 YYERROR;
373 rcparse_discard_strings ();
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;
388 dialog.ex = ((rc_dialog_ex *)
389 res_alloc (sizeof (rc_dialog_ex)));
390 memset (dialog.ex, 0, sizeof (rc_dialog_ex));
391 dialog.controls = NULL;
392 sub_res_info = $3;
393 style = 0;
394 }
395 styles BEG controls END
396 {
397 define_dialog ($1, &sub_res_info, &dialog);
398 if (yychar != YYEMPTY)
399 YYERROR;
400 rcparse_discard_strings ();
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;
415 dialog.ex = ((rc_dialog_ex *)
416 res_alloc (sizeof (rc_dialog_ex)));
417 memset (dialog.ex, 0, sizeof (rc_dialog_ex));
418 dialog.ex->help = $9;
419 dialog.controls = NULL;
420 sub_res_info = $3;
421 style = 0;
422 }
423 styles BEG controls END
424 {
425 define_dialog ($1, &sub_res_info, &dialog);
426 if (yychar != YYEMPTY)
427 YYERROR;
428 rcparse_discard_strings ();
429 }
430 ;
431
432 exstyle:
433 /* empty */
434 {
435 $$ = 0;
436 }
437 | EXSTYLE '=' numexpr
438 {
439 $$ = $3;
440 }
441 ;
442
443 styles:
444 /* empty */
445 | styles CAPTION res_unicode_string_concat
446 {
447 dialog.style |= WS_CAPTION;
448 style |= WS_CAPTION;
449 dialog.caption = $3;
450 }
451 | styles CLASS id
452 {
453 dialog.class = $3;
454 }
455 | styles STYLE
456 styleexpr
457 {
458 dialog.style = style;
459 }
460 | styles EXSTYLE numexpr
461 {
462 dialog.exstyle = $3;
463 }
464 | styles CLASS res_unicode_string_concat
465 {
466 res_unistring_to_id (& dialog.class, $3);
467 }
468 | styles FONT numexpr ',' res_unicode_string_concat
469 {
470 dialog.style |= DS_SETFONT;
471 style |= DS_SETFONT;
472 dialog.pointsize = $3;
473 dialog.font = $5;
474 if (dialog.ex != NULL)
475 {
476 dialog.ex->weight = 0;
477 dialog.ex->italic = 0;
478 dialog.ex->charset = 1;
479 }
480 }
481 | styles FONT numexpr ',' res_unicode_string_concat cnumexpr
482 {
483 dialog.style |= DS_SETFONT;
484 style |= DS_SETFONT;
485 dialog.pointsize = $3;
486 dialog.font = $5;
487 if (dialog.ex == NULL)
488 rcparse_warning (_("extended FONT requires DIALOGEX"));
489 else
490 {
491 dialog.ex->weight = $6;
492 dialog.ex->italic = 0;
493 dialog.ex->charset = 1;
494 }
495 }
496 | styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr
497 {
498 dialog.style |= DS_SETFONT;
499 style |= DS_SETFONT;
500 dialog.pointsize = $3;
501 dialog.font = $5;
502 if (dialog.ex == NULL)
503 rcparse_warning (_("extended FONT requires DIALOGEX"));
504 else
505 {
506 dialog.ex->weight = $6;
507 dialog.ex->italic = $7;
508 dialog.ex->charset = 1;
509 }
510 }
511 | styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr cnumexpr
512 {
513 dialog.style |= DS_SETFONT;
514 style |= DS_SETFONT;
515 dialog.pointsize = $3;
516 dialog.font = $5;
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;
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 {
536 sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT);
537 }
538 | styles VERSIONK numexpr
539 {
540 sub_res_info.version = $3;
541 }
542 ;
543
544 controls:
545 /* empty */
546 | controls control
547 {
548 rc_dialog_control **pp;
549
550 for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
551 ;
552 *pp = $2;
553 }
554 ;
555
556 control:
557 AUTO3STATE optresidc
558 {
559 default_style = BS_AUTO3STATE | WS_TABSTOP;
560 base_style = BS_AUTO3STATE;
561 class.named = 0;
562 class.u.id = CTL_BUTTON;
563 res_text_field = $2;
564 }
565 control_params
566 {
567 $$ = $4;
568 }
569 | AUTOCHECKBOX optresidc
570 {
571 default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
572 base_style = BS_AUTOCHECKBOX;
573 class.named = 0;
574 class.u.id = CTL_BUTTON;
575 res_text_field = $2;
576 }
577 control_params
578 {
579 $$ = $4;
580 }
581 | AUTORADIOBUTTON optresidc
582 {
583 default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
584 base_style = BS_AUTORADIOBUTTON;
585 class.named = 0;
586 class.u.id = CTL_BUTTON;
587 res_text_field = $2;
588 }
589 control_params
590 {
591 $$ = $4;
592 }
593 | BEDIT optresidc
594 {
595 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
596 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
597 class.named = 0;
598 class.u.id = CTL_EDIT;
599 res_text_field = $2;
600 }
601 control_params
602 {
603 $$ = $4;
604 if (dialog.ex == NULL)
605 rcparse_warning (_("BEDIT requires DIALOGEX"));
606 res_string_to_id (&$$->class, "BEDIT");
607 }
608 | CHECKBOX optresidc
609 {
610 default_style = BS_CHECKBOX | WS_TABSTOP;
611 base_style = BS_CHECKBOX | WS_TABSTOP;
612 class.named = 0;
613 class.u.id = CTL_BUTTON;
614 res_text_field = $2;
615 }
616 control_params
617 {
618 $$ = $4;
619 }
620 | COMBOBOX
621 {
622 /* This is as per MSDN documentation. With some (???)
623 versions of MS rc.exe their is no default style. */
624 default_style = CBS_SIMPLE | WS_TABSTOP;
625 base_style = 0;
626 class.named = 0;
627 class.u.id = CTL_COMBOBOX;
628 res_text_field = res_null_text;
629 }
630 control_params
631 {
632 $$ = $3;
633 }
634 | CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
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 }
645 | CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
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 }
654 | CTEXT optresidc
655 {
656 default_style = SS_CENTER | WS_GROUP;
657 base_style = SS_CENTER;
658 class.named = 0;
659 class.u.id = CTL_STATIC;
660 res_text_field = $2;
661 }
662 control_params
663 {
664 $$ = $4;
665 }
666 | DEFPUSHBUTTON optresidc
667 {
668 default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
669 base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
670 class.named = 0;
671 class.u.id = CTL_BUTTON;
672 res_text_field = $2;
673 }
674 control_params
675 {
676 $$ = $4;
677 }
678 | EDITTEXT
679 {
680 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
681 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
682 class.named = 0;
683 class.u.id = CTL_EDIT;
684 res_text_field = res_null_text;
685 }
686 control_params
687 {
688 $$ = $3;
689 }
690 | GROUPBOX optresidc
691 {
692 default_style = BS_GROUPBOX;
693 base_style = BS_GROUPBOX;
694 class.named = 0;
695 class.u.id = CTL_BUTTON;
696 res_text_field = $2;
697 }
698 control_params
699 {
700 $$ = $4;
701 }
702 | HEDIT optresidc
703 {
704 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
705 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
706 class.named = 0;
707 class.u.id = CTL_EDIT;
708 res_text_field = $2;
709 }
710 control_params
711 {
712 $$ = $4;
713 if (dialog.ex == NULL)
714 rcparse_warning (_("IEDIT requires DIALOGEX"));
715 res_string_to_id (&$$->class, "HEDIT");
716 }
717 | ICON resref numexpr cnumexpr cnumexpr opt_control_data
718 {
719 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $6,
720 dialog.ex);
721 }
722 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
723 opt_control_data
724 {
725 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $8,
726 dialog.ex);
727 }
728 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
729 icon_styleexpr optcnumexpr opt_control_data
730 {
731 $$ = define_icon_control ($2, $3, $4, $5, style, $9, 0, $10,
732 dialog.ex);
733 }
734 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
735 icon_styleexpr cnumexpr cnumexpr opt_control_data
736 {
737 $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11,
738 dialog.ex);
739 }
740 | IEDIT optresidc
741 {
742 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
743 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
744 class.named = 0;
745 class.u.id = CTL_EDIT;
746 res_text_field = $2;
747 }
748 control_params
749 {
750 $$ = $4;
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;
759 class.named = 0;
760 class.u.id = CTL_LISTBOX;
761 res_text_field = res_null_text;
762 }
763 control_params
764 {
765 $$ = $3;
766 }
767 | LTEXT optresidc
768 {
769 default_style = SS_LEFT | WS_GROUP;
770 base_style = SS_LEFT;
771 class.named = 0;
772 class.u.id = CTL_STATIC;
773 res_text_field = $2;
774 }
775 control_params
776 {
777 $$ = $4;
778 }
779 | PUSHBOX optresidc
780 {
781 default_style = BS_PUSHBOX | WS_TABSTOP;
782 base_style = BS_PUSHBOX;
783 class.named = 0;
784 class.u.id = CTL_BUTTON;
785 }
786 control_params
787 {
788 $$ = $4;
789 }
790 | PUSHBUTTON optresidc
791 {
792 default_style = BS_PUSHBUTTON | WS_TABSTOP;
793 base_style = BS_PUSHBUTTON | WS_TABSTOP;
794 class.named = 0;
795 class.u.id = CTL_BUTTON;
796 res_text_field = $2;
797 }
798 control_params
799 {
800 $$ = $4;
801 }
802 | RADIOBUTTON optresidc
803 {
804 default_style = BS_RADIOBUTTON | WS_TABSTOP;
805 base_style = BS_RADIOBUTTON;
806 class.named = 0;
807 class.u.id = CTL_BUTTON;
808 res_text_field = $2;
809 }
810 control_params
811 {
812 $$ = $4;
813 }
814 | RTEXT optresidc
815 {
816 default_style = SS_RIGHT | WS_GROUP;
817 base_style = SS_RIGHT;
818 class.named = 0;
819 class.u.id = CTL_STATIC;
820 res_text_field = $2;
821 }
822 control_params
823 {
824 $$ = $4;
825 }
826 | SCROLLBAR
827 {
828 default_style = SBS_HORZ;
829 base_style = 0;
830 class.named = 0;
831 class.u.id = CTL_SCROLLBAR;
832 res_text_field = res_null_text;
833 }
834 control_params
835 {
836 $$ = $3;
837 }
838 | STATE3 optresidc
839 {
840 default_style = BS_3STATE | WS_TABSTOP;
841 base_style = BS_3STATE;
842 class.named = 0;
843 class.u.id = CTL_BUTTON;
844 res_text_field = $2;
845 }
846 control_params
847 {
848 $$ = $4;
849 }
850 | USERBUTTON resref numexpr ',' numexpr ',' numexpr ','
851 numexpr ',' numexpr ','
852 { style = WS_CHILD | WS_VISIBLE; }
853 styleexpr optcnumexpr
854 {
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,
859 style, $15);
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
870 control_params:
871 numexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
872 {
873 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class,
874 default_style | WS_CHILD | WS_VISIBLE, 0);
875 if ($6 != NULL)
876 {
877 if (dialog.ex == NULL)
878 rcparse_warning (_("control data requires DIALOGEX"));
879 $$->data = $6;
880 }
881 }
882 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
883 control_params_styleexpr optcnumexpr opt_control_data
884 {
885 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
886 if ($8 != NULL)
887 {
888 if (dialog.ex == NULL)
889 rcparse_warning (_("control data requires DIALOGEX"));
890 $$->data = $8;
891 }
892 }
893 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
894 control_params_styleexpr cnumexpr cnumexpr opt_control_data
895 {
896 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
897 if (dialog.ex == NULL)
898 rcparse_warning (_("help ID requires DIALOGEX"));
899 $$->help = $8;
900 $$->data = $9;
901 }
902 ;
903
904 cresid:
905 ',' resid
906 {
907 if ($2.named)
908 res_unistring_to_id (&$$, $2.u.n.name);
909 else
910 $$=$2;
911 }
912 ;
913
914 optresidc:
915 /* empty */
916 {
917 res_string_to_id (&$$, "");
918 }
919 | resid ',' { $$=$1; }
920 ;
921
922 resid:
923 posnumexpr
924 {
925 $$.named = 0;
926 $$.u.id = $1;
927 }
928 | res_unicode_string
929 {
930 $$.named = 1;
931 $$.u.n.name = $1;
932 $$.u.n.length = unichar_len ($1);
933 }
934 ;
935
936 opt_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
949 control_styleexpr:
950 ','
951 { style = WS_CHILD | WS_VISIBLE; }
952 styleexpr
953 ;
954
955 icon_styleexpr:
956 ','
957 { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
958 styleexpr
959 ;
960
961 control_params_styleexpr:
962 ','
963 { style = base_style | WS_CHILD | WS_VISIBLE; }
964 styleexpr
965 ;
966
967 /* Font resources. */
968
969 font:
970 id FONT memflags_move_discard file_name
971 {
972 define_font ($1, &$3, $4);
973 if (yychar != YYEMPTY)
974 YYERROR;
975 rcparse_discard_strings ();
976 }
977 ;
978
979 /* Icon resources. */
980
981 icon:
982 id ICON memflags_move_discard file_name
983 {
984 define_icon ($1, &$3, $4);
985 if (yychar != YYEMPTY)
986 YYERROR;
987 rcparse_discard_strings ();
988 }
989 ;
990
991 /* Language command. This changes the static variable language, which
992 affects all subsequent resources. */
993
994 language:
995 LANGUAGE numexpr cnumexpr
996 {
997 language = $2 | ($3 << SUBLANG_SHIFT);
998 }
999 ;
1000
1001 /* Menu resources. */
1002
1003 menu:
1004 id MENU suboptions BEG menuitems END
1005 {
1006 define_menu ($1, &$3, $5);
1007 if (yychar != YYEMPTY)
1008 YYERROR;
1009 rcparse_discard_strings ();
1010 }
1011 ;
1012
1013 menuitems:
1014 /* empty */
1015 {
1016 $$ = NULL;
1017 }
1018 | menuitems menuitem
1019 {
1020 if ($1 == NULL)
1021 $$ = $2;
1022 else
1023 {
1024 rc_menuitem **pp;
1025
1026 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1027 ;
1028 *pp = $2;
1029 $$ = $1;
1030 }
1031 }
1032 ;
1033
1034 menuitem:
1035 MENUITEM res_unicode_string_concat cnumexpr menuitem_flags
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 }
1043 | POPUP res_unicode_string_concat menuitem_flags BEG menuitems END
1044 {
1045 $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
1046 }
1047 ;
1048
1049 menuitem_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
1064 menuitem_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
1093 menuex:
1094 id MENUEX suboptions BEG menuexitems END
1095 {
1096 define_menu ($1, &$3, $5);
1097 if (yychar != YYEMPTY)
1098 YYERROR;
1099 rcparse_discard_strings ();
1100 }
1101 ;
1102
1103 menuexitems:
1104 /* empty */
1105 {
1106 $$ = NULL;
1107 }
1108 | menuexitems menuexitem
1109 {
1110 if ($1 == NULL)
1111 $$ = $2;
1112 else
1113 {
1114 rc_menuitem **pp;
1115
1116 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1117 ;
1118 *pp = $2;
1119 $$ = $1;
1120 }
1121 }
1122 ;
1123
1124 menuexitem:
1125 MENUITEM res_unicode_string_concat
1126 {
1127 $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
1128 }
1129 | MENUITEM res_unicode_string_concat cnumexpr
1130 {
1131 $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
1132 }
1133 | MENUITEM res_unicode_string_concat cnumexpr cnumexpr optcnumexpr
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 }
1141 | POPUP res_unicode_string_concat BEG menuexitems END
1142 {
1143 $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
1144 }
1145 | POPUP res_unicode_string_concat cnumexpr BEG menuexitems END
1146 {
1147 $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
1148 }
1149 | POPUP res_unicode_string_concat cnumexpr cnumexpr BEG menuexitems END
1150 {
1151 $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
1152 }
1153 | POPUP res_unicode_string_concat cnumexpr cnumexpr cnumexpr optcnumexpr
1154 BEG menuexitems END
1155 {
1156 $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
1157 }
1158 ;
1159
1160 /* Messagetable resources. */
1161
1162 messagetable:
1163 id MESSAGETABLE memflags_move file_name
1164 {
1165 define_messagetable ($1, &$3, $4);
1166 if (yychar != YYEMPTY)
1167 YYERROR;
1168 rcparse_discard_strings ();
1169 }
1170 ;
1171
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
1175 optrcdata_data:
1176 {
1177 rcparse_rcdata ();
1178 }
1179 optrcdata_data_int
1180 {
1181 rcparse_normal ();
1182 $$ = $2;
1183 }
1184 ;
1185
1186 optrcdata_data_int:
1187 /* empty */
1188 {
1189 $$.first = NULL;
1190 $$.last = NULL;
1191 }
1192 | rcdata_data
1193 {
1194 $$ = $1;
1195 }
1196 ;
1197
1198 rcdata_data:
1199 sizedstring
1200 {
1201 rc_rcdata_item *ri;
1202
1203 ri = define_rcdata_string ($1.s, $1.length);
1204 $$.first = ri;
1205 $$.last = ri;
1206 }
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 }
1215 | sizednumexpr
1216 {
1217 rc_rcdata_item *ri;
1218
1219 ri = define_rcdata_number ($1.val, $1.dword);
1220 $$.first = ri;
1221 $$.last = ri;
1222 }
1223 | rcdata_data ',' sizedstring
1224 {
1225 rc_rcdata_item *ri;
1226
1227 ri = define_rcdata_string ($3.s, $3.length);
1228 $$.first = $1.first;
1229 $1.last->next = ri;
1230 $$.last = ri;
1231 }
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 }
1241 | rcdata_data ',' sizednumexpr
1242 {
1243 rc_rcdata_item *ri;
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
1254 stringtable:
1255 STRINGTABLE suboptions BEG
1256 { sub_res_info = $2; }
1257 string_data END
1258 ;
1259
1260 string_data:
1261 /* empty */
1262 | string_data numexpr res_unicode_string_concat
1263 {
1264 define_stringtable (&sub_res_info, $2, $3);
1265 if (yychar != YYEMPTY)
1266 YYERROR;
1267 rcparse_discard_strings ();
1268 }
1269 | string_data numexpr ',' res_unicode_string_concat
1270 {
1271 define_stringtable (&sub_res_info, $2, $4);
1272 if (yychar != YYEMPTY)
1273 YYERROR;
1274 rcparse_discard_strings ();
1275 }
1276 ;
1277
1278 rcdata_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
1330 /* User defined resources. We accept general suboptions in the
1331 file_name case to keep the parser happy. */
1332
1333 user:
1334 id rcdata_id suboptions BEG optrcdata_data END
1335 {
1336 define_user_data ($1, $2, &$3, $5.first);
1337 if (yychar != YYEMPTY)
1338 YYERROR;
1339 rcparse_discard_strings ();
1340 }
1341 | id rcdata_id suboptions file_name
1342 {
1343 define_user_file ($1, $2, &$3, $4);
1344 if (yychar != YYEMPTY)
1345 YYERROR;
1346 rcparse_discard_strings ();
1347 }
1348 ;
1349
1350 toolbar:
1351 id TOOLBAR suboptions numexpr cnumexpr BEG toolbar_data END
1352 {
1353 define_toolbar ($1, &$3, $4, $5, $7);
1354 }
1355 ;
1356
1357 toolbar_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
1399 /* Versioninfo resources. */
1400
1401 versioninfo:
1402 id VERSIONINFO fixedverinfo BEG verblocks END
1403 {
1404 define_versioninfo ($1, language, $3, $5);
1405 if (yychar != YYEMPTY)
1406 YYERROR;
1407 rcparse_discard_strings ();
1408 }
1409 ;
1410
1411 fixedverinfo:
1412 /* empty */
1413 {
1414 $$ = ((rc_fixed_versioninfo *)
1415 res_alloc (sizeof (rc_fixed_versioninfo)));
1416 memset ($$, 0, sizeof (rc_fixed_versioninfo));
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
1463 verblocks:
1464 /* empty */
1465 {
1466 $$ = NULL;
1467 }
1468 | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
1469 {
1470 $$ = append_ver_stringfileinfo ($1, $4, $6);
1471 }
1472 | verblocks BLOCKVARFILEINFO BEG VALUE res_unicode_string_concat vertrans END
1473 {
1474 $$ = append_ver_varfileinfo ($1, $5, $6);
1475 }
1476 ;
1477
1478 vervals:
1479 /* empty */
1480 {
1481 $$ = NULL;
1482 }
1483 | vervals VALUE res_unicode_string_concat ',' res_unicode_string_concat
1484 {
1485 $$ = append_verval ($1, $3, $5);
1486 }
1487 ;
1488
1489 vertrans:
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
1502 id:
1503 posnumexpr
1504 {
1505 $$.named = 0;
1506 $$.u.id = $1;
1507 }
1508 | resname
1509 {
1510 res_unistring_to_id (&$$, $1);
1511 }
1512 ;
1513
1514 /* A resource reference. */
1515
1516 resname:
1517 res_unicode_string
1518 {
1519 $$ = $1;
1520 }
1521 | STRING
1522 {
1523 unichar *h = NULL;
1524 unicode_from_ascii ((rc_uint_type *) NULL, &h, $1);
1525 $$ = h;
1526 }
1527 ;
1528
1529
1530 resref:
1531 posnumexpr ','
1532 {
1533 $$.named = 0;
1534 $$.u.id = $1;
1535 }
1536 | resname
1537 {
1538 res_unistring_to_id (&$$, $1);
1539 }
1540 | resname ','
1541 {
1542 res_unistring_to_id (&$$, $1);
1543 }
1544 ;
1545
1546 /* Generic suboptions. These may appear before the BEGIN in any
1547 multiline statement. */
1548
1549 suboptions:
1550 /* empty */
1551 {
1552 memset (&$$, 0, sizeof (rc_res_res_info));
1553 $$.language = language;
1554 /* FIXME: Is this the right default? */
1555 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1556 }
1557 | suboptions memflag
1558 {
1559 $$ = $1;
1560 $$.memflags |= $2.on;
1561 $$.memflags &=~ $2.off;
1562 }
1563 | suboptions CHARACTERISTICS numexpr
1564 {
1565 $$ = $1;
1566 $$.characteristics = $3;
1567 }
1568 | suboptions LANGUAGE numexpr cnumexpr
1569 {
1570 $$ = $1;
1571 $$.language = $3 | ($4 << SUBLANG_SHIFT);
1572 }
1573 | suboptions VERSIONK numexpr
1574 {
1575 $$ = $1;
1576 $$.version = $3;
1577 }
1578 ;
1579
1580 /* Memory flags which default to MOVEABLE and DISCARDABLE. */
1581
1582 memflags_move_discard:
1583 /* empty */
1584 {
1585 memset (&$$, 0, sizeof (rc_res_res_info));
1586 $$.language = language;
1587 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
1588 }
1589 | memflags_move_discard memflag
1590 {
1591 $$ = $1;
1592 $$.memflags |= $2.on;
1593 $$.memflags &=~ $2.off;
1594 }
1595 ;
1596
1597 /* Memory flags which default to MOVEABLE. */
1598
1599 memflags_move:
1600 /* empty */
1601 {
1602 memset (&$$, 0, sizeof (rc_res_res_info));
1603 $$.language = language;
1604 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
1605 }
1606 | memflags_move memflag
1607 {
1608 $$ = $1;
1609 $$.memflags |= $2.on;
1610 $$.memflags &=~ $2.off;
1611 }
1612 ;
1613
1614 /* Memory flags. This returns a struct with two integers, because we
1615 sometimes want to set bits and we sometimes want to clear them. */
1616
1617 memflag:
1618 MOVEABLE
1619 {
1620 $$.on = MEMFLAG_MOVEABLE;
1621 $$.off = 0;
1622 }
1623 | FIXED
1624 {
1625 $$.on = 0;
1626 $$.off = MEMFLAG_MOVEABLE;
1627 }
1628 | PURE
1629 {
1630 $$.on = MEMFLAG_PURE;
1631 $$.off = 0;
1632 }
1633 | IMPURE
1634 {
1635 $$.on = 0;
1636 $$.off = MEMFLAG_PURE;
1637 }
1638 | PRELOAD
1639 {
1640 $$.on = MEMFLAG_PRELOAD;
1641 $$.off = 0;
1642 }
1643 | LOADONCALL
1644 {
1645 $$.on = 0;
1646 $$.off = MEMFLAG_PRELOAD;
1647 }
1648 | DISCARDABLE
1649 {
1650 $$.on = MEMFLAG_DISCARDABLE;
1651 $$.off = 0;
1652 }
1653 ;
1654
1655 /* A file name. */
1656
1657 file_name:
1658 QUOTEDSTRING
1659 {
1660 $$ = $1;
1661 }
1662 | STRING
1663 {
1664 $$ = $1;
1665 }
1666 ;
1667
1668 /* Concat string */
1669 res_unicode_string_concat:
1670 res_unicode_string
1671 {
1672 $$ = $1;
1673 }
1674 |
1675 res_unicode_string_concat res_unicode_string
1676 {
1677 rc_uint_type l1 = unichar_len ($1);
1678 rc_uint_type l2 = unichar_len ($2);
1679 unichar *h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
1680 if (l1 != 0)
1681 memcpy (h, $1, l1 * sizeof (unichar));
1682 if (l2 != 0)
1683 memcpy (h + l1, $2, l2 * sizeof (unichar));
1684 h[l1 + l2] = 0;
1685 $$ = h;
1686 }
1687 ;
1688
1689 res_unicode_string:
1690 QUOTEDUNISTRING
1691 {
1692 $$ = unichar_dup ($1);
1693 }
1694 | QUOTEDSTRING
1695 {
1696 unichar *h = NULL;
1697 unicode_from_ascii ((rc_uint_type *) NULL, &h, $1);
1698 $$ = h;
1699 }
1700 ;
1701
1702 sizedstring:
1703 SIZEDSTRING
1704 {
1705 $$ = $1;
1706 }
1707 | sizedstring SIZEDSTRING
1708 {
1709 rc_uint_type l = $1.length + $2.length;
1710 char *h = (char *) res_alloc (l);
1711 memcpy (h, $1.s, $1.length);
1712 memcpy (h + $1.length, $2.s, $2.length);
1713 $$.s = h;
1714 $$.length = l;
1715 }
1716 ;
1717
1718 sizedunistring:
1719 SIZEDUNISTRING
1720 {
1721 $$ = $1;
1722 }
1723 | sizedunistring SIZEDUNISTRING
1724 {
1725 rc_uint_type l = $1.length + $2.length;
1726 unichar *h = (unichar *) res_alloc (l * sizeof (unichar));
1727 memcpy (h, $1.s, $1.length * sizeof (unichar));
1728 memcpy (h + $1.length, $2.s, $2.length * sizeof (unichar));
1729 $$.s = h;
1730 $$.length = l;
1731 }
1732 ;
1733
1734 /* A style expression. This changes the static variable STYLE. We do
1735 it this way because rc appears to permit a style to be set to
1736 something like
1737 WS_GROUP | NOT WS_TABSTOP
1738 to mean that a default of WS_TABSTOP should be removed. Anything
1739 which wants to accept a style must first set STYLE to the default
1740 value. The styleexpr nonterminal will change STYLE as specified by
1741 the user. Note that we do not accept arbitrary expressions here,
1742 just numbers separated by '|'. */
1743
1744 styleexpr:
1745 parennumber
1746 {
1747 style |= $1;
1748 }
1749 | NOT parennumber
1750 {
1751 style &=~ $2;
1752 }
1753 | styleexpr '|' parennumber
1754 {
1755 style |= $3;
1756 }
1757 | styleexpr '|' NOT parennumber
1758 {
1759 style &=~ $4;
1760 }
1761 ;
1762
1763 parennumber:
1764 NUMBER
1765 {
1766 $$ = $1.val;
1767 }
1768 | '(' numexpr ')'
1769 {
1770 $$ = $2;
1771 }
1772 ;
1773
1774 /* An optional expression with a leading comma. */
1775
1776 optcnumexpr:
1777 /* empty */
1778 {
1779 $$ = 0;
1780 }
1781 | cnumexpr
1782 {
1783 $$ = $1;
1784 }
1785 ;
1786
1787 /* An expression with a leading comma. */
1788
1789 cnumexpr:
1790 ',' numexpr
1791 {
1792 $$ = $2;
1793 }
1794 ;
1795
1796 /* A possibly negated numeric expression. */
1797
1798 numexpr:
1799 sizednumexpr
1800 {
1801 $$ = $1.val;
1802 }
1803 ;
1804
1805 /* A possibly negated expression with a size. */
1806
1807 sizednumexpr:
1808 NUMBER
1809 {
1810 $$ = $1;
1811 }
1812 | '(' sizednumexpr ')'
1813 {
1814 $$ = $2;
1815 }
1816 | '~' sizednumexpr %prec '~'
1817 {
1818 $$.val = ~ $2.val;
1819 $$.dword = $2.dword;
1820 }
1821 | '-' sizednumexpr %prec NEG
1822 {
1823 $$.val = - $2.val;
1824 $$.dword = $2.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 | sizednumexpr '-' sizednumexpr
1847 {
1848 $$.val = $1.val - $3.val;
1849 $$.dword = $1.dword || $3.dword;
1850 }
1851 | sizednumexpr '&' sizednumexpr
1852 {
1853 $$.val = $1.val & $3.val;
1854 $$.dword = $1.dword || $3.dword;
1855 }
1856 | sizednumexpr '^' sizednumexpr
1857 {
1858 $$.val = $1.val ^ $3.val;
1859 $$.dword = $1.dword || $3.dword;
1860 }
1861 | sizednumexpr '|' sizednumexpr
1862 {
1863 $$.val = $1.val | $3.val;
1864 $$.dword = $1.dword || $3.dword;
1865 }
1866 ;
1867
1868 /* An expression with a leading comma which does not use unary
1869 negation. */
1870
1871 cposnumexpr:
1872 ',' posnumexpr
1873 {
1874 $$ = $2;
1875 }
1876 ;
1877
1878 /* An expression which does not use unary negation. */
1879
1880 posnumexpr:
1881 sizedposnumexpr
1882 {
1883 $$ = $1.val;
1884 }
1885 ;
1886
1887 /* An expression which does not use unary negation. We separate unary
1888 negation to avoid parsing conflicts when two numeric expressions
1889 appear consecutively. */
1890
1891 sizedposnumexpr:
1892 NUMBER
1893 {
1894 $$ = $1;
1895 }
1896 | '(' sizednumexpr ')'
1897 {
1898 $$ = $2;
1899 }
1900 | '~' sizednumexpr %prec '~'
1901 {
1902 $$.val = ~ $2.val;
1903 $$.dword = $2.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 | sizedposnumexpr '-' sizednumexpr
1926 {
1927 $$.val = $1.val - $3.val;
1928 $$.dword = $1.dword || $3.dword;
1929 }
1930 | sizedposnumexpr '&' sizednumexpr
1931 {
1932 $$.val = $1.val & $3.val;
1933 $$.dword = $1.dword || $3.dword;
1934 }
1935 | sizedposnumexpr '^' sizednumexpr
1936 {
1937 $$.val = $1.val ^ $3.val;
1938 $$.dword = $1.dword || $3.dword;
1939 }
1940 | sizedposnumexpr '|' sizednumexpr
1941 {
1942 $$.val = $1.val | $3.val;
1943 $$.dword = $1.dword || $3.dword;
1944 }
1945 ;
1946
1947 %%
1948
1949 /* Set the language from the command line. */
1950
1951 void
1952 rcparse_set_language (int lang)
1953 {
1954 language = lang;
1955 }
This page took 0.068765 seconds and 4 git commands to generate.