138889Sjdp%{ /* rcparse.y -- parser for Windows rc files
2218822Sdim   Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
3218822Sdim   Free Software Foundation, Inc.
438889Sjdp   Written by Ian Lance Taylor, Cygnus Support.
5218822Sdim   Extended by Kai Tietz, Onevision.
638889Sjdp
738889Sjdp   This file is part of GNU Binutils.
838889Sjdp
938889Sjdp   This program is free software; you can redistribute it and/or modify
1038889Sjdp   it under the terms of the GNU General Public License as published by
1138889Sjdp   the Free Software Foundation; either version 2 of the License, or
1238889Sjdp   (at your option) any later version.
1338889Sjdp
1438889Sjdp   This program is distributed in the hope that it will be useful,
1538889Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1638889Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1738889Sjdp   GNU General Public License for more details.
1838889Sjdp
1938889Sjdp   You should have received a copy of the GNU General Public License
2038889Sjdp   along with this program; if not, write to the Free Software
21218822Sdim   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22218822Sdim   02110-1301, USA.  */
2338889Sjdp
2438889Sjdp/* This is a parser for Windows rc files.  It is based on the parser
2538889Sjdp   by Gunther Ebert <gunther.ebert@ixos-leipzig.de>.  */
2638889Sjdp
27218822Sdim#include "sysdep.h"
2838889Sjdp#include "bfd.h"
2938889Sjdp#include "bucomm.h"
3038889Sjdp#include "libiberty.h"
3138889Sjdp#include "windres.h"
3289857Sobrien#include "safe-ctype.h"
3338889Sjdp
3438889Sjdp/* The current language.  */
3538889Sjdp
3638889Sjdpstatic unsigned short language;
3738889Sjdp
3838889Sjdp/* The resource information during a sub statement.  */
3938889Sjdp
40218822Sdimstatic rc_res_res_info sub_res_info;
4138889Sjdp
4238889Sjdp/* Dialog information.  This is built by the nonterminals styles and
4338889Sjdp   controls.  */
4438889Sjdp
45218822Sdimstatic rc_dialog dialog;
4638889Sjdp
4738889Sjdp/* This is used when building a style.  It is modified by the
4838889Sjdp   nonterminal styleexpr.  */
4938889Sjdp
5038889Sjdpstatic unsigned long style;
5138889Sjdp
5238889Sjdp/* These are used when building a control.  They are set before using
5338889Sjdp   control_params.  */
5438889Sjdp
55218822Sdimstatic rc_uint_type base_style;
56218822Sdimstatic rc_uint_type default_style;
57218822Sdimstatic rc_res_id class;
58218822Sdimstatic rc_res_id res_text_field;
59218822Sdimstatic unichar null_unichar;
6038889Sjdp
61218822Sdim/* This is used for COMBOBOX, LISTBOX and EDITTEXT which
62218822Sdim   do not allow resource 'text' field in control definition. */
63218822Sdimstatic const rc_res_id res_null_text = { 1, {{0, &null_unichar}}};
64218822Sdim
6538889Sjdp%}
6638889Sjdp
6738889Sjdp%union
6838889Sjdp{
69218822Sdim  rc_accelerator acc;
70218822Sdim  rc_accelerator *pacc;
71218822Sdim  rc_dialog_control *dialog_control;
72218822Sdim  rc_menuitem *menuitem;
7338889Sjdp  struct
7438889Sjdp  {
75218822Sdim    rc_rcdata_item *first;
76218822Sdim    rc_rcdata_item *last;
7738889Sjdp  } rcdata;
78218822Sdim  rc_rcdata_item *rcdata_item;
79218822Sdim  rc_fixed_versioninfo *fixver;
80218822Sdim  rc_ver_info *verinfo;
81218822Sdim  rc_ver_stringinfo *verstring;
82218822Sdim  rc_ver_varinfo *vervar;
83218822Sdim  rc_toolbar_item *toobar_item;
84218822Sdim  rc_res_id id;
85218822Sdim  rc_res_res_info res_info;
8638889Sjdp  struct
8738889Sjdp  {
88218822Sdim    rc_uint_type on;
89218822Sdim    rc_uint_type off;
9038889Sjdp  } memflags;
9138889Sjdp  struct
9238889Sjdp  {
93218822Sdim    rc_uint_type val;
9438889Sjdp    /* Nonzero if this number was explicitly specified as long.  */
9538889Sjdp    int dword;
9638889Sjdp  } i;
97218822Sdim  rc_uint_type il;
98218822Sdim  rc_uint_type is;
9938889Sjdp  const char *s;
10038889Sjdp  struct
10138889Sjdp  {
102218822Sdim    rc_uint_type length;
10338889Sjdp    const char *s;
10438889Sjdp  } ss;
105218822Sdim  unichar *uni;
106218822Sdim  struct
107218822Sdim  {
108218822Sdim    rc_uint_type length;
109218822Sdim    const unichar *s;
110218822Sdim  } suni;
11138889Sjdp};
11238889Sjdp
11338889Sjdp%token BEG END
11438889Sjdp%token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT
11538889Sjdp%token BITMAP
11638889Sjdp%token CURSOR
11738889Sjdp%token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE
11838889Sjdp%token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT
11938889Sjdp%token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON
12038889Sjdp%token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON
12138889Sjdp%token BEDIT HEDIT IEDIT
12238889Sjdp%token FONT
12338889Sjdp%token ICON
124218822Sdim%token ANICURSOR ANIICON DLGINCLUDE DLGINIT FONTDIR HTML MANIFEST PLUGPLAY VXD TOOLBAR BUTTON
12538889Sjdp%token LANGUAGE CHARACTERISTICS VERSIONK
12638889Sjdp%token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
12738889Sjdp%token MENUBARBREAK MENUBREAK
12838889Sjdp%token MESSAGETABLE
12938889Sjdp%token RCDATA
13038889Sjdp%token STRINGTABLE
13138889Sjdp%token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS
13238889Sjdp%token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO
13338889Sjdp%token VALUE
13438889Sjdp%token <s> BLOCK
13538889Sjdp%token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
13638889Sjdp%token NOT
137218822Sdim%token <uni> QUOTEDUNISTRING
13838889Sjdp%token <s> QUOTEDSTRING STRING
13938889Sjdp%token <i> NUMBER
140218822Sdim%token <suni> SIZEDUNISTRING
14138889Sjdp%token <ss> SIZEDSTRING
14260484Sobrien%token IGNORED_TOKEN
14338889Sjdp
14438889Sjdp%type <pacc> acc_entries
14538889Sjdp%type <acc> acc_entry acc_event
14638889Sjdp%type <dialog_control> control control_params
14738889Sjdp%type <menuitem> menuitems menuitem menuexitems menuexitem
14838889Sjdp%type <rcdata> optrcdata_data optrcdata_data_int rcdata_data
14938889Sjdp%type <rcdata_item> opt_control_data
15038889Sjdp%type <fixver> fixedverinfo
15138889Sjdp%type <verinfo> verblocks
15238889Sjdp%type <verstring> vervals
15338889Sjdp%type <vervar> vertrans
154218822Sdim%type <toobar_item> toolbar_data
15538889Sjdp%type <res_info> suboptions memflags_move_discard memflags_move
15638889Sjdp%type <memflags> memflag
157218822Sdim%type <id> id rcdata_id optresidc resref resid cresid
15838889Sjdp%type <il> exstyle parennumber
15938889Sjdp%type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
16038889Sjdp%type <is> acc_options acc_option menuitem_flags menuitem_flag
161218822Sdim%type <s> file_name
162218822Sdim%type <uni> res_unicode_string resname res_unicode_string_concat
163218822Sdim%type <ss> sizedstring
164218822Sdim%type <suni> sizedunistring
16538889Sjdp%type <i> sizednumexpr sizedposnumexpr
16638889Sjdp
16738889Sjdp%left '|'
16838889Sjdp%left '^'
16938889Sjdp%left '&'
17038889Sjdp%left '+' '-'
17138889Sjdp%left '*' '/' '%'
17238889Sjdp%right '~' NEG
17338889Sjdp
17438889Sjdp%%
17538889Sjdp
17638889Sjdpinput:
17738889Sjdp	  /* empty */
17899461Sobrien	| input accelerator
17999461Sobrien	| input bitmap
18099461Sobrien	| input cursor
18199461Sobrien	| input dialog
18299461Sobrien	| input font
18399461Sobrien	| input icon
18499461Sobrien	| input language
18599461Sobrien	| input menu
18699461Sobrien	| input menuex
18799461Sobrien	| input messagetable
18899461Sobrien	| input stringtable
189218822Sdim	| input toolbar
19099461Sobrien	| input user
19199461Sobrien	| input versioninfo
19299461Sobrien	| input IGNORED_TOKEN
19338889Sjdp	;
19438889Sjdp
19538889Sjdp/* Accelerator resources.  */
19638889Sjdp
19738889Sjdpaccelerator:
19838889Sjdp	  id ACCELERATORS suboptions BEG acc_entries END
19938889Sjdp	  {
20038889Sjdp	    define_accelerator ($1, &$3, $5);
20199461Sobrien	    if (yychar != YYEMPTY)
20299461Sobrien	      YYERROR;
20399461Sobrien	    rcparse_discard_strings ();
20438889Sjdp	  }
20538889Sjdp	;
20638889Sjdp
20738889Sjdpacc_entries:
20838889Sjdp	  /* empty */
20938889Sjdp	  {
21038889Sjdp	    $$ = NULL;
21138889Sjdp	  }
21238889Sjdp	| acc_entries acc_entry
21338889Sjdp	  {
214218822Sdim	    rc_accelerator *a;
21538889Sjdp
216218822Sdim	    a = (rc_accelerator *) res_alloc (sizeof *a);
21738889Sjdp	    *a = $2;
21838889Sjdp	    if ($1 == NULL)
21938889Sjdp	      $$ = a;
22038889Sjdp	    else
22138889Sjdp	      {
222218822Sdim		rc_accelerator **pp;
22338889Sjdp
22438889Sjdp		for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
22538889Sjdp		  ;
22638889Sjdp		*pp = a;
22738889Sjdp		$$ = $1;
22838889Sjdp	      }
22938889Sjdp	  }
23038889Sjdp	;
23138889Sjdp
23238889Sjdpacc_entry:
23338889Sjdp	  acc_event cposnumexpr
23438889Sjdp	  {
23538889Sjdp	    $$ = $1;
23638889Sjdp	    $$.id = $2;
23738889Sjdp	  }
23838889Sjdp	| acc_event cposnumexpr ',' acc_options
23938889Sjdp	  {
24038889Sjdp	    $$ = $1;
24138889Sjdp	    $$.id = $2;
24238889Sjdp	    $$.flags |= $4;
24338889Sjdp	    if (($$.flags & ACC_VIRTKEY) == 0
244104834Sobrien		&& ($$.flags & (ACC_SHIFT | ACC_CONTROL)) != 0)
24560484Sobrien	      rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
24638889Sjdp	  }
24738889Sjdp	;
24838889Sjdp
24938889Sjdpacc_event:
25038889Sjdp	  QUOTEDSTRING
25138889Sjdp	  {
25238889Sjdp	    const char *s = $1;
25338889Sjdp	    char ch;
25438889Sjdp
25538889Sjdp	    $$.next = NULL;
25638889Sjdp	    $$.id = 0;
25738889Sjdp	    ch = *s;
25838889Sjdp	    if (ch != '^')
25938889Sjdp	      $$.flags = 0;
26038889Sjdp	    else
26138889Sjdp	      {
26238889Sjdp		$$.flags = ACC_CONTROL | ACC_VIRTKEY;
26338889Sjdp		++s;
264218822Sdim		ch = TOUPPER (s[0]);
26538889Sjdp	      }
26638889Sjdp	    $$.key = ch;
26738889Sjdp	    if (s[1] != '\0')
26860484Sobrien	      rcparse_warning (_("accelerator should only be one character"));
26938889Sjdp	  }
27038889Sjdp	| posnumexpr
27138889Sjdp	  {
27238889Sjdp	    $$.next = NULL;
27338889Sjdp	    $$.flags = 0;
27438889Sjdp	    $$.id = 0;
27538889Sjdp	    $$.key = $1;
27638889Sjdp	  }
27738889Sjdp	;
27838889Sjdp
27938889Sjdpacc_options:
28038889Sjdp	  acc_option
28138889Sjdp	  {
28238889Sjdp	    $$ = $1;
28338889Sjdp	  }
28438889Sjdp	| acc_options ',' acc_option
28538889Sjdp	  {
28638889Sjdp	    $$ = $1 | $3;
28738889Sjdp	  }
28838889Sjdp	/* I've had one report that the comma is optional.  */
28938889Sjdp	| acc_options acc_option
29038889Sjdp	  {
29138889Sjdp	    $$ = $1 | $2;
29238889Sjdp	  }
29338889Sjdp	;
29438889Sjdp
29538889Sjdpacc_option:
29638889Sjdp	  VIRTKEY
29738889Sjdp	  {
29838889Sjdp	    $$ = ACC_VIRTKEY;
29938889Sjdp	  }
30038889Sjdp	| ASCII
30138889Sjdp	  {
30238889Sjdp	    /* This is just the absence of VIRTKEY.  */
30338889Sjdp	    $$ = 0;
30438889Sjdp	  }
30538889Sjdp	| NOINVERT
30638889Sjdp	  {
30738889Sjdp	    $$ = ACC_NOINVERT;
30838889Sjdp	  }
30938889Sjdp	| SHIFT
31038889Sjdp	  {
31138889Sjdp	    $$ = ACC_SHIFT;
31238889Sjdp	  }
31338889Sjdp	| CONTROL
31438889Sjdp	  {
31538889Sjdp	    $$ = ACC_CONTROL;
31638889Sjdp	  }
31738889Sjdp	| ALT
31838889Sjdp	  {
31938889Sjdp	    $$ = ACC_ALT;
32038889Sjdp	  }
32138889Sjdp	;
32238889Sjdp
32338889Sjdp/* Bitmap resources.  */
32438889Sjdp
32538889Sjdpbitmap:
32638889Sjdp	  id BITMAP memflags_move file_name
32738889Sjdp	  {
32838889Sjdp	    define_bitmap ($1, &$3, $4);
32999461Sobrien	    if (yychar != YYEMPTY)
33099461Sobrien	      YYERROR;
33199461Sobrien	    rcparse_discard_strings ();
33238889Sjdp	  }
33338889Sjdp	;
33438889Sjdp
33538889Sjdp/* Cursor resources.  */
33638889Sjdp
33738889Sjdpcursor:
33838889Sjdp	  id CURSOR memflags_move_discard file_name
33938889Sjdp	  {
34038889Sjdp	    define_cursor ($1, &$3, $4);
34199461Sobrien	    if (yychar != YYEMPTY)
34299461Sobrien	      YYERROR;
34399461Sobrien	    rcparse_discard_strings ();
34438889Sjdp	  }
34538889Sjdp	;
34638889Sjdp
34738889Sjdp/* Dialog resources.  */
34838889Sjdp
34938889Sjdpdialog:
35038889Sjdp	  id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr
35138889Sjdp	    cnumexpr
35238889Sjdp	    {
35338889Sjdp	      memset (&dialog, 0, sizeof dialog);
35438889Sjdp	      dialog.x = $5;
35538889Sjdp	      dialog.y = $6;
35638889Sjdp	      dialog.width = $7;
35738889Sjdp	      dialog.height = $8;
35838889Sjdp	      dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
35938889Sjdp	      dialog.exstyle = $4;
36038889Sjdp	      dialog.menu.named = 1;
36138889Sjdp	      dialog.class.named = 1;
36238889Sjdp	      dialog.font = NULL;
36338889Sjdp	      dialog.ex = NULL;
36438889Sjdp	      dialog.controls = NULL;
36538889Sjdp	      sub_res_info = $3;
36699461Sobrien	      style = 0;
36738889Sjdp	    }
36838889Sjdp	    styles BEG controls END
36938889Sjdp	  {
37038889Sjdp	    define_dialog ($1, &sub_res_info, &dialog);
37199461Sobrien	    if (yychar != YYEMPTY)
37299461Sobrien	      YYERROR;
37399461Sobrien	    rcparse_discard_strings ();
37438889Sjdp	  }
37538889Sjdp	| id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
37638889Sjdp	    cnumexpr
37738889Sjdp	    {
37838889Sjdp	      memset (&dialog, 0, sizeof dialog);
37938889Sjdp	      dialog.x = $5;
38038889Sjdp	      dialog.y = $6;
38138889Sjdp	      dialog.width = $7;
38238889Sjdp	      dialog.height = $8;
38338889Sjdp	      dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
38438889Sjdp	      dialog.exstyle = $4;
38538889Sjdp	      dialog.menu.named = 1;
38638889Sjdp	      dialog.class.named = 1;
38738889Sjdp	      dialog.font = NULL;
388218822Sdim	      dialog.ex = ((rc_dialog_ex *)
389218822Sdim			   res_alloc (sizeof (rc_dialog_ex)));
390218822Sdim	      memset (dialog.ex, 0, sizeof (rc_dialog_ex));
39138889Sjdp	      dialog.controls = NULL;
39238889Sjdp	      sub_res_info = $3;
39399461Sobrien	      style = 0;
39438889Sjdp	    }
39538889Sjdp	    styles BEG controls END
39638889Sjdp	  {
39738889Sjdp	    define_dialog ($1, &sub_res_info, &dialog);
39899461Sobrien	    if (yychar != YYEMPTY)
39999461Sobrien	      YYERROR;
40099461Sobrien	    rcparse_discard_strings ();
40138889Sjdp	  }
40238889Sjdp	| id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
40338889Sjdp	    cnumexpr cnumexpr
40438889Sjdp	    {
40538889Sjdp	      memset (&dialog, 0, sizeof dialog);
40638889Sjdp	      dialog.x = $5;
40738889Sjdp	      dialog.y = $6;
40838889Sjdp	      dialog.width = $7;
40938889Sjdp	      dialog.height = $8;
41038889Sjdp	      dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
41138889Sjdp	      dialog.exstyle = $4;
41238889Sjdp	      dialog.menu.named = 1;
41338889Sjdp	      dialog.class.named = 1;
41438889Sjdp	      dialog.font = NULL;
415218822Sdim	      dialog.ex = ((rc_dialog_ex *)
416218822Sdim			   res_alloc (sizeof (rc_dialog_ex)));
417218822Sdim	      memset (dialog.ex, 0, sizeof (rc_dialog_ex));
41838889Sjdp	      dialog.ex->help = $9;
41938889Sjdp	      dialog.controls = NULL;
42038889Sjdp	      sub_res_info = $3;
42199461Sobrien	      style = 0;
42238889Sjdp	    }
42338889Sjdp	    styles BEG controls END
42438889Sjdp	  {
42538889Sjdp	    define_dialog ($1, &sub_res_info, &dialog);
42699461Sobrien	    if (yychar != YYEMPTY)
42799461Sobrien	      YYERROR;
42899461Sobrien	    rcparse_discard_strings ();
42938889Sjdp	  }
43038889Sjdp	;
43138889Sjdp
43238889Sjdpexstyle:
43338889Sjdp	  /* empty */
43438889Sjdp	  {
43538889Sjdp	    $$ = 0;
43638889Sjdp	  }
43738889Sjdp	| EXSTYLE '=' numexpr
43838889Sjdp	  {
43938889Sjdp	    $$ = $3;
44038889Sjdp	  }
44138889Sjdp	;
44238889Sjdp
44338889Sjdpstyles:
44438889Sjdp	  /* empty */
445218822Sdim	| styles CAPTION res_unicode_string_concat
44638889Sjdp	  {
44799461Sobrien	    dialog.style |= WS_CAPTION;
44899461Sobrien	    style |= WS_CAPTION;
449218822Sdim	    dialog.caption = $3;
45038889Sjdp	  }
45138889Sjdp	| styles CLASS id
45238889Sjdp	  {
45338889Sjdp	    dialog.class = $3;
45438889Sjdp	  }
45538889Sjdp	| styles STYLE
45638889Sjdp	    styleexpr
45738889Sjdp	  {
45838889Sjdp	    dialog.style = style;
45938889Sjdp	  }
46038889Sjdp	| styles EXSTYLE numexpr
46138889Sjdp	  {
46238889Sjdp	    dialog.exstyle = $3;
46338889Sjdp	  }
464218822Sdim	| styles CLASS res_unicode_string_concat
46599461Sobrien	  {
466218822Sdim	    res_unistring_to_id (& dialog.class, $3);
46799461Sobrien	  }
468218822Sdim	| styles FONT numexpr ',' res_unicode_string_concat
46938889Sjdp	  {
47038889Sjdp	    dialog.style |= DS_SETFONT;
47199461Sobrien	    style |= DS_SETFONT;
47238889Sjdp	    dialog.pointsize = $3;
473218822Sdim	    dialog.font = $5;
47499461Sobrien	    if (dialog.ex != NULL)
47599461Sobrien	      {
47699461Sobrien		dialog.ex->weight = 0;
47799461Sobrien		dialog.ex->italic = 0;
47899461Sobrien		dialog.ex->charset = 1;
47999461Sobrien	      }
48038889Sjdp	  }
481218822Sdim	| styles FONT numexpr ',' res_unicode_string_concat cnumexpr
48299461Sobrien	  {
48399461Sobrien	    dialog.style |= DS_SETFONT;
48499461Sobrien	    style |= DS_SETFONT;
48599461Sobrien	    dialog.pointsize = $3;
486218822Sdim	    dialog.font = $5;
48799461Sobrien	    if (dialog.ex == NULL)
48899461Sobrien	      rcparse_warning (_("extended FONT requires DIALOGEX"));
48999461Sobrien	    else
49099461Sobrien	      {
49199461Sobrien		dialog.ex->weight = $6;
49299461Sobrien		dialog.ex->italic = 0;
49399461Sobrien		dialog.ex->charset = 1;
49499461Sobrien	      }
49599461Sobrien	  }
496218822Sdim	| styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr
49738889Sjdp	  {
49838889Sjdp	    dialog.style |= DS_SETFONT;
49999461Sobrien	    style |= DS_SETFONT;
50038889Sjdp	    dialog.pointsize = $3;
501218822Sdim	    dialog.font = $5;
50238889Sjdp	    if (dialog.ex == NULL)
50360484Sobrien	      rcparse_warning (_("extended FONT requires DIALOGEX"));
50438889Sjdp	    else
50538889Sjdp	      {
50638889Sjdp		dialog.ex->weight = $6;
50738889Sjdp		dialog.ex->italic = $7;
50899461Sobrien		dialog.ex->charset = 1;
50938889Sjdp	      }
51038889Sjdp	  }
511218822Sdim	| styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr cnumexpr
51299461Sobrien	  {
51399461Sobrien	    dialog.style |= DS_SETFONT;
51499461Sobrien	    style |= DS_SETFONT;
51599461Sobrien	    dialog.pointsize = $3;
516218822Sdim	    dialog.font = $5;
51799461Sobrien	    if (dialog.ex == NULL)
51899461Sobrien	      rcparse_warning (_("extended FONT requires DIALOGEX"));
51999461Sobrien	    else
52099461Sobrien	      {
52199461Sobrien		dialog.ex->weight = $6;
52299461Sobrien		dialog.ex->italic = $7;
52399461Sobrien		dialog.ex->charset = $8;
52499461Sobrien	      }
52599461Sobrien	  }
52638889Sjdp	| styles MENU id
52738889Sjdp	  {
52838889Sjdp	    dialog.menu = $3;
52938889Sjdp	  }
53038889Sjdp	| styles CHARACTERISTICS numexpr
53138889Sjdp	  {
53238889Sjdp	    sub_res_info.characteristics = $3;
53338889Sjdp	  }
53438889Sjdp	| styles LANGUAGE numexpr cnumexpr
53538889Sjdp	  {
53689857Sobrien	    sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT);
53738889Sjdp	  }
53838889Sjdp	| styles VERSIONK numexpr
53938889Sjdp	  {
54038889Sjdp	    sub_res_info.version = $3;
54138889Sjdp	  }
54238889Sjdp	;
54338889Sjdp
54438889Sjdpcontrols:
54538889Sjdp	  /* empty */
54638889Sjdp	| controls control
54738889Sjdp	  {
548218822Sdim	    rc_dialog_control **pp;
54938889Sjdp
55038889Sjdp	    for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
55138889Sjdp	      ;
55238889Sjdp	    *pp = $2;
55338889Sjdp	  }
55438889Sjdp	;
55538889Sjdp
55638889Sjdpcontrol:
557218822Sdim	  AUTO3STATE optresidc
55838889Sjdp	    {
55938889Sjdp	      default_style = BS_AUTO3STATE | WS_TABSTOP;
56038889Sjdp	      base_style = BS_AUTO3STATE;
561218822Sdim	      class.named = 0;
562218822Sdim	      class.u.id = CTL_BUTTON;
563218822Sdim	      res_text_field = $2;
56438889Sjdp	    }
56538889Sjdp	    control_params
56638889Sjdp	  {
567218822Sdim	    $$ = $4;
56838889Sjdp	  }
569218822Sdim	| AUTOCHECKBOX optresidc
57038889Sjdp	    {
57138889Sjdp	      default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
57238889Sjdp	      base_style = BS_AUTOCHECKBOX;
573218822Sdim	      class.named = 0;
574218822Sdim	      class.u.id = CTL_BUTTON;
575218822Sdim	      res_text_field = $2;
57638889Sjdp	    }
57738889Sjdp	    control_params
57838889Sjdp	  {
579218822Sdim	    $$ = $4;
58038889Sjdp	  }
581218822Sdim	| AUTORADIOBUTTON optresidc
58238889Sjdp	    {
58338889Sjdp	      default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
58438889Sjdp	      base_style = BS_AUTORADIOBUTTON;
585218822Sdim	      class.named = 0;
586218822Sdim	      class.u.id = CTL_BUTTON;
587218822Sdim	      res_text_field = $2;
58838889Sjdp	    }
58938889Sjdp	    control_params
59038889Sjdp	  {
591218822Sdim	    $$ = $4;
59238889Sjdp	  }
593218822Sdim	| BEDIT optresidc
59438889Sjdp	    {
59538889Sjdp	      default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
59638889Sjdp	      base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
597218822Sdim	      class.named = 0;
598218822Sdim	      class.u.id = CTL_EDIT;
599218822Sdim	      res_text_field = $2;
60038889Sjdp	    }
60138889Sjdp	    control_params
60238889Sjdp	  {
603218822Sdim	    $$ = $4;
60438889Sjdp	    if (dialog.ex == NULL)
60599461Sobrien	      rcparse_warning (_("BEDIT requires DIALOGEX"));
60638889Sjdp	    res_string_to_id (&$$->class, "BEDIT");
60738889Sjdp	  }
608218822Sdim	| CHECKBOX optresidc
60938889Sjdp	    {
61038889Sjdp	      default_style = BS_CHECKBOX | WS_TABSTOP;
61138889Sjdp	      base_style = BS_CHECKBOX | WS_TABSTOP;
612218822Sdim	      class.named = 0;
613218822Sdim	      class.u.id = CTL_BUTTON;
614218822Sdim	      res_text_field = $2;
61538889Sjdp	    }
61638889Sjdp	    control_params
61738889Sjdp	  {
618218822Sdim	    $$ = $4;
61938889Sjdp	  }
62038889Sjdp	| COMBOBOX
62138889Sjdp	    {
622218822Sdim	      /* This is as per MSDN documentation.  With some (???)
623218822Sdim		 versions of MS rc.exe their is no default style.  */
62438889Sjdp	      default_style = CBS_SIMPLE | WS_TABSTOP;
62538889Sjdp	      base_style = 0;
626218822Sdim	      class.named = 0;
627218822Sdim	      class.u.id = CTL_COMBOBOX;
628218822Sdim	      res_text_field = res_null_text;
62938889Sjdp	    }
63038889Sjdp	    control_params
63138889Sjdp	  {
63238889Sjdp	    $$ = $3;
63338889Sjdp	  }
634218822Sdim	| CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
63538889Sjdp	    cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
63638889Sjdp	  {
63738889Sjdp	    $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
63838889Sjdp	    if ($11 != NULL)
63938889Sjdp	      {
64038889Sjdp		if (dialog.ex == NULL)
64160484Sobrien		  rcparse_warning (_("control data requires DIALOGEX"));
64238889Sjdp		$$->data = $11;
64338889Sjdp	      }
64438889Sjdp	  }
645218822Sdim	| CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
64638889Sjdp	    cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
64738889Sjdp	  {
64838889Sjdp	    $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
64938889Sjdp	    if (dialog.ex == NULL)
65060484Sobrien	      rcparse_warning (_("help ID requires DIALOGEX"));
65138889Sjdp	    $$->help = $11;
65238889Sjdp	    $$->data = $12;
65338889Sjdp	  }
654218822Sdim	| CTEXT optresidc
65538889Sjdp	    {
65638889Sjdp	      default_style = SS_CENTER | WS_GROUP;
65738889Sjdp	      base_style = SS_CENTER;
658218822Sdim	      class.named = 0;
659218822Sdim	      class.u.id = CTL_STATIC;
660218822Sdim	      res_text_field = $2;
66138889Sjdp	    }
66238889Sjdp	    control_params
66338889Sjdp	  {
664218822Sdim	    $$ = $4;
66538889Sjdp	  }
666218822Sdim	| DEFPUSHBUTTON optresidc
66738889Sjdp	    {
66838889Sjdp	      default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
66938889Sjdp	      base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
670218822Sdim	      class.named = 0;
671218822Sdim	      class.u.id = CTL_BUTTON;
672218822Sdim	      res_text_field = $2;
67338889Sjdp	    }
67438889Sjdp	    control_params
67538889Sjdp	  {
676218822Sdim	    $$ = $4;
67738889Sjdp	  }
67838889Sjdp	| EDITTEXT
67938889Sjdp	    {
68038889Sjdp	      default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
68138889Sjdp	      base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
682218822Sdim	      class.named = 0;
683218822Sdim	      class.u.id = CTL_EDIT;
684218822Sdim	      res_text_field = res_null_text;
68538889Sjdp	    }
68638889Sjdp	    control_params
68738889Sjdp	  {
68838889Sjdp	    $$ = $3;
68938889Sjdp	  }
690218822Sdim	| GROUPBOX optresidc
69138889Sjdp	    {
69238889Sjdp	      default_style = BS_GROUPBOX;
69338889Sjdp	      base_style = BS_GROUPBOX;
694218822Sdim	      class.named = 0;
695218822Sdim	      class.u.id = CTL_BUTTON;
696218822Sdim	      res_text_field = $2;
69738889Sjdp	    }
69838889Sjdp	    control_params
69938889Sjdp	  {
700218822Sdim	    $$ = $4;
70138889Sjdp	  }
702218822Sdim	| HEDIT optresidc
70338889Sjdp	    {
70438889Sjdp	      default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
70538889Sjdp	      base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
706218822Sdim	      class.named = 0;
707218822Sdim	      class.u.id = CTL_EDIT;
708218822Sdim	      res_text_field = $2;
70938889Sjdp	    }
71038889Sjdp	    control_params
71138889Sjdp	  {
712218822Sdim	    $$ = $4;
71338889Sjdp	    if (dialog.ex == NULL)
71460484Sobrien	      rcparse_warning (_("IEDIT requires DIALOGEX"));
71538889Sjdp	    res_string_to_id (&$$->class, "HEDIT");
71638889Sjdp	  }
71777298Sobrien	| ICON resref numexpr cnumexpr cnumexpr opt_control_data
71877298Sobrien          {
71977298Sobrien	    $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $6,
72077298Sobrien				      dialog.ex);
72177298Sobrien          }
72277298Sobrien	| ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
72377298Sobrien	    opt_control_data
72477298Sobrien          {
72577298Sobrien	    $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $8,
72677298Sobrien				      dialog.ex);
72777298Sobrien          }
72877298Sobrien	| ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
72938889Sjdp	    icon_styleexpr optcnumexpr opt_control_data
73077298Sobrien          {
73177298Sobrien	    $$ = define_icon_control ($2, $3, $4, $5, style, $9, 0, $10,
73277298Sobrien				      dialog.ex);
73377298Sobrien          }
73477298Sobrien	| ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
73538889Sjdp	    icon_styleexpr cnumexpr cnumexpr opt_control_data
73677298Sobrien          {
73777298Sobrien	    $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11,
73877298Sobrien				      dialog.ex);
73977298Sobrien          }
740218822Sdim	| IEDIT optresidc
74138889Sjdp	    {
74238889Sjdp	      default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
74338889Sjdp	      base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
744218822Sdim	      class.named = 0;
745218822Sdim	      class.u.id = CTL_EDIT;
746218822Sdim	      res_text_field = $2;
74738889Sjdp	    }
74838889Sjdp	    control_params
74938889Sjdp	  {
750218822Sdim	    $$ = $4;
75138889Sjdp	    if (dialog.ex == NULL)
75260484Sobrien	      rcparse_warning (_("IEDIT requires DIALOGEX"));
75338889Sjdp	    res_string_to_id (&$$->class, "IEDIT");
75438889Sjdp	  }
75538889Sjdp	| LISTBOX
75638889Sjdp	    {
75738889Sjdp	      default_style = LBS_NOTIFY | WS_BORDER;
75838889Sjdp	      base_style = LBS_NOTIFY | WS_BORDER;
759218822Sdim	      class.named = 0;
760218822Sdim	      class.u.id = CTL_LISTBOX;
761218822Sdim	      res_text_field = res_null_text;
76238889Sjdp	    }
76338889Sjdp	    control_params
76438889Sjdp	  {
76538889Sjdp	    $$ = $3;
76638889Sjdp	  }
767218822Sdim	| LTEXT optresidc
76838889Sjdp	    {
76938889Sjdp	      default_style = SS_LEFT | WS_GROUP;
77038889Sjdp	      base_style = SS_LEFT;
771218822Sdim	      class.named = 0;
772218822Sdim	      class.u.id = CTL_STATIC;
773218822Sdim	      res_text_field = $2;
77438889Sjdp	    }
77538889Sjdp	    control_params
77638889Sjdp	  {
777218822Sdim	    $$ = $4;
77838889Sjdp	  }
779218822Sdim	| PUSHBOX optresidc
78038889Sjdp	    {
78138889Sjdp	      default_style = BS_PUSHBOX | WS_TABSTOP;
78238889Sjdp	      base_style = BS_PUSHBOX;
783218822Sdim	      class.named = 0;
784218822Sdim	      class.u.id = CTL_BUTTON;
78538889Sjdp	    }
78638889Sjdp	    control_params
78738889Sjdp	  {
788218822Sdim	    $$ = $4;
78938889Sjdp	  }
790218822Sdim	| PUSHBUTTON optresidc
79138889Sjdp	    {
79238889Sjdp	      default_style = BS_PUSHBUTTON | WS_TABSTOP;
79338889Sjdp	      base_style = BS_PUSHBUTTON | WS_TABSTOP;
794218822Sdim	      class.named = 0;
795218822Sdim	      class.u.id = CTL_BUTTON;
796218822Sdim	      res_text_field = $2;
79738889Sjdp	    }
79838889Sjdp	    control_params
79938889Sjdp	  {
800218822Sdim	    $$ = $4;
80138889Sjdp	  }
802218822Sdim	| RADIOBUTTON optresidc
80338889Sjdp	    {
80438889Sjdp	      default_style = BS_RADIOBUTTON | WS_TABSTOP;
80538889Sjdp	      base_style = BS_RADIOBUTTON;
806218822Sdim	      class.named = 0;
807218822Sdim	      class.u.id = CTL_BUTTON;
808218822Sdim	      res_text_field = $2;
80938889Sjdp	    }
81038889Sjdp	    control_params
81138889Sjdp	  {
812218822Sdim	    $$ = $4;
81338889Sjdp	  }
814218822Sdim	| RTEXT optresidc
81538889Sjdp	    {
81638889Sjdp	      default_style = SS_RIGHT | WS_GROUP;
81738889Sjdp	      base_style = SS_RIGHT;
818218822Sdim	      class.named = 0;
819218822Sdim	      class.u.id = CTL_STATIC;
820218822Sdim	      res_text_field = $2;
82138889Sjdp	    }
82238889Sjdp	    control_params
82338889Sjdp	  {
824218822Sdim	    $$ = $4;
82538889Sjdp	  }
82638889Sjdp	| SCROLLBAR
82738889Sjdp	    {
82838889Sjdp	      default_style = SBS_HORZ;
82938889Sjdp	      base_style = 0;
830218822Sdim	      class.named = 0;
831218822Sdim	      class.u.id = CTL_SCROLLBAR;
832218822Sdim	      res_text_field = res_null_text;
83338889Sjdp	    }
83438889Sjdp	    control_params
83538889Sjdp	  {
83638889Sjdp	    $$ = $3;
83738889Sjdp	  }
838218822Sdim	| STATE3 optresidc
83938889Sjdp	    {
84038889Sjdp	      default_style = BS_3STATE | WS_TABSTOP;
84138889Sjdp	      base_style = BS_3STATE;
842218822Sdim	      class.named = 0;
843218822Sdim	      class.u.id = CTL_BUTTON;
844218822Sdim	      res_text_field = $2;
84538889Sjdp	    }
84638889Sjdp	    control_params
84738889Sjdp	  {
848218822Sdim	    $$ = $4;
84938889Sjdp	  }
850218822Sdim	| USERBUTTON resref numexpr ',' numexpr ',' numexpr ','
85138889Sjdp	    numexpr ',' numexpr ','
85238889Sjdp	    { style = WS_CHILD | WS_VISIBLE; }
85338889Sjdp	    styleexpr optcnumexpr
85438889Sjdp	  {
855218822Sdim	    rc_res_id cid;
856218822Sdim	    cid.named = 0;
857218822Sdim	    cid.u.id = CTL_BUTTON;
858218822Sdim	    $$ = define_control ($2, $3, $5, $7, $9, $11, cid,
859218822Sdim				 style, $15);
86038889Sjdp	  }
86138889Sjdp	;
86238889Sjdp
86338889Sjdp/* Parameters for a control.  The static variables DEFAULT_STYLE,
86438889Sjdp   BASE_STYLE, and CLASS must be initialized before this nonterminal
86538889Sjdp   is used.  DEFAULT_STYLE is the style to use if no style expression
86638889Sjdp   is specified.  BASE_STYLE is the base style to use if a style
86738889Sjdp   expression is specified; the style expression modifies the base
86838889Sjdp   style.  CLASS is the class of the control.  */
86938889Sjdp
87038889Sjdpcontrol_params:
871218822Sdim	  numexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
87238889Sjdp	  {
873218822Sdim	    $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class,
87438889Sjdp				 default_style | WS_CHILD | WS_VISIBLE, 0);
875218822Sdim	    if ($6 != NULL)
87638889Sjdp	      {
87738889Sjdp		if (dialog.ex == NULL)
87860484Sobrien		  rcparse_warning (_("control data requires DIALOGEX"));
879218822Sdim		$$->data = $6;
88038889Sjdp	      }
88138889Sjdp	  }
882218822Sdim	| numexpr cnumexpr cnumexpr cnumexpr cnumexpr
88338889Sjdp	    control_params_styleexpr optcnumexpr opt_control_data
88438889Sjdp	  {
885218822Sdim	    $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
886218822Sdim	    if ($8 != NULL)
88738889Sjdp	      {
88838889Sjdp		if (dialog.ex == NULL)
88960484Sobrien		  rcparse_warning (_("control data requires DIALOGEX"));
890218822Sdim		$$->data = $8;
89138889Sjdp	      }
89238889Sjdp	  }
893218822Sdim	| numexpr cnumexpr cnumexpr cnumexpr cnumexpr
89438889Sjdp	    control_params_styleexpr cnumexpr cnumexpr opt_control_data
89538889Sjdp	  {
896218822Sdim	    $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
89738889Sjdp	    if (dialog.ex == NULL)
89860484Sobrien	      rcparse_warning (_("help ID requires DIALOGEX"));
899218822Sdim	    $$->help = $8;
900218822Sdim	    $$->data = $9;
90138889Sjdp	  }
90238889Sjdp	;
90338889Sjdp
904218822Sdimcresid:
905218822Sdim	  ',' resid
906218822Sdim	  {
907218822Sdim	    if ($2.named)
908218822Sdim	      res_unistring_to_id (&$$, $2.u.n.name);
909218822Sdim	    else
910218822Sdim	      $$=$2;
911218822Sdim	  }
912218822Sdim	;
913218822Sdim
914218822Sdimoptresidc:
91538889Sjdp	  /* empty */
91638889Sjdp	  {
917218822Sdim	    res_string_to_id (&$$, "");
91838889Sjdp	  }
919218822Sdim	| resid ',' { $$=$1; }
920218822Sdim	;
921218822Sdim
922218822Sdimresid:
923218822Sdim	  posnumexpr
92477298Sobrien	  {
925218822Sdim	    $$.named = 0;
926218822Sdim	    $$.u.id = $1;
92777298Sobrien	  }
928218822Sdim	| res_unicode_string
92938889Sjdp	  {
930218822Sdim	    $$.named = 1;
931218822Sdim	    $$.u.n.name = $1;
932218822Sdim	    $$.u.n.length = unichar_len ($1);
93338889Sjdp	  }
93438889Sjdp	;
93538889Sjdp
93638889Sjdpopt_control_data:
93738889Sjdp	  /* empty */
93838889Sjdp	  {
93938889Sjdp	    $$ = NULL;
94038889Sjdp	  }
94138889Sjdp	| BEG optrcdata_data END
94238889Sjdp	  {
94338889Sjdp	    $$ = $2.first;
94438889Sjdp	  }
94538889Sjdp	;
94638889Sjdp
94738889Sjdp/* These only exist to parse a reduction out of a common case.  */
94838889Sjdp
94938889Sjdpcontrol_styleexpr:
95038889Sjdp	  ','
95138889Sjdp	  { style = WS_CHILD | WS_VISIBLE; }
95238889Sjdp	  styleexpr
95338889Sjdp	;
95438889Sjdp
95538889Sjdpicon_styleexpr:
95638889Sjdp	  ','
95738889Sjdp	  { style = SS_ICON | WS_CHILD | WS_VISIBLE; }
95838889Sjdp	  styleexpr
95938889Sjdp	;
96038889Sjdp
96138889Sjdpcontrol_params_styleexpr:
96238889Sjdp	  ','
96338889Sjdp	  { style = base_style | WS_CHILD | WS_VISIBLE; }
96438889Sjdp	  styleexpr
96538889Sjdp	;
96638889Sjdp
96738889Sjdp/* Font resources.  */
96838889Sjdp
96938889Sjdpfont:
97038889Sjdp	  id FONT memflags_move_discard file_name
97138889Sjdp	  {
97238889Sjdp	    define_font ($1, &$3, $4);
97399461Sobrien	    if (yychar != YYEMPTY)
97499461Sobrien	      YYERROR;
97599461Sobrien	    rcparse_discard_strings ();
97638889Sjdp	  }
97738889Sjdp	;
97838889Sjdp
97938889Sjdp/* Icon resources.  */
98038889Sjdp
98138889Sjdpicon:
98238889Sjdp	  id ICON memflags_move_discard file_name
98338889Sjdp	  {
98438889Sjdp	    define_icon ($1, &$3, $4);
98599461Sobrien	    if (yychar != YYEMPTY)
98699461Sobrien	      YYERROR;
98799461Sobrien	    rcparse_discard_strings ();
98838889Sjdp	  }
98938889Sjdp	;
99038889Sjdp
99138889Sjdp/* Language command.  This changes the static variable language, which
99238889Sjdp   affects all subsequent resources.  */
99338889Sjdp
99438889Sjdplanguage:
99538889Sjdp	  LANGUAGE numexpr cnumexpr
99638889Sjdp	  {
99789857Sobrien	    language = $2 | ($3 << SUBLANG_SHIFT);
99838889Sjdp	  }
99938889Sjdp	;
100038889Sjdp
100138889Sjdp/* Menu resources.  */
100238889Sjdp
100338889Sjdpmenu:
100438889Sjdp	  id MENU suboptions BEG menuitems END
100538889Sjdp	  {
100638889Sjdp	    define_menu ($1, &$3, $5);
100799461Sobrien	    if (yychar != YYEMPTY)
100899461Sobrien	      YYERROR;
100999461Sobrien	    rcparse_discard_strings ();
101038889Sjdp	  }
101138889Sjdp	;
101238889Sjdp
101338889Sjdpmenuitems:
101438889Sjdp	  /* empty */
101538889Sjdp	  {
101638889Sjdp	    $$ = NULL;
101738889Sjdp	  }
101838889Sjdp	| menuitems menuitem
101938889Sjdp	  {
102038889Sjdp	    if ($1 == NULL)
102138889Sjdp	      $$ = $2;
102238889Sjdp	    else
102338889Sjdp	      {
1024218822Sdim		rc_menuitem **pp;
102538889Sjdp
102638889Sjdp		for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
102738889Sjdp		  ;
102838889Sjdp		*pp = $2;
102938889Sjdp		$$ = $1;
103038889Sjdp	      }
103138889Sjdp	  }
103238889Sjdp	;
103338889Sjdp
103438889Sjdpmenuitem:
1035218822Sdim	  MENUITEM res_unicode_string_concat cnumexpr menuitem_flags
103638889Sjdp	  {
103738889Sjdp	    $$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
103838889Sjdp	  }
103938889Sjdp	| MENUITEM SEPARATOR
104038889Sjdp	  {
104138889Sjdp	    $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
104238889Sjdp	  }
1043218822Sdim	| POPUP res_unicode_string_concat menuitem_flags BEG menuitems END
104438889Sjdp	  {
104538889Sjdp	    $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
104638889Sjdp	  }
104738889Sjdp	;
104838889Sjdp
104938889Sjdpmenuitem_flags:
105038889Sjdp	  /* empty */
105138889Sjdp	  {
105238889Sjdp	    $$ = 0;
105338889Sjdp	  }
105438889Sjdp	| menuitem_flags ',' menuitem_flag
105538889Sjdp	  {
105638889Sjdp	    $$ = $1 | $3;
105738889Sjdp	  }
105838889Sjdp	| menuitem_flags menuitem_flag
105938889Sjdp	  {
106038889Sjdp	    $$ = $1 | $2;
106138889Sjdp	  }
106238889Sjdp	;
106338889Sjdp
106438889Sjdpmenuitem_flag:
106538889Sjdp	  CHECKED
106638889Sjdp	  {
106738889Sjdp	    $$ = MENUITEM_CHECKED;
106838889Sjdp	  }
106938889Sjdp	| GRAYED
107038889Sjdp	  {
107138889Sjdp	    $$ = MENUITEM_GRAYED;
107238889Sjdp	  }
107338889Sjdp	| HELP
107438889Sjdp	  {
107538889Sjdp	    $$ = MENUITEM_HELP;
107638889Sjdp	  }
107738889Sjdp	| INACTIVE
107838889Sjdp	  {
107938889Sjdp	    $$ = MENUITEM_INACTIVE;
108038889Sjdp	  }
108138889Sjdp	| MENUBARBREAK
108238889Sjdp	  {
108338889Sjdp	    $$ = MENUITEM_MENUBARBREAK;
108438889Sjdp	  }
108538889Sjdp	| MENUBREAK
108638889Sjdp	  {
108738889Sjdp	    $$ = MENUITEM_MENUBREAK;
108838889Sjdp	  }
108938889Sjdp	;
109038889Sjdp
109138889Sjdp/* Menuex resources.  */
109238889Sjdp
109338889Sjdpmenuex:
109438889Sjdp	  id MENUEX suboptions BEG menuexitems END
109538889Sjdp	  {
109638889Sjdp	    define_menu ($1, &$3, $5);
109799461Sobrien	    if (yychar != YYEMPTY)
109899461Sobrien	      YYERROR;
109999461Sobrien	    rcparse_discard_strings ();
110038889Sjdp	  }
110138889Sjdp	;
110238889Sjdp
110338889Sjdpmenuexitems:
110438889Sjdp	  /* empty */
110538889Sjdp	  {
110638889Sjdp	    $$ = NULL;
110738889Sjdp	  }
110838889Sjdp	| menuexitems menuexitem
110938889Sjdp	  {
111038889Sjdp	    if ($1 == NULL)
111138889Sjdp	      $$ = $2;
111238889Sjdp	    else
111338889Sjdp	      {
1114218822Sdim		rc_menuitem **pp;
111538889Sjdp
111638889Sjdp		for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
111738889Sjdp		  ;
111838889Sjdp		*pp = $2;
111938889Sjdp		$$ = $1;
112038889Sjdp	      }
112138889Sjdp	  }
112238889Sjdp	;
112338889Sjdp
112438889Sjdpmenuexitem:
1125218822Sdim	  MENUITEM res_unicode_string_concat
112638889Sjdp	  {
112738889Sjdp	    $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
112838889Sjdp	  }
1129218822Sdim	| MENUITEM res_unicode_string_concat cnumexpr
113038889Sjdp	  {
113138889Sjdp	    $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
113238889Sjdp	  }
1133218822Sdim	| MENUITEM res_unicode_string_concat cnumexpr cnumexpr optcnumexpr
113438889Sjdp	  {
113538889Sjdp	    $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
113638889Sjdp	  }
113760484Sobrien 	| MENUITEM SEPARATOR
113860484Sobrien 	  {
113960484Sobrien 	    $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
114060484Sobrien 	  }
1141218822Sdim	| POPUP res_unicode_string_concat BEG menuexitems END
114238889Sjdp	  {
114338889Sjdp	    $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
114438889Sjdp	  }
1145218822Sdim	| POPUP res_unicode_string_concat cnumexpr BEG menuexitems END
114638889Sjdp	  {
114738889Sjdp	    $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
114838889Sjdp	  }
1149218822Sdim	| POPUP res_unicode_string_concat cnumexpr cnumexpr BEG menuexitems END
115038889Sjdp	  {
115138889Sjdp	    $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
115238889Sjdp	  }
1153218822Sdim	| POPUP res_unicode_string_concat cnumexpr cnumexpr cnumexpr optcnumexpr
115438889Sjdp	    BEG menuexitems END
115538889Sjdp	  {
115638889Sjdp	    $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
115738889Sjdp	  }
115838889Sjdp	;
115938889Sjdp
116038889Sjdp/* Messagetable resources.  */
116138889Sjdp
116238889Sjdpmessagetable:
116338889Sjdp	  id MESSAGETABLE memflags_move file_name
116438889Sjdp	  {
116538889Sjdp	    define_messagetable ($1, &$3, $4);
116699461Sobrien	    if (yychar != YYEMPTY)
116799461Sobrien	      YYERROR;
116899461Sobrien	    rcparse_discard_strings ();
116938889Sjdp	  }
117038889Sjdp	;
117138889Sjdp
117238889Sjdp/* We use a different lexing algorithm, because rcdata strings may
117338889Sjdp   contain embedded null bytes, and we need to know the length to use.  */
117438889Sjdp
117538889Sjdpoptrcdata_data:
117638889Sjdp	  {
117738889Sjdp	    rcparse_rcdata ();
117838889Sjdp	  }
117938889Sjdp	  optrcdata_data_int
118038889Sjdp	  {
118138889Sjdp	    rcparse_normal ();
118238889Sjdp	    $$ = $2;
118338889Sjdp	  }
118438889Sjdp	;
118538889Sjdp
118638889Sjdpoptrcdata_data_int:
118738889Sjdp	  /* empty */
118838889Sjdp	  {
118938889Sjdp	    $$.first = NULL;
119038889Sjdp	    $$.last = NULL;
119138889Sjdp	  }
119238889Sjdp	| rcdata_data
119338889Sjdp	  {
119438889Sjdp	    $$ = $1;
119538889Sjdp	  }
119638889Sjdp	;
119738889Sjdp
119838889Sjdprcdata_data:
1199218822Sdim	  sizedstring
120038889Sjdp	  {
1201218822Sdim	    rc_rcdata_item *ri;
120238889Sjdp
120338889Sjdp	    ri = define_rcdata_string ($1.s, $1.length);
120438889Sjdp	    $$.first = ri;
120538889Sjdp	    $$.last = ri;
120638889Sjdp	  }
1207218822Sdim	| sizedunistring
1208218822Sdim	  {
1209218822Sdim	    rc_rcdata_item *ri;
1210218822Sdim
1211218822Sdim	    ri = define_rcdata_unistring ($1.s, $1.length);
1212218822Sdim	    $$.first = ri;
1213218822Sdim	    $$.last = ri;
1214218822Sdim	  }
121538889Sjdp	| sizednumexpr
121638889Sjdp	  {
1217218822Sdim	    rc_rcdata_item *ri;
121838889Sjdp
121938889Sjdp	    ri = define_rcdata_number ($1.val, $1.dword);
122038889Sjdp	    $$.first = ri;
122138889Sjdp	    $$.last = ri;
122238889Sjdp	  }
1223218822Sdim	| rcdata_data ',' sizedstring
122438889Sjdp	  {
1225218822Sdim	    rc_rcdata_item *ri;
122638889Sjdp
122738889Sjdp	    ri = define_rcdata_string ($3.s, $3.length);
122838889Sjdp	    $$.first = $1.first;
122938889Sjdp	    $1.last->next = ri;
123038889Sjdp	    $$.last = ri;
123138889Sjdp	  }
1232218822Sdim	| rcdata_data ',' sizedunistring
1233218822Sdim	  {
1234218822Sdim	    rc_rcdata_item *ri;
1235218822Sdim
1236218822Sdim	    ri = define_rcdata_unistring ($3.s, $3.length);
1237218822Sdim	    $$.first = $1.first;
1238218822Sdim	    $1.last->next = ri;
1239218822Sdim	    $$.last = ri;
1240218822Sdim	  }
124138889Sjdp	| rcdata_data ',' sizednumexpr
124238889Sjdp	  {
1243218822Sdim	    rc_rcdata_item *ri;
124438889Sjdp
124538889Sjdp	    ri = define_rcdata_number ($3.val, $3.dword);
124638889Sjdp	    $$.first = $1.first;
124738889Sjdp	    $1.last->next = ri;
124838889Sjdp	    $$.last = ri;
124938889Sjdp	  }
125038889Sjdp	;
125138889Sjdp
125238889Sjdp/* Stringtable resources.  */
125338889Sjdp
125438889Sjdpstringtable:
125538889Sjdp	  STRINGTABLE suboptions BEG
125638889Sjdp	    { sub_res_info = $2; }
125738889Sjdp	    string_data END
125838889Sjdp	;
125938889Sjdp
126038889Sjdpstring_data:
126138889Sjdp	  /* empty */
1262218822Sdim	| string_data numexpr res_unicode_string_concat
126338889Sjdp	  {
126438889Sjdp	    define_stringtable (&sub_res_info, $2, $3);
126599461Sobrien	    if (yychar != YYEMPTY)
126699461Sobrien	      YYERROR;
126799461Sobrien	    rcparse_discard_strings ();
126838889Sjdp	  }
1269218822Sdim	| string_data numexpr ',' res_unicode_string_concat
127038889Sjdp	  {
127138889Sjdp	    define_stringtable (&sub_res_info, $2, $4);
127299461Sobrien	    if (yychar != YYEMPTY)
127399461Sobrien	      YYERROR;
127499461Sobrien	    rcparse_discard_strings ();
127538889Sjdp	  }
127638889Sjdp	;
127738889Sjdp
1278218822Sdimrcdata_id:
1279218822Sdim	id
1280218822Sdim	  {
1281218822Sdim	    $$=$1;
1282218822Sdim	  }
1283218822Sdim      | HTML
1284218822Sdim	{
1285218822Sdim	  $$.named = 0;
1286218822Sdim	  $$.u.id = 23;
1287218822Sdim	}
1288218822Sdim      | RCDATA
1289218822Sdim        {
1290218822Sdim          $$.named = 0;
1291218822Sdim          $$.u.id = RT_RCDATA;
1292218822Sdim        }
1293218822Sdim      | MANIFEST
1294218822Sdim        {
1295218822Sdim          $$.named = 0;
1296218822Sdim          $$.u.id = RT_MANIFEST;
1297218822Sdim        }
1298218822Sdim      | PLUGPLAY
1299218822Sdim        {
1300218822Sdim          $$.named = 0;
1301218822Sdim          $$.u.id = RT_PLUGPLAY;
1302218822Sdim        }
1303218822Sdim      | VXD
1304218822Sdim        {
1305218822Sdim          $$.named = 0;
1306218822Sdim          $$.u.id = RT_VXD;
1307218822Sdim        }
1308218822Sdim      | DLGINCLUDE
1309218822Sdim        {
1310218822Sdim          $$.named = 0;
1311218822Sdim          $$.u.id = RT_DLGINCLUDE;
1312218822Sdim        }
1313218822Sdim      | DLGINIT
1314218822Sdim        {
1315218822Sdim          $$.named = 0;
1316218822Sdim          $$.u.id = RT_DLGINIT;
1317218822Sdim        }
1318218822Sdim      | ANICURSOR
1319218822Sdim        {
1320218822Sdim          $$.named = 0;
1321218822Sdim          $$.u.id = RT_ANICURSOR;
1322218822Sdim        }
1323218822Sdim      | ANIICON
1324218822Sdim        {
1325218822Sdim          $$.named = 0;
1326218822Sdim          $$.u.id = RT_ANIICON;
1327218822Sdim        }
1328218822Sdim      ;
1329218822Sdim
133038889Sjdp/* User defined resources.  We accept general suboptions in the
133138889Sjdp   file_name case to keep the parser happy.  */
133238889Sjdp
133338889Sjdpuser:
1334218822Sdim	  id rcdata_id suboptions BEG optrcdata_data END
133538889Sjdp	  {
133638889Sjdp	    define_user_data ($1, $2, &$3, $5.first);
133799461Sobrien	    if (yychar != YYEMPTY)
133899461Sobrien	      YYERROR;
133999461Sobrien	    rcparse_discard_strings ();
134038889Sjdp	  }
1341218822Sdim	| id rcdata_id suboptions file_name
134238889Sjdp	  {
134338889Sjdp	    define_user_file ($1, $2, &$3, $4);
134499461Sobrien	    if (yychar != YYEMPTY)
134599461Sobrien	      YYERROR;
134699461Sobrien	    rcparse_discard_strings ();
134738889Sjdp	  }
134838889Sjdp	;
134938889Sjdp
1350218822Sdimtoolbar:
1351218822Sdim	id TOOLBAR suboptions numexpr cnumexpr BEG toolbar_data END
1352218822Sdim	{
1353218822Sdim	  define_toolbar ($1, &$3, $4, $5, $7);
1354218822Sdim	}
1355218822Sdim	;
1356218822Sdim
1357218822Sdimtoolbar_data: /* empty */ { $$= NULL; }
1358218822Sdim	| toolbar_data BUTTON id
1359218822Sdim	{
1360218822Sdim	  rc_toolbar_item *c,*n;
1361218822Sdim	  c = $1;
1362218822Sdim	  n= (rc_toolbar_item *)
1363218822Sdim	      res_alloc (sizeof (rc_toolbar_item));
1364218822Sdim	  if (c != NULL)
1365218822Sdim	    while (c->next != NULL)
1366218822Sdim	      c = c->next;
1367218822Sdim	  n->prev = c;
1368218822Sdim	  n->next = NULL;
1369218822Sdim	  if (c != NULL)
1370218822Sdim	    c->next = n;
1371218822Sdim	  n->id = $3;
1372218822Sdim	  if ($1 == NULL)
1373218822Sdim	    $$ = n;
1374218822Sdim	  else
1375218822Sdim	    $$ = $1;
1376218822Sdim	}
1377218822Sdim	| toolbar_data SEPARATOR
1378218822Sdim	{
1379218822Sdim	  rc_toolbar_item *c,*n;
1380218822Sdim	  c = $1;
1381218822Sdim	  n= (rc_toolbar_item *)
1382218822Sdim	      res_alloc (sizeof (rc_toolbar_item));
1383218822Sdim	  if (c != NULL)
1384218822Sdim	    while (c->next != NULL)
1385218822Sdim	      c = c->next;
1386218822Sdim	  n->prev = c;
1387218822Sdim	  n->next = NULL;
1388218822Sdim	  if (c != NULL)
1389218822Sdim	    c->next = n;
1390218822Sdim	  n->id.named = 0;
1391218822Sdim	  n->id.u.id = 0;
1392218822Sdim	  if ($1 == NULL)
1393218822Sdim	    $$ = n;
1394218822Sdim	  else
1395218822Sdim	    $$ = $1;
1396218822Sdim	}
1397218822Sdim	;
1398218822Sdim
139938889Sjdp/* Versioninfo resources.  */
140038889Sjdp
140138889Sjdpversioninfo:
140238889Sjdp	  id VERSIONINFO fixedverinfo BEG verblocks END
140338889Sjdp	  {
140438889Sjdp	    define_versioninfo ($1, language, $3, $5);
140599461Sobrien	    if (yychar != YYEMPTY)
140699461Sobrien	      YYERROR;
140799461Sobrien	    rcparse_discard_strings ();
140838889Sjdp	  }
140938889Sjdp	;
141038889Sjdp
141138889Sjdpfixedverinfo:
141238889Sjdp	  /* empty */
141338889Sjdp	  {
1414218822Sdim	    $$ = ((rc_fixed_versioninfo *)
1415218822Sdim		  res_alloc (sizeof (rc_fixed_versioninfo)));
1416218822Sdim	    memset ($$, 0, sizeof (rc_fixed_versioninfo));
141738889Sjdp	  }
141838889Sjdp	| fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
141938889Sjdp	  {
142038889Sjdp	    $1->file_version_ms = ($3 << 16) | $4;
142138889Sjdp	    $1->file_version_ls = ($5 << 16) | $6;
142238889Sjdp	    $$ = $1;
142338889Sjdp	  }
142438889Sjdp	| fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
142538889Sjdp	  {
142638889Sjdp	    $1->product_version_ms = ($3 << 16) | $4;
142738889Sjdp	    $1->product_version_ls = ($5 << 16) | $6;
142838889Sjdp	    $$ = $1;
142938889Sjdp	  }
143038889Sjdp	| fixedverinfo FILEFLAGSMASK numexpr
143138889Sjdp	  {
143238889Sjdp	    $1->file_flags_mask = $3;
143338889Sjdp	    $$ = $1;
143438889Sjdp	  }
143538889Sjdp	| fixedverinfo FILEFLAGS numexpr
143638889Sjdp	  {
143738889Sjdp	    $1->file_flags = $3;
143838889Sjdp	    $$ = $1;
143938889Sjdp	  }
144038889Sjdp	| fixedverinfo FILEOS numexpr
144138889Sjdp	  {
144238889Sjdp	    $1->file_os = $3;
144338889Sjdp	    $$ = $1;
144438889Sjdp	  }
144538889Sjdp	| fixedverinfo FILETYPE numexpr
144638889Sjdp	  {
144738889Sjdp	    $1->file_type = $3;
144838889Sjdp	    $$ = $1;
144938889Sjdp	  }
145038889Sjdp	| fixedverinfo FILESUBTYPE numexpr
145138889Sjdp	  {
145238889Sjdp	    $1->file_subtype = $3;
145338889Sjdp	    $$ = $1;
145438889Sjdp	  }
145538889Sjdp	;
145638889Sjdp
145738889Sjdp/* To handle verblocks successfully, the lexer handles BLOCK
145838889Sjdp   specially.  A BLOCK "StringFileInfo" is returned as
145938889Sjdp   BLOCKSTRINGFILEINFO.  A BLOCK "VarFileInfo" is returned as
146038889Sjdp   BLOCKVARFILEINFO.  A BLOCK with some other string returns BLOCK
146138889Sjdp   with the string as the value.  */
146238889Sjdp
146338889Sjdpverblocks:
146438889Sjdp	  /* empty */
146538889Sjdp	  {
146638889Sjdp	    $$ = NULL;
146738889Sjdp	  }
146838889Sjdp	| verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
146938889Sjdp	  {
147038889Sjdp	    $$ = append_ver_stringfileinfo ($1, $4, $6);
147138889Sjdp	  }
1472218822Sdim	| verblocks BLOCKVARFILEINFO BEG VALUE res_unicode_string_concat vertrans END
147338889Sjdp	  {
147438889Sjdp	    $$ = append_ver_varfileinfo ($1, $5, $6);
147538889Sjdp	  }
147638889Sjdp	;
147738889Sjdp
147838889Sjdpvervals:
147938889Sjdp	  /* empty */
148038889Sjdp	  {
148138889Sjdp	    $$ = NULL;
148238889Sjdp	  }
1483218822Sdim	| vervals VALUE res_unicode_string_concat ',' res_unicode_string_concat
148438889Sjdp	  {
148538889Sjdp	    $$ = append_verval ($1, $3, $5);
148638889Sjdp	  }
148738889Sjdp	;
148838889Sjdp
148938889Sjdpvertrans:
149038889Sjdp	  /* empty */
149138889Sjdp	  {
149238889Sjdp	    $$ = NULL;
149338889Sjdp	  }
149438889Sjdp	| vertrans cnumexpr cnumexpr
149538889Sjdp	  {
149638889Sjdp	    $$ = append_vertrans ($1, $2, $3);
149738889Sjdp	  }
149838889Sjdp	;
149938889Sjdp
150038889Sjdp/* A resource ID.  */
150138889Sjdp
150238889Sjdpid:
150338889Sjdp	  posnumexpr
150438889Sjdp	  {
150538889Sjdp	    $$.named = 0;
150638889Sjdp	    $$.u.id = $1;
150738889Sjdp	  }
1508218822Sdim	| resname
150938889Sjdp	  {
1510218822Sdim	    res_unistring_to_id (&$$, $1);
151138889Sjdp	  }
151238889Sjdp	;
151338889Sjdp
151477298Sobrien/* A resource reference.  */
151577298Sobrien
151677298Sobrienresname:
1517218822Sdim	  res_unicode_string
151877298Sobrien	  {
151977298Sobrien	    $$ = $1;
152077298Sobrien	  }
1521218822Sdim	| STRING
152277298Sobrien	  {
1523218822Sdim	    unichar *h = NULL;
1524218822Sdim	    unicode_from_ascii ((rc_uint_type *) NULL, &h, $1);
1525218822Sdim	    $$ = h;
152677298Sobrien	  }
152777298Sobrien	;
152877298Sobrien
152977298Sobrien
153077298Sobrienresref:
153177298Sobrien	  posnumexpr ','
153277298Sobrien	  {
153377298Sobrien	    $$.named = 0;
153477298Sobrien	    $$.u.id = $1;
153577298Sobrien	  }
153677298Sobrien	| resname
153777298Sobrien	  {
1538218822Sdim	    res_unistring_to_id (&$$, $1);
153977298Sobrien	  }
1540218822Sdim	| resname ','
1541218822Sdim	  {
1542218822Sdim	    res_unistring_to_id (&$$, $1);
1543218822Sdim	  }
154477298Sobrien	;
154577298Sobrien
154638889Sjdp/* Generic suboptions.  These may appear before the BEGIN in any
154738889Sjdp   multiline statement.  */
154838889Sjdp
154938889Sjdpsuboptions:
155038889Sjdp	  /* empty */
155138889Sjdp	  {
1552218822Sdim	    memset (&$$, 0, sizeof (rc_res_res_info));
155338889Sjdp	    $$.language = language;
155438889Sjdp	    /* FIXME: Is this the right default?  */
155599461Sobrien	    $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
155638889Sjdp	  }
155738889Sjdp	| suboptions memflag
155838889Sjdp	  {
155938889Sjdp	    $$ = $1;
156038889Sjdp	    $$.memflags |= $2.on;
156138889Sjdp	    $$.memflags &=~ $2.off;
156238889Sjdp	  }
156338889Sjdp	| suboptions CHARACTERISTICS numexpr
156438889Sjdp	  {
156538889Sjdp	    $$ = $1;
156638889Sjdp	    $$.characteristics = $3;
156738889Sjdp	  }
156838889Sjdp	| suboptions LANGUAGE numexpr cnumexpr
156938889Sjdp	  {
157038889Sjdp	    $$ = $1;
157189857Sobrien	    $$.language = $3 | ($4 << SUBLANG_SHIFT);
157238889Sjdp	  }
157338889Sjdp	| suboptions VERSIONK numexpr
157438889Sjdp	  {
157538889Sjdp	    $$ = $1;
157638889Sjdp	    $$.version = $3;
157738889Sjdp	  }
157838889Sjdp	;
157938889Sjdp
158038889Sjdp/* Memory flags which default to MOVEABLE and DISCARDABLE.  */
158138889Sjdp
158238889Sjdpmemflags_move_discard:
158338889Sjdp	  /* empty */
158438889Sjdp	  {
1585218822Sdim	    memset (&$$, 0, sizeof (rc_res_res_info));
158638889Sjdp	    $$.language = language;
158738889Sjdp	    $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
158838889Sjdp	  }
158938889Sjdp	| memflags_move_discard memflag
159038889Sjdp	  {
159138889Sjdp	    $$ = $1;
159238889Sjdp	    $$.memflags |= $2.on;
159338889Sjdp	    $$.memflags &=~ $2.off;
159438889Sjdp	  }
159538889Sjdp	;
159638889Sjdp
159738889Sjdp/* Memory flags which default to MOVEABLE.  */
159838889Sjdp
159938889Sjdpmemflags_move:
160038889Sjdp	  /* empty */
160138889Sjdp	  {
1602218822Sdim	    memset (&$$, 0, sizeof (rc_res_res_info));
160338889Sjdp	    $$.language = language;
160499461Sobrien	    $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
160538889Sjdp	  }
160660484Sobrien	| memflags_move memflag
160738889Sjdp	  {
160838889Sjdp	    $$ = $1;
160938889Sjdp	    $$.memflags |= $2.on;
161038889Sjdp	    $$.memflags &=~ $2.off;
161138889Sjdp	  }
161238889Sjdp	;
161338889Sjdp
161438889Sjdp/* Memory flags.  This returns a struct with two integers, because we
161538889Sjdp   sometimes want to set bits and we sometimes want to clear them.  */
161638889Sjdp
161738889Sjdpmemflag:
161838889Sjdp	  MOVEABLE
161938889Sjdp	  {
162038889Sjdp	    $$.on = MEMFLAG_MOVEABLE;
162138889Sjdp	    $$.off = 0;
162238889Sjdp	  }
162338889Sjdp	| FIXED
162438889Sjdp	  {
162538889Sjdp	    $$.on = 0;
162638889Sjdp	    $$.off = MEMFLAG_MOVEABLE;
162738889Sjdp	  }
162838889Sjdp	| PURE
162938889Sjdp	  {
163038889Sjdp	    $$.on = MEMFLAG_PURE;
163138889Sjdp	    $$.off = 0;
163238889Sjdp	  }
163338889Sjdp	| IMPURE
163438889Sjdp	  {
163538889Sjdp	    $$.on = 0;
163638889Sjdp	    $$.off = MEMFLAG_PURE;
163738889Sjdp	  }
163838889Sjdp	| PRELOAD
163938889Sjdp	  {
164038889Sjdp	    $$.on = MEMFLAG_PRELOAD;
164138889Sjdp	    $$.off = 0;
164238889Sjdp	  }
164338889Sjdp	| LOADONCALL
164438889Sjdp	  {
164538889Sjdp	    $$.on = 0;
164638889Sjdp	    $$.off = MEMFLAG_PRELOAD;
164738889Sjdp	  }
164838889Sjdp	| DISCARDABLE
164938889Sjdp	  {
165038889Sjdp	    $$.on = MEMFLAG_DISCARDABLE;
165138889Sjdp	    $$.off = 0;
165238889Sjdp	  }
165338889Sjdp	;
165438889Sjdp
165538889Sjdp/* A file name.  */
165638889Sjdp
165738889Sjdpfile_name:
165838889Sjdp	  QUOTEDSTRING
165938889Sjdp	  {
166038889Sjdp	    $$ = $1;
166138889Sjdp	  }
166238889Sjdp	| STRING
166338889Sjdp	  {
166438889Sjdp	    $$ = $1;
166538889Sjdp	  }
166638889Sjdp	;
166738889Sjdp
1668218822Sdim/* Concat string */
1669218822Sdimres_unicode_string_concat:
1670218822Sdim	  res_unicode_string
1671218822Sdim	  {
1672218822Sdim	    $$ = $1;
1673218822Sdim	  }
1674218822Sdim	|
1675218822Sdim	  res_unicode_string_concat res_unicode_string
1676218822Sdim	  {
1677218822Sdim	    rc_uint_type l1 = unichar_len ($1);
1678218822Sdim	    rc_uint_type l2 = unichar_len ($2);
1679218822Sdim	    unichar *h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
1680218822Sdim	    if (l1 != 0)
1681218822Sdim	      memcpy (h, $1, l1 * sizeof (unichar));
1682218822Sdim	    if (l2 != 0)
1683218822Sdim	      memcpy (h + l1, $2, l2  * sizeof (unichar));
1684218822Sdim	    h[l1 + l2] = 0;
1685218822Sdim	    $$ = h;
1686218822Sdim	  }
1687218822Sdim	;
1688218822Sdim
1689218822Sdimres_unicode_string:
1690218822Sdim	  QUOTEDUNISTRING
1691218822Sdim	  {
1692218822Sdim	    $$ = unichar_dup ($1);
1693218822Sdim	  }
1694218822Sdim	| QUOTEDSTRING
1695218822Sdim	  {
1696218822Sdim	    unichar *h = NULL;
1697218822Sdim	    unicode_from_ascii ((rc_uint_type *) NULL, &h, $1);
1698218822Sdim	    $$ = h;
1699218822Sdim	  }
1700218822Sdim	;
1701218822Sdim
1702218822Sdimsizedstring:
1703218822Sdim	  SIZEDSTRING
1704218822Sdim	  {
1705218822Sdim	    $$ = $1;
1706218822Sdim	  }
1707218822Sdim	| sizedstring SIZEDSTRING
1708218822Sdim	  {
1709218822Sdim	    rc_uint_type l = $1.length + $2.length;
1710218822Sdim	    char *h = (char *) res_alloc (l);
1711218822Sdim	    memcpy (h, $1.s, $1.length);
1712218822Sdim	    memcpy (h + $1.length, $2.s, $2.length);
1713218822Sdim	    $$.s = h;
1714218822Sdim	    $$.length = l;
1715218822Sdim	  }
1716218822Sdim	;
1717218822Sdim
1718218822Sdimsizedunistring:
1719218822Sdim	  SIZEDUNISTRING
1720218822Sdim	  {
1721218822Sdim	    $$ = $1;
1722218822Sdim	  }
1723218822Sdim	| sizedunistring SIZEDUNISTRING
1724218822Sdim	  {
1725218822Sdim	    rc_uint_type l = $1.length + $2.length;
1726218822Sdim	    unichar *h = (unichar *) res_alloc (l * sizeof (unichar));
1727218822Sdim	    memcpy (h, $1.s, $1.length * sizeof (unichar));
1728218822Sdim	    memcpy (h + $1.length, $2.s, $2.length  * sizeof (unichar));
1729218822Sdim	    $$.s = h;
1730218822Sdim	    $$.length = l;
1731218822Sdim	  }
1732218822Sdim	;
1733218822Sdim
173438889Sjdp/* A style expression.  This changes the static variable STYLE.  We do
173538889Sjdp   it this way because rc appears to permit a style to be set to
173638889Sjdp   something like
173738889Sjdp       WS_GROUP | NOT WS_TABSTOP
173838889Sjdp   to mean that a default of WS_TABSTOP should be removed.  Anything
173938889Sjdp   which wants to accept a style must first set STYLE to the default
174038889Sjdp   value.  The styleexpr nonterminal will change STYLE as specified by
174138889Sjdp   the user.  Note that we do not accept arbitrary expressions here,
174238889Sjdp   just numbers separated by '|'.  */
174338889Sjdp
174438889Sjdpstyleexpr:
174538889Sjdp	  parennumber
174638889Sjdp	  {
174738889Sjdp	    style |= $1;
174838889Sjdp	  }
174938889Sjdp	| NOT parennumber
175038889Sjdp	  {
175138889Sjdp	    style &=~ $2;
175238889Sjdp	  }
175338889Sjdp	| styleexpr '|' parennumber
175438889Sjdp	  {
175538889Sjdp	    style |= $3;
175638889Sjdp	  }
175738889Sjdp	| styleexpr '|' NOT parennumber
175838889Sjdp	  {
175938889Sjdp	    style &=~ $4;
176038889Sjdp	  }
176138889Sjdp	;
176238889Sjdp
176338889Sjdpparennumber:
176438889Sjdp	  NUMBER
176538889Sjdp	  {
176638889Sjdp	    $$ = $1.val;
176738889Sjdp	  }
176838889Sjdp	| '(' numexpr ')'
176938889Sjdp	  {
177038889Sjdp	    $$ = $2;
177138889Sjdp	  }
177238889Sjdp	;
177338889Sjdp
177438889Sjdp/* An optional expression with a leading comma.  */
177538889Sjdp
177638889Sjdpoptcnumexpr:
177738889Sjdp	  /* empty */
177838889Sjdp	  {
177938889Sjdp	    $$ = 0;
178038889Sjdp	  }
178138889Sjdp	| cnumexpr
178238889Sjdp	  {
178338889Sjdp	    $$ = $1;
178438889Sjdp	  }
178538889Sjdp	;
178638889Sjdp
178738889Sjdp/* An expression with a leading comma.  */
178838889Sjdp
178938889Sjdpcnumexpr:
179038889Sjdp	  ',' numexpr
179138889Sjdp	  {
179238889Sjdp	    $$ = $2;
179338889Sjdp	  }
179438889Sjdp	;
179538889Sjdp
179638889Sjdp/* A possibly negated numeric expression.  */
179738889Sjdp
179838889Sjdpnumexpr:
179938889Sjdp	  sizednumexpr
180038889Sjdp	  {
180138889Sjdp	    $$ = $1.val;
180238889Sjdp	  }
180338889Sjdp	;
180438889Sjdp
180538889Sjdp/* A possibly negated expression with a size.  */
180638889Sjdp
180738889Sjdpsizednumexpr:
180838889Sjdp	  NUMBER
180938889Sjdp	  {
181038889Sjdp	    $$ = $1;
181138889Sjdp	  }
181238889Sjdp	| '(' sizednumexpr ')'
181338889Sjdp	  {
181438889Sjdp	    $$ = $2;
181538889Sjdp	  }
181638889Sjdp	| '~' sizednumexpr %prec '~'
181738889Sjdp	  {
181838889Sjdp	    $$.val = ~ $2.val;
181938889Sjdp	    $$.dword = $2.dword;
182038889Sjdp	  }
182138889Sjdp	| '-' sizednumexpr %prec NEG
182238889Sjdp	  {
182338889Sjdp	    $$.val = - $2.val;
182438889Sjdp	    $$.dword = $2.dword;
182538889Sjdp	  }
182638889Sjdp	| sizednumexpr '*' sizednumexpr
182738889Sjdp	  {
182838889Sjdp	    $$.val = $1.val * $3.val;
182938889Sjdp	    $$.dword = $1.dword || $3.dword;
183038889Sjdp	  }
183138889Sjdp	| sizednumexpr '/' sizednumexpr
183238889Sjdp	  {
183338889Sjdp	    $$.val = $1.val / $3.val;
183438889Sjdp	    $$.dword = $1.dword || $3.dword;
183538889Sjdp	  }
183638889Sjdp	| sizednumexpr '%' sizednumexpr
183738889Sjdp	  {
183838889Sjdp	    $$.val = $1.val % $3.val;
183938889Sjdp	    $$.dword = $1.dword || $3.dword;
184038889Sjdp	  }
184138889Sjdp	| sizednumexpr '+' sizednumexpr
184238889Sjdp	  {
184338889Sjdp	    $$.val = $1.val + $3.val;
184438889Sjdp	    $$.dword = $1.dword || $3.dword;
184538889Sjdp	  }
184638889Sjdp	| sizednumexpr '-' sizednumexpr
184738889Sjdp	  {
184838889Sjdp	    $$.val = $1.val - $3.val;
184938889Sjdp	    $$.dword = $1.dword || $3.dword;
185038889Sjdp	  }
185138889Sjdp	| sizednumexpr '&' sizednumexpr
185238889Sjdp	  {
185338889Sjdp	    $$.val = $1.val & $3.val;
185438889Sjdp	    $$.dword = $1.dword || $3.dword;
185538889Sjdp	  }
185638889Sjdp	| sizednumexpr '^' sizednumexpr
185738889Sjdp	  {
185838889Sjdp	    $$.val = $1.val ^ $3.val;
185938889Sjdp	    $$.dword = $1.dword || $3.dword;
186038889Sjdp	  }
186138889Sjdp	| sizednumexpr '|' sizednumexpr
186238889Sjdp	  {
186338889Sjdp	    $$.val = $1.val | $3.val;
186438889Sjdp	    $$.dword = $1.dword || $3.dword;
186538889Sjdp	  }
186638889Sjdp	;
186738889Sjdp
186838889Sjdp/* An expression with a leading comma which does not use unary
186938889Sjdp   negation.  */
187038889Sjdp
187138889Sjdpcposnumexpr:
187238889Sjdp	  ',' posnumexpr
187338889Sjdp	  {
187438889Sjdp	    $$ = $2;
187538889Sjdp	  }
187638889Sjdp	;
187738889Sjdp
187838889Sjdp/* An expression which does not use unary negation.  */
187938889Sjdp
188038889Sjdpposnumexpr:
188138889Sjdp	  sizedposnumexpr
188238889Sjdp	  {
188338889Sjdp	    $$ = $1.val;
188438889Sjdp	  }
188538889Sjdp	;
188638889Sjdp
188738889Sjdp/* An expression which does not use unary negation.  We separate unary
188838889Sjdp   negation to avoid parsing conflicts when two numeric expressions
188938889Sjdp   appear consecutively.  */
189038889Sjdp
189138889Sjdpsizedposnumexpr:
189238889Sjdp	  NUMBER
189338889Sjdp	  {
189438889Sjdp	    $$ = $1;
189538889Sjdp	  }
189638889Sjdp	| '(' sizednumexpr ')'
189738889Sjdp	  {
189838889Sjdp	    $$ = $2;
189938889Sjdp	  }
190038889Sjdp	| '~' sizednumexpr %prec '~'
190138889Sjdp	  {
190238889Sjdp	    $$.val = ~ $2.val;
190338889Sjdp	    $$.dword = $2.dword;
190438889Sjdp	  }
190538889Sjdp	| sizedposnumexpr '*' sizednumexpr
190638889Sjdp	  {
190738889Sjdp	    $$.val = $1.val * $3.val;
190838889Sjdp	    $$.dword = $1.dword || $3.dword;
190938889Sjdp	  }
191038889Sjdp	| sizedposnumexpr '/' sizednumexpr
191138889Sjdp	  {
191238889Sjdp	    $$.val = $1.val / $3.val;
191338889Sjdp	    $$.dword = $1.dword || $3.dword;
191438889Sjdp	  }
191538889Sjdp	| sizedposnumexpr '%' sizednumexpr
191638889Sjdp	  {
191738889Sjdp	    $$.val = $1.val % $3.val;
191838889Sjdp	    $$.dword = $1.dword || $3.dword;
191938889Sjdp	  }
192038889Sjdp	| sizedposnumexpr '+' sizednumexpr
192138889Sjdp	  {
192238889Sjdp	    $$.val = $1.val + $3.val;
192338889Sjdp	    $$.dword = $1.dword || $3.dword;
192438889Sjdp	  }
192538889Sjdp	| sizedposnumexpr '-' sizednumexpr
192638889Sjdp	  {
192738889Sjdp	    $$.val = $1.val - $3.val;
192838889Sjdp	    $$.dword = $1.dword || $3.dword;
192938889Sjdp	  }
193038889Sjdp	| sizedposnumexpr '&' sizednumexpr
193138889Sjdp	  {
193238889Sjdp	    $$.val = $1.val & $3.val;
193338889Sjdp	    $$.dword = $1.dword || $3.dword;
193438889Sjdp	  }
193538889Sjdp	| sizedposnumexpr '^' sizednumexpr
193638889Sjdp	  {
193738889Sjdp	    $$.val = $1.val ^ $3.val;
193838889Sjdp	    $$.dword = $1.dword || $3.dword;
193938889Sjdp	  }
194038889Sjdp	| sizedposnumexpr '|' sizednumexpr
194138889Sjdp	  {
194238889Sjdp	    $$.val = $1.val | $3.val;
194338889Sjdp	    $$.dword = $1.dword || $3.dword;
194438889Sjdp	  }
194538889Sjdp	;
194638889Sjdp
194738889Sjdp%%
194838889Sjdp
194938889Sjdp/* Set the language from the command line.  */
195038889Sjdp
195138889Sjdpvoid
1952218822Sdimrcparse_set_language (int lang)
195338889Sjdp{
195438889Sjdp  language = lang;
195538889Sjdp}
1956