%{
/*
 *
 * Copyright  Martin von Loewis, 1994
 */

#include <stdio.h>
#include "parser.h"
#include "windows.h"
%}
%union{
	gen_res *res;
	char *str;
	int num;
	struct rc_style *style;
}
%token <num> NUMBER
%token <str> STRING SINGLE_QUOTED IDENT
%token ACCELERATORS ALT ASCII tBEGIN tBITMAP CAPTION CHECKBOX CHECKED 
%token CLASS COMBOBOX CONTROL CTEXT CURSOR DEFPUSHBUTTON DIALOG 
%token DISCARDABLE EDITTEXT tEND FIXED FONT GRAYED GROUPBOX HELP ICON 
%token IDENT INACTIVE LISTBOX LTEXT MENU MENUBARBREAK MENUBREAK MENUITEM 
%token MOVEABLE LOADONCALL NOINVERT NOT NOT_SUPPORTED POPUP PRELOAD 
%token PURE PUSHBUTTON RADIOBUTTON RCDATA RTEXT SCROLLBAR SHIFT SEPARATOR 
%token SINGLE_QUOTED STRING STRINGTABLE STYLE VERSIONINFO VIRTKEY
%type <res> resource_file resource resources resource_definition accelerators
%type <res> events bitmap cursor dialog dlg_attributes controls 
%type <res> generic_control labeled_control control_desc font icon 
%type <res> iconinfo menu menu_body item_definitions rcdata raw_data raw_elements 
%type <res> stringtable strings versioninfo
%type <num> acc_options item_options
%type <style> style optional_style
%%

resource_file: resources {create_output($1);}

/*resources are put into a linked list*/
resources:	{$$=0;}
		|resource resources {$$=add_resource($1,$2);}
		;

/* get the name for a single resource*/
resource:	NUMBER resource_definition
		{$$=$2;$$->n.i_name=$1;$$->n_type=0;
			if(verbose)fprintf(stderr,"Got %s %d\n",get_typename($2),$1);
		}
		| IDENT resource_definition
		{$$=$2;$$->n.s_name=$1;$$->n_type=1;
			if(verbose)fprintf(stderr,"Got %s %s\n",get_typename($2),$1);
		}

/* get the value for a single resource*/
resource_definition:	accelerators {$$=$1;}
		| bitmap {$$=$1;}
		| cursor {$$=$1;}
		| dialog {$$=$1;}
		| font {$$=$1;}
		| icon {$$=$1;}
		| menu {$$=$1;}
		| rcdata {$$=$1;}
		| stringtable {$$=$1;}
		| versioninfo {$$=$1;}

/* have to use tBEGIN because BEGIN is predefined */
accelerators:	ACCELERATORS  tBEGIN  events tEND {$$=$3;$$->type=acc;}
/* the events are collected in a gen_res, as the accelerator resource is just
   an array of events */
events:		{$$=new_res();}
		| STRING ',' NUMBER acc_options  events 
			{$$=add_string_accelerator($1,$3,$4,$5);}
		| NUMBER ',' NUMBER ',' ASCII acc_options  events 
			{$$=add_ascii_accelerator($1,$3,$6,$7);}
		| NUMBER ',' NUMBER ',' VIRTKEY acc_options  events 
			{$$=add_vk_accelerator($1,$3,$6,$7);}
acc_options:	{$$=0;}
		| ',' NOINVERT acc_options {$$=$3|2;}
		| ',' ALT acc_options      {$$=$3|16;}
		| ',' SHIFT acc_options	   {$$=$3|4;}
		| ',' CONTROL acc_options  {$$=$3|8;}

bitmap:		tBITMAP load_and_memoption STRING {$$=make_bitmap(load_file($3));}
		| tBITMAP load_and_memoption raw_data {$$=make_bitmap($3);}

/* load and memory options are ignored */
load_and_memoption:	| lamo load_and_memoption
lamo:	PRELOAD | LOADONCALL | FIXED | MOVEABLE | DISCARDABLE | PURE

cursor:		CURSOR load_and_memoption STRING {$$=make_cursor(load_file($3));}
		|CURSOR load_and_memoption raw_data {$$=make_cursor($3);}

dialog:		DIALOG load_and_memoption NUMBER ',' NUMBER ',' NUMBER ',' NUMBER 
		dlg_attributes
		tBEGIN  controls tEND 
		{$$=make_dialog($10,$3,$5,$7,$9,$12);}

dlg_attributes:	{$$=new_dialog();}
		| STYLE style dlg_attributes 
		  {$$=dialog_style($2,$3);}
		| CAPTION STRING dlg_attributes
		  {$$=dialog_caption($2,$3);}
		| FONT NUMBER ',' STRING dlg_attributes 
		  {$$=dialog_font($2,$4,$5);}
		| CLASS STRING dlg_attributes
		  {$$=dialog_class($2,$3);}
		| MENU STRING dlg_attributes
		  {$$=dialog_menu($2,$3);}

/* the controls are collected into a gen_res, and finally the dialog header 
   is put at the beginning */
controls:	{$$=new_res();}
		| CHECKBOX  labeled_control controls 
		  {$$=add_control(CT_BUTTON, BS_CHECKBOX, $2, $3);}
		| COMBOBOX control_desc controls 
		  {$$=add_control(CT_COMBOBOX, 0, $2, $3);}
		| CONTROL generic_control controls
		  {$$=add_generic_control($2, $3);}
		| CTEXT labeled_control controls 
		  {$$=add_control(CT_STATIC, SS_CENTER, $2, $3);}
		| DEFPUSHBUTTON labeled_control controls 
		  {$$=add_control(CT_BUTTON, BS_DEFPUSHBUTTON, $2, $3);}
		| EDITTEXT control_desc controls 
		  {$$=add_control(CT_EDIT, 0, $2, $3);}
		| GROUPBOX labeled_control controls 
		  {$$=add_control(CT_BUTTON, BS_GROUPBOX, $2, $3);}
		/*special treatment for icons, as the extent is optional*/
		| ICON STRING ',' NUMBER ',' NUMBER ',' NUMBER iconinfo controls
		  {$$=add_icon($2, $4, $6, $8, $9, $10);}
		| LISTBOX control_desc controls 
		  {$$=add_control(CT_LISTBOX, 0, $2, $3);}
		| LTEXT labeled_control controls 
		  {$$=add_control(CT_STATIC, SS_LEFT, $2, $3);}
		| PUSHBUTTON labeled_control controls 
		  {$$=add_control(CT_BUTTON, BS_PUSHBUTTON, $2, $3);}
		| RADIOBUTTON labeled_control controls 
		  {$$=add_control(CT_BUTTON, BS_RADIOBUTTON, $2, $3);}
		| RTEXT labeled_control controls 
		  {$$=add_control(CT_STATIC, SS_RIGHT, $2, $3);}
		| SCROLLBAR control_desc controls		
		  {$$=add_control(CT_SCROLLBAR, 0, $2, $3);}


labeled_control: STRING ',' control_desc {$$=label_control_desc($1,$3);}
control_desc:	NUMBER ',' NUMBER ',' NUMBER ',' NUMBER ',' NUMBER optional_style 
		{$$=create_control_desc($1,$3,$5,$7,$9,$10);}

optional_style: {$$=0;}|
		',' style {$$=$2;}

iconinfo:	/*set extent and style to 0 if they are not provided */
		{$$=create_control_desc(0,0,0,0,0,0);} 
		/* x and y are overwritten later */
		| ',' NUMBER ',' NUMBER optional_style
        {$$=create_control_desc(0,0,0,$2,$4,$5);}

generic_control:	STRING ',' NUMBER ',' STRING ',' style ',' NUMBER
		',' NUMBER ',' NUMBER ',' NUMBER
		{$$=create_generic_control($1,$3,$5,$7,$9,$11,$13,$15);}

font:		FONT load_and_memoption STRING {$$=make_font(load_file($3));}

icon:		ICON load_and_memoption STRING {$$=make_icon(load_file($3));}
		| ICON load_and_memoption raw_data {$$=make_icon($3);}

menu:		MENU load_and_memoption menu_body {$$=make_menu($3);}
/* menu items are collected in a gen_res and prefixed with the menu header*/
menu_body:	tBEGIN item_definitions tEND {$$=$2;}
item_definitions:	{$$=new_res();}
		| MENUITEM STRING ',' NUMBER item_options item_definitions
		  {$$=add_menuitem($2,$4,$5,$6);}
		| MENUITEM SEPARATOR item_definitions
		  {$$=add_menuitem("",0,0,$3);}
		| POPUP STRING item_options menu_body item_definitions
		  {$$=add_popup($2,$3,$4,$5);}
item_options:	{$$=0;}
		| ',' CHECKED item_options {$$=$3|MF_CHECKED;}
		| ',' GRAYED item_options {$$=$3|MF_GRAYED;}
		| ',' HELP item_options {$$=$3|MF_HELP;}
		| ',' INACTIVE item_options {$$=$3|MF_DISABLED;}
		| ',' MENUBARBREAK item_options {$$=$3|MF_MENUBARBREAK;}
		| ',' MENUBREAK item_options {$$=$3|MF_MENUBREAK;}

rcdata:		RCDATA load_and_memoption raw_data {$$=make_raw($3);}

raw_data:	tBEGIN raw_elements tEND {$$=$2;}
raw_elements:	SINGLE_QUOTED {$$=hex_to_raw($1,new_res());}
		| NUMBER {$$=int_to_raw($1,new_res());}
		| SINGLE_QUOTED raw_elements {$$=hex_to_raw($1,$2);}
		| NUMBER ',' raw_elements {$$=int_to_raw($1,$3);}

stringtable:	STRINGTABLE load_and_memoption tBEGIN strings tEND
			{$$=$4;}
strings:	{$$=0;}|
		NUMBER STRING strings {$$=0;}

versioninfo:	VERSIONINFO NOT_SUPPORTED {$$=0;}

/* NOT x | NOT y | a | b means (a|b)& ~x & ~y
   NOT is used to disable default styles */
style:		NUMBER {$$=new_style();$$->or=$1;}
		| NOT NUMBER {$$=new_style();$$->and=~($2);}
		| '(' style ')' {$$=$2;}
		| style '|' style {$$=$1;$$->or|=$3->or;$$->and&=$3->and;}
%%
int yyerror(char *s)
{
	puts(s);
}

