3 * Copyright Martin von Loewis, 1994
11 #include <sys/fcntl.h>
12 #include <sys/types.h>
18 char usage
[]="winerc -bdvc -p prefix -o outfile < infile \n"
19 " -b Create a C array from a binary .res file\n"
20 " -c Add 'const' prefix to C constants\n"
21 " -d Output debugging information\n"
22 " -p prefix Give a prefix for the generated names\n"
23 " -v Show each resource as it is processed\n"
24 " -o file Output to file.c and file.h\n"
25 " -w 16|32 Select win16 or win32 output\n";
27 /*might be overwritten by command line*/
28 char *prefix
="_Resource";
33 char hname
[256],sname
[256];
35 int transform_binary_file(void);
38 static void *xmalloc (size_t size
)
42 res
= malloc (size
? size
: 1);
45 fprintf (stderr
, "Virtual memory exhausted.\n");
52 int main(int argc
,char *argv
[])
56 int optc
,lose
,ret
,binary
;
58 while((optc
=getopt(argc
,argv
,"bcdp:vo:w:"))!=EOF
)
61 /* bison will print state transitions on stderr */
68 case 'p':prefix
=strdup(optarg
); break;
69 case 'c':constant
=1;break;
73 case 'o':set_out_file(optarg
);break;
74 case 'w':if(!strcmp(optarg
,"16"))win32
=0;
75 else if(!strcmp(optarg
,"32"))win32
=1;
78 default: lose
++;break;
80 if(lose
)return fprintf(stderr
,usage
),1;
81 if(!header
)header
=stdout
;
84 ret
=transform_binary_file();
92 void set_out_file(char *prefix
)
94 sprintf(sname
,"%s.c",prefix
);
95 code
=fopen(sname
,"w");
96 sprintf(hname
,"%s.h",prefix
);
97 header
=fopen(hname
,"w");
100 int transform_binary_file()
103 fprintf(header
,"#define APPLICATION_HAS_RESOURCES 1\n");
104 fprintf(code
,"char _Application_resources[]={");
109 if(i
%16==0)fputc('\n',code
);
110 fprintf(code
,"%3d,",c
);
112 fprintf(code
,"\n 0};\nint _Application_resources_size=%d;\n",i
);
116 /* SunOS' memcpy is wrong for overlapping arrays */
117 char *save_memcpy(char *d
,char* s
,int l
)
120 for(;l
;l
--)*d
++=*s
++;
122 for(d
+=l
-1,s
+=l
-1;l
;l
--)*d
--=*s
--;
126 /*allow unaligned access*/
127 void put_WORD(unsigned char* p
,WORD w
)
133 void put_DWORD(unsigned char* p
,DWORD d
)
135 put_WORD(p
,d
&0xFFFF);
139 WORD
get_WORD(unsigned char* p
)
141 return *p
|(*(p
+1)<<8);
144 DWORD
get_DWORD(unsigned char* p
)
146 return get_WORD(p
)|(get_WORD(p
+2)<<16);
150 /*create a new gen_res, initial size 100*/
152 { gen_res
* ret
=xmalloc(sizeof(gen_res
)+100);
154 for(i
=0;i
<sizeof(gen_res
)+100;i
++)*((char*)ret
+i
)='\0';
163 gen_res
* grow(gen_res
* res
)
165 res
=realloc(res
,sizeof(gen_res
)+2*res
->space
);
167 fprintf(stderr
,"Out of memory\n"),exit(1);
168 if(!res
->g_prev
)g_start
=res
;
169 else res
->g_prev
->g_next
=res
;
170 if(res
->g_next
)res
->g_next
->g_prev
=res
;
171 res
->space
=2*res
->space
;
176 /* insert bytes at offset 0, increase num_entries */
177 gen_res
* insert_at_beginning(gen_res
* res
,char* entry
,int size
)
179 while(res
->size
+size
>res
->space
)res
=grow(res
);
180 save_memcpy(res
->res
+size
,res
->res
,res
->size
);
181 save_memcpy(res
->res
,entry
,size
);
187 /* insert length characters from bytes into res, starting at start */
188 gen_res
* insert_bytes(gen_res
* res
,char* bytes
,int start
,int length
)
190 while(res
->size
+length
>res
->space
)res
=grow(res
);
191 save_memcpy(res
->res
+start
+length
,res
->res
+start
,res
->size
-start
);
192 save_memcpy(res
->res
+start
,bytes
,length
);
197 /* insert string into res, starting at start */
198 gen_res
* insert_string(gen_res
* res
,unsigned char* string
,int start
,int terminating0
)
201 int lengthA
= strlen(string
) + (terminating0
? 1 : 0);
202 int length
= (win32
? 2 : 1) * lengthA
;
203 while(res
->size
+length
>res
->space
)res
=grow(res
);
204 save_memcpy(res
->res
+start
+length
,res
->res
+start
,res
->size
-start
);
209 put_WORD(p
, *string
++);
218 /* insert string at offset 0, increase num_entries */
219 gen_res
* insert_string_at_beginning(gen_res
* res
,char* entry
,int terminating0
)
221 res
=insert_string(res
,entry
,0,terminating0
);
226 /*delete len bytes from res, starting at start*/
227 gen_res
* delete_bytes(gen_res
* res
,int start
,int len
)
229 save_memcpy(res
->res
+start
,res
->res
+start
+len
,res
->size
-start
-len
);
234 /*create a new style*/
235 rc_style
*new_style()
237 rc_style
*ret
=xmalloc(sizeof(rc_style
));
238 /*initially, no bits have to be reset*/
240 /*initially, no bits are set*/
241 ret
->or=WS_CHILD
| WS_VISIBLE
;
245 /* entries are inserted at the beginning, starting from the last one */
246 gen_res
* add_accelerator(int ev
, int id
, int flags
, gen_res
* prev
)
249 if(prev
->num_entries
==0)flags
|=0x80; /* last entry */
250 accel_entry
[0]=flags
;
251 put_WORD(accel_entry
+1,ev
);
252 put_WORD(accel_entry
+3,id
);
253 return insert_at_beginning(prev
,accel_entry
,5);
257 /* create an integer from the event, taking things as "^c" into account
258 add this as new entry */
259 gen_res
* add_string_accelerator(char *ev
, int id
, int flags
, gen_res
* prev
)
266 return add_accelerator(event
,id
,flags
,prev
);
269 /*is there a difference between ASCII and VIRTKEY accelerators? */
271 gen_res
* add_ascii_accelerator(int ev
, int id
, int flags
, gen_res
* prev
)
273 return add_accelerator(ev
,id
,flags
,prev
);
276 gen_res
* add_vk_accelerator(int ev
, int id
, int flags
, gen_res
* prev
)
278 return add_accelerator(ev
,id
,flags
,prev
);
281 /* create a new dialog header, set all items to 0 */
282 gen_res
* new_dialog()
283 { gen_res
* ret
=new_res();
284 ret
->size
=win32
?24:16; /*all strings "\0", no font*/
288 /* the STYLE option was specified */
289 gen_res
* dialog_style(rc_style
* style
, gen_res
* attr
)
291 /* default dialog styles? Do we need style->and? */
292 /* DS_SETFONT might have been specified before */
293 put_DWORD(attr
->res
,get_DWORD(attr
->res
)|style
->or);
297 /* menu name is at offset 13 (win32: 18) */
298 int dialog_get_menu(gen_res
* attr
)
303 /* the class is after the menu name */
304 int dialog_get_class(gen_res
* attr
)
306 int offs
=dialog_get_menu(attr
);
307 while(attr
->res
[offs
]||(win32
&&attr
->res
[offs
+1]))offs
+=win32
?2:1;
312 /* the caption is after the class */
313 int dialog_get_caption(gen_res
* attr
)
315 int offs
=dialog_get_class(attr
);
316 while(attr
->res
[offs
]||(win32
&&attr
->res
[offs
+1]))offs
+=win32
?2:1;
321 /* the fontsize, if present, is after the caption, followed by the font name */
322 int dialog_get_fontsize(gen_res
* attr
)
324 int offs
=dialog_get_caption(attr
);
325 while(attr
->res
[offs
]||(win32
&&attr
->res
[offs
+1]))offs
+=win32
?2:1;
331 /* the CAPTION option was specified */
332 gen_res
* dialog_caption(char* cap
, gen_res
*attr
)
334 /* we don't need the terminating 0 as it's already there */
335 return insert_string(attr
,cap
,dialog_get_caption(attr
),0);
339 /* the FONT option was specified, set the DS_SETFONT flag */
340 gen_res
* dialog_font(short size
,char* font
,gen_res
*attr
)
343 int offs
=dialog_get_fontsize(attr
);
344 put_DWORD(attr
->res
,get_DWORD(attr
->res
)|DS_SETFONT
);
345 put_WORD(c_size
,size
);
346 attr
=insert_bytes(attr
,c_size
,offs
,2);
348 /* as there is no font name by default, copy the '\0' */
349 return insert_string(attr
,font
,offs
,1);
352 gen_res
* dialog_class(char* cap
, gen_res
*attr
)
354 return insert_string(attr
,cap
,dialog_get_class(attr
),0);
357 gen_res
* dialog_menu_id(short nr
, gen_res
*attr
)
360 int offs
=dialog_get_menu(attr
);
361 attr
->res
[offs
] = 0xff;
362 if (win32
) attr
->res
[offs
+1] = 0xff;
364 return insert_bytes(attr
,c_nr
,offs
+(win32
?2:1),2);
366 gen_res
* dialog_menu_str(char* cap
, gen_res
*attr
)
368 return insert_string(attr
,cap
,dialog_get_menu(attr
),0);
371 /* set the dialogs id, position, extent, and style */
372 gen_res
* create_control_desc(int id
,int x
,int y
,int cx
, int cy
,rc_style
*style
)
373 { gen_res
* ret
=new_res();
374 int s
=WS_VISIBLE
|WS_CHILD
; /*defaults styles for any control*/
377 if(style
)s
=(s
|style
->or)&style
->and;
378 put_DWORD(ret
->res
+0,s
);
380 /* put_WORD(ret->res+4, exStyle); */
381 put_WORD(ret
->res
+8,x
);
382 put_WORD(ret
->res
+10,y
);
383 put_WORD(ret
->res
+12,cx
);
384 put_WORD(ret
->res
+14,cy
);
385 put_WORD(ret
->res
+16,id
);
386 ret
->size
=24; /*empty strings, unused byte*/
390 put_WORD(ret
->res
+0,x
);
391 put_WORD(ret
->res
+2,y
);
392 put_WORD(ret
->res
+4,cx
);
393 put_WORD(ret
->res
+6,cy
);
394 put_WORD(ret
->res
+8,id
);
395 if(style
)s
=(s
|style
->or)&style
->and;
396 put_DWORD(ret
->res
+10,s
);
397 ret
->size
=17; /*empty strings, unused byte*/
402 /* insert the control's label */
403 gen_res
* label_control_desc(char* label
,gen_res
* cd
)
407 if(get_WORD(cd
->res
+18)==0xffff)offs
=20; /* one-character class */
409 for(offs
=18;get_WORD(cd
->res
+offs
);offs
+=2);
414 if(cd
->res
[14]&0x80)offs
=15; /* one-character class */
416 for(offs
=14;cd
->res
[offs
];offs
++);
420 return insert_string(cd
,label
,offs
,0);
423 /* a CONTROL was specified */
424 gen_res
* create_generic_control(char* label
,int id
,char* class,
425 rc_style
*style
,int x
,int y
,int cx
,int cy
)
426 { gen_res
* ret
=new_res();
427 int s
=WS_VISIBLE
|WS_CHILD
; /*default styles for any control*/
428 if(style
)s
=(s
|style
->or)&style
->and;
432 put_DWORD(ret
->res
+0,s
);
434 /* put_DWORD(ret->res+4,exstyle->or); */
435 put_WORD(ret
->res
+8,x
);
436 put_WORD(ret
->res
+10,y
);
437 put_WORD(ret
->res
+12,cx
);
438 put_WORD(ret
->res
+14,cy
);
439 put_WORD(ret
->res
+16,id
);
441 ret
=insert_string(ret
,label
,20,0);
442 /* is it a predefined class? */
444 if(!strcasecmp(class,"BUTTON"))cl
=CT_BUTTON
;
445 if(!strcasecmp(class,"EDIT"))cl
=CT_EDIT
;
446 if(!strcasecmp(class,"STATIC"))cl
=CT_STATIC
;
447 if(!strcasecmp(class,"LISTBOX"))cl
=CT_LISTBOX
;
448 if(!strcasecmp(class,"SCROLLBAR"))cl
=CT_SCROLLBAR
;
449 if(!strcasecmp(class,"COMBOBOX"))cl
=CT_COMBOBOX
;
451 char ffff
[2]={0xff, 0xff};
452 ret
=insert_bytes(ret
,ffff
,18,2);
453 put_WORD(ret
->res
+20,cl
);
455 else ret
=insert_string(ret
,class,18,0);
460 put_WORD(ret
->res
+0,x
);
461 put_WORD(ret
->res
+2,y
);
462 put_WORD(ret
->res
+4,cx
);
463 put_WORD(ret
->res
+6,cy
);
464 put_WORD(ret
->res
+8,id
);
465 put_DWORD(ret
->res
+10,s
);
467 ret
=insert_string(ret
,label
,15,0);
468 /* is it a predefined class? */
470 if(!strcasecmp(class,"BUTTON"))cl
=CT_BUTTON
;
471 if(!strcasecmp(class,"EDIT"))cl
=CT_EDIT
;
472 if(!strcasecmp(class,"STATIC"))cl
=CT_STATIC
;
473 if(!strcasecmp(class,"LISTBOX"))cl
=CT_LISTBOX
;
474 if(!strcasecmp(class,"SCROLLBAR"))cl
=CT_SCROLLBAR
;
475 if(!strcasecmp(class,"COMBOBOX"))cl
=CT_COMBOBOX
;
476 if(cl
)ret
->res
[14]=cl
;
477 else ret
=insert_string(ret
,class,14,0);
482 /* insert cd into rest, set the type, add flags */
483 gen_res
* add_control(int type
,int flags
,gen_res
*cd
,gen_res
* rest
)
485 char zeros
[4]={0,0,0,0};
488 char ffff
[2]={0xff, 0xff};
489 put_DWORD(cd
->res
+0,get_DWORD(cd
->res
+0)|flags
);
490 cd
=insert_bytes(cd
,ffff
,18,2);
491 put_WORD(cd
->res
+20,type
);
495 put_DWORD(cd
->res
+10,get_DWORD(cd
->res
+10)|flags
);
498 /* WIN32: First control is on dword boundary */
499 if(win32
&& cd
->size
%4)
500 cd
=insert_bytes(cd
,zeros
,cd
->size
,4-cd
->size
%4);
501 return insert_at_beginning(rest
,cd
->res
,cd
->size
);
504 /* an ICON control was specified, whf contains width, height, and flags */
505 gen_res
* add_icon(char* name
,int id
,int x
,int y
,gen_res
* whf
,gen_res
* rest
)
509 put_WORD(whf
->res
+8,x
);
510 put_WORD(whf
->res
+10,y
);
511 put_WORD(whf
->res
+16,id
);
515 put_WORD(whf
->res
+0,x
);
516 put_WORD(whf
->res
+2,y
);
517 put_WORD(whf
->res
+8,id
);
519 whf
=label_control_desc(name
,whf
);
520 return add_control(CT_STATIC
,SS_ICON
,whf
,rest
);
523 /* insert the generic control into rest */
524 gen_res
* add_generic_control(gen_res
* ctl
, gen_res
* rest
)
526 char zeros
[4]={0,0,0,0};
527 /* WIN32: Control is on dword boundary */
528 if(win32
&& ctl
->size
%4)
529 ctl
=insert_bytes(ctl
,zeros
,ctl
->size
,4-ctl
->size
%4);
530 return insert_at_beginning(rest
,ctl
->res
,ctl
->size
);
533 /* create a dialog resource by inserting the header into the controls.
534 Set position and extent */
535 gen_res
* make_dialog(gen_res
* header
,int x
,int y
,int cx
,int cy
,gen_res
* ctls
)
537 char zeros
[4]={0,0,0,0};
540 put_WORD(header
->res
+8, ctls
->num_entries
);
542 put_WORD(header
->res
+10,x
);
543 put_WORD(header
->res
+12,y
);
544 put_WORD(header
->res
+14,cx
);
545 put_WORD(header
->res
+16,cy
);
549 header
->res
[4]=ctls
->num_entries
;
551 put_WORD(header
->res
+5,x
);
552 put_WORD(header
->res
+7,y
);
553 put_WORD(header
->res
+9,cx
);
554 put_WORD(header
->res
+11,cy
);
556 /* WIN32: First control is on dword boundary */
557 if(win32
&& header
->size
%4)
558 header
=insert_bytes(header
,zeros
,header
->size
,4-header
->size
%4);
559 return insert_bytes(header
,ctls
->res
,header
->size
,ctls
->size
);
562 /* create {0x15,0x16,0xFF} from '15 16 FF' */
563 gen_res
*hex_to_raw(char *hex
, gen_res
*rest
)
567 for(i
=0;*hex
!='\'';i
++)r2
[i
]=strtoul(hex
,&hex
,16);
568 return insert_bytes(rest
,r2
,0,i
);
571 /* create a bitmap resource */
572 gen_res
*make_bitmap(gen_res
* res
)
574 res
=delete_bytes(res
,0,14); /* skip bitmap file header*/
579 gen_res
*make_icon(gen_res
* res
)
585 gen_res
*make_cursor(gen_res
* res
)
591 /* load resource bytes from the file name */
592 gen_res
*load_file(char* name
)
596 int f
=open(name
,O_RDONLY
);
604 while(res
->space
<st
.st_size
)res
=grow(res
);
605 read(f
,res
->res
,st
.st_size
);
606 res
->size
=st
.st_size
;
611 /* insert a normal menu item into res, starting from the last item */
612 gen_res
*add_menuitem(char* name
,int id
,int flags
,gen_res
*res
)
615 if(res
->num_entries
==0)flags
|=MF_END
;
616 put_WORD(item
,flags
);
618 res
=insert_string_at_beginning(res
,name
,1);
619 res
=insert_bytes(res
,item
,0,4);
623 /* insert a popup item into res */
624 gen_res
*add_popup(char *name
,short flags
, gen_res
* body
, gen_res
*res
)
628 if(res
->num_entries
==0)flags
|=MF_END
;
629 put_WORD(c_flags
,flags
);
630 res
=insert_at_beginning(res
,body
->res
,body
->size
);
631 res
=insert_string(res
,name
,0,1);
632 res
=insert_bytes(res
,c_flags
,0,2);
636 /* prefix the menu header into res */
637 gen_res
*make_menu(gen_res
* res
)
639 static char header
[4]={0,0,0,0};
640 res
=insert_at_beginning(res
,header
,4);
645 /* link top-level resources */
646 gen_res
*add_resource(gen_res
* first
,gen_res
*rest
)
657 typedef struct str_tbl_elm
{
659 struct str_tbl_elm
*next
;
663 str_tbl_elm
* string_table
=NULL
; /* sorted by group */
665 void add_str_tbl_elm(int id
,char* str
)
670 str_tbl_elm
** elm
=&string_table
;
671 while(*elm
&& (*elm
)->group
<group
) elm
=&(*elm
)->next
;
672 if(!*elm
|| (*elm
)->group
!=group
)
675 str_tbl_elm
* new=xmalloc(sizeof(str_tbl_elm
));
676 for(i
=0; i
<16; i
++) new->strings
[i
] = NULL
;
681 (*elm
)->strings
[idx
]=str
;
684 gen_res
* add_string_table(gen_res
* t
)
692 if(!string_table
) return t
;
693 for(ste
=string_table
; ste
; ste
=ste
->next
)
695 for(size
=0,i
=0; i
<16; i
++)
696 size
+= (win32
? 2 : 1) * (ste
->strings
[i
] ? strlen(ste
->strings
[i
])+1 : 1);
698 while(res
->space
<size
)res
=grow(res
);
700 res
->n
.i_name
=ste
->group
;
704 for(p
=res
->res
,i
=0; i
<16; i
++)
705 if((q
=ste
->strings
[i
])==NULL
)
712 put_WORD(p
, strlen(q
));
721 for(p
=res
->res
,i
=0; i
<16; i
++)
722 if((q
=ste
->strings
[i
])==NULL
)
727 while(*q
) *p
++ = *q
++;
729 t
=add_resource(res
,t
);
734 char *get_typename(gen_res
* t
)
737 case acc
:return "ACCELERATOR";
738 case bmp
:return "BITMAP";
739 case cur
:return "CURSOR";
740 case dlg
:return "DIALOG";
741 case fnt
:return "FONT";
742 case ico
:return "ICON";
743 case men
:return "MENU";
744 case rdt
:return "RCDATA";
745 case str
:return "STRINGTABLE";
746 default: return "UNKNOWN";
750 /* create strings like _Sysres_DIALOG_2 */
751 char *get_resource_name(gen_res
*it
)
753 static char buf
[1000];
755 sprintf(buf
,"%s_%s_%s",prefix
,get_typename(it
),it
->n
.s_name
);
757 sprintf(buf
,"%s_%s_%d",prefix
,get_typename(it
),it
->n
.i_name
);
761 #define ISCONSTANT (constant ? "const " : "")
763 /* create the final output */
764 void create_output(gen_res
* top
)
768 top
=add_string_table(top
);
770 fprintf( header
, "/* %s\n"
771 " * This file is automatically generated. Do not edit!\n"
773 "#include \"resource.h\"\n", hname
);
775 /* Declare the resources */
777 for (it
=top
;it
;it
=it
->next
)
778 fprintf( header
,"extern %sstruct resource %s;\n",
779 ISCONSTANT
, get_resource_name(it
) );
780 fprintf( header
,"\nextern %sstruct resource * %s%s_Table[];\n",
781 ISCONSTANT
, ISCONSTANT
, prefix
);
783 /* Print the resources bytes */
785 fprintf( code
, "/* %s\n"
786 " * This file is automatically generated. Do not edit!\n"
788 "#include \"%s\"\n", sname
, hname
);
790 for(it
=top
;it
;it
=it
->next
)
793 fprintf( code
, "static %sunsigned char %s__bytes[]%s = {\n",
794 ISCONSTANT
, get_resource_name(it
),
795 win32
?"\n__attribute__ ((aligned (4)))":"");
796 for (i
=0;i
<it
->size
-1;i
++)
798 fprintf(code
,"0x%02x, ",it
->res
[i
]);
799 if ((i
&7)==7)fputc('\n',code
);
801 fprintf(code
,"0x%02x };\n\n",it
->res
[i
]);
804 /* Print the resources names */
807 for(it
=top
;it
;it
=it
->next
)
810 char s_buffer
[20], *s_name
=s_buffer
;
811 if(it
->n_type
) s_name
=it
->n
.s_name
;
812 else sprintf(s_name
,"@%d",it
->n
.i_name
);
813 fprintf( code
, "static %sunsigned char %s__name[] = {\n",
814 ISCONSTANT
, get_resource_name(it
) );
815 for (i
=0;*s_name
;i
++,s_name
++)
817 fprintf(code
,"0x%02x, 0x00, ",*s_name
);
818 if ((i
&3)==3)fputc('\n',code
);
820 fprintf(code
,"0x00, 0x00};\n\n");
823 /* Print the resources */
824 for (it
=top
;it
;it
=it
->next
)
829 case acc
:type
=(int)RT_ACCELERATOR
;break;
830 case bmp
:type
=(int)RT_BITMAP
;break;
831 case cur
:type
=(int)RT_CURSOR
;break;
832 case dlg
:type
=(int)RT_DIALOG
;break;
833 case fnt
:type
=(int)RT_FONT
;break;
834 case ico
:type
=(int)RT_ICON
;break;
835 case men
:type
=(int)RT_MENU
;break;
836 case rdt
:type
=(int)RT_RCDATA
;break;
837 case str
:type
=(int)RT_STRING
;break;
838 default:fprintf(stderr
,"Unknown restype\n");type
=-1;break;
843 fprintf(code
,"%sstruct resource %s = {0,%d,%s__name,%s__bytes,%d};\n",
844 ISCONSTANT
, get_resource_name(it
), type
, get_resource_name(it
),
845 get_resource_name(it
), it
->size
);
847 fprintf(code
,"%sstruct resource %s = {%d,%d,%s__name,%s__bytes,%d};\n",
848 ISCONSTANT
, get_resource_name(it
), it
->n
.i_name
, type
,
849 get_resource_name(it
), get_resource_name(it
), it
->size
);
854 fprintf(code
,"%sstruct resource %s = {0,%d,\"%s\",%s__bytes,%d};\n",
855 ISCONSTANT
, get_resource_name(it
), type
, it
->n
.s_name
,
856 get_resource_name(it
), it
->size
);
858 fprintf(code
,"%sstruct resource %s = {%d,%d,\"@%d\",%s__bytes,%d};\n",
859 ISCONSTANT
, get_resource_name(it
), it
->n
.i_name
, type
,
860 it
->n
.i_name
, get_resource_name(it
), it
->size
);
864 /* Print the resource table (NULL terminated) */
866 fprintf(code
,"\n%sstruct resource * %s%s_Table[] = {\n",
867 ISCONSTANT
, ISCONSTANT
, prefix
);
868 for (it
=top
;it
;it
=it
->next
)
869 fprintf( code
, " &%s,\n", get_resource_name(it
) );
870 fprintf( code
, " 0\n};\n" );
872 /* Perform autoregistration */
875 "static void DoIt() WINE_CONSTRUCTOR;\n"
876 "static void DoIt()\n"
878 "\tLIBRES_RegisterResources(%s_Table);\n"
880 "#ifndef HAVE_WINE_CONSTRUCTOR\n"
881 "void LIBWINE_Register_%s(){\n"
885 "#endif /*WINELIB*/\n"
889 gen_res
* make_font(gen_res
* res
)
891 fprintf(stderr
,"Fonts not supported\n");
895 gen_res
* make_raw(gen_res
* res
)
897 fprintf(stderr
,"RCData not supported\n");
901 gen_res
* int_to_raw(int i
,gen_res
* res
)
903 fprintf(stderr
,"IntToRaw not supported\n");
907 /* translate "Hello,\\tworld!\\10" to "Hello,\tworld!\n" */
908 char *parse_c_string(char *in
)
910 char *out
=xmalloc(strlen(in
)-1);
913 for(it
=out
,in
++;*in
;in
++)
916 {case 't':*it
++='\t';break;
917 case 'r':*it
++='\r';break;
918 case 'n':*it
++='\n';break;
919 case 'a':*it
++='\a';break;
921 memset(tmp
,0,5);/*make sure it doesn't use more than 4 chars*/
923 *it
++=strtoul(tmp
,&tend
,0);
926 case '1':case '2':case '3':case '4':case '5':
927 case '6':case '7':case '8':case '9':
930 *it
++=strtoul(tmp
,&tend
,10);
936 *it
++=strtoul(tmp
,&tend
,16);