2002-12-06 Andrew Cagney <ac131313@redhat.com>
[deliverable/binutils-gdb.git] / binutils / rcparse.y
index 9ea9cf5eae4b9b5d878301a17cc7ad8b0ee08f69..1f10da7eaf3e23bb258ac04b017e145956cf8738 100644 (file)
@@ -1,5 +1,5 @@
 %{ /* rcparse.y -- parser for Windows rc files
-   Copyright 1997 Free Software Foundation, Inc.
+   Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support.
 
    This file is part of GNU Binutils.
@@ -26,8 +26,7 @@
 #include "bucomm.h"
 #include "libiberty.h"
 #include "windres.h"
-
-#include <ctype.h>
+#include "safe-ctype.h"
 
 /* The current language.  */
 
@@ -107,7 +106,7 @@ static unsigned long class;
 %token BEDIT HEDIT IEDIT
 %token FONT
 %token ICON
-%token LANGUAGE CHARACTERISTICS VERSION
+%token LANGUAGE CHARACTERISTICS VERSIONK
 %token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE
 %token MENUBARBREAK MENUBREAK
 %token MESSAGETABLE
@@ -122,6 +121,7 @@ static unsigned long class;
 %token <s> QUOTEDSTRING STRING
 %token <i> NUMBER
 %token <ss> SIZEDSTRING
+%token IGNORED_TOKEN
 
 %type <pacc> acc_entries
 %type <acc> acc_entry acc_event
@@ -135,11 +135,11 @@ static unsigned long class;
 %type <vervar> vertrans
 %type <res_info> suboptions memflags_move_discard memflags_move
 %type <memflags> memflag
-%type <id> id
+%type <id> id resref
 %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
+%type <s> optstringc file_name resname
 %type <i> sizednumexpr sizedposnumexpr
 
 %left '|'
@@ -153,27 +153,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
-       ;
-
-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 rcdata
+       | input stringtable
+       | input user
+       | input versioninfo
+       | input IGNORED_TOKEN
        ;
 
 /* Accelerator resources.  */
@@ -182,6 +176,9 @@ accelerator:
          id ACCELERATORS suboptions BEG acc_entries END
          {
            define_accelerator ($1, &$3, $5);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -221,6 +218,9 @@ acc_entry:
            $$ = $1;
            $$.id = $2;
            $$.flags |= $4;
+           if (($$.flags & ACC_VIRTKEY) == 0
+               && ($$.flags & (ACC_SHIFT | ACC_CONTROL)) != 0)
+             rcparse_warning (_("inappropriate modifiers for non-VIRTKEY"));
          }
        ;
 
@@ -228,21 +228,27 @@ acc_event:
          QUOTEDSTRING
          {
            const char *s = $1;
+           char ch;
 
+           $$.next = NULL;
            $$.id = 0;
-           if (*s != '^')
+           ch = *s;
+           if (ch != '^')
              $$.flags = 0;
            else
              {
-               $$.flags = ACC_CONTROL;
+               $$.flags = ACC_CONTROL | ACC_VIRTKEY;
                ++s;
+               ch = *s;
+               ch = TOUPPER (ch);
              }
-           $$.key = *s;
+           $$.key = ch;
            if (s[1] != '\0')
-             rcparse_warning ("accelerator should only be one character");
+             rcparse_warning (_("accelerator should only be one character"));
          }
        | posnumexpr
          {
+           $$.next = NULL;
            $$.flags = 0;
            $$.id = 0;
            $$.key = $1;
@@ -258,6 +264,11 @@ acc_options:
          {
            $$ = $1 | $3;
          }
+       /* I've had one report that the comma is optional.  */
+       | acc_options acc_option
+         {
+           $$ = $1 | $2;
+         }
        ;
 
 acc_option:
@@ -294,6 +305,9 @@ bitmap:
          id BITMAP memflags_move file_name
          {
            define_bitmap ($1, &$3, $4);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -303,6 +317,9 @@ cursor:
          id CURSOR memflags_move_discard file_name
          {
            define_cursor ($1, &$3, $4);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -319,14 +336,20 @@ dialog:
              dialog.height = $8;
              dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
              dialog.exstyle = $4;
+             dialog.menu.named = 1;
+             dialog.class.named = 1;
              dialog.font = NULL;
              dialog.ex = NULL;
              dialog.controls = NULL;
              sub_res_info = $3;
+             style = 0;
            }
            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
@@ -338,16 +361,22 @@ dialog:
              dialog.height = $8;
              dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
              dialog.exstyle = $4;
+             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.controls = NULL;
              sub_res_info = $3;
+             style = 0;
            }
            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
@@ -359,6 +388,8 @@ dialog:
              dialog.height = $8;
              dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU;
              dialog.exstyle = $4;
+             dialog.menu.named = 1;
+             dialog.class.named = 1;
              dialog.font = NULL;
              dialog.ex = ((struct dialog_ex *)
                           res_alloc (sizeof (struct dialog_ex)));
@@ -366,10 +397,14 @@ dialog:
              dialog.ex->help = $9;
              dialog.controls = NULL;
              sub_res_info = $3;
+             style = 0;
            }
            styles BEG controls END
          {
            define_dialog ($1, &sub_res_info, &dialog);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -388,6 +423,8 @@ styles:
          /* empty */
        | styles CAPTION QUOTEDSTRING
          {
+           dialog.style |= WS_CAPTION;
+           style |= WS_CAPTION;
            unicode_from_ascii ((int *) NULL, &dialog.caption, $3);
          }
        | styles CLASS id
@@ -395,7 +432,6 @@ styles:
            dialog.class = $3;
          }
        | styles STYLE
-           { style = dialog.style }
            styleexpr
          {
            dialog.style = style;
@@ -404,21 +440,66 @@ styles:
          {
            dialog.exstyle = $3;
          }
+       | styles CLASS QUOTEDSTRING
+         {
+           res_string_to_id (& dialog.class, $3);
+         }
        | styles FONT numexpr ',' QUOTEDSTRING
          {
+           dialog.style |= DS_SETFONT;
+           style |= DS_SETFONT;
+           dialog.pointsize = $3;
+           unicode_from_ascii ((int *) NULL, &dialog.font, $5);
+           if (dialog.ex != NULL)
+             {
+               dialog.ex->weight = 0;
+               dialog.ex->italic = 0;
+               dialog.ex->charset = 1;
+             }
+         }
+       | styles FONT numexpr ',' QUOTEDSTRING cnumexpr
+         {
+           dialog.style |= DS_SETFONT;
+           style |= DS_SETFONT;
            dialog.pointsize = $3;
            unicode_from_ascii ((int *) NULL, &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 ',' QUOTEDSTRING cnumexpr cnumexpr
          {
+           dialog.style |= DS_SETFONT;
+           style |= DS_SETFONT;
            dialog.pointsize = $3;
            unicode_from_ascii ((int *) NULL, &dialog.font, $5);
            if (dialog.ex == NULL)
-             rcparse_warning ("extended FONT requires DIALOGEX");
+             rcparse_warning (_("extended FONT requires DIALOGEX"));
            else
              {
                dialog.ex->weight = $6;
                dialog.ex->italic = $7;
+               dialog.ex->charset = 1;
+             }
+         }
+       | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr cnumexpr
+         {
+           dialog.style |= DS_SETFONT;
+           style |= DS_SETFONT;
+           dialog.pointsize = $3;
+           unicode_from_ascii ((int *) NULL, &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
@@ -431,9 +512,9 @@ styles:
          }
        | styles LANGUAGE numexpr cnumexpr
          {
-           sub_res_info.language = $3 | ($4 << 8);
+           sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT);
          }
-       | styles VERSION numexpr
+       | styles VERSIONK numexpr
          {
            sub_res_info.version = $3;
          }
@@ -492,7 +573,7 @@ control:
          {
            $$ = $3;
            if (dialog.ex == NULL)
-             rcparse_warning ("IEDIT requires DIALOGEX");
+             rcparse_warning (_("BEDIT requires DIALOGEX"));
            res_string_to_id (&$$->class, "BEDIT");
          }
        | CHECKBOX
@@ -522,7 +603,7 @@ control:
            if ($11 != NULL)
              {
                if (dialog.ex == NULL)
-                 rcparse_warning ("control data requires DIALOGEX");
+                 rcparse_warning (_("control data requires DIALOGEX"));
                $$->data = $11;
              }
          }
@@ -531,10 +612,34 @@ control:
          {
            $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10);
            if (dialog.ex == NULL)
-             rcparse_warning ("help ID requires DIALOGEX");
+             rcparse_warning (_("help ID requires DIALOGEX"));
            $$->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
            {
              default_style = SS_CENTER | WS_GROUP;
@@ -585,42 +690,32 @@ control:
          {
            $$ = $3;
            if (dialog.ex == NULL)
-             rcparse_warning ("IEDIT requires DIALOGEX");
+             rcparse_warning (_("IEDIT requires DIALOGEX"));
            res_string_to_id (&$$->class, "HEDIT");
          }
-       | ICON optstringc numexpr cnumexpr cnumexpr opt_control_data
-         {
-           $$ = define_control ($2, $3, $4, $5, 0, 0, CTL_STATIC,
-                                SS_ICON | WS_CHILD | WS_VISIBLE, 0);
-           if ($6 != NULL)
-             {
-               if (dialog.ex == NULL)
-                 rcparse_warning ("control data requires DIALOGEX");
-               $$->data = $6;
-             }
-         }
-       | ICON optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
+       | ICON resref numexpr cnumexpr cnumexpr opt_control_data
+          {
+           $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $6,
+                                     dialog.ex);
+          }
+       | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
+           opt_control_data
+          {
+           $$ = define_icon_control ($2, $3, $4, $5, 0, 0, 0, $8,
+                                     dialog.ex);
+          }
+       | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
            icon_styleexpr optcnumexpr opt_control_data
-         {
-           $$ = define_control ($2, $3, $4, $5, $6, $7, CTL_STATIC,
-                                style, $9);
-           if ($10 != NULL)
-             {
-               if (dialog.ex == NULL)
-                 rcparse_warning ("control data requires DIALOGEX");
-               $$->data = $10;
-             }
-         }
-       | ICON optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr
+          {
+           $$ = define_icon_control ($2, $3, $4, $5, style, $9, 0, $10,
+                                     dialog.ex);
+          }
+       | ICON resref numexpr cnumexpr cnumexpr cnumexpr cnumexpr
            icon_styleexpr cnumexpr cnumexpr opt_control_data
-         {
-           $$ = define_control ($2, $3, $4, $5, $6, $7, CTL_STATIC,
-                                style, $9);
-           if (dialog.ex == NULL)
-             rcparse_warning ("help ID requires DIALOGEX");
-           $$->help = $10;
-           $$->data = $11;
-         }
+          {
+           $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11,
+                                     dialog.ex);
+          }
        | IEDIT
            {
              default_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
@@ -631,7 +726,7 @@ control:
          {
            $$ = $3;
            if (dialog.ex == NULL)
-             rcparse_warning ("IEDIT requires DIALOGEX");
+             rcparse_warning (_("IEDIT requires DIALOGEX"));
            res_string_to_id (&$$->class, "IEDIT");
          }
        | LISTBOX
@@ -716,7 +811,7 @@ control:
          }
        | USERBUTTON QUOTEDSTRING ',' numexpr ',' numexpr ',' numexpr ','
            numexpr ',' numexpr ',' 
-           { style = WS_CHILD | WS_VISIBLE }
+           { style = WS_CHILD | WS_VISIBLE; }
            styleexpr optcnumexpr
          {
            $$ = define_control ($2, $4, $6, $8, $10, $12, CTL_BUTTON,
@@ -740,7 +835,7 @@ control_params:
            if ($7 != NULL)
              {
                if (dialog.ex == NULL)
-                 rcparse_warning ("control data requires DIALOGEX");
+                 rcparse_warning (_("control data requires DIALOGEX"));
                $$->data = $7;
              }
          }
@@ -751,7 +846,7 @@ control_params:
            if ($9 != NULL)
              {
                if (dialog.ex == NULL)
-                 rcparse_warning ("control data requires DIALOGEX");
+                 rcparse_warning (_("control data requires DIALOGEX"));
                $$->data = $9;
              }
          }
@@ -760,7 +855,7 @@ control_params:
          {
            $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8);
            if (dialog.ex == NULL)
-             rcparse_warning ("help ID requires DIALOGEX");
+             rcparse_warning (_("help ID requires DIALOGEX"));
            $$->help = $9;
            $$->data = $10;
          }
@@ -771,6 +866,10 @@ optstringc:
          {
            $$ = NULL;
          }
+       | QUOTEDSTRING
+         {
+           $$ = $1;
+         }
        | QUOTEDSTRING ','
          {
            $$ = $1;
@@ -814,6 +913,9 @@ font:
          id FONT memflags_move_discard file_name
          {
            define_font ($1, &$3, $4);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -823,6 +925,9 @@ icon:
          id ICON memflags_move_discard file_name
          {
            define_icon ($1, &$3, $4);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -832,7 +937,7 @@ icon:
 language:
          LANGUAGE numexpr cnumexpr
          {
-           language = $2 | ($3 << 8);
+           language = $2 | ($3 << SUBLANG_SHIFT);
          }
        ;
 
@@ -842,6 +947,9 @@ menu:
          id MENU suboptions BEG menuitems END
          {
            define_menu ($1, &$3, $5);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -929,6 +1037,9 @@ menuex:
          id MENUEX suboptions BEG menuexitems END
          {
            define_menu ($1, &$3, $5);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -966,6 +1077,10 @@ menuexitem:
          {
            $$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
          }
+       | MENUITEM SEPARATOR
+         {
+           $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
+         }
        | POPUP QUOTEDSTRING BEG menuexitems END
          {
            $$ = define_menuitem ($2, 0, 0, 0, 0, $4);
@@ -991,6 +1106,9 @@ messagetable:
          id MESSAGETABLE memflags_move file_name
          {
            define_messagetable ($1, &$3, $4);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -1000,6 +1118,9 @@ rcdata:
          id RCDATA suboptions BEG optrcdata_data END
          {
            define_rcdata ($1, &$3, $5.first);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -1079,10 +1200,16 @@ string_data:
        | string_data numexpr QUOTEDSTRING
          {
            define_stringtable (&sub_res_info, $2, $3);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        | string_data numexpr ',' QUOTEDSTRING
          {
            define_stringtable (&sub_res_info, $2, $4);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -1093,10 +1220,16 @@ user:
          id 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
          {
            define_user_file ($1, $2, &$3, $4);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -1106,6 +1239,9 @@ versioninfo:
          id VERSIONINFO fixedverinfo BEG verblocks END
          {
            define_versioninfo ($1, language, $3, $5);
+           if (yychar != YYEMPTY)
+             YYERROR;
+           rcparse_discard_strings ();
          }
        ;
 
@@ -1213,8 +1349,44 @@ id:
            /* It seems that resource ID's are forced to upper case.  */
            copy = xstrdup ($1);
            for (s = copy; *s != '\0'; s++)
-             if (islower (*s))
-               *s = toupper (*s);
+             *s = TOUPPER (*s);
+           res_string_to_id (&$$, copy);
+           free (copy);
+         }
+       ;
+
+/* A resource reference.  */
+
+resname:
+         QUOTEDSTRING
+         {
+           $$ = $1;
+         }
+       | QUOTEDSTRING ','
+         {
+           $$ = $1;
+         }
+       | STRING ','
+         {
+           $$ = $1;
+         }
+       ;
+
+
+resref:
+         posnumexpr ','
+         {
+           $$.named = 0;
+           $$.u.id = $1;
+         }
+       | 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);
          }
@@ -1229,7 +1401,7 @@ suboptions:
            memset (&$$, 0, sizeof (struct res_res_info));
            $$.language = language;
            /* FIXME: Is this the right default?  */
-           $$.memflags = MEMFLAG_MOVEABLE;
+           $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
          }
        | suboptions memflag
          {
@@ -1245,9 +1417,9 @@ suboptions:
        | suboptions LANGUAGE numexpr cnumexpr
          {
            $$ = $1;
-           $$.language = $3 | ($4 << 8);
+           $$.language = $3 | ($4 << SUBLANG_SHIFT);
          }
-       | suboptions VERSION numexpr
+       | suboptions VERSIONK numexpr
          {
            $$ = $1;
            $$.version = $3;
@@ -1278,9 +1450,9 @@ memflags_move:
          {
            memset (&$$, 0, sizeof (struct res_res_info));
            $$.language = language;
-           $$.memflags = MEMFLAG_MOVEABLE;
+           $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_PURE | MEMFLAG_DISCARDABLE;
          }
-       | memflags_move_discard memflag
+       | memflags_move memflag
          {
            $$ = $1;
            $$.memflags |= $2.on;
This page took 0.03328 seconds and 4 git commands to generate.