3 * Copyright Martin von Loewis, 1994
12 #include <sys/types.h>
16 #include "wine/winuser16.h"
19 char usage
[]="winerc -bdvc -p prefix -o outfile < infile \n"
20 " -b Create a C array from a binary .res file\n"
21 " -c Add 'const' prefix to C constants\n"
22 " -d Output debugging information\n"
23 " -h Also generate a .h file\n"
24 " -p prefix Give a prefix for the generated names\n"
25 " -v Show each resource as it is processed\n"
26 " -o file Output to file.c and file.h\n"
27 " -w 16|32 Select win16 or win32 output\n";
29 /*might be overwritten by command line*/
30 char *prefix
="_Resource";
34 static FILE *header
= NULL
, *code
= NULL
;
36 int transform_binary_file(void);
39 static void *xmalloc (size_t size
)
43 res
= malloc (size
? size
: 1);
46 fprintf (stderr
, "Virtual memory exhausted.\n");
53 int main(int argc
,char *argv
[])
57 int optc
,lose
= 0, ret
, binary
= 0, output_header
= 0;
58 char output_name
[256];
60 while((optc
=getopt(argc
,argv
,"bcdhp:vo:w:"))!=EOF
)
63 /* bison will print state transitions on stderr */
70 case 'h':output_header
=1; break;
71 case 'p':prefix
=strdup(optarg
); break;
72 case 'c':constant
=1;break;
76 case 'o':sprintf(output_name
,"%s.c",optarg
); break;
77 case 'w':if(!strcmp(optarg
,"16"))win32
=0;
78 else if(!strcmp(optarg
,"32"))win32
=1;
81 default: lose
++;break;
83 if(lose
)return fprintf(stderr
,usage
),1;
87 code
= fopen( output_name
, "w" );
90 output_name
[strlen(output_name
)-1] = 'h';
91 header
= fopen( output_name
, "w" );
94 if (!code
) code
= stdout
;
96 ret
=transform_binary_file();
99 if (header
) fclose(header
);
101 if (ret
) /* There was an error */
103 if (header
) unlink( output_name
);
104 output_name
[strlen(output_name
)-1] = 'c';
105 unlink( output_name
);
110 int transform_binary_file()
113 if (header
) fprintf(header
,"#define APPLICATION_HAS_RESOURCES 1\n");
114 fprintf(code
,"char _Application_resources[]={");
119 if(i
%16==0)fputc('\n',code
);
120 fprintf(code
,"%3d,",c
);
122 fprintf(code
,"\n 0};\nint _Application_resources_size=%d;\n",i
);
126 /* SunOS' memcpy is wrong for overlapping arrays */
127 char *save_memcpy(char *d
,char* s
,int l
)
130 for(;l
;l
--)*d
++=*s
++;
132 for(d
+=l
-1,s
+=l
-1;l
;l
--)*d
--=*s
--;
136 /*allow unaligned access*/
137 void put_WORD(unsigned char* p
,WORD w
)
143 void put_DWORD(unsigned char* p
,DWORD d
)
145 put_WORD(p
,d
&0xFFFF);
149 WORD
get_WORD(unsigned char* p
)
151 return *p
|(*(p
+1)<<8);
154 DWORD
get_DWORD(unsigned char* p
)
156 return get_WORD(p
)|(get_WORD(p
+2)<<16);
160 /*create a new gen_res, initial size 100*/
162 { gen_res
* ret
=xmalloc(sizeof(gen_res
)+100);
164 for(i
=0;i
<sizeof(gen_res
)+100;i
++)*((char*)ret
+i
)='\0';
173 gen_res
* grow(gen_res
* res
)
175 res
=realloc(res
,sizeof(gen_res
)+2*res
->space
);
177 fprintf(stderr
,"Out of memory\n"),exit(1);
178 if(!res
->g_prev
)g_start
=res
;
179 else res
->g_prev
->g_next
=res
;
180 if(res
->g_next
)res
->g_next
->g_prev
=res
;
181 res
->space
=2*res
->space
;
186 /* insert bytes at offset 0, increase num_entries */
187 gen_res
* insert_at_beginning(gen_res
* res
,char* entry
,int size
)
189 while(res
->size
+size
>res
->space
)res
=grow(res
);
190 save_memcpy(res
->res
+size
,res
->res
,res
->size
);
191 save_memcpy(res
->res
,entry
,size
);
197 /* insert length characters from bytes into res, starting at start */
198 gen_res
* insert_bytes(gen_res
* res
,char* bytes
,int start
,int length
)
200 while(res
->size
+length
>res
->space
)res
=grow(res
);
201 save_memcpy(res
->res
+start
+length
,res
->res
+start
,res
->size
-start
);
202 save_memcpy(res
->res
+start
,bytes
,length
);
207 /* insert string into res, starting at start */
208 gen_res
* insert_string(gen_res
* res
,unsigned char* string
,int start
,int terminating0
)
211 int lengthA
= strlen(string
) + (terminating0
? 1 : 0);
212 int length
= (win32
? 2 : 1) * lengthA
;
213 while(res
->size
+length
>res
->space
)res
=grow(res
);
214 save_memcpy(res
->res
+start
+length
,res
->res
+start
,res
->size
-start
);
219 put_WORD(p
, *string
++);
228 /* insert string at offset 0, increase num_entries */
229 gen_res
* insert_string_at_beginning(gen_res
* res
,char* entry
,int terminating0
)
231 res
=insert_string(res
,entry
,0,terminating0
);
236 /*delete len bytes from res, starting at start*/
237 gen_res
* delete_bytes(gen_res
* res
,int start
,int len
)
239 save_memcpy(res
->res
+start
,res
->res
+start
+len
,res
->size
-start
-len
);
244 /*create a new style*/
245 rc_style
*new_style()
247 rc_style
*ret
=xmalloc(sizeof(rc_style
));
248 /*initially, no bits have to be reset*/
250 /*initially, no bits are set*/
251 ret
->or=WS_CHILD
| WS_VISIBLE
;
255 /* entries are inserted at the beginning, starting from the last one */
256 gen_res
* add_accelerator(int ev
, int id
, int flags
, gen_res
* prev
)
259 if(prev
->num_entries
==0)flags
|=0x80; /* last entry */
260 accel_entry
[0]=flags
;
261 put_WORD(accel_entry
+1,ev
);
262 put_WORD(accel_entry
+3,id
);
263 return insert_at_beginning(prev
,accel_entry
,5);
267 /* create an integer from the event, taking things as "^c" into account
268 add this as new entry */
269 gen_res
* add_string_accelerator(char *ev
, int id
, int flags
, gen_res
* prev
)
276 return add_accelerator(event
,id
,flags
,prev
);
279 /*is there a difference between ASCII and VIRTKEY accelerators? */
281 gen_res
* add_ascii_accelerator(int ev
, int id
, int flags
, gen_res
* prev
)
283 return add_accelerator(ev
,id
,flags
,prev
);
286 gen_res
* add_vk_accelerator(int ev
, int id
, int flags
, gen_res
* prev
)
288 return add_accelerator(ev
,id
,flags
,prev
);
291 /* create a new dialog header, set all items to 0 */
292 gen_res
* new_dialog()
293 { gen_res
* ret
=new_res();
294 ret
->size
=win32
?24:16; /*all strings "\0", no font*/
298 /* the STYLE option was specified */
299 gen_res
* dialog_style(rc_style
* style
, gen_res
* attr
)
301 /* default dialog styles? Do we need style->and? */
302 /* DS_SETFONT might have been specified before */
303 put_DWORD(attr
->res
,get_DWORD(attr
->res
)|style
->or);
307 /* menu name is at offset 13 (win32: 18) */
308 int dialog_get_menu(gen_res
* attr
)
313 /* the class is after the menu name */
314 int dialog_get_class(gen_res
* attr
)
316 int offs
=dialog_get_menu(attr
);
317 while(attr
->res
[offs
]||(win32
&&attr
->res
[offs
+1]))offs
+=win32
?2:1;
322 /* the caption is after the class */
323 int dialog_get_caption(gen_res
* attr
)
325 int offs
=dialog_get_class(attr
);
326 while(attr
->res
[offs
]||(win32
&&attr
->res
[offs
+1]))offs
+=win32
?2:1;
331 /* the fontsize, if present, is after the caption, followed by the font name */
332 int dialog_get_fontsize(gen_res
* attr
)
334 int offs
=dialog_get_caption(attr
);
335 while(attr
->res
[offs
]||(win32
&&attr
->res
[offs
+1]))offs
+=win32
?2:1;
341 /* the CAPTION option was specified */
342 gen_res
* dialog_caption(char* cap
, gen_res
*attr
)
344 /* we don't need the terminating 0 as it's already there */
345 return insert_string(attr
,cap
,dialog_get_caption(attr
),0);
349 /* the FONT option was specified, set the DS_SETFONT flag */
350 gen_res
* dialog_font(short size
,char* font
,gen_res
*attr
)
353 int offs
=dialog_get_fontsize(attr
);
354 put_DWORD(attr
->res
,get_DWORD(attr
->res
)|DS_SETFONT
);
355 put_WORD(c_size
,size
);
356 attr
=insert_bytes(attr
,c_size
,offs
,2);
358 /* as there is no font name by default, copy the '\0' */
359 return insert_string(attr
,font
,offs
,1);
362 gen_res
* dialog_class(char* cap
, gen_res
*attr
)
364 return insert_string(attr
,cap
,dialog_get_class(attr
),0);
367 gen_res
* dialog_menu_id(short nr
, gen_res
*attr
)
370 int offs
=dialog_get_menu(attr
);
371 attr
->res
[offs
] = 0xff;
372 if (win32
) attr
->res
[offs
+1] = 0xff;
374 return insert_bytes(attr
,c_nr
,offs
+(win32
?2:1),2);
376 gen_res
* dialog_menu_str(char* cap
, gen_res
*attr
)
378 return insert_string(attr
,cap
,dialog_get_menu(attr
),0);
381 /* set the dialogs id, position, extent, and style */
382 gen_res
* create_control_desc(int id
,int x
,int y
,int cx
, int cy
,rc_style
*style
)
383 { gen_res
* ret
=new_res();
384 int s
=WS_VISIBLE
|WS_CHILD
; /*defaults styles for any control*/
387 if(style
)s
=(s
|style
->or)&style
->and;
388 put_DWORD(ret
->res
+0,s
);
390 /* put_WORD(ret->res+4, exStyle); */
391 put_WORD(ret
->res
+8,x
);
392 put_WORD(ret
->res
+10,y
);
393 put_WORD(ret
->res
+12,cx
);
394 put_WORD(ret
->res
+14,cy
);
395 put_WORD(ret
->res
+16,id
);
396 ret
->size
=24; /*empty strings, unused byte*/
400 put_WORD(ret
->res
+0,x
);
401 put_WORD(ret
->res
+2,y
);
402 put_WORD(ret
->res
+4,cx
);
403 put_WORD(ret
->res
+6,cy
);
404 put_WORD(ret
->res
+8,id
);
405 if(style
)s
=(s
|style
->or)&style
->and;
406 put_DWORD(ret
->res
+10,s
);
407 ret
->size
=17; /*empty strings, unused byte*/
412 /* insert the control's label */
413 gen_res
* label_control_desc(char* label
,gen_res
* cd
)
417 if(get_WORD(cd
->res
+18)==0xffff)offs
=20; /* one-character class */
419 for(offs
=18;get_WORD(cd
->res
+offs
);offs
+=2);
424 if(cd
->res
[14]&0x80)offs
=15; /* one-character class */
426 for(offs
=14;cd
->res
[offs
];offs
++);
430 return insert_string(cd
,label
,offs
,0);
433 /* a CONTROL was specified */
434 gen_res
* create_generic_control(char* label
,int id
,char* class,
435 rc_style
*style
,int x
,int y
,int cx
,int cy
)
436 { gen_res
* ret
=new_res();
437 int s
=WS_VISIBLE
|WS_CHILD
; /*default styles for any control*/
438 if(style
)s
=(s
|style
->or)&style
->and;
442 put_DWORD(ret
->res
+0,s
);
444 /* put_DWORD(ret->res+4,exstyle->or); */
445 put_WORD(ret
->res
+8,x
);
446 put_WORD(ret
->res
+10,y
);
447 put_WORD(ret
->res
+12,cx
);
448 put_WORD(ret
->res
+14,cy
);
449 put_WORD(ret
->res
+16,id
);
451 ret
=insert_string(ret
,label
,20,0);
452 /* is it a predefined class? */
454 if(!strcasecmp(class,"BUTTON"))cl
=CT_BUTTON
;
455 if(!strcasecmp(class,"EDIT"))cl
=CT_EDIT
;
456 if(!strcasecmp(class,"STATIC"))cl
=CT_STATIC
;
457 if(!strcasecmp(class,"LISTBOX"))cl
=CT_LISTBOX
;
458 if(!strcasecmp(class,"SCROLLBAR"))cl
=CT_SCROLLBAR
;
459 if(!strcasecmp(class,"COMBOBOX"))cl
=CT_COMBOBOX
;
461 char ffff
[2]={0xff, 0xff};
462 ret
=insert_bytes(ret
,ffff
,18,2);
463 put_WORD(ret
->res
+20,cl
);
465 else ret
=insert_string(ret
,class,18,0);
470 put_WORD(ret
->res
+0,x
);
471 put_WORD(ret
->res
+2,y
);
472 put_WORD(ret
->res
+4,cx
);
473 put_WORD(ret
->res
+6,cy
);
474 put_WORD(ret
->res
+8,id
);
475 put_DWORD(ret
->res
+10,s
);
477 ret
=insert_string(ret
,label
,15,0);
478 /* is it a predefined class? */
480 if(!strcasecmp(class,"BUTTON"))cl
=CT_BUTTON
;
481 if(!strcasecmp(class,"EDIT"))cl
=CT_EDIT
;
482 if(!strcasecmp(class,"STATIC"))cl
=CT_STATIC
;
483 if(!strcasecmp(class,"LISTBOX"))cl
=CT_LISTBOX
;
484 if(!strcasecmp(class,"SCROLLBAR"))cl
=CT_SCROLLBAR
;
485 if(!strcasecmp(class,"COMBOBOX"))cl
=CT_COMBOBOX
;
486 if(cl
)ret
->res
[14]=cl
;
487 else ret
=insert_string(ret
,class,14,0);
492 /* insert cd into rest, set the type, add flags */
493 gen_res
* add_control(int type
,int flags
,gen_res
*cd
,gen_res
* rest
)
495 char zeros
[4]={0,0,0,0};
498 char ffff
[2]={0xff, 0xff};
499 put_DWORD(cd
->res
+0,get_DWORD(cd
->res
+0)|flags
);
500 cd
=insert_bytes(cd
,ffff
,18,2);
501 put_WORD(cd
->res
+20,type
);
505 put_DWORD(cd
->res
+10,get_DWORD(cd
->res
+10)|flags
);
508 /* WIN32: First control is on dword boundary */
509 if(win32
&& cd
->size
%4)
510 cd
=insert_bytes(cd
,zeros
,cd
->size
,4-cd
->size
%4);
511 return insert_at_beginning(rest
,cd
->res
,cd
->size
);
514 /* an ICON control was specified, whf contains width, height, and flags */
515 gen_res
* add_icon(char* name
,int id
,int x
,int y
,gen_res
* whf
,gen_res
* rest
)
519 put_WORD(whf
->res
+8,x
);
520 put_WORD(whf
->res
+10,y
);
521 put_WORD(whf
->res
+16,id
);
525 put_WORD(whf
->res
+0,x
);
526 put_WORD(whf
->res
+2,y
);
527 put_WORD(whf
->res
+8,id
);
529 whf
=label_control_desc(name
,whf
);
530 return add_control(CT_STATIC
,SS_ICON
,whf
,rest
);
533 /* insert the generic control into rest */
534 gen_res
* add_generic_control(gen_res
* ctl
, gen_res
* rest
)
536 char zeros
[4]={0,0,0,0};
537 /* WIN32: Control is on dword boundary */
538 if(win32
&& ctl
->size
%4)
539 ctl
=insert_bytes(ctl
,zeros
,ctl
->size
,4-ctl
->size
%4);
540 return insert_at_beginning(rest
,ctl
->res
,ctl
->size
);
543 /* create a dialog resource by inserting the header into the controls.
544 Set position and extent */
545 gen_res
* make_dialog(gen_res
* header
,int x
,int y
,int cx
,int cy
,gen_res
* ctls
)
547 char zeros
[4]={0,0,0,0};
550 put_WORD(header
->res
+8, ctls
->num_entries
);
552 put_WORD(header
->res
+10,x
);
553 put_WORD(header
->res
+12,y
);
554 put_WORD(header
->res
+14,cx
);
555 put_WORD(header
->res
+16,cy
);
559 header
->res
[4]=ctls
->num_entries
;
561 put_WORD(header
->res
+5,x
);
562 put_WORD(header
->res
+7,y
);
563 put_WORD(header
->res
+9,cx
);
564 put_WORD(header
->res
+11,cy
);
566 /* WIN32: First control is on dword boundary */
567 if(win32
&& header
->size
%4)
568 header
=insert_bytes(header
,zeros
,header
->size
,4-header
->size
%4);
569 return insert_bytes(header
,ctls
->res
,header
->size
,ctls
->size
);
572 /* create {0x15,0x16,0xFF} from '15 16 FF' */
573 gen_res
*hex_to_raw(char *hex
, gen_res
*rest
)
577 for(i
=0;*hex
!='\'';i
++)r2
[i
]=strtoul(hex
,&hex
,16);
578 return insert_bytes(rest
,r2
,0,i
);
581 /* create a bitmap resource */
582 gen_res
*make_bitmap(gen_res
* res
)
584 res
=delete_bytes(res
,0,14); /* skip bitmap file header*/
589 gen_res
*make_icon(gen_res
* res
)
595 gen_res
*make_cursor(gen_res
* res
)
601 /* load resource bytes from the file name */
602 gen_res
*load_file(char* name
)
606 int f
=open(name
,O_RDONLY
);
614 while(res
->space
<st
.st_size
)res
=grow(res
);
615 read(f
,res
->res
,st
.st_size
);
616 res
->size
=st
.st_size
;
621 /* insert a normal menu item into res, starting from the last item */
622 gen_res
*add_menuitem(char* name
,int id
,int flags
,gen_res
*res
)
625 if(res
->num_entries
==0)flags
|=MF_END
;
626 put_WORD(item
,flags
);
628 res
=insert_string_at_beginning(res
,name
,1);
629 res
=insert_bytes(res
,item
,0,4);
633 /* insert a popup item into res */
634 gen_res
*add_popup(char *name
,short flags
, gen_res
* body
, gen_res
*res
)
638 if(res
->num_entries
==0)flags
|=MF_END
;
639 put_WORD(c_flags
,flags
);
640 res
=insert_at_beginning(res
,body
->res
,body
->size
);
641 res
=insert_string(res
,name
,0,1);
642 res
=insert_bytes(res
,c_flags
,0,2);
646 /* prefix the menu header into res */
647 gen_res
*make_menu(gen_res
* res
)
649 static char header
[4]={0,0,0,0};
650 res
=insert_at_beginning(res
,header
,4);
655 /* link top-level resources */
656 gen_res
*add_resource(gen_res
* first
,gen_res
*rest
)
667 typedef struct str_tbl_elm
{
669 struct str_tbl_elm
*next
;
673 str_tbl_elm
* string_table
=NULL
; /* sorted by group */
675 void add_str_tbl_elm(int id
,char* str
)
680 str_tbl_elm
** elm
=&string_table
;
681 while(*elm
&& (*elm
)->group
<group
) elm
=&(*elm
)->next
;
682 if(!*elm
|| (*elm
)->group
!=group
)
685 str_tbl_elm
* new=xmalloc(sizeof(str_tbl_elm
));
686 for(i
=0; i
<16; i
++) new->strings
[i
] = NULL
;
691 (*elm
)->strings
[idx
]=str
;
694 gen_res
* add_string_table(gen_res
* t
)
702 if(!string_table
) return t
;
703 for(ste
=string_table
; ste
; ste
=ste
->next
)
705 for(size
=0,i
=0; i
<16; i
++)
706 size
+= (win32
? 2 : 1) * (ste
->strings
[i
] ? strlen(ste
->strings
[i
])+1 : 1);
708 while(res
->space
<size
)res
=grow(res
);
710 res
->n
.i_name
=ste
->group
;
714 for(p
=res
->res
,i
=0; i
<16; i
++)
715 if((q
=ste
->strings
[i
])==NULL
)
722 put_WORD(p
, strlen(q
));
731 for(p
=res
->res
,i
=0; i
<16; i
++)
732 if((q
=ste
->strings
[i
])==NULL
)
737 while(*q
) *p
++ = *q
++;
739 t
=add_resource(res
,t
);
744 char *get_typename(gen_res
* t
)
747 case acc
:return "ACCELERATOR";
748 case bmp
:return "BITMAP";
749 case cur
:return "CURSOR";
750 case dlg
:return "DIALOG";
751 case fnt
:return "FONT";
752 case ico
:return "ICON";
753 case men
:return "MENU";
754 case rdt
:return "RCDATA";
755 case str
:return "STRINGTABLE";
756 default: return "UNKNOWN";
760 /* create strings like _Sysres_DIALOG_2 */
761 char *get_resource_name(gen_res
*it
)
763 static char buf
[1000];
765 sprintf(buf
,"%s_%s_%s",prefix
,get_typename(it
),it
->n
.s_name
);
767 sprintf(buf
,"%s_%s_%d",prefix
,get_typename(it
),it
->n
.i_name
);
771 #define ISCONSTANT (constant ? "const " : "")
773 /* create the final output */
774 void create_output(gen_res
* top
)
778 top
=add_string_table(top
);
780 /* Generate the header */
786 " * This file is automatically generated. Do not edit!\n"
790 "struct resource;\n\n",
793 /* Declare the resources */
794 for (it
=top
;it
;it
=it
->next
)
795 fprintf( header
,"extern %sstruct resource %s;\n",
796 ISCONSTANT
, get_resource_name(it
) );
797 fprintf( header
,"\nextern %sstruct resource * %s%s_Table[];\n\n",
798 ISCONSTANT
, ISCONSTANT
, prefix
);
799 fprintf( header
, "#endif /* __%s_H */\n", prefix
);
802 /* Print the resources bytes */
804 fprintf( code
, "/*\n"
805 " * This file is automatically generated. Do not edit!\n"
807 "struct resource {\n"
810 "\tconst char *name;\n"
811 "\tconst unsigned char* bytes;\n"
815 for(it
=top
;it
;it
=it
->next
)
818 fprintf( code
, "static %sunsigned char %s__bytes[]%s = {\n",
819 ISCONSTANT
, get_resource_name(it
),
820 win32
?"\n__attribute__ ((aligned (4)))":"");
821 for (i
=0;i
<it
->size
-1;i
++)
823 fprintf(code
,"0x%02x, ",it
->res
[i
]);
824 if ((i
&7)==7)fputc('\n',code
);
826 fprintf(code
,"0x%02x };\n\n",it
->res
[i
]);
829 /* Print the resources names */
832 for(it
=top
;it
;it
=it
->next
)
835 char s_buffer
[20], *s_name
=s_buffer
;
836 if(it
->n_type
) s_name
=it
->n
.s_name
;
837 else sprintf(s_name
,"@%d",it
->n
.i_name
);
838 fprintf( code
, "static %sunsigned char %s__name[] = {\n",
839 ISCONSTANT
, get_resource_name(it
) );
840 for (i
=0;*s_name
;i
++,s_name
++)
842 fprintf(code
,"0x%02x, 0x00, ",*s_name
);
843 if ((i
&3)==3)fputc('\n',code
);
845 fprintf(code
,"0x00, 0x00};\n\n");
848 /* Print the resources */
849 for (it
=top
;it
;it
=it
->next
)
854 case acc
:type
=(int)RT_ACCELERATOR16
;break;
855 case bmp
:type
=(int)RT_BITMAP16
;break;
856 case cur
:type
=(int)RT_CURSOR16
;break;
857 case dlg
:type
=(int)RT_DIALOG16
;break;
858 case fnt
:type
=(int)RT_FONT16
;break;
859 case ico
:type
=(int)RT_ICON16
;break;
860 case men
:type
=(int)RT_MENU16
;break;
861 case rdt
:type
=(int)RT_RCDATA16
;break;
862 case str
:type
=(int)RT_STRING16
;break;
863 default:fprintf(stderr
,"Unknown restype\n");type
=-1;break;
868 fprintf(code
,"%sstruct resource %s = {0,%d,%s__name,%s__bytes,%d};\n",
869 ISCONSTANT
, get_resource_name(it
), type
, get_resource_name(it
),
870 get_resource_name(it
), it
->size
);
872 fprintf(code
,"%sstruct resource %s = {%d,%d,%s__name,%s__bytes,%d};\n",
873 ISCONSTANT
, get_resource_name(it
), it
->n
.i_name
, type
,
874 get_resource_name(it
), get_resource_name(it
), it
->size
);
879 fprintf(code
,"%sstruct resource %s = {0,%d,\"%s\",%s__bytes,%d};\n",
880 ISCONSTANT
, get_resource_name(it
), type
, it
->n
.s_name
,
881 get_resource_name(it
), it
->size
);
883 fprintf(code
,"%sstruct resource %s = {%d,%d,\"@%d\",%s__bytes,%d};\n",
884 ISCONSTANT
, get_resource_name(it
), it
->n
.i_name
, type
,
885 it
->n
.i_name
, get_resource_name(it
), it
->size
);
889 /* Print the resource table (NULL terminated) */
891 fprintf(code
,"\n%sstruct resource * %s%s_Table[] = {\n",
892 ISCONSTANT
, ISCONSTANT
, prefix
);
893 for (it
=top
;it
;it
=it
->next
)
894 fprintf( code
, " &%s,\n", get_resource_name(it
) );
895 fprintf( code
, " 0\n};\n\n\n" );
897 /* Perform autoregistration */
900 "#if defined(__GNUC__) && ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)))\n"
901 "static void DoIt(void) __attribute__((constructor));\n"
903 "static void DoIt(void);\n"
904 "void LIBWINE_Register_%s(void) { DoIt(); }\n"
906 "static void DoIt(void)\n"
908 "\textern void LIBRES_RegisterResources(const struct resource* const * Res);\n"
909 "\tLIBRES_RegisterResources(%s_Table);\n"
911 "#endif /* __WINE__ */\n"
915 gen_res
* make_font(gen_res
* res
)
917 fprintf(stderr
,"Fonts not supported\n");
921 gen_res
* make_raw(gen_res
* res
)
923 fprintf(stderr
,"RCData not supported\n");
927 gen_res
* int_to_raw(int i
,gen_res
* res
)
929 fprintf(stderr
,"IntToRaw not supported\n");
933 /* translate "Hello,\\tworld!\\10" to "Hello,\tworld!\n" */
934 char *parse_c_string(char *in
)
936 char *out
=xmalloc(strlen(in
)-1);
939 for(it
=out
,in
++;*in
;in
++)
942 {case 't':*it
++='\t';break;
943 case 'r':*it
++='\r';break;
944 case 'n':*it
++='\n';break;
945 case 'a':*it
++='\a';break;
947 memset(tmp
,0,5);/*make sure it doesn't use more than 4 chars*/
949 *it
++=strtoul(tmp
,&tend
,0);
952 case '1':case '2':case '3':case '4':case '5':
953 case '6':case '7':case '8':case '9':
956 *it
++=strtoul(tmp
,&tend
,10);
962 *it
++=strtoul(tmp
,&tend
,16);