/*
 *
 * 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 "parser.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"
	"   -w 16|32      Select win16 or win32 output\n";

/*might be overwritten by command line*/
char *prefix="_Resource";
int win32=1;
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;
	int optc,lose,ret,binary;
	lose=binary=0;
	while((optc=getopt(argc,argv,"bcdp:vo:w:"))!=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); break;
			case 'c':constant=1;break;
			case 'v':verbose=1;
					 setbuf(stderr,0);
					break;
			case 'o':set_out_file(optarg);break;
			case 'w':if(!strcmp(optarg,"16"))win32=0;
				 else if(!strcmp(optarg,"32"))win32=1;
				 else lose++;
				 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;
}

/* insert string into res, starting at start */
gen_res* insert_string(gen_res* res,unsigned char* string,int start,int terminating0)
{
	unsigned char* p;
	int lengthA = strlen(string) + (terminating0 ? 1 : 0);
	int length = (win32 ? 2 : 1) * lengthA; 
	while(res->size+length>res->space)res=grow(res);
	save_memcpy(res->res+start+length,res->res+start,res->size-start);
	p=res->res+start;
	while(lengthA--)
		if (win32)
		{
			put_WORD(p, *string++);
			p+=2;
		}
		else
			*p++=*string++;
	res->size+=length;
	return res;
}

/* insert string at offset 0, increase num_entries */
gen_res* insert_string_at_beginning(gen_res* res,char* entry,int terminating0)
{
	res=insert_string(res,entry,0,terminating0);
	res->num_entries++;
	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=win32?24: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 (win32: 18) */
int dialog_get_menu(gen_res* attr)
{
	return win32?18: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]||(win32&&attr->res[offs+1]))offs+=win32?2:1;
	offs+=win32?2:1;
	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]||(win32&&attr->res[offs+1]))offs+=win32?2:1;
	offs+=win32?2:1;
	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]||(win32&&attr->res[offs+1]))offs+=win32?2:1;
	offs+=win32?2:1;
	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_string(attr,cap,dialog_get_caption(attr),0);
}


/* 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_string(attr,font,offs,1);
}

gen_res* dialog_class(char* cap, gen_res*attr)
{
	return insert_string(attr,cap,dialog_get_class(attr),0);
}

gen_res* dialog_menu(char* cap, gen_res*attr)
{
	return insert_string(attr,cap,dialog_get_menu(attr),0);
}

/* 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*/
	if(win32)
	{
		if(style)s=(s|style->or)&style->and;
		put_DWORD(ret->res+0,s);
		/* FIXME */
		/* put_WORD(ret->res+4, exStyle); */
		put_WORD(ret->res+8,x);
		put_WORD(ret->res+10,y);
		put_WORD(ret->res+12,cx);
		put_WORD(ret->res+14,cy);
		put_WORD(ret->res+16,id);
		ret->size=24; /*empty strings, unused byte*/
	}
	else
	{
		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(win32) {
		if(get_WORD(cd->res+18)==0xffff)offs=20; /* one-character class */
		else {
			for(offs=18;get_WORD(cd->res+offs);offs+=2);
			offs+=2;
		}
	}
	else {
		if(cd->res[14]&0x80)offs=15; /* one-character class */
		else {
			for(offs=14;cd->res[offs];offs++);
			offs++;
		}
	}
	return insert_string(cd,label,offs,0);
}

/* 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)
{	gen_res* ret=new_res();
	if(win32)
	{
		WORD cl;
		put_DWORD(ret->res+0,style->or);
		/* FIXME */
		/* put_DWORD(ret->res+4,exstyle->or); */
		put_WORD(ret->res+8,x);
		put_WORD(ret->res+10,y);
		put_WORD(ret->res+12,cx);
		put_WORD(ret->res+14,cy);
		put_WORD(ret->res+16,id);
		ret->size=win32?24:17;
		ret=insert_string(ret,label,20,0);
		/* 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) {
			char ffff[2]={0xff, 0xff};
			ret=insert_bytes(ret,ffff,18,2);
			put_WORD(ret->res+20,cl);
		}
		else ret=insert_string(ret,class,18,0);
	}
	else
	{
		char cl;
		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_string(ret,label,15,0);
		/* 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_string(ret,class,14,0);
	}
	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)
{
	char zeros[4]={0,0,0,0};
	if(win32)
	{
		char ffff[2]={0xff, 0xff};
		put_DWORD(cd->res+0,get_DWORD(cd->res+0)|flags);
		cd=insert_bytes(cd,ffff,18,2);
		put_WORD(cd->res+20,type);
	}
	else
	{
		put_DWORD(cd->res+10,get_DWORD(cd->res+10)|flags);
		cd->res[14]=type;
	}
	/* WIN32: First control is on dword boundary */
	if(win32 && cd->size%4)
		cd=insert_bytes(cd,zeros,cd->size,4-cd->size%4);
	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)
{
	char zeros[4]={0,0,0,0};
	if(win32)
	{
		put_WORD(header->res+8, ctls->num_entries);
		header->type=dlg;
		put_WORD(header->res+10,x);
		put_WORD(header->res+12,y);
		put_WORD(header->res+14,cx);
		put_WORD(header->res+16,cy);
	}
	else
	{
		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);
	}
	/* WIN32: First control is on dword boundary */
	if(win32 && header->size%4)
		header=insert_bytes(header,zeros,header->size,4-header->size%4);
	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_string_at_beginning(res,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_string(res,name,0,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;
  unsigned char* q;

  if(!string_table) return t;
  for(ste=string_table; ste; ste=ste->next)
  {
    for(size=0,i=0; i<16; i++)
      size += (win32 ? 2 : 1) * (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;
    if (win32)
      for(p=res->res,i=0; i<16; i++)
        if((q=ste->strings[i])==NULL)
        {
	  put_WORD(p, 0);
	  p+=2;
	}
	else
	{
	  put_WORD(p, strlen(q));
	  p+=2;
	  while(*q)
	  {
	    put_WORD(p, *q++);
	    p+=2;
	  }
	}
    else
      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[]%s = {\n",
                 ISCONSTANT, get_resource_name(it),
		 win32?"\n__attribute__ ((aligned (4)))":"");
        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 names */

    if (win32)
        for(it=top;it;it=it->next)
        {
            int i;
	    char s_buffer[20], *s_name=s_buffer;
	    if(it->n_type) s_name=it->n.s_name;
	    else sprintf(s_name,"@%d",it->n.i_name);
	    fprintf( code, "static %sunsigned char %s__name[] = {\n",
		     ISCONSTANT, get_resource_name(it) );
	    for (i=0;*s_name;i++,s_name++)
	      {
		fprintf(code,"0x%02x, 0x00, ",*s_name);
		if ((i&3)==3)fputc('\n',code);
	      }
	    fprintf(code,"0x00, 0x00};\n\n");
	}

    /* 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(win32)
	{
            if(it->n_type)
                fprintf(code,"%sstruct resource %s = {0,%d,%s__name,%s__bytes,%d};\n",
			ISCONSTANT, get_resource_name(it), type, get_resource_name(it),
			get_resource_name(it), it->size );
	    else
	        fprintf(code,"%sstruct resource %s = {%d,%d,%s__name,%s__bytes,%d};\n",
			ISCONSTANT, get_resource_name(it), it->n.i_name, type,
			get_resource_name(it), get_resource_name(it), it->size );
	}
	else
	{
            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;
}
