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

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <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"
        "   -h            Also generate a .h file\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;
static FILE *header = NULL, *code = NULL;

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 = 0, ret, binary = 0, output_header = 0;
        char output_name[256];

	while((optc=getopt(argc,argv,"bcdhp: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 'h':output_header=1; break;
			case 'p':prefix=strdup(optarg); break;
			case 'c':constant=1;break;
			case 'v':verbose=1;
					 setbuf(stderr,0);
					break;
			case 'o':sprintf(output_name,"%s.c",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 (output_name[0])
        {
            code = fopen( output_name, "w" );
            if (output_header)
            {
                output_name[strlen(output_name)-1] = 'h';
                header = fopen( output_name, "w" );
            }
        }
        if (!code) code = stdout;
	if(binary)
		ret=transform_binary_file();
	else
		ret=yyparse();
	if (header) fclose(header);
	fclose(code);
        if (ret) /* There was an error */
        {
            if (header) unlink( output_name );
            output_name[strlen(output_name)-1] = 'c';
            unlink( output_name );
        }
	return ret;
}

int transform_binary_file()
{
	int i,c;
	if (header) 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_id(short nr, gen_res*attr)
{
	char c_nr[2];
	int offs=dialog_get_menu(attr);
	attr->res[offs] = 0xff;
	if (win32) attr->res[offs+1] = 0xff;
	put_WORD(c_nr,nr);
	return insert_bytes(attr,c_nr,offs+(win32?2:1),2);
}
gen_res* dialog_menu_str(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();
	int s=WS_VISIBLE|WS_CHILD; /*default styles for any control*/
	if(style)s=(s|style->or)&style->and;
	if(win32)
	{
		WORD cl;
		put_DWORD(ret->res+0,s);
		/* 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=24;
		ret=insert_string(ret,label,20,0);
		/* is it a predefined class? */
		cl=0;
		if(!strcasecmp(class,"BUTTON"))cl=CT_BUTTON;
		if(!strcasecmp(class,"EDIT"))cl=CT_EDIT;
		if(!strcasecmp(class,"STATIC"))cl=CT_STATIC;
		if(!strcasecmp(class,"LISTBOX"))cl=CT_LISTBOX;
		if(!strcasecmp(class,"SCROLLBAR"))cl=CT_SCROLLBAR;
		if(!strcasecmp(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,s);
		ret->size=17;
		ret=insert_string(ret,label,15,0);
		/* is it a predefined class? */
		cl=0;
		if(!strcasecmp(class,"BUTTON"))cl=CT_BUTTON;
		if(!strcasecmp(class,"EDIT"))cl=CT_EDIT;
		if(!strcasecmp(class,"STATIC"))cl=CT_STATIC;
		if(!strcasecmp(class,"LISTBOX"))cl=CT_LISTBOX;
		if(!strcasecmp(class,"SCROLLBAR"))cl=CT_SCROLLBAR;
		if(!strcasecmp(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)
{
    if (win32)
    {
	put_WORD(whf->res+8,x);
	put_WORD(whf->res+10,y);
	put_WORD(whf->res+16,id);
    }
    else
    {
	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)
{
	char zeros[4]={0,0,0,0};
	/* WIN32: Control is on dword boundary */
	if(win32 && ctl->size%4)
		ctl=insert_bytes(ctl,zeros,ctl->size,4-ctl->size%4);
	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<0)
	{
	  perror(name);
	  exit(1);
	}
	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)
  {
    int i;
    str_tbl_elm* new=xmalloc(sizeof(str_tbl_elm));
    for(i=0; i<16; i++) new->strings[i] = NULL;
    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);

    /* Generate the header */

    if (header)
    {
        fprintf( header,
                 "/*\n"
                 " * This file is automatically generated. Do not edit!\n"
                 " */\n\n"
                 "#ifndef __%s_H\n"
                 "#define __%s_H\n\n"
                 "struct resource;\n\n",
                 prefix, prefix );

        /* 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\n",
                 ISCONSTANT, ISCONSTANT, prefix );
        fprintf( header, "#endif  /* __%s_H */\n", prefix );
    }

    /* Print the resources bytes */

    fprintf( code, "/*\n"
                   " * This file is automatically generated. Do not edit!\n"
                   " */\n\n"
                   "struct resource {\n"
                   "\tint id;\n"
                   "\tint type;\n"
                   "\tconst char *name;\n"
                   "\tconst unsigned char* bytes;\n"
                   "\tunsigned size;\n"
                   "};\n\n" );

    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\n\n" );

    /* Perform autoregistration */
    fprintf( code, 
             "#ifndef __WINE__\n"
             "#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)\n"
             "static void DoIt(void) __attribute__((constructor));\n"
             "#else\n"
             "static void DoIt(void);\n"
             "void LIBWINE_Register_%s(void) { DoIt(); }\n"
             "#endif\n"
             "static void DoIt(void)\n"
             "{\n"
             "\textern void LIBRES_RegisterResources(const struct resource* const * Res);\n"
             "\tLIBRES_RegisterResources(%s_Table);\n"
             "}\n\n"
             "#endif /* __WINE__ */\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;
}
