Change sources over to using GPLv3
[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 3 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
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
28 #include "sysdep.h"
29 #include "bfd.h"
30 #include "bucomm.h"
31 #include "libiberty.h"
32 #include "windres.h"
33 #include "safe-ctype.h"
34
35 /* The current language. */
36
37 static unsigned short language;
38
39 /* The resource information during a sub statement. */
40
41 static rc_res_res_info sub_res_info;
42
43 /* Dialog information. This is built by the nonterminals styles and
44 controls. */
45
46 static rc_dialog dialog;
47
48 /* This is used when building a style. It is modified by the
49 nonterminal styleexpr. */
50
51 static unsigned long style;
52
53 /* These are used when building a control. They are set before using
54 control_params. */
55
56 static rc_uint_type base_style;
57 static rc_uint_type default_style;
58 static rc_res_id class;
59 static rc_res_id res_text_field;
60 static unichar null_unichar;
61
62 /* This is used for COMBOBOX, LISTBOX and EDITTEXT which
63 do not allow resource 'text' field in control definition. */
64 static const rc_res_id res_null_text = { 1, {{0, &null_unichar}}};
65
66 %}
67
68 %union
69 {
70 rc_accelerator acc;
71 rc_accelerator *pacc;
72 rc_dialog_control *dialog_control;
73 rc_menuitem *menuitem;
74 struct
75 {
76 rc_rcdata_item *first;
77 rc_rcdata_item *last;
78 } rcdata;
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;
87 struct
88 {
89 rc_uint_type on;
90 rc_uint_type off;
91 } memflags;
92 struct
93 {
94 rc_uint_type val;
95 /* Nonzero if this number was explicitly specified as long. */
96 int dword;
97 } i;
98 rc_uint_type il;
99 rc_uint_type is;
100 const char *s;
101 struct
102 {
103 rc_uint_type length;
104 const char *s;
105 } ss;
106 unichar *uni;
107 struct
108 {
109 rc_uint_type length;
110 const unichar *s;
111 } suni;
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
125 %token ANICURSOR ANIICON DLGINCLUDE DLGINIT FONTDIR HTML MANIFEST PLUGPLAY VXD TOOLBAR BUTTON
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
138 %token <uni> QUOTEDUNISTRING
139 %token <s> QUOTEDSTRING STRING
140 %token <i> NUMBER
141 %token <suni> SIZEDUNISTRING
142 %token <ss> SIZEDSTRING
143 %token IGNORED_TOKEN
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
155 %type <toobar_item> toolbar_data
156 %type <res_info> suboptions memflags_move_discard memflags_move
157 %type <memflags> memflag
158 %type <id> id rcdata_id optresidc resref resid cresid
159 %type <il> exstyle parennumber
160 %type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
161 %type <is> acc_options acc_option menuitem_flags menuitem_flag
162 %type <s> file_name
163 %type <uni> res_unicode_string resname res_unicode_string_concat
164 %type <ss> sizedstring
165 %type <suni> sizedunistring
166 %type <i> sizednumexpr sizedposnumexpr
167
168 %left '|'
169 %left '^'
170 %left '&'
171 %left '+' '-'
172 %left '*' '/' '%'
173 %right '~' NEG
174
175 %%
176
177 input:
178 /* empty */
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
189 | input stringtable
190 | input toolbar
191 | input user
192 | input versioninfo
193 | input IGNORED_TOKEN
194 ;
195
196 /* Accelerator resources. */
197
198 accelerator:
199 id ACCELERATORS suboptions BEG acc_entries END
200 {
201 define_accelerator ($1, &$3, $5);
202 if (yychar != YYEMPTY)
203 YYERROR;
204 rcparse_discard_strings ();
205 }
206 ;
207
208 acc_entries:
209 /* empty */
210 {
211 $$ = NULL;
212 }
213 | acc_entries acc_entry
214 {
215 rc_accelerator *a;
216
217 a = (rc_accelerator *) res_alloc (sizeof *a);
218 *a = $2;
219 if ($1 == NULL)
220 $$ = a;
221 else
222 {
223 rc_accelerator **pp;
224
225 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
226 ;
227 *pp = a;
228 $$ = $1;
229 }
230 }
231 ;
232
233 acc_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
245 && ($$.flags & (ACC_SHIFT | ACC_CONTROL)) != 0)
246 rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
247 }
248 ;
249
250 acc_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;
265 ch = TOUPPER (s[0]);
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
280 acc_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
296 acc_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
326 bitmap:
327 id BITMAP memflags_move file_name
328 {
329 define_bitmap ($1, &$3, $4);
330 if (yychar != YYEMPTY)
331 YYERROR;
332 rcparse_discard_strings ();
333 }
334 ;
335
336 /* Cursor resources. */
337
338 cursor:
339 id CURSOR memflags_move_discard file_name
340 {
341 define_cursor ($1, &$3, $4);
342 if (yychar != YYEMPTY)
343 YYERROR;
344 rcparse_discard_strings ();
345 }
346 ;
347
348 /* Dialog resources. */
349
350 dialog:
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;
367 style = 0;
368 }
369 styles BEG controls END
370 {
371 define_dialog ($1, &sub_res_info, &dialog);
372 if (yychar != YYEMPTY)
373 YYERROR;
374 rcparse_discard_strings ();
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;
389 dialog.ex = ((rc_dialog_ex *)
390 res_alloc (sizeof (rc_dialog_ex)));
391 memset (dialog.ex, 0, sizeof (rc_dialog_ex));
392 dialog.controls = NULL;
393 sub_res_info = $3;
394 style = 0;
395 }
396 styles BEG controls END
397 {
398 define_dialog ($1, &sub_res_info, &dialog);
399 if (yychar != YYEMPTY)
400 YYERROR;
401 rcparse_discard_strings ();
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;
416 dialog.ex = ((rc_dialog_ex *)
417 res_alloc (sizeof (rc_dialog_ex)));
418 memset (dialog.ex, 0, sizeof (rc_dialog_ex));
419 dialog.ex->help = $9;
420 dialog.controls = NULL;
421 sub_res_info = $3;
422 style = 0;
423 }
424 styles BEG controls END
425 {
426 define_dialog ($1, &sub_res_info, &dialog);
427 if (yychar != YYEMPTY)
428 YYERROR;
429 rcparse_discard_strings ();
430 }
431 ;
432
433 exstyle:
434 /* empty */
435 {
436 $$ = 0;
437 }
438 | EXSTYLE '=' numexpr
439 {
440 $$ = $3;
441 }
442 ;
443
444 styles:
445 /* empty */
446 | styles CAPTION res_unicode_string_concat
447 {
448 dialog.style |= WS_CAPTION;
449 style |= WS_CAPTION;
450 dialog.caption = $3;
451 }
452 | styles CLASS id
453 {
454 dialog.class = $3;
455 }
456 | styles STYLE
457 styleexpr
458 {
459 dialog.style = style;
460 }
461 | styles EXSTYLE numexpr
462 {
463 dialog.exstyle = $3;
464 }
465 | styles CLASS res_unicode_string_concat
466 {
467 res_unistring_to_id (& dialog.class, $3);
468 }
469 | styles FONT numexpr ',' res_unicode_string_concat
470 {
471 dialog.style |= DS_SETFONT;
472 style |= DS_SETFONT;
473 dialog.pointsize = $3;
474 dialog.font = $5;
475 if (dialog.ex != NULL)
476 {
477 dialog.ex->weight = 0;
478 dialog.ex->italic = 0;
479 dialog.ex->charset = 1;
480 }
481 }
482 | styles FONT numexpr ',' res_unicode_string_concat cnumexpr
483 {
484 dialog.style |= DS_SETFONT;
485 style |= DS_SETFONT;
486 dialog.pointsize = $3;
487 dialog.font = $5;
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 }
496 }
497 | styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr
498 {
499 dialog.style |= DS_SETFONT;
500 style |= DS_SETFONT;
501 dialog.pointsize = $3;
502 dialog.font = $5;
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;
509 dialog.ex->charset = 1;
510 }
511 }
512 | styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr cnumexpr
513 {
514 dialog.style |= DS_SETFONT;
515 style |= DS_SETFONT;
516 dialog.pointsize = $3;
517 dialog.font = $5;
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;
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 {
537 sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT);
538 }
539 | styles VERSIONK numexpr
540 {
541 sub_res_info.version = $3;
542 }
543 ;
544
545 controls:
546 /* empty */
547 | controls control
548 {
549 rc_dialog_control **pp;
550
551 for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
552 ;
553 *pp = $2;
554 }
555 ;
556
557 control:
558 AUTO3STATE optresidc
559 {
560 default_style = BS_AUTO3STATE | WS_TABSTOP;
561 base_style = BS_AUTO3STATE;
562 class.named = 0;
563 class.u.id = CTL_BUTTON;
564 res_text_field = $2;
565 }
566 control_params
567 {
568 $$ = $4;
569 }
570 | AUTOCHECKBOX optresidc
571 {
572 default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
573 base_style = BS_AUTOCHECKBOX;
574 class.named = 0;
575 class.u.id = CTL_BUTTON;
576 res_text_field = $2;
577 }
578 control_params
579 {
580 $$ = $4;
581 }
582 | AUTORADIOBUTTON optresidc
583 {
584 default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
585 base_style = BS_AUTORADIOBUTTON;
586 class.named = 0;
587 class.u.id = CTL_BUTTON;
588 res_text_field = $2;
589 }
590 control_params
591 {
592 $$ = $4;
593 }
594 | BEDIT optresidc
595 {
596 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
597 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
598 class.named = 0;
599 class.u.id = CTL_EDIT;
600 res_text_field = $2;
601 }
602 control_params
603 {
604 $$ = $4;
605 if (dialog.ex == NULL)
606 rcparse_warning (_("BEDIT requires DIALOGEX"));
607 res_string_to_id (&$$->class, "BEDIT");
608 }
609 | CHECKBOX optresidc
610 {
611 default_style = BS_CHECKBOX | WS_TABSTOP;
612 base_style = BS_CHECKBOX | WS_TABSTOP;
613 class.named = 0;
614 class.u.id = CTL_BUTTON;
615 res_text_field = $2;
616 }
617 control_params
618 {
619 $$ = $4;
620 }
621 | COMBOBOX
622 {
623 /* This is as per MSDN documentation. With some (???)
624 versions of MS rc.exe their is no default style. */
625 default_style = CBS_SIMPLE | WS_TABSTOP;
626 base_style = 0;
627 class.named = 0;
628 class.u.id = CTL_COMBOBOX;
629 res_text_field = res_null_text;
630 }
631 control_params
632 {
633 $$ = $3;
634 }
635 | CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
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 }
646 | CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
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 }
655 | CTEXT optresidc
656 {
657 default_style = SS_CENTER | WS_GROUP;
658 base_style = SS_CENTER;
659 class.named = 0;
660 class.u.id = CTL_STATIC;
661 res_text_field = $2;
662 }
663 control_params
664 {
665 $$ = $4;
666 }
667 | DEFPUSHBUTTON optresidc
668 {
669 default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
670 base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
671 class.named = 0;
672 class.u.id = CTL_BUTTON;
673 res_text_field = $2;
674 }
675 control_params
676 {
677 $$ = $4;
678 }
679 | EDITTEXT
680 {
681 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
682 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
683 class.named = 0;
684 class.u.id = CTL_EDIT;
685 res_text_field = res_null_text;
686 }
687 control_params
688 {
689 $$ = $3;
690 }
691 | GROUPBOX optresidc
692 {
693 default_style = BS_GROUPBOX;
694 base_style = BS_GROUPBOX;
695 class.named = 0;
696 class.u.id = CTL_BUTTON;
697 res_text_field = $2;
698 }
699 control_params
700 {
701 $$ = $4;
702 }
703 | HEDIT optresidc
704 {
705 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
706 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
707 class.named = 0;
708 class.u.id = CTL_EDIT;
709 res_text_field = $2;
710 }
711 control_params
712 {
713 $$ = $4;
714 if (dialog.ex == NULL)
715 rcparse_warning (_("IEDIT requires DIALOGEX"));
716 res_string_to_id (&$$->class, "HEDIT");
717 }
718 | ICON resref numexpr cnumexpr cnumexpr opt_control_data
719 {
720 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $6,
721 dialog.ex);
722 }
723 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
724 opt_control_data
725 {
726 $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $8,
727 dialog.ex);
728 }
729 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
730 icon_styleexpr optcnumexpr opt_control_data
731 {
732 $$ = define_icon_control ($2, $3, $4, $5, style, $9, 0, $10,
733 dialog.ex);
734 }
735 | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
736 icon_styleexpr cnumexpr cnumexpr opt_control_data
737 {
738 $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11,
739 dialog.ex);
740 }
741 | IEDIT optresidc
742 {
743 default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
744 base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
745 class.named = 0;
746 class.u.id = CTL_EDIT;
747 res_text_field = $2;
748 }
749 control_params
750 {
751 $$ = $4;
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;
760 class.named = 0;
761 class.u.id = CTL_LISTBOX;
762 res_text_field = res_null_text;
763 }
764 control_params
765 {
766 $$ = $3;
767 }
768 | LTEXT optresidc
769 {
770 default_style = SS_LEFT | WS_GROUP;
771 base_style = SS_LEFT;
772 class.named = 0;
773 class.u.id = CTL_STATIC;
774 res_text_field = $2;
775 }
776 control_params
777 {
778 $$ = $4;
779 }
780 | PUSHBOX optresidc
781 {
782 default_style = BS_PUSHBOX | WS_TABSTOP;
783 base_style = BS_PUSHBOX;
784 class.named = 0;
785 class.u.id = CTL_BUTTON;
786 }
787 control_params
788 {
789 $$ = $4;
790 }
791 | PUSHBUTTON optresidc
792 {
793 default_style = BS_PUSHBUTTON | WS_TABSTOP;
794 base_style = BS_PUSHBUTTON | WS_TABSTOP;
795 class.named = 0;
796 class.u.id = CTL_BUTTON;
797 res_text_field = $2;
798 }
799 control_params
800 {
801 $$ = $4;
802 }
803 | RADIOBUTTON optresidc
804 {
805 default_style = BS_RADIOBUTTON | WS_TABSTOP;
806 base_style = BS_RADIOBUTTON;
807 class.named = 0;
808 class.u.id = CTL_BUTTON;
809 res_text_field = $2;
810 }
811 control_params
812 {
813 $$ = $4;
814 }
815 | RTEXT optresidc
816 {
817 default_style = SS_RIGHT | WS_GROUP;
818 base_style = SS_RIGHT;
819 class.named = 0;
820 class.u.id = CTL_STATIC;
821 res_text_field = $2;
822 }
823 control_params
824 {
825 $$ = $4;
826 }
827 | SCROLLBAR
828 {
829 default_style = SBS_HORZ;
830 base_style = 0;
831 class.named = 0;
832 class.u.id = CTL_SCROLLBAR;
833 res_text_field = res_null_text;
834 }
835 control_params
836 {
837 $$ = $3;
838 }
839 | STATE3 optresidc
840 {
841 default_style = BS_3STATE | WS_TABSTOP;
842 base_style = BS_3STATE;
843 class.named = 0;
844 class.u.id = CTL_BUTTON;
845 res_text_field = $2;
846 }
847 control_params
848 {
849 $$ = $4;
850 }
851 | USERBUTTON resref numexpr ',' numexpr ',' numexpr ','
852 numexpr ',' numexpr ','
853 { style = WS_CHILD | WS_VISIBLE; }
854 styleexpr optcnumexpr
855 {
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,
860 style, $15);
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
871 control_params:
872 numexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
873 {
874 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class,
875 default_style | WS_CHILD | WS_VISIBLE, 0);
876 if ($6 != NULL)
877 {
878 if (dialog.ex == NULL)
879 rcparse_warning (_("control data requires DIALOGEX"));
880 $$->data = $6;
881 }
882 }
883 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
884 control_params_styleexpr optcnumexpr opt_control_data
885 {
886 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
887 if ($8 != NULL)
888 {
889 if (dialog.ex == NULL)
890 rcparse_warning (_("control data requires DIALOGEX"));
891 $$->data = $8;
892 }
893 }
894 | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
895 control_params_styleexpr cnumexpr cnumexpr opt_control_data
896 {
897 $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
898 if (dialog.ex == NULL)
899 rcparse_warning (_("help ID requires DIALOGEX"));
900 $$->help = $8;
901 $$->data = $9;
902 }
903 ;
904
905 cresid:
906 ',' resid
907 {
908 if ($2.named)
909 res_unistring_to_id (&$$, $2.u.n.name);
910 else
911 $$=$2;
912 }
913 ;
914
915 optresidc:
916 /* empty */
917 {
918 res_string_to_id (&$$, "");
919 }
920 | resid ',' { $$=$1; }
921 ;
922
923 resid:
924 posnumexpr
925 {
926 $$.named = 0;
927 $$.u.id = $1;
928 }
929 | res_unicode_string
930 {
931 $$.named = 1;
932 $$.u.n.name = $1;
933 $$.u.n.length = unichar_len ($1);
934 }
935 ;
936
937 opt_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
950 control_styleexpr:
951 ','
952 { style = WS_CHILD | WS_VISIBLE; }
953 styleexpr
954 ;
955
956 icon_styleexpr:
957 ','
958 { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
959 styleexpr
960 ;
961
962 control_params_styleexpr:
963 ','
964 { style = base_style | WS_CHILD | WS_VISIBLE; }
965 styleexpr
966 ;
967
968 /* Font resources. */
969
970 font:
971 id FONT memflags_move_discard file_name
972 {
973 define_font ($1, &$3, $4);
974 if (yychar != YYEMPTY)
975 YYERROR;
976 rcparse_discard_strings ();
977 }
978 ;
979
980 /* Icon resources. */
981
982 icon:
983 id ICON memflags_move_discard file_name
984 {
985 define_icon ($1, &$3, $4);
986 if (yychar != YYEMPTY)
987 YYERROR;
988 rcparse_discard_strings ();
989 }
990 ;
991
992 /* Language command. This changes the static variable language, which
993 affects all subsequent resources. */
994
995 language:
996 LANGUAGE numexpr cnumexpr
997 {
998 language = $2 | ($3 << SUBLANG_SHIFT);
999 }
1000 ;
1001
1002 /* Menu resources. */
1003
1004 menu:
1005 id MENU suboptions BEG menuitems END
1006 {
1007 define_menu ($1, &$3, $5);
1008 if (yychar != YYEMPTY)
1009 YYERROR;
1010 rcparse_discard_strings ();
1011 }
1012 ;
1013
1014 menuitems:
1015 /* empty */
1016 {
1017 $$ = NULL;
1018 }
1019 | menuitems menuitem
1020 {
1021 if ($1 == NULL)
1022 $$ = $2;
1023 else
1024 {
1025 rc_menuitem **pp;
1026
1027 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1028 ;
1029 *pp = $2;
1030 $$ = $1;
1031 }
1032 }
1033 ;
1034
1035 menuitem:
1036 MENUITEM res_unicode_string_concat cnumexpr menuitem_flags
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 }
1044 | POPUP res_unicode_string_concat menuitem_flags BEG menuitems END
1045 {
1046 $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
1047 }
1048 ;
1049
1050 menuitem_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
1065 menuitem_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
1094 menuex:
1095 id MENUEX suboptions BEG menuexitems END
1096 {
1097 define_menu ($1, &$3, $5);
1098 if (yychar != YYEMPTY)
1099 YYERROR;
1100 rcparse_discard_strings ();
1101 }
1102 ;
1103
1104 menuexitems:
1105 /* empty */
1106 {
1107 $$ = NULL;
1108 }
1109 | menuexitems menuexitem
1110 {
1111 if ($1 == NULL)
1112 $$ = $2;
1113 else
1114 {
1115 rc_menuitem **pp;
1116
1117 for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
1118 ;
1119 *pp = $2;
1120 $$ = $1;
1121 }
1122 }
1123 ;
1124
1125 menuexitem:
1126 MENUITEM res_unicode_string_concat
1127 {
1128 $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
1129 }
1130 | MENUITEM res_unicode_string_concat cnumexpr
1131 {
1132 $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
1133 }
1134 | MENUITEM res_unicode_string_concat cnumexpr cnumexpr optcnumexpr
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 }
1142 | POPUP res_unicode_string_concat BEG menuexitems END
1143 {
1144 $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
1145 }
1146 | POPUP res_unicode_string_concat cnumexpr BEG menuexitems END
1147 {
1148 $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
1149 }
1150 | POPUP res_unicode_string_concat cnumexpr cnumexpr BEG menuexitems END
1151 {
1152 $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
1153 }
1154 | POPUP res_unicode_string_concat cnumexpr cnumexpr cnumexpr optcnumexpr
1155 BEG menuexitems END
1156 {
1157 $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
1158 }
1159 ;
1160
1161 /* Messagetable resources. */
1162
1163 messagetable:
1164 id MESSAGETABLE memflags_move file_name
1165 {
1166 define_messagetable ($1, &$3, $4);
1167 if (yychar != YYEMPTY)
1168 YYERROR;
1169 rcparse_discard_strings ();
1170 }
1171 ;
1172
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
1176 optrcdata_data:
1177 {
1178 rcparse_rcdata ();
1179 }
1180 optrcdata_data_int
1181 {
1182 rcparse_normal ();
1183 $$ = $2;
1184 }
1185 ;
1186
1187 optrcdata_data_int:
1188 /* empty */
1189 {
1190 $$.first = NULL;
1191 $$.last = NULL;
1192 }
1193 | rcdata_data
1194 {
1195 $$ = $1;
1196 }
1197 ;
1198
1199 rcdata_data:
1200 sizedstring
1201 {
1202 rc_rcdata_item *ri;
1203
1204 ri = define_rcdata_string ($1.s, $1.length);
1205 $$.first = ri;
1206 $$.last = ri;
1207 }
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 }
1216 | sizednumexpr
1217 {
1218 rc_rcdata_item *ri;
1219
1220 ri = define_rcdata_number ($1.val, $1.dword);
1221 $$.first = ri;
1222 $$.last = ri;
1223 }
1224 | rcdata_data ',' sizedstring
1225 {
1226 rc_rcdata_item *ri;
1227
1228 ri = define_rcdata_string ($3.s, $3.length);
1229 $$.first = $1.first;
1230 $1.last->next = ri;
1231 $$.last = ri;
1232 }
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 }
1242 | rcdata_data ',' sizednumexpr
1243 {
1244 rc_rcdata_item *ri;
1245
1246 ri = define_rcdata_number ($3.val, $3.dword);
1247 $$.first = $1.first;
1248 $1.last->next = ri;
1249 $$.last = ri;
1250 }
1251 ;
1252
1253 /* Stringtable resources. */
1254
1255 stringtable:
1256 STRINGTABLE suboptions BEG
1257 { sub_res_info = $2; }
1258 string_data END
1259 ;
1260
1261 string_data:
1262 /* empty */
1263 | string_data numexpr res_unicode_string_concat
1264 {
1265 define_stringtable (&sub_res_info, $2, $3);
1266 if (yychar != YYEMPTY)
1267 YYERROR;
1268 rcparse_discard_strings ();
1269 }
1270 | string_data numexpr ',' res_unicode_string_concat
1271 {
1272 define_stringtable (&sub_res_info, $2, $4);
1273 if (yychar != YYEMPTY)
1274 YYERROR;
1275 rcparse_discard_strings ();
1276 }
1277 ;
1278
1279 rcdata_id:
1280 id
1281 {
1282 $$=$1;
1283 }
1284 | HTML
1285 {
1286 $$.named = 0;
1287 $$.u.id = 23;
1288 }
1289 | RCDATA
1290 {
1291 $$.named = 0;
1292 $$.u.id = RT_RCDATA;
1293 }
1294 | MANIFEST
1295 {
1296 $$.named = 0;
1297 $$.u.id = RT_MANIFEST;
1298 }
1299 | PLUGPLAY
1300 {
1301 $$.named = 0;
1302 $$.u.id = RT_PLUGPLAY;
1303 }
1304 | VXD
1305 {
1306 $$.named = 0;
1307 $$.u.id = RT_VXD;
1308 }
1309 | DLGINCLUDE
1310 {
1311 $$.named = 0;
1312 $$.u.id = RT_DLGINCLUDE;
1313 }
1314 | DLGINIT
1315 {
1316 $$.named = 0;
1317 $$.u.id = RT_DLGINIT;
1318 }
1319 | ANICURSOR
1320 {
1321 $$.named = 0;
1322 $$.u.id = RT_ANICURSOR;
1323 }
1324 | ANIICON
1325 {
1326 $$.named = 0;
1327 $$.u.id = RT_ANIICON;
1328 }
1329 ;
1330
1331 /* User defined resources. We accept general suboptions in the
1332 file_name case to keep the parser happy. */
1333
1334 user:
1335 id rcdata_id suboptions BEG optrcdata_data END
1336 {
1337 define_user_data ($1, $2, &$3, $5.first);
1338 if (yychar != YYEMPTY)
1339 YYERROR;
1340 rcparse_discard_strings ();
1341 }
1342 | id rcdata_id suboptions file_name
1343 {
1344 define_user_file ($1, $2, &$3, $4);
1345 if (yychar != YYEMPTY)
1346 YYERROR;
1347 rcparse_discard_strings ();
1348 }
1349 ;
1350
1351 toolbar:
1352 id TOOLBAR suboptions numexpr cnumexpr BEG toolbar_data END
1353 {
1354 define_toolbar ($1, &$3, $4, $5, $7);
1355 }
1356 ;
1357
1358 toolbar_data: /* empty */ { $$= NULL; }
1359 | toolbar_data BUTTON id
1360 {
1361 rc_toolbar_item *c,*n;
1362 c = $1;
1363 n= (rc_toolbar_item *)
1364 res_alloc (sizeof (rc_toolbar_item));
1365 if (c != NULL)
1366 while (c->next != NULL)
1367 c = c->next;
1368 n->prev = c;
1369 n->next = NULL;
1370 if (c != NULL)
1371 c->next = n;
1372 n->id = $3;
1373 if ($1 == NULL)
1374 $$ = n;
1375 else
1376 $$ = $1;
1377 }
1378 | toolbar_data SEPARATOR
1379 {
1380 rc_toolbar_item *c,*n;
1381 c = $1;
1382 n= (rc_toolbar_item *)
1383 res_alloc (sizeof (rc_toolbar_item));
1384 if (c != NULL)
1385 while (c->next != NULL)
1386 c = c->next;
1387 n->prev = c;
1388 n->next = NULL;
1389 if (c != NULL)
1390 c->next = n;
1391 n->id.named = 0;
1392 n->id.u.id = 0;
1393 if ($1 == NULL)
1394 $$ = n;
1395 else
1396 $$ = $1;
1397 }
1398 ;
1399
1400 /* Versioninfo resources. */
1401
1402 versioninfo:
1403 id VERSIONINFO fixedverinfo BEG verblocks END
1404 {
1405 define_versioninfo ($1, language, $3, $5);
1406 if (yychar != YYEMPTY)
1407 YYERROR;
1408 rcparse_discard_strings ();
1409 }
1410 ;
1411
1412 fixedverinfo:
1413 /* empty */
1414 {
1415 $$ = ((rc_fixed_versioninfo *)
1416 res_alloc (sizeof (rc_fixed_versioninfo)));
1417 memset ($$, 0, sizeof (rc_fixed_versioninfo));
1418 }
1419 | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
1420 {
1421 $1->file_version_ms = ($3 << 16) | $4;
1422 $1->file_version_ls = ($5 << 16) | $6;
1423 $$ = $1;
1424 }
1425 | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
1426 {
1427 $1->product_version_ms = ($3 << 16) | $4;
1428 $1->product_version_ls = ($5 << 16) | $6;
1429 $$ = $1;
1430 }
1431 | fixedverinfo FILEFLAGSMASK numexpr
1432 {
1433 $1->file_flags_mask = $3;
1434 $$ = $1;
1435 }
1436 | fixedverinfo FILEFLAGS numexpr
1437 {
1438 $1->file_flags = $3;
1439 $$ = $1;
1440 }
1441 | fixedverinfo FILEOS numexpr
1442 {
1443 $1->file_os = $3;
1444 $$ = $1;
1445 }
1446 | fixedverinfo FILETYPE numexpr
1447 {
1448 $1->file_type = $3;
1449 $$ = $1;
1450 }
1451 | fixedverinfo FILESUBTYPE numexpr
1452 {
1453 $1->file_subtype = $3;
1454 $$ = $1;
1455 }
1456 ;
1457
1458 /* To handle verblocks successfully, the lexer handles BLOCK
1459 specially. A BLOCK "StringFileInfo" is returned as
1460 BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as
1461 BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK
1462 with the string as the value. */
1463
1464 verblocks:
1465 /* empty */
1466 {
1467 $$ = NULL;
1468 }
1469 | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
1470 {
1471 $$ = append_ver_stringfileinfo ($1, $4, $6);
1472 }
1473 | verblocks BLOCKVARFILEINFO BEG VALUE res_unicode_string_concat vertrans END
1474 {
1475 $$ = append_ver_varfileinfo ($1, $5, $6);
1476 }
1477 ;
1478
1479 vervals:
1480 /* empty */
1481 {
1482 $$ = NULL;
1483 }
1484 | vervals VALUE res_unicode_string_concat ',' res_unicode_string_concat
1485 {
1486 $$ = append_verval ($1, $3, $5);
1487 }
1488 ;
1489
1490 vertrans:
1491 /* empty */
1492 {
1493 $$ = NULL;
1494 }
1495 | vertrans cnumexpr cnumexpr
1496 {
1497 $$ = append_vertrans ($1, $2, $3);
1498 }
1499 ;
1500
1501 /* A resource ID. */
1502
1503 id:
1504 posnumexpr
1505 {
1506 $$.named = 0;
1507 $$.u.id = $1;
1508 }
1509 | resname
1510 {
1511 res_unistring_to_id (&$$, $1);
1512 }
1513 ;
1514
1515 /* A resource reference. */
1516
1517 resname:
1518 res_unicode_string
1519 {
1520 $$ = $1;
1521 }
1522 | STRING
1523 {
1524 unichar *h = NULL;
1525 unicode_from_ascii ((rc_uint_type *) NULL, &h, $1);
1526 $$ = h;
1527 }
1528 ;
1529
1530
1531 resref:
1532 posnumexpr ','
1533 {
1534 $$.named = 0;
1535 $$.u.id = $1;
1536 }
1537 | resname
1538 {
1539 res_unistring_to_id (&$$, $1);
1540 }
1541 | resname ','
1542 {
1543 res_unistring_to_id (&$$, $1);
1544 }
1545 ;
1546
1547 /* Generic suboptions. These may appear before the BEGIN in any
1548 multiline statement. */
1549
1550 suboptions:
1551 /* empty */
1552 {
1553 memset (&$$, 0, sizeof (rc_res_res_info));
1554 $$.language = language;
1555 /* FIXME: Is this the right default? */
1556 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
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;
1572 $$.language = $3 | ($4 << SUBLANG_SHIFT);
1573 }
1574 | suboptions VERSIONK numexpr
1575 {
1576 $$ = $1;
1577 $$.version = $3;
1578 }
1579 ;
1580
1581 /* Memory flags which default to MOVEABLE and DISCARDABLE. */
1582
1583 memflags_move_discard:
1584 /* empty */
1585 {
1586 memset (&$$, 0, sizeof (rc_res_res_info));
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
1600 memflags_move:
1601 /* empty */
1602 {
1603 memset (&$$, 0, sizeof (rc_res_res_info));
1604 $$.language = language;
1605 $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
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
1618 memflag:
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
1658 file_name:
1659 QUOTEDSTRING
1660 {
1661 $$ = $1;
1662 }
1663 | STRING
1664 {
1665 $$ = $1;
1666 }
1667 ;
1668
1669 /* Concat string */
1670 res_unicode_string_concat:
1671 res_unicode_string
1672 {
1673 $$ = $1;
1674 }
1675 |
1676 res_unicode_string_concat res_unicode_string
1677 {
1678 rc_uint_type l1 = unichar_len ($1);
1679 rc_uint_type l2 = unichar_len ($2);
1680 unichar *h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
1681 if (l1 != 0)
1682 memcpy (h, $1, l1 * sizeof (unichar));
1683 if (l2 != 0)
1684 memcpy (h + l1, $2, l2 * sizeof (unichar));
1685 h[l1 + l2] = 0;
1686 $$ = h;
1687 }
1688 ;
1689
1690 res_unicode_string:
1691 QUOTEDUNISTRING
1692 {
1693 $$ = unichar_dup ($1);
1694 }
1695 | QUOTEDSTRING
1696 {
1697 unichar *h = NULL;
1698 unicode_from_ascii ((rc_uint_type *) NULL, &h, $1);
1699 $$ = h;
1700 }
1701 ;
1702
1703 sizedstring:
1704 SIZEDSTRING
1705 {
1706 $$ = $1;
1707 }
1708 | sizedstring SIZEDSTRING
1709 {
1710 rc_uint_type l = $1.length + $2.length;
1711 char *h = (char *) res_alloc (l);
1712 memcpy (h, $1.s, $1.length);
1713 memcpy (h + $1.length, $2.s, $2.length);
1714 $$.s = h;
1715 $$.length = l;
1716 }
1717 ;
1718
1719 sizedunistring:
1720 SIZEDUNISTRING
1721 {
1722 $$ = $1;
1723 }
1724 | sizedunistring SIZEDUNISTRING
1725 {
1726 rc_uint_type l = $1.length + $2.length;
1727 unichar *h = (unichar *) res_alloc (l * sizeof (unichar));
1728 memcpy (h, $1.s, $1.length * sizeof (unichar));
1729 memcpy (h + $1.length, $2.s, $2.length * sizeof (unichar));
1730 $$.s = h;
1731 $$.length = l;
1732 }
1733 ;
1734
1735 /* A style expression. This changes the static variable STYLE. We do
1736 it this way because rc appears to permit a style to be set to
1737 something like
1738 WS_GROUP | NOT WS_TABSTOP
1739 to mean that a default of WS_TABSTOP should be removed. Anything
1740 which wants to accept a style must first set STYLE to the default
1741 value. The styleexpr nonterminal will change STYLE as specified by
1742 the user. Note that we do not accept arbitrary expressions here,
1743 just numbers separated by '|'. */
1744
1745 styleexpr:
1746 parennumber
1747 {
1748 style |= $1;
1749 }
1750 | NOT parennumber
1751 {
1752 style &=~ $2;
1753 }
1754 | styleexpr '|' parennumber
1755 {
1756 style |= $3;
1757 }
1758 | styleexpr '|' NOT parennumber
1759 {
1760 style &=~ $4;
1761 }
1762 ;
1763
1764 parennumber:
1765 NUMBER
1766 {
1767 $$ = $1.val;
1768 }
1769 | '(' numexpr ')'
1770 {
1771 $$ = $2;
1772 }
1773 ;
1774
1775 /* An optional expression with a leading comma. */
1776
1777 optcnumexpr:
1778 /* empty */
1779 {
1780 $$ = 0;
1781 }
1782 | cnumexpr
1783 {
1784 $$ = $1;
1785 }
1786 ;
1787
1788 /* An expression with a leading comma. */
1789
1790 cnumexpr:
1791 ',' numexpr
1792 {
1793 $$ = $2;
1794 }
1795 ;
1796
1797 /* A possibly negated numeric expression. */
1798
1799 numexpr:
1800 sizednumexpr
1801 {
1802 $$ = $1.val;
1803 }
1804 ;
1805
1806 /* A possibly negated expression with a size. */
1807
1808 sizednumexpr:
1809 NUMBER
1810 {
1811 $$ = $1;
1812 }
1813 | '(' sizednumexpr ')'
1814 {
1815 $$ = $2;
1816 }
1817 | '~' sizednumexpr %prec '~'
1818 {
1819 $$.val = ~ $2.val;
1820 $$.dword = $2.dword;
1821 }
1822 | '-' sizednumexpr %prec NEG
1823 {
1824 $$.val = - $2.val;
1825 $$.dword = $2.dword;
1826 }
1827 | sizednumexpr '*' sizednumexpr
1828 {
1829 $$.val = $1.val * $3.val;
1830 $$.dword = $1.dword || $3.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 ;
1868
1869 /* An expression with a leading comma which does not use unary
1870 negation. */
1871
1872 cposnumexpr:
1873 ',' posnumexpr
1874 {
1875 $$ = $2;
1876 }
1877 ;
1878
1879 /* An expression which does not use unary negation. */
1880
1881 posnumexpr:
1882 sizedposnumexpr
1883 {
1884 $$ = $1.val;
1885 }
1886 ;
1887
1888 /* An expression which does not use unary negation. We separate unary
1889 negation to avoid parsing conflicts when two numeric expressions
1890 appear consecutively. */
1891
1892 sizedposnumexpr:
1893 NUMBER
1894 {
1895 $$ = $1;
1896 }
1897 | '(' sizednumexpr ')'
1898 {
1899 $$ = $2;
1900 }
1901 | '~' sizednumexpr %prec '~'
1902 {
1903 $$.val = ~ $2.val;
1904 $$.dword = $2.dword;
1905 }
1906 | sizedposnumexpr '*' sizednumexpr
1907 {
1908 $$.val = $1.val * $3.val;
1909 $$.dword = $1.dword || $3.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 ;
1947
1948 %%
1949
1950 /* Set the language from the command line. */
1951
1952 void
1953 rcparse_set_language (int lang)
1954 {
1955 language = lang;
1956 }
This page took 0.067537 seconds and 5 git commands to generate.