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

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <windows.h>
/* #include <neexe.h> */
#include "parser.h"
#include "y.tab.h"

char usage[]="winerc -bdvc -p prefix -o outfile < infile \n"
	"   -b            Create a C array from a binary .res file\n"
        "   -c            Add 'const' prefix to C constants\n"
	"   -d            Output debugging information\n"
	"   -p prefix     Give a prefix for the generated names\n"
	"   -v            Show each resource as it is processed\n"
	"   -o file       Output to file.c and file.h\n";


/*might be overwritten by command line*/
char *prefix="_Resource";
int verbose,constant;
gen_res* g_start;
FILE *header,*code;
char hname[256],sname[256];

int transform_binary_file(void);
int yyparse(void);

static void *xmalloc (size_t size)
{
    void *res;

    res = malloc (size ? size : 1);
    if (res == NULL)
    {
        fprintf (stderr, "Virtual memory exhausted.\n");
        exit (1);
    }
    return res;
}


int main(int argc,char *argv[])
{  
	extern int yydebug;
	extern char* optarg;
	char* tmpc;
	int optc,lose,ret,binary;
	lose=binary=0;
	while((optc=getopt(argc,argv,"bcdp:vo:"))!=EOF)
		switch(optc)
		{
			/* bison will print state transitions on stderr */
			case 'b':binary=1;
					 break;
			case 'd':yydebug=1;
					 setbuf(stdout,0);
					 setbuf(stderr,0);
					break;
			case 'p':prefix=strdup(optarg);
					 if(!isalpha(*prefix))*prefix='_';
					 for(tmpc=prefix;*tmpc;tmpc++)
					  if( !isalnum(*tmpc) && *tmpc!='_')
					   *tmpc='_';
					break;
			case 'c':constant=1;break;
			case 'v':verbose=1;
					 setbuf(stderr,0);
					break;
			case 'o':set_out_file(optarg);break;
			default: lose++;break;
		}
	if(lose)return fprintf(stderr,usage),1;
	if(!header)header=stdout;
	if(!code)code=stdout;
	if(binary)
		ret=transform_binary_file();
	else
		ret=yyparse();
	fclose(header);
	fclose(code);
	return ret;
}

void set_out_file(char *prefix)
{
	sprintf(sname,"%s.c",prefix);
	code=fopen(sname,"w");
	sprintf(hname,"%s.h",prefix);
	header=fopen(hname,"w");
}

int transform_binary_file()
{
	int i,c;
	fprintf(header,"#define APPLICATION_HAS_RESOURCES 1\n");
	fprintf(code,"char _Application_resources[]={");
	for(i=0;;i++)
	{
		c=getchar();
		if(c==-1)break;
		if(i%16==0)fputc('\n',code);
		fprintf(code,"%3d,",c);
	}
	fprintf(code,"\n  0};\nint _Application_resources_size=%d;\n",i);
	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=xmalloc(sizeof(gen_res)+100);
	int i;
	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=xmalloc(sizeof(rc_style));
	/*initially, no bits have to be reset*/
	ret->and=-1;
	/*initially, no bits are set*/
	ret->or=WS_CHILD | WS_VISIBLE;
	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];
	flags|=MF_POPUP;
	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)
{
    if(first)
    {
	first->next=rest;
	return first;
    }
    else
        return rest;
}

typedef struct str_tbl_elm{
	int group;
	struct str_tbl_elm *next;
	char* strings[16];
} str_tbl_elm;

str_tbl_elm* string_table=NULL; /* sorted by group */

void add_str_tbl_elm(int id,char* str)
{
  int group=(id>>4)+1;
  int idx=id & 0x000f;

  str_tbl_elm** elm=&string_table;
  while(*elm && (*elm)->group<group) elm=&(*elm)->next;
  if(!*elm || (*elm)->group!=group)
  {
    str_tbl_elm* new=xmalloc(sizeof(str_tbl_elm));
    new->group=group;
    new->next=*elm;
    *elm=new;
  }
  (*elm)->strings[idx]=str;
}

gen_res* add_string_table(gen_res* t)
{
  str_tbl_elm* ste;
  int size,i;
  gen_res* res;
  unsigned char* p;
  char* q;

  if(!string_table) return t;
  for(ste=string_table; ste; ste=ste->next)
  {
    for(size=0,i=0; i<16; i++)
      size += ste->strings[i] ? strlen(ste->strings[i])+1 : 1;
    res=new_res();
    while(res->space<size)res=grow(res);
    res->type=str;
    res->n.i_name=ste->group;
    res->n_type=0;
    res->size=size;
    for(p=res->res,i=0; i<16; i++)
      if((q=ste->strings[i])==NULL)
	*p++ = 0;
      else
      {
	*p++ = strlen(q);
	while(*q) *p++ = *q++;
      }
    t=add_resource(res,t);
  }
  return t;
}

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;
}

#define ISCONSTANT	(constant ? "const " : "")

/* create the final output */
void create_output(gen_res* top)
{
    gen_res *it;

    top=add_string_table(top);

    fprintf( header, "/* %s\n"
                     " * This file is automatically generated. Do not edit!\n"
                     " */\n\n"
                     "#include \"resource.h\"\n", hname );

    /* Declare the resources */

    for (it=top;it;it=it->next)
        fprintf( header,"extern %sstruct resource %s;\n",
                 ISCONSTANT, get_resource_name(it) );
    fprintf( header,"\nextern %sstruct resource * %s%s_Table[];\n",
             ISCONSTANT, ISCONSTANT, prefix );

    /* Print the resources bytes */

    fprintf( code, "/* %s\n"
                   " * This file is automatically generated. Do not edit!\n"
                   " */\n\n"
                   "#include \"%s\"\n", sname, hname );

    for(it=top;it;it=it->next)
    {
        int i;
        fprintf( code, "static %sunsigned char %s__bytes[] = {\n",
                 ISCONSTANT, get_resource_name(it) );
        for (i=0;i<it->size-1;i++)
        {
            fprintf(code,"0x%02x, ",it->res[i]);
            if ((i&7)==7)fputc('\n',code);
        }
        fprintf(code,"0x%02x };\n\n",it->res[i]);
    }

    /* Print the resources */
    for (it=top;it;it=it->next)
    {
        int type;
        switch(it->type)
        {
        case acc:type=(int)RT_ACCELERATOR;break;
        case bmp:type=(int)RT_BITMAP;break;
        case cur:type=(int)RT_CURSOR;break;
        case dlg:type=(int)RT_DIALOG;break;
        case fnt:type=(int)RT_FONT;break;
        case ico:type=(int)RT_ICON;break;
        case men:type=(int)RT_MENU;break;
        case rdt:type=(int)RT_RCDATA;break;
        case str:type=(int)RT_STRING;break;
        default:fprintf(stderr,"Unknown restype\n");type=-1;break;
        }
        if(it->n_type)
            fprintf(code,"%sstruct resource %s = {0,%d,\"%s\",%s__bytes,%d};\n",
                    ISCONSTANT, get_resource_name(it), type, it->n.s_name,
                    get_resource_name(it), it->size );
        else
            fprintf(code,"%sstruct resource %s = {%d,%d,\"@%d\",%s__bytes,%d};\n",
                    ISCONSTANT, get_resource_name(it), it->n.i_name, type,
                    it->n.i_name, get_resource_name(it), it->size );
    }

    /* Print the resource table (NULL terminated) */

    fprintf(code,"\n%sstruct resource * %s%s_Table[] = {\n",
	    ISCONSTANT, ISCONSTANT, prefix);
    for (it=top;it;it=it->next)
        fprintf( code, "  &%s,\n", get_resource_name(it) );
    fprintf( code, "  0\n};\n" );

        /* Perform autoregistration */
        fprintf( code, 
                "#ifdef WINELIB\n"
                "static void DoIt() WINE_CONSTRUCTOR;\n"
                "static void DoIt()\n"
                "{\n"
                "\tLIBRES_RegisterResources(%s_Table);\n"
                "}\n\n"
                "#ifndef HAVE_WINE_CONSTRUCTOR\n"
                "void LIBWINE_Register_%s(){\n"
                "\tDoIt();\n"
                "}\n"
                "#endif\n"
                "#endif /*WINELIB*/\n"
                ,prefix,prefix);
}

gen_res* make_font(gen_res* res)
{
	fprintf(stderr,"Fonts not supported\n");
	return NULL;
}

gen_res* make_raw(gen_res* res)
{
	fprintf(stderr,"RCData not supported\n");
	return NULL;
}

gen_res* int_to_raw(int i,gen_res* res)
{
	fprintf(stderr,"IntToRaw not supported\n");
	return NULL;
}

/* translate "Hello,\\tworld!\\10" to "Hello,\tworld!\n" */
char *parse_c_string(char *in)
{
	char *out=xmalloc(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;
}
