/*
 *
 * 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;
	char* tmpc;
	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);
					 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;
			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;
}
