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

#include <stdio.h>
#include <stdlib.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 style_elm 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);
		}
                | stringtable
                {$$=$1; /* <-- should be NULL */
			if(verbose)fprintf(stderr,"Got STRINGTABLE\n");
                }
                ;

/* 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;}
		| 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;add_str_tbl_elm($1,$2);}

versioninfo:	VERSIONINFO NOT_SUPPORTED {$$=0;}

/* NOT x | NOT y | a | b means (a|b)& ~x & ~y
   NOT is used to disable default styles */
style:	        {$$=new_style();}
                | style_elm {$$=$1;}
		| style_elm '|' style 
                {$$=$1;$$->or|=$3->or;$$->and&=$3->and;free($3);}

style_elm:      NUMBER {$$=new_style();$$->or=$1;}
		| NOT NUMBER {$$=new_style();$$->and=~($2);}
		| '(' style ')' {$$=$2;}
%%
extern int line_number;
extern char* yytext;

int yyerror(char *s)
{
	fprintf(stderr,"stdin:%d: %s before '%s'\n",line_number,s,yytext);
	return 0;
}

