X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=binutils%2Frcparse.y;h=78ce917e233c5efdba82c409e2d913c949bba531;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=67079a5fd81ef6b4353771b971372961e377236a;hpb=252b5132c753830d5fd56823373aed85f2a0db63;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/rcparse.y b/binutils/rcparse.y index 67079a5fd8..78ce917e23 100644 --- a/binutils/rcparse.y +++ b/binutils/rcparse.y @@ -1,12 +1,13 @@ %{ /* rcparse.y -- parser for Windows rc files - Copyright 1997, 1998 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, @@ -16,18 +17,19 @@ 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 . */ +#include "sysdep.h" #include "bfd.h" #include "bucomm.h" #include "libiberty.h" #include "windres.h" - -#include +#include "safe-ctype.h" /* The current language. */ @@ -35,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. */ @@ -50,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 @@ -107,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 @@ -119,9 +135,12 @@ static unsigned long class; %token BLOCK %token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE %token NOT +%token QUOTEDUNISTRING %token QUOTEDSTRING STRING %token NUMBER +%token SIZEDUNISTRING %token SIZEDSTRING +%token IGNORED_TOKEN %type acc_entries %type acc_entry acc_event @@ -131,15 +150,20 @@ static unsigned long class; %type opt_control_data %type fixedverinfo %type verblocks +%type verstringtables %type vervals %type vertrans +%type toolbar_data %type suboptions memflags_move_discard memflags_move %type memflag -%type id +%type id rcdata_id optresidc resref resid cresid %type exstyle parennumber %type numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr %type acc_options acc_option menuitem_flags menuitem_flag -%type optstringc file_name +%type file_name +%type res_unicode_string resname res_unicode_string_concat +%type sizedstring +%type sizedunistring res_unicode_sizedstring res_unicode_sizedstring_concat %type sizednumexpr sizedposnumexpr %left '|' @@ -153,27 +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 - ; - -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. */ @@ -182,6 +200,9 @@ accelerator: id ACCELERATORS suboptions BEG acc_entries END { define_accelerator ($1, &$3, $5); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -192,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) ; @@ -222,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")); } ; @@ -242,8 +263,7 @@ acc_event: { $$.flags = ACC_CONTROL | ACC_VIRTKEY; ++s; - ch = *s; - ch = toupper ((unsigned char) ch); + ch = TOUPPER (s[0]); } $$.key = ch; if (s[1] != '\0') @@ -308,6 +328,9 @@ bitmap: id BITMAP memflags_move file_name { define_bitmap ($1, &$3, $4); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -317,6 +340,9 @@ cursor: id CURSOR memflags_move_discard file_name { define_cursor ($1, &$3, $4); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -339,10 +365,14 @@ dialog: 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 @@ -357,15 +387,19 @@ 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; } 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 @@ -380,16 +414,20 @@ 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; + style = 0; } styles BEG controls END { define_dialog ($1, &sub_res_info, &dialog); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -406,16 +444,17 @@ 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 { dialog.class = $3; } | styles STYLE - { style = dialog.style; } styleexpr { dialog.style = style; @@ -424,23 +463,66 @@ styles: { dialog.exstyle = $3; } - | styles FONT numexpr ',' QUOTEDSTRING + | styles CLASS res_unicode_string_concat + { + res_unistring_to_id (& dialog.class, $3); + } + | styles FONT numexpr ',' res_unicode_string_concat + { + dialog.style |= DS_SETFONT; + style |= DS_SETFONT; + dialog.pointsize = $3; + dialog.font = $5; + if (dialog.ex != NULL) + { + dialog.ex->weight = 0; + dialog.ex->italic = 0; + dialog.ex->charset = 1; + } + } + | styles FONT numexpr ',' res_unicode_string_concat 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 = 0; + dialog.ex->charset = 1; + } + } + | styles FONT numexpr ',' res_unicode_string_concat cnumexpr 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 = $7; + dialog.ex->charset = 1; + } } - | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr + | styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr 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 = $7; + dialog.ex->charset = $8; } } | styles MENU id @@ -453,7 +535,7 @@ styles: } | styles LANGUAGE numexpr cnumexpr { - sub_res_info.language = $3 | ($4 << 8); + sub_res_info.language = $3 | ($4 << SUBLANG_SHIFT); } | styles VERSIONK numexpr { @@ -465,7 +547,7 @@ controls: /* empty */ | controls control { - struct dialog_control **pp; + rc_dialog_control **pp; for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next) ; @@ -474,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 (_("IEDIT requires DIALOGEX")); + 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); @@ -548,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); @@ -557,125 +653,103 @@ 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"); } - | 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; - } - | IEDIT + { + $$ = define_icon_control ($2, $3, $4, $5, style, $9, $10, $11, + dialog.ex); + } + | 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"); @@ -684,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); } ; @@ -778,48 +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; } ; -optstringc: +cresid: + ',' resid + { + if ($2.named) + res_unistring_to_id (&$$, $2.u.n.name); + else + $$=$2; + } + ; + +optresidc: /* empty */ { - $$ = NULL; + res_string_to_id (&$$, ""); } - | QUOTEDSTRING ',' + | resid ',' { $$=$1; } + ; + +resid: + posnumexpr { - $$ = $1; + $$.named = 0; + $$.u.id = $1; + } + | res_unicode_string_concat + { + $$.named = 1; + $$.u.n.name = $1; + $$.u.n.length = unichar_len ($1); } ; @@ -860,6 +972,9 @@ font: id FONT memflags_move_discard file_name { define_font ($1, &$3, $4); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -869,6 +984,9 @@ icon: id ICON memflags_move_discard file_name { define_icon ($1, &$3, $4); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -878,7 +996,7 @@ icon: language: LANGUAGE numexpr cnumexpr { - language = $2 | ($3 << 8); + language = $2 | ($3 << SUBLANG_SHIFT); } ; @@ -888,6 +1006,9 @@ menu: id MENU suboptions BEG menuitems END { define_menu ($1, &$3, $5); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -902,7 +1023,7 @@ menuitems: $$ = $2; else { - struct menuitem **pp; + rc_menuitem **pp; for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next) ; @@ -913,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); } @@ -921,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); } @@ -975,6 +1096,9 @@ menuex: id MENUEX suboptions BEG menuexitems END { define_menu ($1, &$3, $5); + if (yychar != YYEMPTY) + YYERROR; + rcparse_discard_strings (); } ; @@ -989,7 +1113,7 @@ menuexitems: $$ = $2; else { - struct menuitem **pp; + rc_menuitem **pp; for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next) ; @@ -1000,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); } @@ -1016,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); @@ -1041,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 (); } ; @@ -1080,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 @@ -1216,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); } @@ -1256,17 +1525,41 @@ id: $$.named = 0; $$.u.id = $1; } + | resname + { + res_unistring_to_id (&$$, $1); + } + ; + +/* A resource reference. */ + +resname: + res_unicode_string + { + $$ = $1; + } | STRING { - char *copy, *s; + unichar *h = NULL; + unicode_from_ascii ((rc_uint_type *) NULL, &h, $1); + $$ = h; + } + ; + - /* It seems that resource ID's are forced to upper case. */ - copy = xstrdup ($1); - for (s = copy; *s != '\0'; s++) - if (islower ((unsigned char) *s)) - *s = toupper ((unsigned char) *s); - res_string_to_id (&$$, copy); - free (copy); +resref: + posnumexpr ',' + { + $$.named = 0; + $$.u.id = $1; + } + | resname + { + res_unistring_to_id (&$$, $1); + } + | resname ',' + { + res_unistring_to_id (&$$, $1); } ; @@ -1276,10 +1569,10 @@ id: 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 { @@ -1295,7 +1588,7 @@ suboptions: | suboptions LANGUAGE numexpr cnumexpr { $$ = $1; - $$.language = $3 | ($4 << 8); + $$.language = $3 | ($4 << SUBLANG_SHIFT); } | suboptions VERSIONK numexpr { @@ -1309,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; } @@ -1326,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 { @@ -1392,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 @@ -1491,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 @@ -1570,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 @@ -1610,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; }