gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / binutils / rcparse.y
index fcd34cc231523df4df371c14749e344de49c4ba9..78ce917e233c5efdba82c409e2d913c949bba531 100644 (file)
@@ -1,12 +1,13 @@
 %{ /* rcparse.y -- parser for Windows rc files
-   Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1997-2020 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
+   Extended by Kai Tietz, Onevision.
 
    This file is part of GNU Binutils.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
+
 
 /* This is a parser for Windows rc files.  It is based on the parser
    by Gunther Ebert <gunther.ebert@ixos-leipzig.de>.  */
 
+#include "sysdep.h"
 #include "bfd.h"
 #include "bucomm.h"
 #include "libiberty.h"
@@ -34,12 +37,12 @@ static unsigned short language;
 
 /* The resource information during a sub statement.  */
 
-static struct res_res_info sub_res_info;
+static rc_res_res_info sub_res_info;
 
 /* Dialog information.  This is built by the nonterminals styles and
    controls.  */
 
-static struct dialog dialog;
+static rc_dialog dialog;
 
 /* This is used when building a style.  It is modified by the
    nonterminal styleexpr.  */
@@ -49,50 +52,63 @@ static unsigned long style;
 /* These are used when building a control.  They are set before using
    control_params.  */
 
-static unsigned long base_style;
-static unsigned long default_style;
-static unsigned long class;
+static rc_uint_type base_style;
+static rc_uint_type default_style;
+static rc_res_id class;
+static rc_res_id res_text_field;
+static unichar null_unichar;
+
+/* This is used for COMBOBOX, LISTBOX and EDITTEXT which
+   do not allow resource 'text' field in control definition. */
+static const rc_res_id res_null_text = { 1, {{0, &null_unichar}}};
 
 %}
 
 %union
 {
-  struct accelerator acc;
-  struct accelerator *pacc;
-  struct dialog_control *dialog_control;
-  struct menuitem *menuitem;
+  rc_accelerator acc;
+  rc_accelerator *pacc;
+  rc_dialog_control *dialog_control;
+  rc_menuitem *menuitem;
   struct
   {
-    struct rcdata_item *first;
-    struct rcdata_item *last;
+    rc_rcdata_item *first;
+    rc_rcdata_item *last;
   } rcdata;
-  struct rcdata_item *rcdata_item;
-  struct stringtable_data *stringtable;
-  struct fixed_versioninfo *fixver;
-  struct ver_info *verinfo;
-  struct ver_stringinfo *verstring;
-  struct ver_varinfo *vervar;
-  struct res_id id;
-  struct res_res_info res_info;
+  rc_rcdata_item *rcdata_item;
+  rc_fixed_versioninfo *fixver;
+  rc_ver_info *verinfo;
+  rc_ver_stringtable *verstringtable;
+  rc_ver_stringinfo *verstring;
+  rc_ver_varinfo *vervar;
+  rc_toolbar_item *toobar_item;
+  rc_res_id id;
+  rc_res_res_info res_info;
   struct
   {
-    unsigned short on;
-    unsigned short off;
+    rc_uint_type on;
+    rc_uint_type off;
   } memflags;
   struct
   {
-    unsigned long val;
+    rc_uint_type val;
     /* Nonzero if this number was explicitly specified as long.  */
     int dword;
   } i;
-  unsigned long il;
-  unsigned short is;
+  rc_uint_type il;
+  rc_uint_type is;
   const char *s;
   struct
   {
-    unsigned long length;
+    rc_uint_type length;
     const char *s;
   } ss;
+  unichar *uni;
+  struct
+  {
+    rc_uint_type length;
+    const unichar *s;
+  } suni;
 };
 
 %token BEG END
@@ -106,6 +122,7 @@ static unsigned long class;
 %token BEDIT HEDIT IEDIT
 %token FONT
 %token ICON
+%token ANICURSOR ANIICON DLGINCLUDE DLGINIT FONTDIR HTML MANIFEST PLUGPLAY VXD TOOLBAR BUTTON
 %token LANGUAGE CHARACTERISTICS VERSIONK
 %token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
 %token MENUBARBREAK MENUBREAK
@@ -118,8 +135,10 @@ static unsigned long class;
 %token <s> BLOCK
 %token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE
 %token NOT
+%token <uni> QUOTEDUNISTRING
 %token <s> QUOTEDSTRING STRING
 %token <i> NUMBER
+%token <suni> SIZEDUNISTRING
 %token <ss> SIZEDSTRING
 %token IGNORED_TOKEN
 
@@ -131,15 +150,20 @@ static unsigned long class;
 %type <rcdata_item> opt_control_data
 %type <fixver> fixedverinfo
 %type <verinfo> verblocks
+%type <verstringtable> verstringtables
 %type <verstring> vervals
 %type <vervar> vertrans
+%type <toobar_item> toolbar_data
 %type <res_info> suboptions memflags_move_discard memflags_move
 %type <memflags> memflag
-%type <id> id resref
+%type <id> id rcdata_id optresidc resref resid cresid
 %type <il> exstyle parennumber
 %type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
 %type <is> acc_options acc_option menuitem_flags menuitem_flag
-%type <s> optstringc file_name resname
+%type <s> file_name
+%type <uni> res_unicode_string resname res_unicode_string_concat
+%type <ss> sizedstring
+%type <suni> sizedunistring res_unicode_sizedstring res_unicode_sizedstring_concat
 %type <i> sizednumexpr sizedposnumexpr
 
 %left '|'
@@ -153,28 +177,21 @@ static unsigned long class;
 
 input:
          /* empty */
-       | input newcmd accelerator
-       | input newcmd bitmap
-       | input newcmd cursor
-       | input newcmd dialog
-       | input newcmd font
-       | input newcmd icon
-       | input newcmd language
-       | input newcmd menu
-       | input newcmd menuex
-       | input newcmd messagetable
-       | input newcmd rcdata
-       | input newcmd stringtable
-       | input newcmd user
-       | input newcmd versioninfo
-       | input newcmd IGNORED_TOKEN
-       ;
-
-newcmd:
-         /* empty */
-         {
-           rcparse_discard_strings ();
-         }
+       | input accelerator
+       | input bitmap
+       | input cursor
+       | input dialog
+       | input font
+       | input icon
+       | input language
+       | input menu
+       | input menuex
+       | input messagetable
+       | input stringtable
+       | input toolbar
+       | input user
+       | input versioninfo
+       | input IGNORED_TOKEN
        ;
 
 /* Accelerator resources.  */
@@ -183,6 +200,9 @@ accelerator:
          id ACCELERATORS suboptions BEG acc_entries END
          {
            define_accelerator ($1, &$3, $5);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -193,15 +213,15 @@ acc_entries:
          }
        | acc_entries acc_entry
          {
-           struct accelerator *a;
+           rc_accelerator *a;
 
-           a = (struct accelerator *) res_alloc (sizeof *a);
+           a = (rc_accelerator *) res_alloc (sizeof *a);
            *a = $2;
            if ($1 == NULL)
              $$ = a;
            else
              {
-               struct accelerator **pp;
+               rc_accelerator **pp;
 
                for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
                  ;
@@ -223,7 +243,7 @@ acc_entry:
            $$.id = $2;
            $$.flags |= $4;
            if (($$.flags & ACC_VIRTKEY) == 0
-               && ($$.flags & (ACC_SHIFT | ACC_CONTROL | ACC_ALT)) != 0)
+               && ($$.flags & (ACC_SHIFT | ACC_CONTROL)) != 0)
              rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
          }
        ;
@@ -243,8 +263,7 @@ acc_event:
              {
                $$.flags = ACC_CONTROL | ACC_VIRTKEY;
                ++s;
-               ch = *s;
-               ch = TOUPPER (ch);
+               ch = TOUPPER (s[0]);
              }
            $$.key = ch;
            if (s[1] != '\0')
@@ -309,6 +328,9 @@ bitmap:
          id BITMAP memflags_move file_name
          {
            define_bitmap ($1, &$3, $4);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -318,6 +340,9 @@ cursor:
          id CURSOR memflags_move_discard file_name
          {
            define_cursor ($1, &$3, $4);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -345,6 +370,9 @@ dialog:
            styles BEG controls END
          {
            define_dialog ($1, &sub_res_info, &dialog);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
            cnumexpr
@@ -359,9 +387,9 @@ dialog:
              dialog.menu.named = 1;
              dialog.class.named = 1;
              dialog.font = NULL;
-             dialog.ex = ((struct dialog_ex *)
-                          res_alloc (sizeof (struct dialog_ex)));
-             memset (dialog.ex, 0, sizeof (struct dialog_ex));
+             dialog.ex = ((rc_dialog_ex *)
+                          res_alloc (sizeof (rc_dialog_ex)));
+             memset (dialog.ex, 0, sizeof (rc_dialog_ex));
              dialog.controls = NULL;
              sub_res_info = $3;
              style = 0;
@@ -369,6 +397,9 @@ dialog:
            styles BEG controls END
          {
            define_dialog ($1, &sub_res_info, &dialog);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr
            cnumexpr cnumexpr
@@ -383,9 +414,9 @@ dialog:
              dialog.menu.named = 1;
              dialog.class.named = 1;
              dialog.font = NULL;
-             dialog.ex = ((struct dialog_ex *)
-                          res_alloc (sizeof (struct dialog_ex)));
-             memset (dialog.ex, 0, sizeof (struct dialog_ex));
+             dialog.ex = ((rc_dialog_ex *)
+                          res_alloc (sizeof (rc_dialog_ex)));
+             memset (dialog.ex, 0, sizeof (rc_dialog_ex));
              dialog.ex->help = $9;
              dialog.controls = NULL;
              sub_res_info = $3;
@@ -394,6 +425,9 @@ dialog:
            styles BEG controls END
          {
            define_dialog ($1, &sub_res_info, &dialog);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -410,9 +444,11 @@ exstyle:
 
 styles:
          /* empty */
-       | styles CAPTION QUOTEDSTRING
+       | styles CAPTION res_unicode_string_concat
          {
-           unicode_from_ascii ((int *) NULL, &dialog.caption, $3);
+           dialog.style |= WS_CAPTION;
+           style |= WS_CAPTION;
+           dialog.caption = $3;
          }
        | styles CLASS id
          {
@@ -427,29 +463,66 @@ styles:
          {
            dialog.exstyle = $3;
          }
-       | styles CLASS QUOTEDSTRING
+       | styles CLASS res_unicode_string_concat
          {
-           res_string_to_id (& dialog.class, $3);
+           res_unistring_to_id (& dialog.class, $3);
          }
-       | styles FONT numexpr ',' QUOTEDSTRING
+       | styles FONT numexpr ',' res_unicode_string_concat
          {
            dialog.style |= DS_SETFONT;
            style |= DS_SETFONT;
            dialog.pointsize = $3;
-           unicode_from_ascii ((int *) NULL, &dialog.font, $5);
+           dialog.font = $5;
+           if (dialog.ex != NULL)
+             {
+               dialog.ex->weight = 0;
+               dialog.ex->italic = 0;
+               dialog.ex->charset = 1;
+             }
          }
-       | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr
+       | styles FONT numexpr ',' res_unicode_string_concat cnumexpr
          {
            dialog.style |= DS_SETFONT;
            style |= DS_SETFONT;
            dialog.pointsize = $3;
-           unicode_from_ascii ((int *) NULL, &dialog.font, $5);
+           dialog.font = $5;
+           if (dialog.ex == NULL)
+             rcparse_warning (_("extended FONT requires DIALOGEX"));
+           else
+             {
+               dialog.ex->weight = $6;
+               dialog.ex->italic = 0;
+               dialog.ex->charset = 1;
+             }
+         }
+       | styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr
+         {
+           dialog.style |= DS_SETFONT;
+           style |= DS_SETFONT;
+           dialog.pointsize = $3;
+           dialog.font = $5;
+           if (dialog.ex == NULL)
+             rcparse_warning (_("extended FONT requires DIALOGEX"));
+           else
+             {
+               dialog.ex->weight = $6;
+               dialog.ex->italic = $7;
+               dialog.ex->charset = 1;
+             }
+         }
+       | styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr cnumexpr
+         {
+           dialog.style |= DS_SETFONT;
+           style |= DS_SETFONT;
+           dialog.pointsize = $3;
+           dialog.font = $5;
            if (dialog.ex == NULL)
              rcparse_warning (_("extended FONT requires DIALOGEX"));
            else
              {
                dialog.ex->weight = $6;
                dialog.ex->italic = $7;
+               dialog.ex->charset = $8;
              }
          }
        | styles MENU id
@@ -474,7 +547,7 @@ controls:
          /* empty */
        | controls control
          {
-           struct dialog_control **pp;
+           rc_dialog_control **pp;
 
            for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next)
              ;
@@ -483,70 +556,84 @@ controls:
        ;
 
 control:
-         AUTO3STATE
+         AUTO3STATE optresidc
            {
              default_style = BS_AUTO3STATE | WS_TABSTOP;
              base_style = BS_AUTO3STATE;
-             class = CTL_BUTTON;
+             class.named = 0;
+             class.u.id = CTL_BUTTON;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
          }
-       | AUTOCHECKBOX
+       | AUTOCHECKBOX optresidc
            {
              default_style = BS_AUTOCHECKBOX | WS_TABSTOP;
              base_style = BS_AUTOCHECKBOX;
-             class = CTL_BUTTON;
+             class.named = 0;
+             class.u.id = CTL_BUTTON;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
          }
-       | AUTORADIOBUTTON
+       | AUTORADIOBUTTON optresidc
            {
              default_style = BS_AUTORADIOBUTTON | WS_TABSTOP;
              base_style = BS_AUTORADIOBUTTON;
-             class = CTL_BUTTON;
+             class.named = 0;
+             class.u.id = CTL_BUTTON;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
          }
-       | BEDIT
+       | BEDIT optresidc
            {
              default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
              base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
-             class = CTL_EDIT;
+             class.named = 0;
+             class.u.id = CTL_EDIT;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
            if (dialog.ex == NULL)
              rcparse_warning (_("BEDIT requires DIALOGEX"));
            res_string_to_id (&$$->class, "BEDIT");
          }
-       | CHECKBOX
+       | CHECKBOX optresidc
            {
              default_style = BS_CHECKBOX | WS_TABSTOP;
              base_style = BS_CHECKBOX | WS_TABSTOP;
-             class = CTL_BUTTON;
+             class.named = 0;
+             class.u.id = CTL_BUTTON;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
          }
        | COMBOBOX
            {
+             /* This is as per MSDN documentation.  With some (???)
+                versions of MS rc.exe their is no default style.  */
              default_style = CBS_SIMPLE | WS_TABSTOP;
              base_style = 0;
-             class = CTL_COMBOBOX;
+             class.named = 0;
+             class.u.id = CTL_COMBOBOX;
+             res_text_field = res_null_text;
            }
            control_params
          {
            $$ = $3;
          }
-       | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
+       | CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
            cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
          {
            $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
@@ -557,7 +644,7 @@ control:
                $$->data = $11;
              }
          }
-       | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr
+       | CONTROL optresidc numexpr cresid control_styleexpr cnumexpr
            cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
          {
            $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
@@ -566,79 +653,65 @@ control:
            $$->help = $11;
            $$->data = $12;
          }
-       | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr
-           cnumexpr cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data
-         {
-           $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
-           if ($12 != NULL)
-             {
-               if (dialog.ex == NULL)
-                 rcparse_warning ("control data requires DIALOGEX");
-               $$->data = $12;
-             }
-           $$->class.named = 1;
-           unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5);
-         }
-       | CONTROL optstringc numexpr ',' QUOTEDSTRING control_styleexpr
-           cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
-         {
-           $$ = define_control ($2, $3, $7, $8, $9, $10, 0, style, $11);
-           if (dialog.ex == NULL)
-             rcparse_warning ("help ID requires DIALOGEX");
-           $$->help = $12;
-           $$->data = $13;
-           $$->class.named = 1;
-           unicode_from_ascii (&$$->class.u.n.length, &$$->class.u.n.name, $5);
-         }
-       | CTEXT
+       | CTEXT optresidc
            {
              default_style = SS_CENTER | WS_GROUP;
              base_style = SS_CENTER;
-             class = CTL_STATIC;
+             class.named = 0;
+             class.u.id = CTL_STATIC;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
          }
-       | DEFPUSHBUTTON
+       | DEFPUSHBUTTON optresidc
            {
              default_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
              base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
-             class = CTL_BUTTON;
+             class.named = 0;
+             class.u.id = CTL_BUTTON;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
          }
        | EDITTEXT
            {
              default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
              base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
-             class = CTL_EDIT;
+             class.named = 0;
+             class.u.id = CTL_EDIT;
+             res_text_field = res_null_text;
            }
            control_params
          {
            $$ = $3;
          }
-       | GROUPBOX
+       | GROUPBOX optresidc
            {
              default_style = BS_GROUPBOX;
              base_style = BS_GROUPBOX;
-             class = CTL_BUTTON;
+             class.named = 0;
+             class.u.id = CTL_BUTTON;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
          }
-       | HEDIT
+       | HEDIT optresidc
            {
              default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
              base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
-             class = CTL_EDIT;
+             class.named = 0;
+             class.u.id = CTL_EDIT;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
            if (dialog.ex == NULL)
              rcparse_warning (_("IEDIT requires DIALOGEX"));
            res_string_to_id (&$$->class, "HEDIT");
@@ -666,15 +739,17 @@ control:
            $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11,
                                      dialog.ex);
           }
-       | IEDIT
+       | IEDIT optresidc
            {
              default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
              base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
-             class = CTL_EDIT;
+             class.named = 0;
+             class.u.id = CTL_EDIT;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
            if (dialog.ex == NULL)
              rcparse_warning (_("IEDIT requires DIALOGEX"));
            res_string_to_id (&$$->class, "IEDIT");
@@ -683,89 +758,107 @@ control:
            {
              default_style = LBS_NOTIFY | WS_BORDER;
              base_style = LBS_NOTIFY | WS_BORDER;
-             class = CTL_LISTBOX;
+             class.named = 0;
+             class.u.id = CTL_LISTBOX;
+             res_text_field = res_null_text;
            }
            control_params
          {
            $$ = $3;
          }
-       | LTEXT
+       | LTEXT optresidc
            {
              default_style = SS_LEFT | WS_GROUP;
              base_style = SS_LEFT;
-             class = CTL_STATIC;
+             class.named = 0;
+             class.u.id = CTL_STATIC;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
          }
-       | PUSHBOX
+       | PUSHBOX optresidc
            {
              default_style = BS_PUSHBOX | WS_TABSTOP;
              base_style = BS_PUSHBOX;
-             class = CTL_BUTTON;
+             class.named = 0;
+             class.u.id = CTL_BUTTON;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
          }
-       | PUSHBUTTON
+       | PUSHBUTTON optresidc
            {
              default_style = BS_PUSHBUTTON | WS_TABSTOP;
              base_style = BS_PUSHBUTTON | WS_TABSTOP;
-             class = CTL_BUTTON;
+             class.named = 0;
+             class.u.id = CTL_BUTTON;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
          }
-       | RADIOBUTTON
+       | RADIOBUTTON optresidc
            {
              default_style = BS_RADIOBUTTON | WS_TABSTOP;
              base_style = BS_RADIOBUTTON;
-             class = CTL_BUTTON;
+             class.named = 0;
+             class.u.id = CTL_BUTTON;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
          }
-       | RTEXT
+       | RTEXT optresidc
            {
              default_style = SS_RIGHT | WS_GROUP;
              base_style = SS_RIGHT;
-             class = CTL_STATIC;
+             class.named = 0;
+             class.u.id = CTL_STATIC;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
          }
        | SCROLLBAR
            {
              default_style = SBS_HORZ;
              base_style = 0;
-             class = CTL_SCROLLBAR;
+             class.named = 0;
+             class.u.id = CTL_SCROLLBAR;
+             res_text_field = res_null_text;
            }
            control_params
          {
            $$ = $3;
          }
-       | STATE3
+       | STATE3 optresidc
            {
              default_style = BS_3STATE | WS_TABSTOP;
              base_style = BS_3STATE;
-             class = CTL_BUTTON;
+             class.named = 0;
+             class.u.id = CTL_BUTTON;
+             res_text_field = $2;
            }
            control_params
          {
-           $$ = $3;
+           $$ = $4;
          }
-       | USERBUTTON QUOTEDSTRING ',' numexpr ',' numexpr ',' numexpr ','
-           numexpr ',' numexpr ',' 
+       | USERBUTTON resref numexpr ',' numexpr ',' numexpr ','
+           numexpr ',' numexpr ','
            { style = WS_CHILD | WS_VISIBLE; }
            styleexpr optcnumexpr
          {
-           $$ = define_control ($2, $4, $6, $8, $10, $12, CTL_BUTTON,
-                                style, $16);
+           rc_res_id cid;
+           cid.named = 0;
+           cid.u.id = CTL_BUTTON;
+           $$ = define_control ($2, $3, $5, $7, $9, $11, cid,
+                                style, $15);
          }
        ;
 
@@ -777,52 +870,68 @@ control:
    style.  CLASS is the class of the control.  */
 
 control_params:
-         optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
-           opt_control_data
+         numexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data
          {
-           $$ = define_control ($1, $2, $3, $4, $5, $6, class,
+           $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class,
                                 default_style | WS_CHILD | WS_VISIBLE, 0);
-           if ($7 != NULL)
+           if ($6 != NULL)
              {
                if (dialog.ex == NULL)
                  rcparse_warning (_("control data requires DIALOGEX"));
-               $$->data = $7;
+               $$->data = $6;
              }
          }
-       | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
+       | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
            control_params_styleexpr optcnumexpr opt_control_data
          {
-           $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
-           if ($9 != NULL)
+           $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
+           if ($8 != NULL)
              {
                if (dialog.ex == NULL)
                  rcparse_warning (_("control data requires DIALOGEX"));
-               $$->data = $9;
+               $$->data = $8;
              }
          }
-       | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
+       | numexpr cnumexpr cnumexpr cnumexpr cnumexpr
            control_params_styleexpr cnumexpr cnumexpr opt_control_data
          {
-           $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
+           $$ = define_control (res_text_field, $1, $2, $3, $4, $5, class, style, $7);
            if (dialog.ex == NULL)
              rcparse_warning (_("help ID requires DIALOGEX"));
-           $$->help = $9;
-           $$->data = $10;
+           $$->help = $8;
+           $$->data = $9;
+         }
+       ;
+
+cresid:
+         ',' resid
+         {
+           if ($2.named)
+             res_unistring_to_id (&$$, $2.u.n.name);
+           else
+             $$=$2;
          }
        ;
 
-optstringc:
+optresidc:
          /* empty */
          {
-           $$ = NULL;
+           res_string_to_id (&$$, "");
          }
-       | QUOTEDSTRING
+       | resid ',' { $$=$1; }
+       ;
+
+resid:
+         posnumexpr
          {
-           $$ = $1;
+           $$.named = 0;
+           $$.u.id = $1;
          }
-       | QUOTEDSTRING ','
+       | res_unicode_string_concat
          {
-           $$ = $1;
+           $$.named = 1;
+           $$.u.n.name = $1;
+           $$.u.n.length = unichar_len ($1);
          }
        ;
 
@@ -863,6 +972,9 @@ font:
          id FONT memflags_move_discard file_name
          {
            define_font ($1, &$3, $4);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -872,6 +984,9 @@ icon:
          id ICON memflags_move_discard file_name
          {
            define_icon ($1, &$3, $4);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -891,6 +1006,9 @@ menu:
          id MENU suboptions BEG menuitems END
          {
            define_menu ($1, &$3, $5);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -905,7 +1023,7 @@ menuitems:
              $$ = $2;
            else
              {
-               struct menuitem **pp;
+               rc_menuitem **pp;
 
                for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
                  ;
@@ -916,7 +1034,7 @@ menuitems:
        ;
 
 menuitem:
-         MENUITEM QUOTEDSTRING cnumexpr menuitem_flags
+         MENUITEM res_unicode_string_concat cnumexpr menuitem_flags
          {
            $$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
          }
@@ -924,7 +1042,7 @@ menuitem:
          {
            $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
          }
-       | POPUP QUOTEDSTRING menuitem_flags BEG menuitems END
+       | POPUP res_unicode_string_concat menuitem_flags BEG menuitems END
          {
            $$ = define_menuitem ($2, 0, $3, 0, 0, $5);
          }
@@ -978,6 +1096,9 @@ menuex:
          id MENUEX suboptions BEG menuexitems END
          {
            define_menu ($1, &$3, $5);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -992,7 +1113,7 @@ menuexitems:
              $$ = $2;
            else
              {
-               struct menuitem **pp;
+               rc_menuitem **pp;
 
                for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next)
                  ;
@@ -1003,15 +1124,15 @@ menuexitems:
        ;
 
 menuexitem:
-         MENUITEM QUOTEDSTRING
+         MENUITEM res_unicode_string_concat
          {
            $$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
          }
-       | MENUITEM QUOTEDSTRING cnumexpr
+       | MENUITEM res_unicode_string_concat cnumexpr
          {
            $$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
          }
-       | MENUITEM QUOTEDSTRING cnumexpr cnumexpr optcnumexpr
+       | MENUITEM res_unicode_string_concat cnumexpr cnumexpr optcnumexpr
          {
            $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
          }
@@ -1019,19 +1140,19 @@ menuexitem:
          {
            $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
          }
-       | POPUP QUOTEDSTRING BEG menuexitems END
+       | POPUP res_unicode_string_concat BEG menuexitems END
          {
            $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
          }
-       | POPUP QUOTEDSTRING cnumexpr BEG menuexitems END
+       | POPUP res_unicode_string_concat cnumexpr BEG menuexitems END
          {
            $$ = define_menuitem ($2, $3, 0, 0, 0, $5);
          }
-       | POPUP QUOTEDSTRING cnumexpr cnumexpr BEG menuexitems END
+       | POPUP res_unicode_string_concat cnumexpr cnumexpr BEG menuexitems END
          {
            $$ = define_menuitem ($2, $3, $4, 0, 0, $6);
          }
-       | POPUP QUOTEDSTRING cnumexpr cnumexpr cnumexpr optcnumexpr
+       | POPUP res_unicode_string_concat cnumexpr cnumexpr cnumexpr optcnumexpr
            BEG menuexitems END
          {
            $$ = define_menuitem ($2, $3, $4, $5, $6, $8);
@@ -1044,15 +1165,9 @@ messagetable:
          id MESSAGETABLE memflags_move file_name
          {
            define_messagetable ($1, &$3, $4);
-         }
-       ;
-
-/* Rcdata resources.  */
-
-rcdata:
-         id RCDATA suboptions BEG optrcdata_data END
-         {
-           define_rcdata ($1, &$3, $5.first);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -1083,102 +1198,242 @@ optrcdata_data_int:
        ;
 
 rcdata_data:
-         SIZEDSTRING
+         sizedstring
          {
-           struct rcdata_item *ri;
+           rc_rcdata_item *ri;
 
            ri = define_rcdata_string ($1.s, $1.length);
            $$.first = ri;
            $$.last = ri;
          }
+       | sizedunistring
+         {
+           rc_rcdata_item *ri;
+
+           ri = define_rcdata_unistring ($1.s, $1.length);
+           $$.first = ri;
+           $$.last = ri;
+         }
        | sizednumexpr
          {
-           struct rcdata_item *ri;
+           rc_rcdata_item *ri;
 
            ri = define_rcdata_number ($1.val, $1.dword);
            $$.first = ri;
            $$.last = ri;
          }
-       | rcdata_data ',' SIZEDSTRING
+       | rcdata_data ',' sizedstring
          {
-           struct rcdata_item *ri;
+           rc_rcdata_item *ri;
 
            ri = define_rcdata_string ($3.s, $3.length);
            $$.first = $1.first;
            $1.last->next = ri;
            $$.last = ri;
          }
+       | rcdata_data ',' sizedunistring
+         {
+           rc_rcdata_item *ri;
+
+           ri = define_rcdata_unistring ($3.s, $3.length);
+           $$.first = $1.first;
+           $1.last->next = ri;
+           $$.last = ri;
+         }
        | rcdata_data ',' sizednumexpr
          {
-           struct rcdata_item *ri;
+           rc_rcdata_item *ri;
 
            ri = define_rcdata_number ($3.val, $3.dword);
            $$.first = $1.first;
            $1.last->next = ri;
            $$.last = ri;
          }
+       | rcdata_data ','
+         {
+           $$=$1;
+         }
        ;
 
 /* Stringtable resources.  */
 
 stringtable:
-         STRINGTABLE suboptions BEG 
-           { sub_res_info = $2; }
-           string_data END
+         STRINGTABLE suboptions BEG
+           { sub_res_info = $2; rcparse_rcdata (); }
+           string_data END { rcparse_normal (); }
        ;
 
 string_data:
          /* empty */
-       | string_data numexpr QUOTEDSTRING
+       | string_data numexpr res_unicode_sizedstring_concat
+         {
+           define_stringtable (&sub_res_info, $2, $3.s, $3.length);
+           rcparse_discard_strings ();
+         }
+       | string_data numexpr ',' res_unicode_sizedstring_concat
          {
-           define_stringtable (&sub_res_info, $2, $3);
+           define_stringtable (&sub_res_info, $2, $4.s, $4.length);
+           rcparse_discard_strings ();
          }
-       | string_data numexpr ',' QUOTEDSTRING
+       | string_data error
          {
-           define_stringtable (&sub_res_info, $2, $4);
+           rcparse_warning (_("invalid stringtable resource."));
+           abort ();
          }
        ;
 
+rcdata_id:
+       id
+         {
+           $$=$1;
+         }
+      | HTML
+       {
+         $$.named = 0;
+         $$.u.id = 23;
+       }
+      | RCDATA
+        {
+          $$.named = 0;
+          $$.u.id = RT_RCDATA;
+        }
+      | MANIFEST
+        {
+          $$.named = 0;
+          $$.u.id = RT_MANIFEST;
+        }
+      | PLUGPLAY
+        {
+          $$.named = 0;
+          $$.u.id = RT_PLUGPLAY;
+        }
+      | VXD
+        {
+          $$.named = 0;
+          $$.u.id = RT_VXD;
+        }
+      | DLGINCLUDE
+        {
+          $$.named = 0;
+          $$.u.id = RT_DLGINCLUDE;
+        }
+      | DLGINIT
+        {
+          $$.named = 0;
+          $$.u.id = RT_DLGINIT;
+        }
+      | ANICURSOR
+        {
+          $$.named = 0;
+          $$.u.id = RT_ANICURSOR;
+        }
+      | ANIICON
+        {
+          $$.named = 0;
+          $$.u.id = RT_ANIICON;
+        }
+      ;
+
 /* User defined resources.  We accept general suboptions in the
    file_name case to keep the parser happy.  */
 
 user:
-         id id suboptions BEG optrcdata_data END
+         id rcdata_id suboptions BEG optrcdata_data END
          {
            define_user_data ($1, $2, &$3, $5.first);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
-       | id id suboptions file_name
+       | id rcdata_id suboptions file_name
          {
            define_user_file ($1, $2, &$3, $4);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
+toolbar:
+       id TOOLBAR suboptions numexpr cnumexpr BEG toolbar_data END
+       {
+         define_toolbar ($1, &$3, $4, $5, $7);
+       }
+       ;
+
+toolbar_data: /* empty */ { $$= NULL; }
+       | toolbar_data BUTTON id
+       {
+         rc_toolbar_item *c,*n;
+         c = $1;
+         n= (rc_toolbar_item *)
+             res_alloc (sizeof (rc_toolbar_item));
+         if (c != NULL)
+           while (c->next != NULL)
+             c = c->next;
+         n->prev = c;
+         n->next = NULL;
+         if (c != NULL)
+           c->next = n;
+         n->id = $3;
+         if ($1 == NULL)
+           $$ = n;
+         else
+           $$ = $1;
+       }
+       | toolbar_data SEPARATOR
+       {
+         rc_toolbar_item *c,*n;
+         c = $1;
+         n= (rc_toolbar_item *)
+             res_alloc (sizeof (rc_toolbar_item));
+         if (c != NULL)
+           while (c->next != NULL)
+             c = c->next;
+         n->prev = c;
+         n->next = NULL;
+         if (c != NULL)
+           c->next = n;
+         n->id.named = 0;
+         n->id.u.id = 0;
+         if ($1 == NULL)
+           $$ = n;
+         else
+           $$ = $1;
+       }
+       ;
+
 /* Versioninfo resources.  */
 
 versioninfo:
          id VERSIONINFO fixedverinfo BEG verblocks END
          {
            define_versioninfo ($1, language, $3, $5);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
 fixedverinfo:
          /* empty */
          {
-           $$ = ((struct fixed_versioninfo *)
-                 res_alloc (sizeof (struct fixed_versioninfo)));
-           memset ($$, 0, sizeof (struct fixed_versioninfo));
+           $$ = ((rc_fixed_versioninfo *)
+                 res_alloc (sizeof (rc_fixed_versioninfo)));
+           memset ($$, 0, sizeof (rc_fixed_versioninfo));
          }
-       | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr
+       | fixedverinfo FILEVERSION numexpr optcnumexpr optcnumexpr
+         optcnumexpr
          {
-           $1->file_version_ms = ($3 << 16) | $4;
-           $1->file_version_ls = ($5 << 16) | $6;
+           $1->file_version_ms = ($3 << 16) | ($4 & 0xffff);
+           $1->file_version_ls = ($5 << 16) | ($6 & 0xffff);
            $$ = $1;
          }
-       | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr
+       | fixedverinfo PRODUCTVERSION numexpr optcnumexpr optcnumexpr
+         optcnumexpr
          {
-           $1->product_version_ms = ($3 << 16) | $4;
-           $1->product_version_ls = ($5 << 16) | $6;
+           $1->product_version_ms = ($3 << 16) | ($4 & 0xffff);
+           $1->product_version_ls = ($5 << 16) | ($6 & 0xffff);
            $$ = $1;
          }
        | fixedverinfo FILEFLAGSMASK numexpr
@@ -1219,22 +1474,33 @@ verblocks:
          {
            $$ = NULL;
          }
-       | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END
+       | verblocks BLOCKSTRINGFILEINFO BEG verstringtables END
          {
-           $$ = append_ver_stringfileinfo ($1, $4, $6);
+           $$ = append_ver_stringfileinfo ($1, $4);
          }
-       | verblocks BLOCKVARFILEINFO BEG VALUE QUOTEDSTRING vertrans END
+       | verblocks BLOCKVARFILEINFO BEG VALUE res_unicode_string_concat vertrans END
          {
            $$ = append_ver_varfileinfo ($1, $5, $6);
          }
        ;
 
+verstringtables:
+      /* empty */
+         {
+           $$ = NULL;
+         }
+       | verstringtables BLOCK BEG vervals END
+         {
+           $$ = append_ver_stringtable ($1, $2, $4);
+         }
+       ;
+
 vervals:
          /* empty */
          {
            $$ = NULL;
          }
-       | vervals VALUE QUOTEDSTRING ',' QUOTEDSTRING
+       | vervals VALUE res_unicode_string_concat ',' res_unicode_string_concat
          {
            $$ = append_verval ($1, $3, $5);
          }
@@ -1259,33 +1525,24 @@ id:
            $$.named = 0;
            $$.u.id = $1;
          }
-       | STRING
+       | resname
          {
-           char *copy, *s;
-
-           /* It seems that resource ID's are forced to upper case.  */
-           copy = xstrdup ($1);
-           for (s = copy; *s != '\0'; s++)
-             *s = TOUPPER (*s);
-           res_string_to_id (&$$, copy);
-           free (copy);
+           res_unistring_to_id (&$$, $1);
          }
        ;
 
 /* A resource reference.  */
 
 resname:
-         QUOTEDSTRING
+         res_unicode_string
          {
            $$ = $1;
          }
-       | QUOTEDSTRING ','
-         {
-           $$ = $1;
-         }
-       | STRING ','
+       | STRING
          {
-           $$ = $1;
+           unichar *h = NULL;
+           unicode_from_ascii ((rc_uint_type *) NULL, &h, $1);
+           $$ = h;
          }
        ;
 
@@ -1298,14 +1555,11 @@ resref:
          }
        | resname
          {
-           char *copy, *s;
-
-           /* It seems that resource ID's are forced to upper case.  */
-           copy = xstrdup ($1);
-           for (s = copy; *s != '\0'; s++)
-             *s = TOUPPER (*s);
-           res_string_to_id (&$$, copy);
-           free (copy);
+           res_unistring_to_id (&$$, $1);
+         }
+       | resname ','
+         {
+           res_unistring_to_id (&$$, $1);
          }
        ;
 
@@ -1315,10 +1569,10 @@ resref:
 suboptions:
          /* empty */
          {
-           memset (&$$, 0, sizeof (struct res_res_info));
+           memset (&$$, 0, sizeof (rc_res_res_info));
            $$.language = language;
            /* FIXME: Is this the right default?  */
-           $$.memflags = MEMFLAG_MOVEABLE;
+           $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
          }
        | suboptions memflag
          {
@@ -1348,7 +1602,7 @@ suboptions:
 memflags_move_discard:
          /* empty */
          {
-           memset (&$$, 0, sizeof (struct res_res_info));
+           memset (&$$, 0, sizeof (rc_res_res_info));
            $$.language = language;
            $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE;
          }
@@ -1365,9 +1619,9 @@ memflags_move_discard:
 memflags_move:
          /* empty */
          {
-           memset (&$$, 0, sizeof (struct res_res_info));
+           memset (&$$, 0, sizeof (rc_res_res_info));
            $$.language = language;
-           $$.memflags = MEMFLAG_MOVEABLE;
+           $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
          }
        | memflags_move memflag
          {
@@ -1431,6 +1685,109 @@ file_name:
          }
        ;
 
+/* Concat string */
+res_unicode_string_concat:
+         res_unicode_string
+         {
+           $$ = $1;
+         }
+       |
+         res_unicode_string_concat res_unicode_string
+         {
+           rc_uint_type l1 = unichar_len ($1);
+           rc_uint_type l2 = unichar_len ($2);
+           unichar *h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
+           if (l1 != 0)
+             memcpy (h, $1, l1 * sizeof (unichar));
+           if (l2 != 0)
+             memcpy (h + l1, $2, l2  * sizeof (unichar));
+           h[l1 + l2] = 0;
+           $$ = h;
+         }
+       ;
+
+res_unicode_string:
+         QUOTEDUNISTRING
+         {
+           $$ = unichar_dup ($1);
+         }
+       | QUOTEDSTRING
+         {
+           unichar *h = NULL;
+           unicode_from_ascii ((rc_uint_type *) NULL, &h, $1);
+           $$ = h;
+         }
+       ;
+
+res_unicode_sizedstring:
+         sizedunistring
+         {
+           $$ = $1;
+         }
+       | sizedstring
+         {
+           unichar *h = NULL;
+           rc_uint_type l = 0;
+           unicode_from_ascii_len (&l, &h, $1.s, $1.length);
+           $$.s = h;
+           $$.length = l;
+         }
+       ;
+
+/* Concat string */
+res_unicode_sizedstring_concat:
+         res_unicode_sizedstring
+         {
+           $$ = $1;
+         }
+       |
+         res_unicode_sizedstring_concat res_unicode_sizedstring
+         {
+           rc_uint_type l1 = $1.length;
+           rc_uint_type l2 = $2.length;
+           unichar *h = (unichar *) res_alloc ((l1 + l2 + 1) * sizeof (unichar));
+           if (l1 != 0)
+             memcpy (h, $1.s, l1 * sizeof (unichar));
+           if (l2 != 0)
+             memcpy (h + l1, $2.s, l2  * sizeof (unichar));
+           h[l1 + l2] = 0;
+           $$.length = l1 + l2;
+           $$.s = h;
+         }
+       ;
+
+sizedstring:
+         SIZEDSTRING
+         {
+           $$ = $1;
+         }
+       | sizedstring SIZEDSTRING
+         {
+           rc_uint_type l = $1.length + $2.length;
+           char *h = (char *) res_alloc (l);
+           memcpy (h, $1.s, $1.length);
+           memcpy (h + $1.length, $2.s, $2.length);
+           $$.s = h;
+           $$.length = l;
+         }
+       ;
+
+sizedunistring:
+         SIZEDUNISTRING
+         {
+           $$ = $1;
+         }
+       | sizedunistring SIZEDUNISTRING
+         {
+           rc_uint_type l = $1.length + $2.length;
+           unichar *h = (unichar *) res_alloc (l * sizeof (unichar));
+           memcpy (h, $1.s, $1.length * sizeof (unichar));
+           memcpy (h + $1.length, $2.s, $2.length  * sizeof (unichar));
+           $$.s = h;
+           $$.length = l;
+         }
+       ;
+
 /* A style expression.  This changes the static variable STYLE.  We do
    it this way because rc appears to permit a style to be set to
    something like
@@ -1530,12 +1887,12 @@ sizednumexpr:
          }
        | sizednumexpr '/' sizednumexpr
          {
-           $$.val = $1.val / $3.val;
+           $$.val = $1.val / ($3.val ? $3.val : 1);
            $$.dword = $1.dword || $3.dword;
          }
        | sizednumexpr '%' sizednumexpr
          {
-           $$.val = $1.val % $3.val;
+           $$.val = $1.val % ($3.val ? $3.val : 1);
            $$.dword = $1.dword || $3.dword;
          }
        | sizednumexpr '+' sizednumexpr
@@ -1609,12 +1966,13 @@ sizedposnumexpr:
          }
        | sizedposnumexpr '/' sizednumexpr
          {
-           $$.val = $1.val / $3.val;
+           $$.val = $1.val / ($3.val ? $3.val : 1);
            $$.dword = $1.dword || $3.dword;
          }
        | sizedposnumexpr '%' sizednumexpr
          {
-           $$.val = $1.val % $3.val;
+           /* PR 17512: file: 89105a25.  */
+           $$.val = $1.val % ($3.val ? $3.val : 1);
            $$.dword = $1.dword || $3.dword;
          }
        | sizedposnumexpr '+' sizednumexpr
@@ -1649,8 +2007,7 @@ sizedposnumexpr:
 /* Set the language from the command line.  */
 
 void
-rcparse_set_language (lang)
-     int lang;
+rcparse_set_language (int lang)
 {
   language = lang;
 }
This page took 0.044684 seconds and 4 git commands to generate.