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

static char Copyright[] = "Copyright Martin von Loewis, 1994";

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/types.h>
#include <windows.h>
#include <neexe.h>
#include "rc.h"
#include "rc.tab.h"

char usage[]="winerc -dv -p <prefix> < infile > outfile\n";

/*might be overwritten by command line*/
char *prefix="_Resource";
int verbose;
gen_res* g_start;

main(int argc,char *argv[])
{  
	extern int yydebug;
	extern char* optarg;
	int optc,lose;
	lose=0;
	while((optc=getopt(argc,argv,"dp:v",0))!=EOF)
		switch(optc)
		{
			/* bison will print state transitions on stderr */
			case 'd':yydebug=1;
					 setbuf(stdout,0);
					 setbuf(stderr,0);
					break;
			case 'p':prefix=optarg;break;
			case 'v':verbose=1;
					 setbuf(stderr,0);
					break;
			default: lose++;break;
		}
	if(lose)return fprintf(stderr,usage),1;
	yyparse();
	return 0;
}

/* SunOS' memcpy is wrong for overlapping arrays */
char *save_memcpy(char *d,char* s,int l)
{
	if(d<s)
		for(;l;l--)*d++=*s++;
	else
		for(d+=l-1,s+=l-1;l;l--)*d--=*s--;
	return d;
}

/*allow unaligned access*/
void put_WORD(unsigned char* p,WORD w)
{
	*p=w&0xFF;
	*(p+1)=w>>8;
}

void put_DWORD(unsigned char* p,DWORD d)
{
	put_WORD(p,d&0xFFFF);
	put_WORD(p+2,d>>16);
}

WORD get_WORD(unsigned char* p)
{
	return *p|(*(p+1)<<8);
}

DWORD get_DWORD(unsigned char* p)
{
	return get_WORD(p)|(get_WORD(p+2)<<16);
}


/*create a new gen_res, initial size 100*/
gen_res *new_res()
{	gen_res* ret=malloc(sizeof(gen_res)+100);
	int i;
	if(!ret)
		fprintf(stderr,"Out of memory\n"),exit(1);
	for(i=0;i<sizeof(gen_res)+100;i++)*((char*)ret+i)='\0';
	ret->g_next=g_start;
	ret->g_prev=0;
	g_start=ret;
	ret->space=100;
	return ret;
}

/*double the space*/
gen_res* grow(gen_res* res)
{
	res=realloc(res,sizeof(gen_res)+2*res->space);
	if(!res)
		fprintf(stderr,"Out of memory\n"),exit(1);
	if(!res->g_prev)g_start=res;
	else res->g_prev->g_next=res;
	if(res->g_next)res->g_next->g_prev=res;
	res->space=2*res->space;
	return res;
}


/* insert bytes at offset 0, increase num_entries */
gen_res* insert_at_beginning(gen_res* res,char* entry,int size)
{
	while(res->size+size>res->space)res=grow(res);
	save_memcpy(res->res+size,res->res,res->size);
	save_memcpy(res->res,entry,size);
	res->size+=size;
	res->num_entries++;
	return res;
}

/* insert length characters from bytes into res, starting at start */
gen_res* insert_bytes(gen_res* res,char* bytes,int start,int length)
{
	while(res->size+length>res->space)res=grow(res);
	save_memcpy(res->res+start+length,res->res+start,res->size-start);
	save_memcpy(res->res+start,bytes,length);
	res->size+=length;
	return res;
}

/*delete len bytes from res, starting at start*/
gen_res* delete_bytes(gen_res* res,int start,int len)
{
	save_memcpy(res->res+start,res->res+start+len,res->size-start-len);
	res->size-=len;
	return res;
}

/*create a new style*/
rc_style *new_style()
{
	rc_style *ret=malloc(sizeof(rc_style));
	/*initially, no bits have to be reset*/
	ret->and=-1;
	/*initially, no bits are set*/
	ret->or=0;
	return ret;
}

/* entries are inserted at the beginning, starting from the last one */
gen_res* add_accelerator(int ev, int id, int flags, gen_res* prev)
{
	char accel_entry[5];
	if(prev->num_entries==0)flags|=0x80; /* last entry */
	accel_entry[0]=flags;
	put_WORD(accel_entry+1,ev);
	put_WORD(accel_entry+3,id);
	return insert_at_beginning(prev,accel_entry,5);
}


/* create an integer from the event, taking things as "^c" into account
   add this as new entry */
gen_res* add_string_accelerator(char *ev, int id, int flags, gen_res* prev)
{
	int event;
	if(*ev=='^')
		event=ev[1]-'a';
	else
		event=ev[0];
	return add_accelerator(event,id,flags,prev);
}

/*is there a difference between ASCII and VIRTKEY accelerators? */

gen_res* add_ascii_accelerator(int ev, int id, int flags, gen_res* prev)
{
	return add_accelerator(ev,id,flags,prev);
}

gen_res* add_vk_accelerator(int ev, int id, int flags, gen_res* prev)
{
	return add_accelerator(ev,id,flags,prev);
}

/* create a new dialog header, set all items to 0 */
gen_res* new_dialog()
{	gen_res* ret=new_res();
	ret->size=16; /*all strings "\0", no font*/
	return ret;
}

/* the STYLE option was specified */
gen_res* dialog_style(rc_style* style, gen_res* attr)
{
	/* default dialog styles? Do we need style->and? */
	/* DS_SETFONT might have been specified before */
	put_DWORD(attr->res,get_DWORD(attr->res)|style->or);
	return attr;
}

/* menu name is at offset 13 */
int dialog_get_menu(gen_res* attr)
{
	return 13;
}

/* the class is after the menu name */
int dialog_get_class(gen_res* attr)
{
	int offs=dialog_get_menu(attr);
	while(attr->res[offs])offs++;
	offs++;
	return offs;
}

/* the caption is after the class */
int dialog_get_caption(gen_res* attr)
{
	int offs=dialog_get_class(attr);
	while(attr->res[offs])offs++;
	offs++;
	return offs;
}

/* the fontsize, if present, is after the caption, followed by the font name */
int dialog_get_fontsize(gen_res* attr)
{
	int offs=dialog_get_caption(attr);
	while(attr->res[offs])offs++;
	offs++;
	return offs;
}


/* the CAPTION option was specified */
gen_res* dialog_caption(char* cap, gen_res*attr)
{
	/* we don't need the terminating 0 as it's already there */
	return insert_bytes(attr,cap,dialog_get_caption(attr),strlen(cap));
}


/* the FONT option was specified, set the DS_SETFONT flag */
gen_res* dialog_font(short size,char* font,gen_res *attr)
{
	char c_size[2];
	int offs=dialog_get_fontsize(attr);
	put_DWORD(attr->res,get_DWORD(attr->res)|DS_SETFONT);
	put_WORD(c_size,size);
	attr=insert_bytes(attr,c_size,offs,2);
	offs+=2;
	/* as there is no font name by default, copy the '\0' */
	return insert_bytes(attr,font,offs,strlen(font)+1);
}

gen_res* dialog_class(char* cap, gen_res*attr)
{
	return insert_bytes(attr,cap,dialog_get_class(attr),strlen(cap));
}

gen_res* dialog_menu(char* cap, gen_res*attr)
{
	return insert_bytes(attr,cap,dialog_get_menu(attr),strlen(cap));
}

/* set the dialogs id, position, extent, and style */
gen_res* create_control_desc(int id,int x,int y,int cx, int cy,rc_style *style)
{	gen_res* ret=new_res();
	int s=WS_VISIBLE|WS_CHILD; /*defaults styles for any control*/
	put_WORD(ret->res+0,x);
	put_WORD(ret->res+2,y);
	put_WORD(ret->res+4,cx);
	put_WORD(ret->res+6,cy);
	put_WORD(ret->res+8,id);
	if(style)s=(s|style->or)&style->and;
	put_DWORD(ret->res+10,s);
	ret->size=17; /*empty strings, unused byte*/
	return ret;
}

/* insert the control's label */
gen_res* label_control_desc(char* label,gen_res* cd)
{
	int offs;
	if(cd->res[14]&0x80)offs=15; /* one-character class */
	else {
		for(offs=14;cd->res[offs];offs++);
		offs++;
	}
	return insert_bytes(cd,label,offs,strlen(label));
}

/* a CONTROL was specified */
gen_res* create_generic_control(char* label,int id,char* class,
	rc_style*style,int x,int y,int cx,int cy)
{	char cl;
	gen_res* ret=new_res();
	put_WORD(ret->res+0,x);
    put_WORD(ret->res+2,y);
    put_WORD(ret->res+4,cx);
    put_WORD(ret->res+6,cy);
    put_WORD(ret->res+8,id);
	put_DWORD(ret->res+10,style->or);
	ret->size=17;
	ret=insert_bytes(ret,label,15,strlen(label));
	/* is it a predefined class? */
	cl=0;
	if(!strcmp(class,"BUTTON"))cl=CT_BUTTON;
	if(!strcmp(class,"EDIT"))cl=CT_EDIT;
	if(!strcmp(class,"STATIC"))cl=CT_STATIC;
	if(!strcmp(class,"LISTBOX"))cl=CT_LISTBOX;
	if(!strcmp(class,"SCROLLBAR"))cl=CT_SCROLLBAR;
	if(!strcmp(class,"COMBOBOX"))cl=CT_COMBOBOX;
	if(cl)ret->res[14]=cl;
	else ret=insert_bytes(ret,class,14,strlen(class));
	return ret;
}

/* insert cd into rest, set the type, add flags */
gen_res* add_control(int type,int flags,gen_res*cd,gen_res* rest)
{
	put_DWORD(cd->res+10,get_DWORD(cd->res+10)|flags);
	cd->res[14]=type;
	return insert_at_beginning(rest,cd->res,cd->size);
}

/* an ICON control was specified, whf contains width, height, and flags */
gen_res* add_icon(char* name,int id,int x,int y,gen_res* whf,gen_res* rest)
{
	put_WORD(whf->res+0,x);
	put_WORD(whf->res+2,y);
	put_WORD(whf->res+8,id);
	whf=label_control_desc(name,whf);
	return add_control(CT_STATIC,SS_ICON,whf,rest);
}

/* insert the generic control into rest */
gen_res* add_generic_control(gen_res* ctl, gen_res* rest)
{
	return insert_at_beginning(rest,ctl->res,ctl->size);
}

/* create a dialog resource by inserting the header into the controls.
   Set position and extent */
gen_res* make_dialog(gen_res* header,int x,int y,int cx,int cy,gen_res* ctls)
{
	header->res[4]=ctls->num_entries;
	header->type=dlg;
	put_WORD(header->res+5,x);
	put_WORD(header->res+7,y);
	put_WORD(header->res+9,cx);
	put_WORD(header->res+11,cy);
	return insert_bytes(header,ctls->res,header->size,ctls->size);
}

/* create {0x15,0x16,0xFF} from '15 16 FF' */
gen_res *hex_to_raw(char *hex, gen_res*rest)
{
	char r2[16];
    int i;
	for(i=0;*hex!='\'';i++)r2[i]=strtoul(hex,&hex,16);
	return insert_bytes(rest,r2,0,i);
}

/* create a bitmap resource */
gen_res *make_bitmap(gen_res* res)
{
	res=delete_bytes(res,0,14); /* skip bitmap file header*/
	res->type=bmp;
	return res;
}

gen_res *make_icon(gen_res* res)
{
	res->type=ico;
	return res;
}

gen_res *make_cursor(gen_res* res)
{
	res->type=cur;
	return res;
}

/* load resource bytes from the file name */
gen_res *load_file(char* name)
{
	gen_res *res;
	struct stat st;
	int f=open(name,O_RDONLY);
	if(!f)perror(name);
	fstat(f,&st);
	res=new_res();
	while(res->space<st.st_size)res=grow(res);
	read(f,res->res,st.st_size);
	res->size=st.st_size;
	close(f);
	return res;
}

/* insert a normal menu item into res, starting from the last item */
gen_res *add_menuitem(char* name,int id,int flags,gen_res *res)
{
	char item[4];
	if(res->num_entries==0)flags|=MF_END;
	put_WORD(item,flags);
	put_WORD(item+2,id);
	res=insert_at_beginning(res,name,strlen(name)+1);
	res=insert_bytes(res,item,0,4);
	return res;
}

/* insert a popup item into res */
gen_res *add_popup(char *name,short flags, gen_res* body, gen_res*res)
{
	char c_flags[2];
	if(res->num_entries==0)flags|=MF_END;
	put_WORD(c_flags,flags);
	res=insert_at_beginning(res,body->res,body->size);
	res=insert_bytes(res,name,0,strlen(name)+1);
	res=insert_bytes(res,c_flags,0,2);
	return res;
}

/* prefix the menu header into res */
gen_res *make_menu(gen_res* res)
{
	static char header[4]={0,0,0,0};
	res=insert_at_beginning(res,header,4);
	res->type=men;
	return res;
}

/* link top-level resources */
gen_res *add_resource(gen_res* first,gen_res *rest)
{
	first->next=rest;
	return first;
}

char *get_typename(gen_res* t)
{
	switch(t->type){
	case acc:return "ACCELERATOR";
	case bmp:return "BITMAP";
	case cur:return "CURSOR";
	case dlg:return "DIALOG";
	case fnt:return "FONT";
	case ico:return "ICON";
	case men:return "MENU";
	case rdt:return "RCDATA";
	case str:return "STRINGTABLE";
	default: return "UNKNOWN";
	}
}

/* create strings like _Sysres_DIALOG_2 */
char *get_resource_name(gen_res*it)
{
	static char buf[1000];
	if(it->n_type)
		sprintf(buf,"%s_%s_%s",prefix,get_typename(it),it->n.s_name);
	else
		sprintf(buf,"%s_%s_%d",prefix,get_typename(it),it->n.i_name);
	return buf;
}

/* create the final output */
void create_output(gen_res* top)
{
	gen_res *it;
	/* print the type */
	printf("struct ResourceTable{\n\tint id,type;\n\t"
		"char *name;\n\tconst unsigned char* value;\n};\n\n");
	/* declare the resources */
	for(it=top;it;it=it->next)
		printf("const unsigned char %s[];\n",get_resource_name(it));

	/* print the resource table (0 terminated) */
	printf("\nconst struct ResourceTable %sTable[]={\n",prefix);
	for(it=top;it;it=it->next)
	{	int type;
		switch(it->type)
		{case acc:type=NE_RSCTYPE_ACCELERATOR;break;
		 case bmp:type=NE_RSCTYPE_BITMAP;break;
		 case cur:type=NE_RSCTYPE_CURSOR;break;
		 case dlg:type=NE_RSCTYPE_DIALOG;break;
		 case fnt:type=NE_RSCTYPE_FONT;break;
		 case ico:type=NE_RSCTYPE_ICON;break;
		 case men:type=NE_RSCTYPE_MENU;break;
		 case rdt:type=NE_RSCTYPE_RCDATA;break;
		 case str:type=NE_RSCTYPE_STRING;break;
		 default:fprintf(stderr,"Unknown restype\n");type=-1;break;
		}
		if(it->n_type)
			printf("{0,%d,\"%s\",%s},\n",
			type,it->n.s_name,get_resource_name(it));
		else
			printf("{%d,%d,\"@%d\",%s},\n",
			it->n.i_name,type,it->n.i_name,get_resource_name(it));
	}
	printf("{0,0,0,0}};\n\n");

	/* print the resources */
	for(it=top;it;it=it->next)
	{	int i;
		printf("const unsigned char %s[]={\n",get_resource_name(it));
		for(i=0;i<it->size-1;i++)
		{
			printf("%#4x,",it->res[i]);
			if((i&7)==7)putchar('\n');
        }
		printf("%#4x};\n",it->res[i]);
	}
}

void make_font()
{
	fprintf(stderr,"Fonts not supported\n");
}

void make_raw()
{
	fprintf(stderr,"RCData not supported\n");
}

void int_to_raw()
{
	fprintf(stderr,"IntToRaw not supported\n");
}

/* translate "Hello,\\tworld!\\10" to "Hello,\tworld!\n" */
char *parse_c_string(char *in)
{
	char *out=malloc(strlen(in)-1);
	char *it;
	char tmp[5],*tend;
	for(it=out,in++;*in;in++)
	if(*in=='\\')
		switch(*++in)
		{case 't':*it++='\t';break;
		 case 'r':*it++='\r';break;
		 case 'n':*it++='\n';break;
		 case 'a':*it++='\a';break;
		 case '0':
			memset(tmp,0,5);/*make sure it doesn't use more than 4 chars*/
			memcpy(tmp,in,4);
			*it++=strtoul(tmp,&tend,0);
			in+=tend-tmp-1;
			break;
		 case '1':case '2':case '3':case '4':case '5':
		 case '6':case '7':case '8':case '9':
			memset(tmp,0,5);
			memcpy(tmp,in,3);
			*it++=strtoul(tmp,&tend,10);
			in+=tend-tmp-1;
			break;
		 case 'x':
			memset(tmp,0,5);
			memcpy(tmp,++in,2);
			*it++=strtoul(tmp,&tend,16);
			in+=tend-tmp-1;
			break;
		 default:*it++=*in;
		}
	else
		*it++=*in;
	*(it-1)='\0';
	return out;
}
