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