rcparse.y revision 38889
138889Sjdp%{ /* rcparse.y -- parser for Windows rc files 238889Sjdp Copyright 1997 Free Software Foundation, Inc. 338889Sjdp Written by Ian Lance Taylor, Cygnus Support. 438889Sjdp 538889Sjdp This file is part of GNU Binutils. 638889Sjdp 738889Sjdp This program is free software; you can redistribute it and/or modify 838889Sjdp it under the terms of the GNU General Public License as published by 938889Sjdp the Free Software Foundation; either version 2 of the License, or 1038889Sjdp (at your option) any later version. 1138889Sjdp 1238889Sjdp This program is distributed in the hope that it will be useful, 1338889Sjdp but WITHOUT ANY WARRANTY; without even the implied warranty of 1438889Sjdp MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1538889Sjdp GNU General Public License for more details. 1638889Sjdp 1738889Sjdp You should have received a copy of the GNU General Public License 1838889Sjdp along with this program; if not, write to the Free Software 1938889Sjdp Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 2038889Sjdp 02111-1307, USA. */ 2138889Sjdp 2238889Sjdp/* This is a parser for Windows rc files. It is based on the parser 2338889Sjdp by Gunther Ebert <gunther.ebert@ixos-leipzig.de>. */ 2438889Sjdp 2538889Sjdp#include "bfd.h" 2638889Sjdp#include "bucomm.h" 2738889Sjdp#include "libiberty.h" 2838889Sjdp#include "windres.h" 2938889Sjdp 3038889Sjdp#include <ctype.h> 3138889Sjdp 3238889Sjdp/* The current language. */ 3338889Sjdp 3438889Sjdpstatic unsigned short language; 3538889Sjdp 3638889Sjdp/* The resource information during a sub statement. */ 3738889Sjdp 3838889Sjdpstatic struct res_res_info sub_res_info; 3938889Sjdp 4038889Sjdp/* Dialog information. This is built by the nonterminals styles and 4138889Sjdp controls. */ 4238889Sjdp 4338889Sjdpstatic struct dialog dialog; 4438889Sjdp 4538889Sjdp/* This is used when building a style. It is modified by the 4638889Sjdp nonterminal styleexpr. */ 4738889Sjdp 4838889Sjdpstatic unsigned long style; 4938889Sjdp 5038889Sjdp/* These are used when building a control. They are set before using 5138889Sjdp control_params. */ 5238889Sjdp 5338889Sjdpstatic unsigned long base_style; 5438889Sjdpstatic unsigned long default_style; 5538889Sjdpstatic unsigned long class; 5638889Sjdp 5738889Sjdp%} 5838889Sjdp 5938889Sjdp%union 6038889Sjdp{ 6138889Sjdp struct accelerator acc; 6238889Sjdp struct accelerator *pacc; 6338889Sjdp struct dialog_control *dialog_control; 6438889Sjdp struct menuitem *menuitem; 6538889Sjdp struct 6638889Sjdp { 6738889Sjdp struct rcdata_item *first; 6838889Sjdp struct rcdata_item *last; 6938889Sjdp } rcdata; 7038889Sjdp struct rcdata_item *rcdata_item; 7138889Sjdp struct stringtable_data *stringtable; 7238889Sjdp struct fixed_versioninfo *fixver; 7338889Sjdp struct ver_info *verinfo; 7438889Sjdp struct ver_stringinfo *verstring; 7538889Sjdp struct ver_varinfo *vervar; 7638889Sjdp struct res_id id; 7738889Sjdp struct res_res_info res_info; 7838889Sjdp struct 7938889Sjdp { 8038889Sjdp unsigned short on; 8138889Sjdp unsigned short off; 8238889Sjdp } memflags; 8338889Sjdp struct 8438889Sjdp { 8538889Sjdp unsigned long val; 8638889Sjdp /* Nonzero if this number was explicitly specified as long. */ 8738889Sjdp int dword; 8838889Sjdp } i; 8938889Sjdp unsigned long il; 9038889Sjdp unsigned short is; 9138889Sjdp const char *s; 9238889Sjdp struct 9338889Sjdp { 9438889Sjdp unsigned long length; 9538889Sjdp const char *s; 9638889Sjdp } ss; 9738889Sjdp}; 9838889Sjdp 9938889Sjdp%token BEG END 10038889Sjdp%token ACCELERATORS VIRTKEY ASCII NOINVERT SHIFT CONTROL ALT 10138889Sjdp%token BITMAP 10238889Sjdp%token CURSOR 10338889Sjdp%token DIALOG DIALOGEX EXSTYLE CAPTION CLASS STYLE 10438889Sjdp%token AUTO3STATE AUTOCHECKBOX AUTORADIOBUTTON CHECKBOX COMBOBOX CTEXT 10538889Sjdp%token DEFPUSHBUTTON EDITTEXT GROUPBOX LISTBOX LTEXT PUSHBOX PUSHBUTTON 10638889Sjdp%token RADIOBUTTON RTEXT SCROLLBAR STATE3 USERBUTTON 10738889Sjdp%token BEDIT HEDIT IEDIT 10838889Sjdp%token FONT 10938889Sjdp%token ICON 11038889Sjdp%token LANGUAGE CHARACTERISTICS VERSIONK 11138889Sjdp%token MENU MENUEX MENUITEM SEPARATOR POPUP CHECKED GRAYED HELP INACTIVE 11238889Sjdp%token MENUBARBREAK MENUBREAK 11338889Sjdp%token MESSAGETABLE 11438889Sjdp%token RCDATA 11538889Sjdp%token STRINGTABLE 11638889Sjdp%token VERSIONINFO FILEVERSION PRODUCTVERSION FILEFLAGSMASK FILEFLAGS 11738889Sjdp%token FILEOS FILETYPE FILESUBTYPE BLOCKSTRINGFILEINFO BLOCKVARFILEINFO 11838889Sjdp%token VALUE 11938889Sjdp%token <s> BLOCK 12038889Sjdp%token MOVEABLE FIXED PURE IMPURE PRELOAD LOADONCALL DISCARDABLE 12138889Sjdp%token NOT 12238889Sjdp%token <s> QUOTEDSTRING STRING 12338889Sjdp%token <i> NUMBER 12438889Sjdp%token <ss> SIZEDSTRING 12538889Sjdp 12638889Sjdp%type <pacc> acc_entries 12738889Sjdp%type <acc> acc_entry acc_event 12838889Sjdp%type <dialog_control> control control_params 12938889Sjdp%type <menuitem> menuitems menuitem menuexitems menuexitem 13038889Sjdp%type <rcdata> optrcdata_data optrcdata_data_int rcdata_data 13138889Sjdp%type <rcdata_item> opt_control_data 13238889Sjdp%type <fixver> fixedverinfo 13338889Sjdp%type <verinfo> verblocks 13438889Sjdp%type <verstring> vervals 13538889Sjdp%type <vervar> vertrans 13638889Sjdp%type <res_info> suboptions memflags_move_discard memflags_move 13738889Sjdp%type <memflags> memflag 13838889Sjdp%type <id> id 13938889Sjdp%type <il> exstyle parennumber 14038889Sjdp%type <il> numexpr posnumexpr cnumexpr optcnumexpr cposnumexpr 14138889Sjdp%type <is> acc_options acc_option menuitem_flags menuitem_flag 14238889Sjdp%type <s> optstringc file_name 14338889Sjdp%type <i> sizednumexpr sizedposnumexpr 14438889Sjdp 14538889Sjdp%left '|' 14638889Sjdp%left '^' 14738889Sjdp%left '&' 14838889Sjdp%left '+' '-' 14938889Sjdp%left '*' '/' '%' 15038889Sjdp%right '~' NEG 15138889Sjdp 15238889Sjdp%% 15338889Sjdp 15438889Sjdpinput: 15538889Sjdp /* empty */ 15638889Sjdp | input newcmd accelerator 15738889Sjdp | input newcmd bitmap 15838889Sjdp | input newcmd cursor 15938889Sjdp | input newcmd dialog 16038889Sjdp | input newcmd font 16138889Sjdp | input newcmd icon 16238889Sjdp | input newcmd language 16338889Sjdp | input newcmd menu 16438889Sjdp | input newcmd menuex 16538889Sjdp | input newcmd messagetable 16638889Sjdp | input newcmd rcdata 16738889Sjdp | input newcmd stringtable 16838889Sjdp | input newcmd user 16938889Sjdp | input newcmd versioninfo 17038889Sjdp ; 17138889Sjdp 17238889Sjdpnewcmd: 17338889Sjdp /* empty */ 17438889Sjdp { 17538889Sjdp rcparse_discard_strings (); 17638889Sjdp } 17738889Sjdp ; 17838889Sjdp 17938889Sjdp/* Accelerator resources. */ 18038889Sjdp 18138889Sjdpaccelerator: 18238889Sjdp id ACCELERATORS suboptions BEG acc_entries END 18338889Sjdp { 18438889Sjdp define_accelerator ($1, &$3, $5); 18538889Sjdp } 18638889Sjdp ; 18738889Sjdp 18838889Sjdpacc_entries: 18938889Sjdp /* empty */ 19038889Sjdp { 19138889Sjdp $$ = NULL; 19238889Sjdp } 19338889Sjdp | acc_entries acc_entry 19438889Sjdp { 19538889Sjdp struct accelerator *a; 19638889Sjdp 19738889Sjdp a = (struct accelerator *) res_alloc (sizeof *a); 19838889Sjdp *a = $2; 19938889Sjdp if ($1 == NULL) 20038889Sjdp $$ = a; 20138889Sjdp else 20238889Sjdp { 20338889Sjdp struct accelerator **pp; 20438889Sjdp 20538889Sjdp for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next) 20638889Sjdp ; 20738889Sjdp *pp = a; 20838889Sjdp $$ = $1; 20938889Sjdp } 21038889Sjdp } 21138889Sjdp ; 21238889Sjdp 21338889Sjdpacc_entry: 21438889Sjdp acc_event cposnumexpr 21538889Sjdp { 21638889Sjdp $$ = $1; 21738889Sjdp $$.id = $2; 21838889Sjdp } 21938889Sjdp | acc_event cposnumexpr ',' acc_options 22038889Sjdp { 22138889Sjdp $$ = $1; 22238889Sjdp $$.id = $2; 22338889Sjdp $$.flags |= $4; 22438889Sjdp if (($$.flags & ACC_VIRTKEY) == 0 22538889Sjdp && ($$.flags & (ACC_SHIFT | ACC_CONTROL | ACC_ALT)) != 0) 22638889Sjdp rcparse_warning ("inappropriate modifiers for non-VIRTKEY"); 22738889Sjdp } 22838889Sjdp ; 22938889Sjdp 23038889Sjdpacc_event: 23138889Sjdp QUOTEDSTRING 23238889Sjdp { 23338889Sjdp const char *s = $1; 23438889Sjdp char ch; 23538889Sjdp 23638889Sjdp $$.next = NULL; 23738889Sjdp $$.id = 0; 23838889Sjdp ch = *s; 23938889Sjdp if (ch != '^') 24038889Sjdp $$.flags = 0; 24138889Sjdp else 24238889Sjdp { 24338889Sjdp $$.flags = ACC_CONTROL | ACC_VIRTKEY; 24438889Sjdp ++s; 24538889Sjdp ch = *s; 24638889Sjdp ch = toupper ((unsigned char) ch); 24738889Sjdp } 24838889Sjdp $$.key = ch; 24938889Sjdp if (s[1] != '\0') 25038889Sjdp rcparse_warning ("accelerator should only be one character"); 25138889Sjdp } 25238889Sjdp | posnumexpr 25338889Sjdp { 25438889Sjdp $$.next = NULL; 25538889Sjdp $$.flags = 0; 25638889Sjdp $$.id = 0; 25738889Sjdp $$.key = $1; 25838889Sjdp } 25938889Sjdp ; 26038889Sjdp 26138889Sjdpacc_options: 26238889Sjdp acc_option 26338889Sjdp { 26438889Sjdp $$ = $1; 26538889Sjdp } 26638889Sjdp | acc_options ',' acc_option 26738889Sjdp { 26838889Sjdp $$ = $1 | $3; 26938889Sjdp } 27038889Sjdp /* I've had one report that the comma is optional. */ 27138889Sjdp | acc_options acc_option 27238889Sjdp { 27338889Sjdp $$ = $1 | $2; 27438889Sjdp } 27538889Sjdp ; 27638889Sjdp 27738889Sjdpacc_option: 27838889Sjdp VIRTKEY 27938889Sjdp { 28038889Sjdp $$ = ACC_VIRTKEY; 28138889Sjdp } 28238889Sjdp | ASCII 28338889Sjdp { 28438889Sjdp /* This is just the absence of VIRTKEY. */ 28538889Sjdp $$ = 0; 28638889Sjdp } 28738889Sjdp | NOINVERT 28838889Sjdp { 28938889Sjdp $$ = ACC_NOINVERT; 29038889Sjdp } 29138889Sjdp | SHIFT 29238889Sjdp { 29338889Sjdp $$ = ACC_SHIFT; 29438889Sjdp } 29538889Sjdp | CONTROL 29638889Sjdp { 29738889Sjdp $$ = ACC_CONTROL; 29838889Sjdp } 29938889Sjdp | ALT 30038889Sjdp { 30138889Sjdp $$ = ACC_ALT; 30238889Sjdp } 30338889Sjdp ; 30438889Sjdp 30538889Sjdp/* Bitmap resources. */ 30638889Sjdp 30738889Sjdpbitmap: 30838889Sjdp id BITMAP memflags_move file_name 30938889Sjdp { 31038889Sjdp define_bitmap ($1, &$3, $4); 31138889Sjdp } 31238889Sjdp ; 31338889Sjdp 31438889Sjdp/* Cursor resources. */ 31538889Sjdp 31638889Sjdpcursor: 31738889Sjdp id CURSOR memflags_move_discard file_name 31838889Sjdp { 31938889Sjdp define_cursor ($1, &$3, $4); 32038889Sjdp } 32138889Sjdp ; 32238889Sjdp 32338889Sjdp/* Dialog resources. */ 32438889Sjdp 32538889Sjdpdialog: 32638889Sjdp id DIALOG memflags_move exstyle posnumexpr cnumexpr cnumexpr 32738889Sjdp cnumexpr 32838889Sjdp { 32938889Sjdp memset (&dialog, 0, sizeof dialog); 33038889Sjdp dialog.x = $5; 33138889Sjdp dialog.y = $6; 33238889Sjdp dialog.width = $7; 33338889Sjdp dialog.height = $8; 33438889Sjdp dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU; 33538889Sjdp dialog.exstyle = $4; 33638889Sjdp dialog.menu.named = 1; 33738889Sjdp dialog.class.named = 1; 33838889Sjdp dialog.font = NULL; 33938889Sjdp dialog.ex = NULL; 34038889Sjdp dialog.controls = NULL; 34138889Sjdp sub_res_info = $3; 34238889Sjdp } 34338889Sjdp styles BEG controls END 34438889Sjdp { 34538889Sjdp define_dialog ($1, &sub_res_info, &dialog); 34638889Sjdp } 34738889Sjdp | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr 34838889Sjdp cnumexpr 34938889Sjdp { 35038889Sjdp memset (&dialog, 0, sizeof dialog); 35138889Sjdp dialog.x = $5; 35238889Sjdp dialog.y = $6; 35338889Sjdp dialog.width = $7; 35438889Sjdp dialog.height = $8; 35538889Sjdp dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU; 35638889Sjdp dialog.exstyle = $4; 35738889Sjdp dialog.menu.named = 1; 35838889Sjdp dialog.class.named = 1; 35938889Sjdp dialog.font = NULL; 36038889Sjdp dialog.ex = ((struct dialog_ex *) 36138889Sjdp res_alloc (sizeof (struct dialog_ex))); 36238889Sjdp memset (dialog.ex, 0, sizeof (struct dialog_ex)); 36338889Sjdp dialog.controls = NULL; 36438889Sjdp sub_res_info = $3; 36538889Sjdp } 36638889Sjdp styles BEG controls END 36738889Sjdp { 36838889Sjdp define_dialog ($1, &sub_res_info, &dialog); 36938889Sjdp } 37038889Sjdp | id DIALOGEX memflags_move exstyle posnumexpr cnumexpr cnumexpr 37138889Sjdp cnumexpr cnumexpr 37238889Sjdp { 37338889Sjdp memset (&dialog, 0, sizeof dialog); 37438889Sjdp dialog.x = $5; 37538889Sjdp dialog.y = $6; 37638889Sjdp dialog.width = $7; 37738889Sjdp dialog.height = $8; 37838889Sjdp dialog.style = WS_POPUP | WS_BORDER | WS_SYSMENU; 37938889Sjdp dialog.exstyle = $4; 38038889Sjdp dialog.menu.named = 1; 38138889Sjdp dialog.class.named = 1; 38238889Sjdp dialog.font = NULL; 38338889Sjdp dialog.ex = ((struct dialog_ex *) 38438889Sjdp res_alloc (sizeof (struct dialog_ex))); 38538889Sjdp memset (dialog.ex, 0, sizeof (struct dialog_ex)); 38638889Sjdp dialog.ex->help = $9; 38738889Sjdp dialog.controls = NULL; 38838889Sjdp sub_res_info = $3; 38938889Sjdp } 39038889Sjdp styles BEG controls END 39138889Sjdp { 39238889Sjdp define_dialog ($1, &sub_res_info, &dialog); 39338889Sjdp } 39438889Sjdp ; 39538889Sjdp 39638889Sjdpexstyle: 39738889Sjdp /* empty */ 39838889Sjdp { 39938889Sjdp $$ = 0; 40038889Sjdp } 40138889Sjdp | EXSTYLE '=' numexpr 40238889Sjdp { 40338889Sjdp $$ = $3; 40438889Sjdp } 40538889Sjdp ; 40638889Sjdp 40738889Sjdpstyles: 40838889Sjdp /* empty */ 40938889Sjdp | styles CAPTION QUOTEDSTRING 41038889Sjdp { 41138889Sjdp unicode_from_ascii ((int *) NULL, &dialog.caption, $3); 41238889Sjdp } 41338889Sjdp | styles CLASS id 41438889Sjdp { 41538889Sjdp dialog.class = $3; 41638889Sjdp } 41738889Sjdp | styles STYLE 41838889Sjdp { style = dialog.style; } 41938889Sjdp styleexpr 42038889Sjdp { 42138889Sjdp dialog.style = style; 42238889Sjdp } 42338889Sjdp | styles EXSTYLE numexpr 42438889Sjdp { 42538889Sjdp dialog.exstyle = $3; 42638889Sjdp } 42738889Sjdp | styles FONT numexpr ',' QUOTEDSTRING 42838889Sjdp { 42938889Sjdp dialog.style |= DS_SETFONT; 43038889Sjdp dialog.pointsize = $3; 43138889Sjdp unicode_from_ascii ((int *) NULL, &dialog.font, $5); 43238889Sjdp } 43338889Sjdp | styles FONT numexpr ',' QUOTEDSTRING cnumexpr cnumexpr 43438889Sjdp { 43538889Sjdp dialog.style |= DS_SETFONT; 43638889Sjdp dialog.pointsize = $3; 43738889Sjdp unicode_from_ascii ((int *) NULL, &dialog.font, $5); 43838889Sjdp if (dialog.ex == NULL) 43938889Sjdp rcparse_warning ("extended FONT requires DIALOGEX"); 44038889Sjdp else 44138889Sjdp { 44238889Sjdp dialog.ex->weight = $6; 44338889Sjdp dialog.ex->italic = $7; 44438889Sjdp } 44538889Sjdp } 44638889Sjdp | styles MENU id 44738889Sjdp { 44838889Sjdp dialog.menu = $3; 44938889Sjdp } 45038889Sjdp | styles CHARACTERISTICS numexpr 45138889Sjdp { 45238889Sjdp sub_res_info.characteristics = $3; 45338889Sjdp } 45438889Sjdp | styles LANGUAGE numexpr cnumexpr 45538889Sjdp { 45638889Sjdp sub_res_info.language = $3 | ($4 << 8); 45738889Sjdp } 45838889Sjdp | styles VERSIONK numexpr 45938889Sjdp { 46038889Sjdp sub_res_info.version = $3; 46138889Sjdp } 46238889Sjdp ; 46338889Sjdp 46438889Sjdpcontrols: 46538889Sjdp /* empty */ 46638889Sjdp | controls control 46738889Sjdp { 46838889Sjdp struct dialog_control **pp; 46938889Sjdp 47038889Sjdp for (pp = &dialog.controls; *pp != NULL; pp = &(*pp)->next) 47138889Sjdp ; 47238889Sjdp *pp = $2; 47338889Sjdp } 47438889Sjdp ; 47538889Sjdp 47638889Sjdpcontrol: 47738889Sjdp AUTO3STATE 47838889Sjdp { 47938889Sjdp default_style = BS_AUTO3STATE | WS_TABSTOP; 48038889Sjdp base_style = BS_AUTO3STATE; 48138889Sjdp class = CTL_BUTTON; 48238889Sjdp } 48338889Sjdp control_params 48438889Sjdp { 48538889Sjdp $$ = $3; 48638889Sjdp } 48738889Sjdp | AUTOCHECKBOX 48838889Sjdp { 48938889Sjdp default_style = BS_AUTOCHECKBOX | WS_TABSTOP; 49038889Sjdp base_style = BS_AUTOCHECKBOX; 49138889Sjdp class = CTL_BUTTON; 49238889Sjdp } 49338889Sjdp control_params 49438889Sjdp { 49538889Sjdp $$ = $3; 49638889Sjdp } 49738889Sjdp | AUTORADIOBUTTON 49838889Sjdp { 49938889Sjdp default_style = BS_AUTORADIOBUTTON | WS_TABSTOP; 50038889Sjdp base_style = BS_AUTORADIOBUTTON; 50138889Sjdp class = CTL_BUTTON; 50238889Sjdp } 50338889Sjdp control_params 50438889Sjdp { 50538889Sjdp $$ = $3; 50638889Sjdp } 50738889Sjdp | BEDIT 50838889Sjdp { 50938889Sjdp default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 51038889Sjdp base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 51138889Sjdp class = CTL_EDIT; 51238889Sjdp } 51338889Sjdp control_params 51438889Sjdp { 51538889Sjdp $$ = $3; 51638889Sjdp if (dialog.ex == NULL) 51738889Sjdp rcparse_warning ("IEDIT requires DIALOGEX"); 51838889Sjdp res_string_to_id (&$$->class, "BEDIT"); 51938889Sjdp } 52038889Sjdp | CHECKBOX 52138889Sjdp { 52238889Sjdp default_style = BS_CHECKBOX | WS_TABSTOP; 52338889Sjdp base_style = BS_CHECKBOX | WS_TABSTOP; 52438889Sjdp class = CTL_BUTTON; 52538889Sjdp } 52638889Sjdp control_params 52738889Sjdp { 52838889Sjdp $$ = $3; 52938889Sjdp } 53038889Sjdp | COMBOBOX 53138889Sjdp { 53238889Sjdp default_style = CBS_SIMPLE | WS_TABSTOP; 53338889Sjdp base_style = 0; 53438889Sjdp class = CTL_COMBOBOX; 53538889Sjdp } 53638889Sjdp control_params 53738889Sjdp { 53838889Sjdp $$ = $3; 53938889Sjdp } 54038889Sjdp | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr 54138889Sjdp cnumexpr cnumexpr cnumexpr optcnumexpr opt_control_data 54238889Sjdp { 54338889Sjdp $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10); 54438889Sjdp if ($11 != NULL) 54538889Sjdp { 54638889Sjdp if (dialog.ex == NULL) 54738889Sjdp rcparse_warning ("control data requires DIALOGEX"); 54838889Sjdp $$->data = $11; 54938889Sjdp } 55038889Sjdp } 55138889Sjdp | CONTROL optstringc numexpr cnumexpr control_styleexpr cnumexpr 55238889Sjdp cnumexpr cnumexpr cnumexpr cnumexpr cnumexpr opt_control_data 55338889Sjdp { 55438889Sjdp $$ = define_control ($2, $3, $6, $7, $8, $9, $4, style, $10); 55538889Sjdp if (dialog.ex == NULL) 55638889Sjdp rcparse_warning ("help ID requires DIALOGEX"); 55738889Sjdp $$->help = $11; 55838889Sjdp $$->data = $12; 55938889Sjdp } 56038889Sjdp | CTEXT 56138889Sjdp { 56238889Sjdp default_style = SS_CENTER | WS_GROUP; 56338889Sjdp base_style = SS_CENTER; 56438889Sjdp class = CTL_STATIC; 56538889Sjdp } 56638889Sjdp control_params 56738889Sjdp { 56838889Sjdp $$ = $3; 56938889Sjdp } 57038889Sjdp | DEFPUSHBUTTON 57138889Sjdp { 57238889Sjdp default_style = BS_DEFPUSHBUTTON | WS_TABSTOP; 57338889Sjdp base_style = BS_DEFPUSHBUTTON | WS_TABSTOP; 57438889Sjdp class = CTL_BUTTON; 57538889Sjdp } 57638889Sjdp control_params 57738889Sjdp { 57838889Sjdp $$ = $3; 57938889Sjdp } 58038889Sjdp | EDITTEXT 58138889Sjdp { 58238889Sjdp default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 58338889Sjdp base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 58438889Sjdp class = CTL_EDIT; 58538889Sjdp } 58638889Sjdp control_params 58738889Sjdp { 58838889Sjdp $$ = $3; 58938889Sjdp } 59038889Sjdp | GROUPBOX 59138889Sjdp { 59238889Sjdp default_style = BS_GROUPBOX; 59338889Sjdp base_style = BS_GROUPBOX; 59438889Sjdp class = CTL_BUTTON; 59538889Sjdp } 59638889Sjdp control_params 59738889Sjdp { 59838889Sjdp $$ = $3; 59938889Sjdp } 60038889Sjdp | HEDIT 60138889Sjdp { 60238889Sjdp default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 60338889Sjdp base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 60438889Sjdp class = CTL_EDIT; 60538889Sjdp } 60638889Sjdp control_params 60738889Sjdp { 60838889Sjdp $$ = $3; 60938889Sjdp if (dialog.ex == NULL) 61038889Sjdp rcparse_warning ("IEDIT requires DIALOGEX"); 61138889Sjdp res_string_to_id (&$$->class, "HEDIT"); 61238889Sjdp } 61338889Sjdp | ICON optstringc numexpr cnumexpr cnumexpr opt_control_data 61438889Sjdp { 61538889Sjdp $$ = define_control ($2, $3, $4, $5, 0, 0, CTL_STATIC, 61638889Sjdp SS_ICON | WS_CHILD | WS_VISIBLE, 0); 61738889Sjdp if ($6 != NULL) 61838889Sjdp { 61938889Sjdp if (dialog.ex == NULL) 62038889Sjdp rcparse_warning ("control data requires DIALOGEX"); 62138889Sjdp $$->data = $6; 62238889Sjdp } 62338889Sjdp } 62438889Sjdp | ICON optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr 62538889Sjdp icon_styleexpr optcnumexpr opt_control_data 62638889Sjdp { 62738889Sjdp $$ = define_control ($2, $3, $4, $5, $6, $7, CTL_STATIC, 62838889Sjdp style, $9); 62938889Sjdp if ($10 != NULL) 63038889Sjdp { 63138889Sjdp if (dialog.ex == NULL) 63238889Sjdp rcparse_warning ("control data requires DIALOGEX"); 63338889Sjdp $$->data = $10; 63438889Sjdp } 63538889Sjdp } 63638889Sjdp | ICON optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr 63738889Sjdp icon_styleexpr cnumexpr cnumexpr opt_control_data 63838889Sjdp { 63938889Sjdp $$ = define_control ($2, $3, $4, $5, $6, $7, CTL_STATIC, 64038889Sjdp style, $9); 64138889Sjdp if (dialog.ex == NULL) 64238889Sjdp rcparse_warning ("help ID requires DIALOGEX"); 64338889Sjdp $$->help = $10; 64438889Sjdp $$->data = $11; 64538889Sjdp } 64638889Sjdp | IEDIT 64738889Sjdp { 64838889Sjdp default_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 64938889Sjdp base_style = ES_LEFT | WS_BORDER | WS_TABSTOP; 65038889Sjdp class = CTL_EDIT; 65138889Sjdp } 65238889Sjdp control_params 65338889Sjdp { 65438889Sjdp $$ = $3; 65538889Sjdp if (dialog.ex == NULL) 65638889Sjdp rcparse_warning ("IEDIT requires DIALOGEX"); 65738889Sjdp res_string_to_id (&$$->class, "IEDIT"); 65838889Sjdp } 65938889Sjdp | LISTBOX 66038889Sjdp { 66138889Sjdp default_style = LBS_NOTIFY | WS_BORDER; 66238889Sjdp base_style = LBS_NOTIFY | WS_BORDER; 66338889Sjdp class = CTL_LISTBOX; 66438889Sjdp } 66538889Sjdp control_params 66638889Sjdp { 66738889Sjdp $$ = $3; 66838889Sjdp } 66938889Sjdp | LTEXT 67038889Sjdp { 67138889Sjdp default_style = SS_LEFT | WS_GROUP; 67238889Sjdp base_style = SS_LEFT; 67338889Sjdp class = CTL_STATIC; 67438889Sjdp } 67538889Sjdp control_params 67638889Sjdp { 67738889Sjdp $$ = $3; 67838889Sjdp } 67938889Sjdp | PUSHBOX 68038889Sjdp { 68138889Sjdp default_style = BS_PUSHBOX | WS_TABSTOP; 68238889Sjdp base_style = BS_PUSHBOX; 68338889Sjdp class = CTL_BUTTON; 68438889Sjdp } 68538889Sjdp control_params 68638889Sjdp { 68738889Sjdp $$ = $3; 68838889Sjdp } 68938889Sjdp | PUSHBUTTON 69038889Sjdp { 69138889Sjdp default_style = BS_PUSHBUTTON | WS_TABSTOP; 69238889Sjdp base_style = BS_PUSHBUTTON | WS_TABSTOP; 69338889Sjdp class = CTL_BUTTON; 69438889Sjdp } 69538889Sjdp control_params 69638889Sjdp { 69738889Sjdp $$ = $3; 69838889Sjdp } 69938889Sjdp | RADIOBUTTON 70038889Sjdp { 70138889Sjdp default_style = BS_RADIOBUTTON | WS_TABSTOP; 70238889Sjdp base_style = BS_RADIOBUTTON; 70338889Sjdp class = CTL_BUTTON; 70438889Sjdp } 70538889Sjdp control_params 70638889Sjdp { 70738889Sjdp $$ = $3; 70838889Sjdp } 70938889Sjdp | RTEXT 71038889Sjdp { 71138889Sjdp default_style = SS_RIGHT | WS_GROUP; 71238889Sjdp base_style = SS_RIGHT; 71338889Sjdp class = CTL_STATIC; 71438889Sjdp } 71538889Sjdp control_params 71638889Sjdp { 71738889Sjdp $$ = $3; 71838889Sjdp } 71938889Sjdp | SCROLLBAR 72038889Sjdp { 72138889Sjdp default_style = SBS_HORZ; 72238889Sjdp base_style = 0; 72338889Sjdp class = CTL_SCROLLBAR; 72438889Sjdp } 72538889Sjdp control_params 72638889Sjdp { 72738889Sjdp $$ = $3; 72838889Sjdp } 72938889Sjdp | STATE3 73038889Sjdp { 73138889Sjdp default_style = BS_3STATE | WS_TABSTOP; 73238889Sjdp base_style = BS_3STATE; 73338889Sjdp class = CTL_BUTTON; 73438889Sjdp } 73538889Sjdp control_params 73638889Sjdp { 73738889Sjdp $$ = $3; 73838889Sjdp } 73938889Sjdp | USERBUTTON QUOTEDSTRING ',' numexpr ',' numexpr ',' numexpr ',' 74038889Sjdp numexpr ',' numexpr ',' 74138889Sjdp { style = WS_CHILD | WS_VISIBLE; } 74238889Sjdp styleexpr optcnumexpr 74338889Sjdp { 74438889Sjdp $$ = define_control ($2, $4, $6, $8, $10, $12, CTL_BUTTON, 74538889Sjdp style, $16); 74638889Sjdp } 74738889Sjdp ; 74838889Sjdp 74938889Sjdp/* Parameters for a control. The static variables DEFAULT_STYLE, 75038889Sjdp BASE_STYLE, and CLASS must be initialized before this nonterminal 75138889Sjdp is used. DEFAULT_STYLE is the style to use if no style expression 75238889Sjdp is specified. BASE_STYLE is the base style to use if a style 75338889Sjdp expression is specified; the style expression modifies the base 75438889Sjdp style. CLASS is the class of the control. */ 75538889Sjdp 75638889Sjdpcontrol_params: 75738889Sjdp optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr 75838889Sjdp opt_control_data 75938889Sjdp { 76038889Sjdp $$ = define_control ($1, $2, $3, $4, $5, $6, class, 76138889Sjdp default_style | WS_CHILD | WS_VISIBLE, 0); 76238889Sjdp if ($7 != NULL) 76338889Sjdp { 76438889Sjdp if (dialog.ex == NULL) 76538889Sjdp rcparse_warning ("control data requires DIALOGEX"); 76638889Sjdp $$->data = $7; 76738889Sjdp } 76838889Sjdp } 76938889Sjdp | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr 77038889Sjdp control_params_styleexpr optcnumexpr opt_control_data 77138889Sjdp { 77238889Sjdp $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8); 77338889Sjdp if ($9 != NULL) 77438889Sjdp { 77538889Sjdp if (dialog.ex == NULL) 77638889Sjdp rcparse_warning ("control data requires DIALOGEX"); 77738889Sjdp $$->data = $9; 77838889Sjdp } 77938889Sjdp } 78038889Sjdp | optstringc numexpr cnumexpr cnumexpr cnumexpr cnumexpr 78138889Sjdp control_params_styleexpr cnumexpr cnumexpr opt_control_data 78238889Sjdp { 78338889Sjdp $$ = define_control ($1, $2, $3, $4, $5, $6, class, style, $8); 78438889Sjdp if (dialog.ex == NULL) 78538889Sjdp rcparse_warning ("help ID requires DIALOGEX"); 78638889Sjdp $$->help = $9; 78738889Sjdp $$->data = $10; 78838889Sjdp } 78938889Sjdp ; 79038889Sjdp 79138889Sjdpoptstringc: 79238889Sjdp /* empty */ 79338889Sjdp { 79438889Sjdp $$ = NULL; 79538889Sjdp } 79638889Sjdp | QUOTEDSTRING ',' 79738889Sjdp { 79838889Sjdp $$ = $1; 79938889Sjdp } 80038889Sjdp ; 80138889Sjdp 80238889Sjdpopt_control_data: 80338889Sjdp /* empty */ 80438889Sjdp { 80538889Sjdp $$ = NULL; 80638889Sjdp } 80738889Sjdp | BEG optrcdata_data END 80838889Sjdp { 80938889Sjdp $$ = $2.first; 81038889Sjdp } 81138889Sjdp ; 81238889Sjdp 81338889Sjdp/* These only exist to parse a reduction out of a common case. */ 81438889Sjdp 81538889Sjdpcontrol_styleexpr: 81638889Sjdp ',' 81738889Sjdp { style = WS_CHILD | WS_VISIBLE; } 81838889Sjdp styleexpr 81938889Sjdp ; 82038889Sjdp 82138889Sjdpicon_styleexpr: 82238889Sjdp ',' 82338889Sjdp { style = SS_ICON | WS_CHILD | WS_VISIBLE; } 82438889Sjdp styleexpr 82538889Sjdp ; 82638889Sjdp 82738889Sjdpcontrol_params_styleexpr: 82838889Sjdp ',' 82938889Sjdp { style = base_style | WS_CHILD | WS_VISIBLE; } 83038889Sjdp styleexpr 83138889Sjdp ; 83238889Sjdp 83338889Sjdp/* Font resources. */ 83438889Sjdp 83538889Sjdpfont: 83638889Sjdp id FONT memflags_move_discard file_name 83738889Sjdp { 83838889Sjdp define_font ($1, &$3, $4); 83938889Sjdp } 84038889Sjdp ; 84138889Sjdp 84238889Sjdp/* Icon resources. */ 84338889Sjdp 84438889Sjdpicon: 84538889Sjdp id ICON memflags_move_discard file_name 84638889Sjdp { 84738889Sjdp define_icon ($1, &$3, $4); 84838889Sjdp } 84938889Sjdp ; 85038889Sjdp 85138889Sjdp/* Language command. This changes the static variable language, which 85238889Sjdp affects all subsequent resources. */ 85338889Sjdp 85438889Sjdplanguage: 85538889Sjdp LANGUAGE numexpr cnumexpr 85638889Sjdp { 85738889Sjdp language = $2 | ($3 << 8); 85838889Sjdp } 85938889Sjdp ; 86038889Sjdp 86138889Sjdp/* Menu resources. */ 86238889Sjdp 86338889Sjdpmenu: 86438889Sjdp id MENU suboptions BEG menuitems END 86538889Sjdp { 86638889Sjdp define_menu ($1, &$3, $5); 86738889Sjdp } 86838889Sjdp ; 86938889Sjdp 87038889Sjdpmenuitems: 87138889Sjdp /* empty */ 87238889Sjdp { 87338889Sjdp $$ = NULL; 87438889Sjdp } 87538889Sjdp | menuitems menuitem 87638889Sjdp { 87738889Sjdp if ($1 == NULL) 87838889Sjdp $$ = $2; 87938889Sjdp else 88038889Sjdp { 88138889Sjdp struct menuitem **pp; 88238889Sjdp 88338889Sjdp for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next) 88438889Sjdp ; 88538889Sjdp *pp = $2; 88638889Sjdp $$ = $1; 88738889Sjdp } 88838889Sjdp } 88938889Sjdp ; 89038889Sjdp 89138889Sjdpmenuitem: 89238889Sjdp MENUITEM QUOTEDSTRING cnumexpr menuitem_flags 89338889Sjdp { 89438889Sjdp $$ = define_menuitem ($2, $3, $4, 0, 0, NULL); 89538889Sjdp } 89638889Sjdp | MENUITEM SEPARATOR 89738889Sjdp { 89838889Sjdp $$ = define_menuitem (NULL, 0, 0, 0, 0, NULL); 89938889Sjdp } 90038889Sjdp | POPUP QUOTEDSTRING menuitem_flags BEG menuitems END 90138889Sjdp { 90238889Sjdp $$ = define_menuitem ($2, 0, $3, 0, 0, $5); 90338889Sjdp } 90438889Sjdp ; 90538889Sjdp 90638889Sjdpmenuitem_flags: 90738889Sjdp /* empty */ 90838889Sjdp { 90938889Sjdp $$ = 0; 91038889Sjdp } 91138889Sjdp | menuitem_flags ',' menuitem_flag 91238889Sjdp { 91338889Sjdp $$ = $1 | $3; 91438889Sjdp } 91538889Sjdp | menuitem_flags menuitem_flag 91638889Sjdp { 91738889Sjdp $$ = $1 | $2; 91838889Sjdp } 91938889Sjdp ; 92038889Sjdp 92138889Sjdpmenuitem_flag: 92238889Sjdp CHECKED 92338889Sjdp { 92438889Sjdp $$ = MENUITEM_CHECKED; 92538889Sjdp } 92638889Sjdp | GRAYED 92738889Sjdp { 92838889Sjdp $$ = MENUITEM_GRAYED; 92938889Sjdp } 93038889Sjdp | HELP 93138889Sjdp { 93238889Sjdp $$ = MENUITEM_HELP; 93338889Sjdp } 93438889Sjdp | INACTIVE 93538889Sjdp { 93638889Sjdp $$ = MENUITEM_INACTIVE; 93738889Sjdp } 93838889Sjdp | MENUBARBREAK 93938889Sjdp { 94038889Sjdp $$ = MENUITEM_MENUBARBREAK; 94138889Sjdp } 94238889Sjdp | MENUBREAK 94338889Sjdp { 94438889Sjdp $$ = MENUITEM_MENUBREAK; 94538889Sjdp } 94638889Sjdp ; 94738889Sjdp 94838889Sjdp/* Menuex resources. */ 94938889Sjdp 95038889Sjdpmenuex: 95138889Sjdp id MENUEX suboptions BEG menuexitems END 95238889Sjdp { 95338889Sjdp define_menu ($1, &$3, $5); 95438889Sjdp } 95538889Sjdp ; 95638889Sjdp 95738889Sjdpmenuexitems: 95838889Sjdp /* empty */ 95938889Sjdp { 96038889Sjdp $$ = NULL; 96138889Sjdp } 96238889Sjdp | menuexitems menuexitem 96338889Sjdp { 96438889Sjdp if ($1 == NULL) 96538889Sjdp $$ = $2; 96638889Sjdp else 96738889Sjdp { 96838889Sjdp struct menuitem **pp; 96938889Sjdp 97038889Sjdp for (pp = &$1->next; *pp != NULL; pp = &(*pp)->next) 97138889Sjdp ; 97238889Sjdp *pp = $2; 97338889Sjdp $$ = $1; 97438889Sjdp } 97538889Sjdp } 97638889Sjdp ; 97738889Sjdp 97838889Sjdpmenuexitem: 97938889Sjdp MENUITEM QUOTEDSTRING 98038889Sjdp { 98138889Sjdp $$ = define_menuitem ($2, 0, 0, 0, 0, NULL); 98238889Sjdp } 98338889Sjdp | MENUITEM QUOTEDSTRING cnumexpr 98438889Sjdp { 98538889Sjdp $$ = define_menuitem ($2, $3, 0, 0, 0, NULL); 98638889Sjdp } 98738889Sjdp | MENUITEM QUOTEDSTRING cnumexpr cnumexpr optcnumexpr 98838889Sjdp { 98938889Sjdp $$ = define_menuitem ($2, $3, $4, $5, 0, NULL); 99038889Sjdp } 99138889Sjdp | POPUP QUOTEDSTRING BEG menuexitems END 99238889Sjdp { 99338889Sjdp $$ = define_menuitem ($2, 0, 0, 0, 0, $4); 99438889Sjdp } 99538889Sjdp | POPUP QUOTEDSTRING cnumexpr BEG menuexitems END 99638889Sjdp { 99738889Sjdp $$ = define_menuitem ($2, $3, 0, 0, 0, $5); 99838889Sjdp } 99938889Sjdp | POPUP QUOTEDSTRING cnumexpr cnumexpr BEG menuexitems END 100038889Sjdp { 100138889Sjdp $$ = define_menuitem ($2, $3, $4, 0, 0, $6); 100238889Sjdp } 100338889Sjdp | POPUP QUOTEDSTRING cnumexpr cnumexpr cnumexpr optcnumexpr 100438889Sjdp BEG menuexitems END 100538889Sjdp { 100638889Sjdp $$ = define_menuitem ($2, $3, $4, $5, $6, $8); 100738889Sjdp } 100838889Sjdp ; 100938889Sjdp 101038889Sjdp/* Messagetable resources. */ 101138889Sjdp 101238889Sjdpmessagetable: 101338889Sjdp id MESSAGETABLE memflags_move file_name 101438889Sjdp { 101538889Sjdp define_messagetable ($1, &$3, $4); 101638889Sjdp } 101738889Sjdp ; 101838889Sjdp 101938889Sjdp/* Rcdata resources. */ 102038889Sjdp 102138889Sjdprcdata: 102238889Sjdp id RCDATA suboptions BEG optrcdata_data END 102338889Sjdp { 102438889Sjdp define_rcdata ($1, &$3, $5.first); 102538889Sjdp } 102638889Sjdp ; 102738889Sjdp 102838889Sjdp/* We use a different lexing algorithm, because rcdata strings may 102938889Sjdp contain embedded null bytes, and we need to know the length to use. */ 103038889Sjdp 103138889Sjdpoptrcdata_data: 103238889Sjdp { 103338889Sjdp rcparse_rcdata (); 103438889Sjdp } 103538889Sjdp optrcdata_data_int 103638889Sjdp { 103738889Sjdp rcparse_normal (); 103838889Sjdp $$ = $2; 103938889Sjdp } 104038889Sjdp ; 104138889Sjdp 104238889Sjdpoptrcdata_data_int: 104338889Sjdp /* empty */ 104438889Sjdp { 104538889Sjdp $$.first = NULL; 104638889Sjdp $$.last = NULL; 104738889Sjdp } 104838889Sjdp | rcdata_data 104938889Sjdp { 105038889Sjdp $$ = $1; 105138889Sjdp } 105238889Sjdp ; 105338889Sjdp 105438889Sjdprcdata_data: 105538889Sjdp SIZEDSTRING 105638889Sjdp { 105738889Sjdp struct rcdata_item *ri; 105838889Sjdp 105938889Sjdp ri = define_rcdata_string ($1.s, $1.length); 106038889Sjdp $$.first = ri; 106138889Sjdp $$.last = ri; 106238889Sjdp } 106338889Sjdp | sizednumexpr 106438889Sjdp { 106538889Sjdp struct rcdata_item *ri; 106638889Sjdp 106738889Sjdp ri = define_rcdata_number ($1.val, $1.dword); 106838889Sjdp $$.first = ri; 106938889Sjdp $$.last = ri; 107038889Sjdp } 107138889Sjdp | rcdata_data ',' SIZEDSTRING 107238889Sjdp { 107338889Sjdp struct rcdata_item *ri; 107438889Sjdp 107538889Sjdp ri = define_rcdata_string ($3.s, $3.length); 107638889Sjdp $$.first = $1.first; 107738889Sjdp $1.last->next = ri; 107838889Sjdp $$.last = ri; 107938889Sjdp } 108038889Sjdp | rcdata_data ',' sizednumexpr 108138889Sjdp { 108238889Sjdp struct rcdata_item *ri; 108338889Sjdp 108438889Sjdp ri = define_rcdata_number ($3.val, $3.dword); 108538889Sjdp $$.first = $1.first; 108638889Sjdp $1.last->next = ri; 108738889Sjdp $$.last = ri; 108838889Sjdp } 108938889Sjdp ; 109038889Sjdp 109138889Sjdp/* Stringtable resources. */ 109238889Sjdp 109338889Sjdpstringtable: 109438889Sjdp STRINGTABLE suboptions BEG 109538889Sjdp { sub_res_info = $2; } 109638889Sjdp string_data END 109738889Sjdp ; 109838889Sjdp 109938889Sjdpstring_data: 110038889Sjdp /* empty */ 110138889Sjdp | string_data numexpr QUOTEDSTRING 110238889Sjdp { 110338889Sjdp define_stringtable (&sub_res_info, $2, $3); 110438889Sjdp } 110538889Sjdp | string_data numexpr ',' QUOTEDSTRING 110638889Sjdp { 110738889Sjdp define_stringtable (&sub_res_info, $2, $4); 110838889Sjdp } 110938889Sjdp ; 111038889Sjdp 111138889Sjdp/* User defined resources. We accept general suboptions in the 111238889Sjdp file_name case to keep the parser happy. */ 111338889Sjdp 111438889Sjdpuser: 111538889Sjdp id id suboptions BEG optrcdata_data END 111638889Sjdp { 111738889Sjdp define_user_data ($1, $2, &$3, $5.first); 111838889Sjdp } 111938889Sjdp | id id suboptions file_name 112038889Sjdp { 112138889Sjdp define_user_file ($1, $2, &$3, $4); 112238889Sjdp } 112338889Sjdp ; 112438889Sjdp 112538889Sjdp/* Versioninfo resources. */ 112638889Sjdp 112738889Sjdpversioninfo: 112838889Sjdp id VERSIONINFO fixedverinfo BEG verblocks END 112938889Sjdp { 113038889Sjdp define_versioninfo ($1, language, $3, $5); 113138889Sjdp } 113238889Sjdp ; 113338889Sjdp 113438889Sjdpfixedverinfo: 113538889Sjdp /* empty */ 113638889Sjdp { 113738889Sjdp $$ = ((struct fixed_versioninfo *) 113838889Sjdp res_alloc (sizeof (struct fixed_versioninfo))); 113938889Sjdp memset ($$, 0, sizeof (struct fixed_versioninfo)); 114038889Sjdp } 114138889Sjdp | fixedverinfo FILEVERSION numexpr cnumexpr cnumexpr cnumexpr 114238889Sjdp { 114338889Sjdp $1->file_version_ms = ($3 << 16) | $4; 114438889Sjdp $1->file_version_ls = ($5 << 16) | $6; 114538889Sjdp $$ = $1; 114638889Sjdp } 114738889Sjdp | fixedverinfo PRODUCTVERSION numexpr cnumexpr cnumexpr cnumexpr 114838889Sjdp { 114938889Sjdp $1->product_version_ms = ($3 << 16) | $4; 115038889Sjdp $1->product_version_ls = ($5 << 16) | $6; 115138889Sjdp $$ = $1; 115238889Sjdp } 115338889Sjdp | fixedverinfo FILEFLAGSMASK numexpr 115438889Sjdp { 115538889Sjdp $1->file_flags_mask = $3; 115638889Sjdp $$ = $1; 115738889Sjdp } 115838889Sjdp | fixedverinfo FILEFLAGS numexpr 115938889Sjdp { 116038889Sjdp $1->file_flags = $3; 116138889Sjdp $$ = $1; 116238889Sjdp } 116338889Sjdp | fixedverinfo FILEOS numexpr 116438889Sjdp { 116538889Sjdp $1->file_os = $3; 116638889Sjdp $$ = $1; 116738889Sjdp } 116838889Sjdp | fixedverinfo FILETYPE numexpr 116938889Sjdp { 117038889Sjdp $1->file_type = $3; 117138889Sjdp $$ = $1; 117238889Sjdp } 117338889Sjdp | fixedverinfo FILESUBTYPE numexpr 117438889Sjdp { 117538889Sjdp $1->file_subtype = $3; 117638889Sjdp $$ = $1; 117738889Sjdp } 117838889Sjdp ; 117938889Sjdp 118038889Sjdp/* To handle verblocks successfully, the lexer handles BLOCK 118138889Sjdp specially. A BLOCK "StringFileInfo" is returned as 118238889Sjdp BLOCKSTRINGFILEINFO. A BLOCK "VarFileInfo" is returned as 118338889Sjdp BLOCKVARFILEINFO. A BLOCK with some other string returns BLOCK 118438889Sjdp with the string as the value. */ 118538889Sjdp 118638889Sjdpverblocks: 118738889Sjdp /* empty */ 118838889Sjdp { 118938889Sjdp $$ = NULL; 119038889Sjdp } 119138889Sjdp | verblocks BLOCKSTRINGFILEINFO BEG BLOCK BEG vervals END END 119238889Sjdp { 119338889Sjdp $$ = append_ver_stringfileinfo ($1, $4, $6); 119438889Sjdp } 119538889Sjdp | verblocks BLOCKVARFILEINFO BEG VALUE QUOTEDSTRING vertrans END 119638889Sjdp { 119738889Sjdp $$ = append_ver_varfileinfo ($1, $5, $6); 119838889Sjdp } 119938889Sjdp ; 120038889Sjdp 120138889Sjdpvervals: 120238889Sjdp /* empty */ 120338889Sjdp { 120438889Sjdp $$ = NULL; 120538889Sjdp } 120638889Sjdp | vervals VALUE QUOTEDSTRING ',' QUOTEDSTRING 120738889Sjdp { 120838889Sjdp $$ = append_verval ($1, $3, $5); 120938889Sjdp } 121038889Sjdp ; 121138889Sjdp 121238889Sjdpvertrans: 121338889Sjdp /* empty */ 121438889Sjdp { 121538889Sjdp $$ = NULL; 121638889Sjdp } 121738889Sjdp | vertrans cnumexpr cnumexpr 121838889Sjdp { 121938889Sjdp $$ = append_vertrans ($1, $2, $3); 122038889Sjdp } 122138889Sjdp ; 122238889Sjdp 122338889Sjdp/* A resource ID. */ 122438889Sjdp 122538889Sjdpid: 122638889Sjdp posnumexpr 122738889Sjdp { 122838889Sjdp $$.named = 0; 122938889Sjdp $$.u.id = $1; 123038889Sjdp } 123138889Sjdp | STRING 123238889Sjdp { 123338889Sjdp char *copy, *s; 123438889Sjdp 123538889Sjdp /* It seems that resource ID's are forced to upper case. */ 123638889Sjdp copy = xstrdup ($1); 123738889Sjdp for (s = copy; *s != '\0'; s++) 123838889Sjdp if (islower (*s)) 123938889Sjdp *s = toupper (*s); 124038889Sjdp res_string_to_id (&$$, copy); 124138889Sjdp free (copy); 124238889Sjdp } 124338889Sjdp ; 124438889Sjdp 124538889Sjdp/* Generic suboptions. These may appear before the BEGIN in any 124638889Sjdp multiline statement. */ 124738889Sjdp 124838889Sjdpsuboptions: 124938889Sjdp /* empty */ 125038889Sjdp { 125138889Sjdp memset (&$$, 0, sizeof (struct res_res_info)); 125238889Sjdp $$.language = language; 125338889Sjdp /* FIXME: Is this the right default? */ 125438889Sjdp $$.memflags = MEMFLAG_MOVEABLE; 125538889Sjdp } 125638889Sjdp | suboptions memflag 125738889Sjdp { 125838889Sjdp $$ = $1; 125938889Sjdp $$.memflags |= $2.on; 126038889Sjdp $$.memflags &=~ $2.off; 126138889Sjdp } 126238889Sjdp | suboptions CHARACTERISTICS numexpr 126338889Sjdp { 126438889Sjdp $$ = $1; 126538889Sjdp $$.characteristics = $3; 126638889Sjdp } 126738889Sjdp | suboptions LANGUAGE numexpr cnumexpr 126838889Sjdp { 126938889Sjdp $$ = $1; 127038889Sjdp $$.language = $3 | ($4 << 8); 127138889Sjdp } 127238889Sjdp | suboptions VERSIONK numexpr 127338889Sjdp { 127438889Sjdp $$ = $1; 127538889Sjdp $$.version = $3; 127638889Sjdp } 127738889Sjdp ; 127838889Sjdp 127938889Sjdp/* Memory flags which default to MOVEABLE and DISCARDABLE. */ 128038889Sjdp 128138889Sjdpmemflags_move_discard: 128238889Sjdp /* empty */ 128338889Sjdp { 128438889Sjdp memset (&$$, 0, sizeof (struct res_res_info)); 128538889Sjdp $$.language = language; 128638889Sjdp $$.memflags = MEMFLAG_MOVEABLE | MEMFLAG_DISCARDABLE; 128738889Sjdp } 128838889Sjdp | memflags_move_discard memflag 128938889Sjdp { 129038889Sjdp $$ = $1; 129138889Sjdp $$.memflags |= $2.on; 129238889Sjdp $$.memflags &=~ $2.off; 129338889Sjdp } 129438889Sjdp ; 129538889Sjdp 129638889Sjdp/* Memory flags which default to MOVEABLE. */ 129738889Sjdp 129838889Sjdpmemflags_move: 129938889Sjdp /* empty */ 130038889Sjdp { 130138889Sjdp memset (&$$, 0, sizeof (struct res_res_info)); 130238889Sjdp $$.language = language; 130338889Sjdp $$.memflags = MEMFLAG_MOVEABLE; 130438889Sjdp } 130538889Sjdp | memflags_move_discard memflag 130638889Sjdp { 130738889Sjdp $$ = $1; 130838889Sjdp $$.memflags |= $2.on; 130938889Sjdp $$.memflags &=~ $2.off; 131038889Sjdp } 131138889Sjdp ; 131238889Sjdp 131338889Sjdp/* Memory flags. This returns a struct with two integers, because we 131438889Sjdp sometimes want to set bits and we sometimes want to clear them. */ 131538889Sjdp 131638889Sjdpmemflag: 131738889Sjdp MOVEABLE 131838889Sjdp { 131938889Sjdp $$.on = MEMFLAG_MOVEABLE; 132038889Sjdp $$.off = 0; 132138889Sjdp } 132238889Sjdp | FIXED 132338889Sjdp { 132438889Sjdp $$.on = 0; 132538889Sjdp $$.off = MEMFLAG_MOVEABLE; 132638889Sjdp } 132738889Sjdp | PURE 132838889Sjdp { 132938889Sjdp $$.on = MEMFLAG_PURE; 133038889Sjdp $$.off = 0; 133138889Sjdp } 133238889Sjdp | IMPURE 133338889Sjdp { 133438889Sjdp $$.on = 0; 133538889Sjdp $$.off = MEMFLAG_PURE; 133638889Sjdp } 133738889Sjdp | PRELOAD 133838889Sjdp { 133938889Sjdp $$.on = MEMFLAG_PRELOAD; 134038889Sjdp $$.off = 0; 134138889Sjdp } 134238889Sjdp | LOADONCALL 134338889Sjdp { 134438889Sjdp $$.on = 0; 134538889Sjdp $$.off = MEMFLAG_PRELOAD; 134638889Sjdp } 134738889Sjdp | DISCARDABLE 134838889Sjdp { 134938889Sjdp $$.on = MEMFLAG_DISCARDABLE; 135038889Sjdp $$.off = 0; 135138889Sjdp } 135238889Sjdp ; 135338889Sjdp 135438889Sjdp/* A file name. */ 135538889Sjdp 135638889Sjdpfile_name: 135738889Sjdp QUOTEDSTRING 135838889Sjdp { 135938889Sjdp $$ = $1; 136038889Sjdp } 136138889Sjdp | STRING 136238889Sjdp { 136338889Sjdp $$ = $1; 136438889Sjdp } 136538889Sjdp ; 136638889Sjdp 136738889Sjdp/* A style expression. This changes the static variable STYLE. We do 136838889Sjdp it this way because rc appears to permit a style to be set to 136938889Sjdp something like 137038889Sjdp WS_GROUP | NOT WS_TABSTOP 137138889Sjdp to mean that a default of WS_TABSTOP should be removed. Anything 137238889Sjdp which wants to accept a style must first set STYLE to the default 137338889Sjdp value. The styleexpr nonterminal will change STYLE as specified by 137438889Sjdp the user. Note that we do not accept arbitrary expressions here, 137538889Sjdp just numbers separated by '|'. */ 137638889Sjdp 137738889Sjdpstyleexpr: 137838889Sjdp parennumber 137938889Sjdp { 138038889Sjdp style |= $1; 138138889Sjdp } 138238889Sjdp | NOT parennumber 138338889Sjdp { 138438889Sjdp style &=~ $2; 138538889Sjdp } 138638889Sjdp | styleexpr '|' parennumber 138738889Sjdp { 138838889Sjdp style |= $3; 138938889Sjdp } 139038889Sjdp | styleexpr '|' NOT parennumber 139138889Sjdp { 139238889Sjdp style &=~ $4; 139338889Sjdp } 139438889Sjdp ; 139538889Sjdp 139638889Sjdpparennumber: 139738889Sjdp NUMBER 139838889Sjdp { 139938889Sjdp $$ = $1.val; 140038889Sjdp } 140138889Sjdp | '(' numexpr ')' 140238889Sjdp { 140338889Sjdp $$ = $2; 140438889Sjdp } 140538889Sjdp ; 140638889Sjdp 140738889Sjdp/* An optional expression with a leading comma. */ 140838889Sjdp 140938889Sjdpoptcnumexpr: 141038889Sjdp /* empty */ 141138889Sjdp { 141238889Sjdp $$ = 0; 141338889Sjdp } 141438889Sjdp | cnumexpr 141538889Sjdp { 141638889Sjdp $$ = $1; 141738889Sjdp } 141838889Sjdp ; 141938889Sjdp 142038889Sjdp/* An expression with a leading comma. */ 142138889Sjdp 142238889Sjdpcnumexpr: 142338889Sjdp ',' numexpr 142438889Sjdp { 142538889Sjdp $$ = $2; 142638889Sjdp } 142738889Sjdp ; 142838889Sjdp 142938889Sjdp/* A possibly negated numeric expression. */ 143038889Sjdp 143138889Sjdpnumexpr: 143238889Sjdp sizednumexpr 143338889Sjdp { 143438889Sjdp $$ = $1.val; 143538889Sjdp } 143638889Sjdp ; 143738889Sjdp 143838889Sjdp/* A possibly negated expression with a size. */ 143938889Sjdp 144038889Sjdpsizednumexpr: 144138889Sjdp NUMBER 144238889Sjdp { 144338889Sjdp $$ = $1; 144438889Sjdp } 144538889Sjdp | '(' sizednumexpr ')' 144638889Sjdp { 144738889Sjdp $$ = $2; 144838889Sjdp } 144938889Sjdp | '~' sizednumexpr %prec '~' 145038889Sjdp { 145138889Sjdp $$.val = ~ $2.val; 145238889Sjdp $$.dword = $2.dword; 145338889Sjdp } 145438889Sjdp | '-' sizednumexpr %prec NEG 145538889Sjdp { 145638889Sjdp $$.val = - $2.val; 145738889Sjdp $$.dword = $2.dword; 145838889Sjdp } 145938889Sjdp | sizednumexpr '*' sizednumexpr 146038889Sjdp { 146138889Sjdp $$.val = $1.val * $3.val; 146238889Sjdp $$.dword = $1.dword || $3.dword; 146338889Sjdp } 146438889Sjdp | sizednumexpr '/' sizednumexpr 146538889Sjdp { 146638889Sjdp $$.val = $1.val / $3.val; 146738889Sjdp $$.dword = $1.dword || $3.dword; 146838889Sjdp } 146938889Sjdp | sizednumexpr '%' sizednumexpr 147038889Sjdp { 147138889Sjdp $$.val = $1.val % $3.val; 147238889Sjdp $$.dword = $1.dword || $3.dword; 147338889Sjdp } 147438889Sjdp | sizednumexpr '+' sizednumexpr 147538889Sjdp { 147638889Sjdp $$.val = $1.val + $3.val; 147738889Sjdp $$.dword = $1.dword || $3.dword; 147838889Sjdp } 147938889Sjdp | sizednumexpr '-' sizednumexpr 148038889Sjdp { 148138889Sjdp $$.val = $1.val - $3.val; 148238889Sjdp $$.dword = $1.dword || $3.dword; 148338889Sjdp } 148438889Sjdp | sizednumexpr '&' sizednumexpr 148538889Sjdp { 148638889Sjdp $$.val = $1.val & $3.val; 148738889Sjdp $$.dword = $1.dword || $3.dword; 148838889Sjdp } 148938889Sjdp | sizednumexpr '^' sizednumexpr 149038889Sjdp { 149138889Sjdp $$.val = $1.val ^ $3.val; 149238889Sjdp $$.dword = $1.dword || $3.dword; 149338889Sjdp } 149438889Sjdp | sizednumexpr '|' sizednumexpr 149538889Sjdp { 149638889Sjdp $$.val = $1.val | $3.val; 149738889Sjdp $$.dword = $1.dword || $3.dword; 149838889Sjdp } 149938889Sjdp ; 150038889Sjdp 150138889Sjdp/* An expression with a leading comma which does not use unary 150238889Sjdp negation. */ 150338889Sjdp 150438889Sjdpcposnumexpr: 150538889Sjdp ',' posnumexpr 150638889Sjdp { 150738889Sjdp $$ = $2; 150838889Sjdp } 150938889Sjdp ; 151038889Sjdp 151138889Sjdp/* An expression which does not use unary negation. */ 151238889Sjdp 151338889Sjdpposnumexpr: 151438889Sjdp sizedposnumexpr 151538889Sjdp { 151638889Sjdp $$ = $1.val; 151738889Sjdp } 151838889Sjdp ; 151938889Sjdp 152038889Sjdp/* An expression which does not use unary negation. We separate unary 152138889Sjdp negation to avoid parsing conflicts when two numeric expressions 152238889Sjdp appear consecutively. */ 152338889Sjdp 152438889Sjdpsizedposnumexpr: 152538889Sjdp NUMBER 152638889Sjdp { 152738889Sjdp $$ = $1; 152838889Sjdp } 152938889Sjdp | '(' sizednumexpr ')' 153038889Sjdp { 153138889Sjdp $$ = $2; 153238889Sjdp } 153338889Sjdp | '~' sizednumexpr %prec '~' 153438889Sjdp { 153538889Sjdp $$.val = ~ $2.val; 153638889Sjdp $$.dword = $2.dword; 153738889Sjdp } 153838889Sjdp | sizedposnumexpr '*' sizednumexpr 153938889Sjdp { 154038889Sjdp $$.val = $1.val * $3.val; 154138889Sjdp $$.dword = $1.dword || $3.dword; 154238889Sjdp } 154338889Sjdp | sizedposnumexpr '/' sizednumexpr 154438889Sjdp { 154538889Sjdp $$.val = $1.val / $3.val; 154638889Sjdp $$.dword = $1.dword || $3.dword; 154738889Sjdp } 154838889Sjdp | sizedposnumexpr '%' sizednumexpr 154938889Sjdp { 155038889Sjdp $$.val = $1.val % $3.val; 155138889Sjdp $$.dword = $1.dword || $3.dword; 155238889Sjdp } 155338889Sjdp | sizedposnumexpr '+' sizednumexpr 155438889Sjdp { 155538889Sjdp $$.val = $1.val + $3.val; 155638889Sjdp $$.dword = $1.dword || $3.dword; 155738889Sjdp } 155838889Sjdp | sizedposnumexpr '-' sizednumexpr 155938889Sjdp { 156038889Sjdp $$.val = $1.val - $3.val; 156138889Sjdp $$.dword = $1.dword || $3.dword; 156238889Sjdp } 156338889Sjdp | sizedposnumexpr '&' sizednumexpr 156438889Sjdp { 156538889Sjdp $$.val = $1.val & $3.val; 156638889Sjdp $$.dword = $1.dword || $3.dword; 156738889Sjdp } 156838889Sjdp | sizedposnumexpr '^' sizednumexpr 156938889Sjdp { 157038889Sjdp $$.val = $1.val ^ $3.val; 157138889Sjdp $$.dword = $1.dword || $3.dword; 157238889Sjdp } 157338889Sjdp | sizedposnumexpr '|' sizednumexpr 157438889Sjdp { 157538889Sjdp $$.val = $1.val | $3.val; 157638889Sjdp $$.dword = $1.dword || $3.dword; 157738889Sjdp } 157838889Sjdp ; 157938889Sjdp 158038889Sjdp%% 158138889Sjdp 158238889Sjdp/* Set the language from the command line. */ 158338889Sjdp 158438889Sjdpvoid 158538889Sjdprcparse_set_language (lang) 158638889Sjdp int lang; 158738889Sjdp{ 158838889Sjdp language = lang; 158938889Sjdp} 1590