%{ /* rcparse.y -- parser for Windows rc files
- Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1997-2019 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
Extended by Kai Tietz, Onevision.
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,
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>. */
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;
%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 <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr
%type <is> acc_options acc_option menuitem_flags menuitem_flag
%type <s> file_name
-%type <uni> res_unicode_string resname
+%type <uni> res_unicode_string resname res_unicode_string_concat
%type <ss> sizedstring
-%type <suni> sizedunistring
+%type <suni> sizedunistring res_unicode_sizedstring res_unicode_sizedstring_concat
%type <i> sizednumexpr sizedposnumexpr
%left '|'
styles:
/* empty */
- | styles CAPTION res_unicode_string
+ | styles CAPTION res_unicode_string_concat
{
dialog.style |= WS_CAPTION;
style |= WS_CAPTION;
{
dialog.exstyle = $3;
}
- | styles CLASS res_unicode_string
+ | styles CLASS res_unicode_string_concat
{
res_unistring_to_id (& dialog.class, $3);
}
- | styles FONT numexpr ',' res_unicode_string
+ | styles FONT numexpr ',' res_unicode_string_concat
{
dialog.style |= DS_SETFONT;
style |= DS_SETFONT;
dialog.ex->charset = 1;
}
}
- | styles FONT numexpr ',' res_unicode_string cnumexpr
+ | styles FONT numexpr ',' res_unicode_string_concat cnumexpr
{
dialog.style |= DS_SETFONT;
style |= DS_SETFONT;
dialog.ex->charset = 1;
}
}
- | styles FONT numexpr ',' res_unicode_string cnumexpr cnumexpr
+ | styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr
{
dialog.style |= DS_SETFONT;
style |= DS_SETFONT;
dialog.ex->charset = 1;
}
}
- | styles FONT numexpr ',' res_unicode_string cnumexpr cnumexpr cnumexpr
+ | styles FONT numexpr ',' res_unicode_string_concat cnumexpr cnumexpr cnumexpr
{
dialog.style |= DS_SETFONT;
style |= DS_SETFONT;
base_style = BS_AUTO3STATE;
class.named = 0;
class.u.id = CTL_BUTTON;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = BS_AUTOCHECKBOX;
class.named = 0;
class.u.id = CTL_BUTTON;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = BS_AUTORADIOBUTTON;
class.named = 0;
class.u.id = CTL_BUTTON;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
class.named = 0;
class.u.id = CTL_EDIT;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = BS_CHECKBOX | WS_TABSTOP;
class.named = 0;
class.u.id = CTL_BUTTON;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = 0;
class.named = 0;
class.u.id = CTL_COMBOBOX;
- res_text_field = res_null_text;
+ res_text_field = res_null_text;
}
control_params
{
base_style = SS_CENTER;
class.named = 0;
class.u.id = CTL_STATIC;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = BS_DEFPUSHBUTTON | WS_TABSTOP;
class.named = 0;
class.u.id = CTL_BUTTON;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
class.named = 0;
class.u.id = CTL_EDIT;
- res_text_field = res_null_text;
+ res_text_field = res_null_text;
}
control_params
{
base_style = BS_GROUPBOX;
class.named = 0;
class.u.id = CTL_BUTTON;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
class.named = 0;
class.u.id = CTL_EDIT;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = ES_LEFT | WS_BORDER | WS_TABSTOP;
class.named = 0;
class.u.id = CTL_EDIT;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = LBS_NOTIFY | WS_BORDER;
class.named = 0;
class.u.id = CTL_LISTBOX;
- res_text_field = res_null_text;
+ res_text_field = res_null_text;
}
control_params
{
base_style = SS_LEFT;
class.named = 0;
class.u.id = CTL_STATIC;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = BS_PUSHBUTTON | WS_TABSTOP;
class.named = 0;
class.u.id = CTL_BUTTON;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = BS_RADIOBUTTON;
class.named = 0;
class.u.id = CTL_BUTTON;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = SS_RIGHT;
class.named = 0;
class.u.id = CTL_STATIC;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
base_style = 0;
class.named = 0;
class.u.id = CTL_SCROLLBAR;
- res_text_field = res_null_text;
+ res_text_field = res_null_text;
}
control_params
{
base_style = BS_3STATE;
class.named = 0;
class.u.id = CTL_BUTTON;
- res_text_field = $2;
+ res_text_field = $2;
}
control_params
{
$$ = $4;
}
| USERBUTTON resref numexpr ',' numexpr ',' numexpr ','
- numexpr ',' numexpr ','
+ numexpr ',' numexpr ','
{ style = WS_CHILD | WS_VISIBLE; }
styleexpr optcnumexpr
{
$$.named = 0;
$$.u.id = $1;
}
- | res_unicode_string
+ | res_unicode_string_concat
{
$$.named = 1;
$$.u.n.name = $1;
;
menuitem:
- MENUITEM res_unicode_string cnumexpr menuitem_flags
+ MENUITEM res_unicode_string_concat cnumexpr menuitem_flags
{
$$ = define_menuitem ($2, $3, $4, 0, 0, NULL);
}
{
$$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
}
- | POPUP res_unicode_string menuitem_flags BEG menuitems END
+ | POPUP res_unicode_string_concat menuitem_flags BEG menuitems END
{
$$ = define_menuitem ($2, 0, $3, 0, 0, $5);
}
;
menuexitem:
- MENUITEM res_unicode_string
+ MENUITEM res_unicode_string_concat
{
$$ = define_menuitem ($2, 0, 0, 0, 0, NULL);
}
- | MENUITEM res_unicode_string cnumexpr
+ | MENUITEM res_unicode_string_concat cnumexpr
{
$$ = define_menuitem ($2, $3, 0, 0, 0, NULL);
}
- | MENUITEM res_unicode_string cnumexpr cnumexpr optcnumexpr
+ | MENUITEM res_unicode_string_concat cnumexpr cnumexpr optcnumexpr
{
$$ = define_menuitem ($2, $3, $4, $5, 0, NULL);
}
{
$$ = define_menuitem (NULL, 0, 0, 0, 0, NULL);
}
- | POPUP res_unicode_string BEG menuexitems END
+ | POPUP res_unicode_string_concat BEG menuexitems END
{
$$ = define_menuitem ($2, 0, 0, 0, 0, $4);
}
- | POPUP res_unicode_string cnumexpr BEG menuexitems END
+ | POPUP res_unicode_string_concat cnumexpr BEG menuexitems END
{
$$ = define_menuitem ($2, $3, 0, 0, 0, $5);
}
- | POPUP res_unicode_string cnumexpr cnumexpr BEG menuexitems END
+ | POPUP res_unicode_string_concat cnumexpr cnumexpr BEG menuexitems END
{
$$ = define_menuitem ($2, $3, $4, 0, 0, $6);
}
- | POPUP res_unicode_string cnumexpr cnumexpr cnumexpr optcnumexpr
+ | POPUP res_unicode_string_concat cnumexpr cnumexpr cnumexpr optcnumexpr
BEG menuexitems END
{
$$ = define_menuitem ($2, $3, $4, $5, $6, $8);
$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 res_unicode_string
+ | string_data numexpr res_unicode_sizedstring_concat
{
- define_stringtable (&sub_res_info, $2, $3);
- if (yychar != YYEMPTY)
- YYERROR;
+ define_stringtable (&sub_res_info, $2, $3.s, $3.length);
rcparse_discard_strings ();
}
- | string_data numexpr ',' res_unicode_string
+ | string_data numexpr ',' res_unicode_sizedstring_concat
{
- define_stringtable (&sub_res_info, $2, $4);
- if (yychar != YYEMPTY)
- YYERROR;
+ define_stringtable (&sub_res_info, $2, $4.s, $4.length);
rcparse_discard_strings ();
}
+ | string_data error
+ {
+ rcparse_warning (_("invalid stringtable resource."));
+ abort ();
+ }
;
rcdata_id:
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
{
$$ = 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 res_unicode_string 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 res_unicode_string ',' res_unicode_string
+ | vervals VALUE res_unicode_string_concat ',' res_unicode_string_concat
{
$$ = append_verval ($1, $3, $5);
}
$$.named = 0;
$$.u.id = $1;
}
-
| resname
{
res_unistring_to_id (&$$, $1);
}
;
+/* 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
{
}
;
+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
{
}
| 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
}
| 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