Bugfix: GetFullPathName sets lpFilePart only when the last element
[wine/multimedia.git] / tools / wrc / genres.c
blob0f863d45d3cce12fe6ddeaf2cc11046ed5f86ca5
1 /*
2 * Generate .res format from a resource-tree
4 * Copyright 1998 Bertho A. Stultiens
6 * 25-May-1998 BS - Added simple unicode -> char conversion for resource
7 * names in .s and .h files.
8 */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <assert.h>
14 #include <ctype.h>
16 #include <config.h>
17 #include "wrc.h"
18 #include "genres.h"
19 #include "utils.h"
21 #define SetResSize(res, tag) *(DWORD *)&((res)->data[(tag)]) = \
22 (res)->size - *(DWORD *)&((res)->data[(tag)])
24 res_t *new_res(void)
26 res_t *r;
27 r = (res_t *)xmalloc(sizeof(res_t));
28 r->allocsize = RES_BLOCKSIZE;
29 r->size = 0;
30 r->data = (char *)xmalloc(RES_BLOCKSIZE);
31 return r;
34 res_t *grow_res(res_t *r, int add)
36 r->allocsize += add;
37 r->data = (char *)xrealloc(r->data, r->allocsize);
38 return r;
42 *****************************************************************************
43 * Function : put_byte
44 * put_word
45 * put_dword
46 * Syntax : void put_byte(res_t *res, unsigned c)
47 * void put_word(res_t *res, unsigned w)
48 * void put_dword(res_t *res, unsigned d)
49 * Input :
50 * res - Binary resource to put the data in
51 * c, w, d - Data to put
52 * Output : nop
53 * Description : Put primitives that put an item in the binary resource.
54 * The data array grows automatically.
55 * Remarks :
56 *****************************************************************************
58 void put_byte(res_t *res, unsigned c)
60 if(res->allocsize - res->size < sizeof(char))
61 grow_res(res, RES_BLOCKSIZE);
62 *(char *)&(res->data[res->size]) = (char)c;
63 res->size += sizeof(char);
66 void put_word(res_t *res, unsigned w)
68 if(res->allocsize - res->size < sizeof(WORD))
69 grow_res(res, RES_BLOCKSIZE);
70 *(WORD *)&(res->data[res->size]) = (WORD)w;
71 res->size += sizeof(WORD);
74 void put_dword(res_t *res, unsigned d)
76 if(res->allocsize - res->size < sizeof(DWORD))
77 grow_res(res, RES_BLOCKSIZE);
78 *(DWORD *)&(res->data[res->size]) = (DWORD)d;
79 res->size += sizeof(DWORD);
82 void put_pad(res_t *res)
84 while(res->size & 0x3)
85 put_byte(res, 0);
89 *****************************************************************************
90 * Function : string_to_upper
91 * Syntax : void string_to_upper(string_t *str)
92 * Input :
93 * Output :
94 * Description :
95 * Remarks : FIXME: codepages...
96 *****************************************************************************
98 void string_to_upper(string_t *str)
100 if(str->type == str_char)
102 char *cptr = str->str.cstr;
103 for(; *cptr; cptr++)
104 *cptr = (char)toupper(*cptr);
106 else if(str->type == str_unicode)
108 short *sptr = str->str.wstr;
109 for(; *sptr; sptr++)
110 if(isalpha(*sptr))
111 *sptr = (short)toupper(*sptr);
113 else
115 internal_error(__FILE__, __LINE__, "Invalid string type %d", str->type);
120 *****************************************************************************
121 * Function : put_string
122 * Syntax : void put_string(res_t *res, string_t *str, enum str_e type,
123 * int isterm)
124 * Input :
125 * res - Binary resource to put the data in
126 * str - String to put
127 * type - Data has to be written in either str_char or str_unicode
128 * isterm - The string is '\0' terminated (disregard the string's
129 * size member)
130 * Output : nop
131 * Description :
132 * Remarks :
133 *****************************************************************************
135 void put_string(res_t *res, string_t *str, enum str_e type, int isterm)
137 int cnt;
138 int c = !0;
139 assert(res != NULL);
140 assert(str != NULL);
141 if(!isterm && str->size == 0)
143 warning("String length is zero, not written");
144 return;
147 if(str->type == str_unicode && type == str_unicode)
149 for(cnt = 0; cnt < str->size; cnt++)
151 c = str->str.wstr[cnt];
152 put_word(res, c);
153 if(isterm && !c)
154 break;
156 if(isterm && (str->size == 0 || (cnt == str->size && c)))
157 put_word(res, 0);
159 else if(str->type == str_char && type == str_char)
161 for(cnt = 0; cnt < str->size; cnt++)
163 c = str->str.cstr[cnt];
164 put_byte(res, c);
165 if(isterm && !c)
166 break;
168 if(isterm && (str->size == 0 || (cnt == str->size && c)))
169 put_byte(res, 0);
171 else if(str->type == str_unicode && type == str_char)
173 for(cnt = 0; cnt < str->size; cnt++)
175 c = str->str.wstr[cnt];
176 put_byte(res, c);
177 if(isterm && !c)
178 break;
180 if(isterm && (str->size == 0 || (cnt == str->size && c)))
181 put_byte(res, 0);
183 else /* str->type == str_char && type == str_unicode */
185 for(cnt = 0; cnt < str->size; cnt++)
187 c = str->str.cstr[cnt];
188 put_word(res, c & 0xff);
189 if(isterm && !c)
190 break;
192 if(isterm && (str->size == 0 || (cnt == str->size && c)))
193 put_word(res, 0);
198 *****************************************************************************
199 * Function : put_name_id
200 * Syntax : void put_name_id(res_t *res, name_id_t *nid, int upcase)
201 * Input :
202 * Output :
203 * Description :
204 * Remarks :
205 *****************************************************************************
207 void put_name_id(res_t *res, name_id_t *nid, int upcase)
209 if(nid->type == name_ord)
211 if(win32)
212 put_word(res, 0xffff);
213 else
214 put_byte(res, 0xff);
215 put_word(res, (WORD)nid->name.i_name);
217 else if(nid->type == name_str)
219 if(upcase)
220 string_to_upper(nid->name.s_name);
221 put_string(res, nid->name.s_name, win32 ? str_unicode : str_char, TRUE);
223 else
225 internal_error(__FILE__, __LINE__, "Invalid name_id type %d", nid->type);
230 *****************************************************************************
231 * Function : put_lvc
232 * Syntax : void put_lvc(res_t *res, lvc_t *lvc)
233 * Input :
234 * Output :
235 * Description :
236 * Remarks :
237 *****************************************************************************
239 void put_lvc(res_t *res, lvc_t *lvc)
241 if(lvc && lvc->language)
242 put_word(res, MAKELANGID(lvc->language->id, lvc->language->sub));
243 else
244 put_word(res, 0); /* Neutral */
245 if(lvc && lvc->version)
246 put_dword(res, *(lvc->version));
247 else
248 put_dword(res, 0);
249 if(lvc && lvc->characts)
250 put_dword(res, *(lvc->characts));
251 else
252 put_dword(res, 0);
256 *****************************************************************************
257 * Function : put_raw_data
258 * Syntax : void put_raw_data(res_t *res, raw_data_t *raw, int offset)
259 * Input :
260 * Output :
261 * Description :
262 * Remarks :
263 *****************************************************************************
265 void put_raw_data(res_t *res, raw_data_t *raw, int offset)
267 int wsize = raw->size - offset;
268 if(res->allocsize - res->size < wsize)
269 grow_res(res, wsize);
270 memcpy(&(res->data[res->size]), raw->data + offset, wsize);
271 res->size += wsize;
275 *****************************************************************************
276 * Function : put_res_header
277 * Syntax : intput_res_header(res_t *res, int type, name_id_t *ntype,
278 * name_id_t *name, DWORD memopt, lvc_t *lvc)
280 * Input :
281 * res - Binary resource descriptor to write to
282 * type - Resource identifier (if ntype == NULL)
283 * ntype - Name id of type
284 * name - Resource's name
285 * memopt - Resource's memory options to write
286 * lvc - Language, version and characteristics (win32 only)
287 * Output : An index to the resource size field. The resource size field
288 * contains the header size upon exit.
289 * Description :
290 * Remarks :
291 *****************************************************************************
293 int put_res_header(res_t *res, int type, name_id_t *ntype, name_id_t *name,
294 DWORD memopt, lvc_t *lvc)
296 if(win32)
298 put_dword(res, 0); /* We will overwrite these later */
299 put_dword(res, 0);
300 if(!ntype)
302 put_word(res, 0xffff); /* ResType */
303 put_word(res, type);
305 else
306 put_name_id(res, ntype, TRUE);
307 put_name_id(res, name, TRUE); /* ResName */
308 put_pad(res);
309 put_dword(res, 0); /* DataVersion */
310 put_word(res, memopt); /* Memory options */
311 put_lvc(res, lvc); /* Language, version and characts */
312 ((DWORD *)res->data)[0] = res->size; /* Set preliminary resource */
313 ((DWORD *)res->data)[1] = res->size; /* Set HeaderSize */
314 res->dataidx = res->size;
315 return 0;
317 else /* win16 */
319 int tag;
320 if(!ntype)
322 put_byte(res, 0xff); /* ResType */
323 put_word(res, type);
325 else
326 put_name_id(res, ntype, TRUE);
327 put_name_id(res, name, TRUE); /* ResName */
328 put_word(res, memopt); /* Memory options */
329 tag = res->size;
330 put_dword(res, 0); /* ResSize overwritten later*/
331 *(DWORD *)&(res->data[tag]) = res->size;
332 res->dataidx = res->size;
333 return tag;
338 *****************************************************************************
339 * Function : accelerator2res
340 * Syntax : res_t *accelerator2res(name_id_t *name, accelerator_t *acc)
341 * Input :
342 * name - Name/ordinal of the resource
343 * acc - The accelerator descriptor
344 * Output : New .res format structure
345 * Description :
346 * Remarks :
347 *****************************************************************************
349 res_t *accelerator2res(name_id_t *name, accelerator_t *acc)
351 int restag;
352 res_t *res;
353 event_t *ev;
354 assert(name != NULL);
355 assert(acc != NULL);
357 ev = acc->events;
358 res = new_res();
359 if(win32)
361 restag = put_res_header(res, WRC_RT_ACCELERATOR, NULL, name, acc->memopt, &(acc->lvc));
362 while(ev)
364 put_word(res, ev->flags | (ev->next ? 0 : 0x80));
365 put_word(res, ev->key);
366 put_word(res, ev->id);
367 put_word(res, 0); /* Padding */
368 ev = ev->next;
370 put_pad(res);
372 else /* win16 */
374 restag = put_res_header(res, WRC_RT_ACCELERATOR, NULL, name, acc->memopt, NULL);
375 while(ev)
377 put_byte(res, ev->flags | (ev->next ? 0 : 0x80));
378 put_word(res, ev->key);
379 put_word(res, ev->id);
380 ev = ev->next;
383 /* Set ResourceSize */
384 SetResSize(res, restag);
385 return res;
389 *****************************************************************************
390 * Function : dialog2res
391 * Syntax : res_t *dialog2res(name_id_t *name, dialog_t *dlg)
392 * Input :
393 * name - Name/ordinal of the resource
394 * dlg - The dialog descriptor
395 * Output : New .res format structure
396 * Description :
397 * Remarks :
398 *****************************************************************************
400 res_t *dialog2res(name_id_t *name, dialog_t *dlg)
402 int restag;
403 res_t *res;
404 control_t *ctrl;
405 int tag_nctrl;
406 int nctrl = 0;
407 assert(name != NULL);
408 assert(dlg != NULL);
410 ctrl = dlg->controls;
411 res = new_res();
412 if(win32)
414 restag = put_res_header(res, WRC_RT_DIALOG, NULL, name, dlg->memopt, &(dlg->lvc));
416 put_dword(res, dlg->style);
417 put_dword(res, dlg->gotexstyle ? dlg->exstyle : 0);
418 tag_nctrl = res->size;
419 put_word(res, 0); /* Number of controls */
420 put_word(res, dlg->x);
421 put_word(res, dlg->y);
422 put_word(res, dlg->width);
423 put_word(res, dlg->height);
424 if(dlg->menu)
425 put_name_id(res, dlg->menu, TRUE);
426 else
427 put_word(res, 0);
428 if(dlg->dlgclass)
429 put_name_id(res, dlg->dlgclass, TRUE);
430 else
431 put_word(res, 0);
432 if(dlg->title)
433 put_string(res, dlg->title, str_unicode, TRUE);
434 else
435 put_word(res, 0);
436 if(dlg->font)
438 put_word(res, dlg->font->size);
439 put_string(res, dlg->font->name, str_unicode, TRUE);
442 put_pad(res);
443 while(ctrl)
445 /* FIXME: what is default control style? */
446 put_dword(res, ctrl->gotstyle ? ctrl->style : WS_CHILD);
447 put_dword(res, ctrl->gotexstyle ? ctrl->exstyle : 0);
448 put_word(res, ctrl->x);
449 put_word(res, ctrl->y);
450 put_word(res, ctrl->width);
451 put_word(res, ctrl->height);
452 put_word(res, ctrl->id);
453 if(ctrl->ctlclass)
454 put_name_id(res, ctrl->ctlclass, TRUE);
455 else
456 internal_error(__FILE__, __LINE__, "Control has no control-class");
457 if(ctrl->title)
458 put_string(res, ctrl->title, str_unicode, TRUE);
459 else
460 put_word(res, 0);
461 if(ctrl->extra)
463 put_word(res, ctrl->extra->size+2);
464 put_pad(res);
465 put_raw_data(res, ctrl->extra, 0);
467 else
468 put_word(res, 0);
470 if(ctrl->next)
471 put_pad(res);
472 nctrl++;
473 ctrl = ctrl->next;
475 /* Set number of controls */
476 *(WORD *)&((char *)res->data)[tag_nctrl] = (WORD)nctrl;
478 else /* win16 */
480 restag = put_res_header(res, WRC_RT_DIALOG, NULL, name, dlg->memopt, NULL);
482 put_dword(res, dlg->gotstyle ? dlg->style : WS_POPUPWINDOW);
483 tag_nctrl = res->size;
484 put_byte(res, 0); /* Number of controls */
485 put_word(res, dlg->x);
486 put_word(res, dlg->y);
487 put_word(res, dlg->width);
488 put_word(res, dlg->height);
489 if(dlg->menu)
490 put_name_id(res, dlg->menu, TRUE);
491 else
492 put_byte(res, 0);
493 if(dlg->dlgclass)
494 put_name_id(res, dlg->dlgclass, TRUE);
495 else
496 put_byte(res, 0);
497 if(dlg->title)
498 put_string(res, dlg->title, str_char, TRUE);
499 else
500 put_byte(res, 0);
501 if(dlg->font)
503 put_word(res, dlg->font->size);
504 put_string(res, dlg->font->name, str_char, TRUE);
507 while(ctrl)
509 put_word(res, ctrl->x);
510 put_word(res, ctrl->y);
511 put_word(res, ctrl->width);
512 put_word(res, ctrl->height);
513 put_word(res, ctrl->id);
514 put_dword(res, ctrl->gotstyle ? ctrl->style : WS_CHILD);
515 if(ctrl->ctlclass)
517 if(ctrl->ctlclass->type == name_ord
518 && ctrl->ctlclass->name.i_name >= 0x80
519 && ctrl->ctlclass->name.i_name <= 0x85)
520 put_byte(res, ctrl->ctlclass->name.i_name);
521 else if(ctrl->ctlclass->type == name_str)
522 put_name_id(res, ctrl->ctlclass, FALSE);
523 else
524 error("Unknown control-class %04x", ctrl->ctlclass->name.i_name);
526 else
527 internal_error(__FILE__, __LINE__, "Control has no control-class");
528 if(ctrl->title)
529 put_string(res, ctrl->title, str_char, TRUE);
530 else
531 put_byte(res, 0);
533 /* FIXME: What is this extra byte doing here? */
534 put_byte(res, 0);
536 nctrl++;
537 ctrl = ctrl->next;
539 /* Set number of controls */
540 ((char *)res->data)[tag_nctrl] = (char)nctrl;
542 /* Set ResourceSize */
543 SetResSize(res, restag);
544 return res;
548 *****************************************************************************
549 * Function : dialogex2res
550 * Syntax : res_t *dialogex2res(name_id_t *name, dialogex_t *dlgex)
551 * Input :
552 * name - Name/ordinal of the resource
553 * dlgex - The dialogex descriptor
554 * Output : New .res format structure
555 * Description :
556 * Remarks :
557 *****************************************************************************
559 res_t *dialogex2res(name_id_t *name, dialogex_t *dlgex)
561 int restag;
562 res_t *res;
563 control_t *ctrl;
564 int tag_nctrl;
565 int nctrl = 0;
566 assert(name != NULL);
567 assert(dlgex != NULL);
569 ctrl = dlgex->controls;
570 res = new_res();
571 if(win32)
573 restag = put_res_header(res, WRC_RT_DIALOG, NULL, name, dlgex->memopt, &(dlgex->lvc));
575 /* FIXME: MS doc says thet the first word must contain 0xffff
576 * and the second 0x0001 to signal a DLGTEMPLATEEX. Borland's
577 * compiler reverses the two words.
578 * I don't know which one to choose, but I write it as Mr. B
579 * writes it.
581 put_word(res, 1); /* Signature */
582 put_word(res, 0xffff); /* DlgVer */
583 put_dword(res, dlgex->gothelpid ? dlgex->helpid : 0);
584 put_dword(res, dlgex->gotexstyle ? dlgex->exstyle : 0);
585 put_dword(res, dlgex->gotstyle ? dlgex->style : WS_POPUPWINDOW);
586 tag_nctrl = res->size;
587 put_word(res, 0); /* Number of controls */
588 put_word(res, dlgex->x);
589 put_word(res, dlgex->y);
590 put_word(res, dlgex->width);
591 put_word(res, dlgex->height);
592 if(dlgex->menu)
593 put_name_id(res, dlgex->menu, TRUE);
594 else
595 put_word(res, 0);
596 if(dlgex->dlgclass)
597 put_name_id(res, dlgex->dlgclass, TRUE);
598 else
599 put_word(res, 0);
600 if(dlgex->title)
601 put_string(res, dlgex->title, str_unicode, TRUE);
602 else
603 put_word(res, 0);
604 if(dlgex->font)
606 put_word(res, dlgex->font->size);
607 put_word(res, dlgex->font->weight);
608 /* FIXME: ? TRUE should be sufficient to say that its
609 * italic, but Borland's compiler says its 0x0101.
610 * I just copy it here, and hope for the best.
612 put_word(res, dlgex->font->italic ? 0x0101 : 0);
613 put_string(res, dlgex->font->name, str_unicode, TRUE);
616 put_pad(res);
617 while(ctrl)
619 put_dword(res, ctrl->gothelpid ? ctrl->helpid : 0);
620 put_dword(res, ctrl->gotexstyle ? ctrl->exstyle : 0);
621 /* FIXME: what is default control style? */
622 put_dword(res, ctrl->gotstyle ? ctrl->style : WS_CHILD | WS_VISIBLE);
623 put_word(res, ctrl->x);
624 put_word(res, ctrl->y);
625 put_word(res, ctrl->width);
626 put_word(res, ctrl->height);
627 put_word(res, ctrl->id);
628 /* FIXME: Pad is _NOT_ documented!?! */
629 put_pad(res);
630 if(ctrl->ctlclass)
631 put_name_id(res, ctrl->ctlclass, TRUE);
632 else
633 internal_error(__FILE__, __LINE__, "Control has no control-class");
634 if(ctrl->title)
635 put_string(res, ctrl->title, str_unicode, TRUE);
636 else
637 put_word(res, 0);
638 if(ctrl->extra)
640 put_pad(res);
641 put_word(res, ctrl->extra->size);
642 put_raw_data(res, ctrl->extra, 0);
644 else
645 put_word(res, 0);
647 put_pad(res);
648 nctrl++;
649 ctrl = ctrl->next;
651 /* Set number of controls */
652 *(WORD *)&((char *)res->data)[tag_nctrl] = (WORD)nctrl;
653 /* Set ResourceSize */
654 SetResSize(res, restag);
655 put_pad(res);
657 else /* win16 */
659 /* Do not generate anything in 16-bit mode */
660 free(res->data);
661 free(res);
662 return NULL;
664 return res;
668 *****************************************************************************
669 * Function : menuitem2res
670 * Syntax : void menuitem2res(res_t *res, menu_item_t *item)
671 * Input :
672 * Output :
673 * Description :
674 * Remarks : Self recursive
675 *****************************************************************************
677 void menuitem2res(res_t *res, menu_item_t *menitem)
679 menu_item_t *itm = menitem;
680 if(win32)
682 while(itm)
684 put_word(res, itm->state | (itm->popup ? MF_POPUP : 0) | (!itm->next ? MF_END : 0));
685 if(!itm->popup)
686 put_word(res, itm->id);
687 if(itm->name)
688 put_string(res, itm->name, str_unicode, TRUE);
689 else
690 put_word(res, 0);
691 if(itm->popup)
692 menuitem2res(res, itm->popup);
693 itm = itm->next;
696 else /* win16 */
698 while(itm)
700 put_word(res, itm->state | (itm->popup ? MF_POPUP : 0) | (!itm->next ? MF_END : 0));
701 if(!itm->popup)
702 put_word(res, itm->id);
703 if(itm->name)
704 put_string(res, itm->name, str_char, TRUE);
705 else
706 put_byte(res, 0);
707 if(itm->popup)
708 menuitem2res(res, itm->popup);
709 itm = itm->next;
716 *****************************************************************************
717 * Function : menu2res
718 * Syntax : res_t *menu2res(name_id_t *name, menu_t *men)
719 * Input :
720 * name - Name/ordinal of the resource
721 * men - The menu descriptor
722 * Output : New .res format structure
723 * Description :
724 * Remarks :
725 *****************************************************************************
727 res_t *menu2res(name_id_t *name, menu_t *men)
729 int restag;
730 res_t *res;
731 assert(name != NULL);
732 assert(men != NULL);
734 res = new_res();
735 restag = put_res_header(res, WRC_RT_MENU, NULL, name, men->memopt, win32 ? &(men->lvc) : NULL);
737 put_dword(res, 0); /* Menuheader: Version and HeaderSize */
738 menuitem2res(res, men->items);
739 /* Set ResourceSize */
740 SetResSize(res, restag);
741 if(win32)
742 put_pad(res);
743 return res;
747 *****************************************************************************
748 * Function : menuexitem2res
749 * Syntax : void menuexitem2res(res_t *res, menuex_item_t *item)
750 * Input :
751 * Output : nop
752 * Description :
753 * Remarks : Self recursive
754 *****************************************************************************
756 void menuexitem2res(res_t *res, menuex_item_t *menitem)
758 menuex_item_t *itm = menitem;
759 assert(win32 != 0);
760 while(itm)
762 put_dword(res, itm->gottype ? itm->type : 0);
763 put_dword(res, itm->gotstate ? itm->state : 0);
764 put_dword(res, itm->gotid ? itm->id : 0); /* FIXME: Docu. says word */
765 put_word(res, (itm->popup ? 0x01 : 0) | (!itm->next ? MF_END : 0));
766 if(itm->name)
767 put_string(res, itm->name, str_unicode, TRUE);
768 else
769 put_word(res, 0);
770 put_pad(res);
771 if(itm->popup)
773 put_dword(res, itm->gothelpid ? itm->helpid : 0);
774 menuexitem2res(res, itm->popup);
776 itm = itm->next;
782 *****************************************************************************
783 * Function : menuex2res
784 * Syntax : res_t *menuex2res(name_id_t *name, menuex_t *menex)
785 * Input :
786 * name - Name/ordinal of the resource
787 * menex - The menuex descriptor
788 * Output : New .res format structure
789 * Description :
790 * Remarks :
791 *****************************************************************************
793 res_t *menuex2res(name_id_t *name, menuex_t *menex)
795 int restag;
796 res_t *res;
797 assert(name != NULL);
798 assert(menex != NULL);
800 res = new_res();
801 if(win32)
803 restag = put_res_header(res, WRC_RT_MENU, NULL, name, menex->memopt, &(menex->lvc));
805 put_word(res, 1); /* Menuheader: Version */
806 put_word(res, 4); /* Offset */
807 put_dword(res, 0); /* HelpId */
808 put_pad(res);
809 menuexitem2res(res, menex->items);
810 /* Set ResourceSize */
811 SetResSize(res, restag);
812 put_pad(res);
814 else /* win16 */
816 /* Do not generate anything in 16-bit mode */
817 free(res->data);
818 free(res);
819 return NULL;
821 return res;
825 *****************************************************************************
826 * Function : cursorgroup2res
827 * Syntax : res_t *cursorgroup2res(name_id_t *name, cursor_group_t *curg)
828 * Input :
829 * name - Name/ordinal of the resource
830 * curg - The cursor descriptor
831 * Output : New .res format structure
832 * Description :
833 * Remarks :
834 *****************************************************************************
836 res_t *cursorgroup2res(name_id_t *name, cursor_group_t *curg)
838 int restag;
839 res_t *res;
840 cursor_t *cur;
841 assert(name != NULL);
842 assert(curg != NULL);
844 res = new_res();
845 restag = put_res_header(res, WRC_RT_GROUP_CURSOR, NULL, name, curg->memopt, &(curg->lvc));
846 if(win32)
848 put_word(res, 0); /* Reserved */
849 /* FIXME: The ResType in the NEWHEADER structure should
850 * contain 14 according to the MS win32 doc. This is
851 * not the case with the BRC compiler and I really doubt
852 * the latter. Putting one here is compliant to win16 spec,
853 * but who knows the true value?
855 put_word(res, 2); /* ResType */
856 put_word(res, curg->ncursor);
857 #if 0
858 for(cur = curg->cursorlist; cur; cur = cur->next)
859 #else
860 cur = curg->cursorlist;
861 while(cur->next)
862 cur = cur->next;
863 for(; cur; cur = cur->prev)
864 #endif
866 put_word(res, cur->width);
867 /* FIXME: The height of a cursor is half the size of
868 * the bitmap's height. BRC puts the height from the
869 * BITMAPINFOHEADER here instead of the cursorfile's
870 * height. MS doesn't seem to care...
872 put_word(res, cur->height);
873 /* FIXME: The next two are reversed in BRC and I don't
874 * know why. Probably a bug. But, we can safely ignore
875 * it because win16 does not support color cursors.
876 * A warning should have been generated by the parser.
878 put_word(res, cur->planes);
879 put_word(res, cur->bits);
880 /* FIXME: The +4 is the hotspot in the cursor resource.
881 * However, I cound not find this in the documentation.
882 * The hotspot bytes must either be included or MS
883 * doesn't care.
885 put_dword(res, cur->data->size +4);
886 put_word(res, cur->id);
889 else /* win16 */
891 put_word(res, 0); /* Reserved */
892 put_word(res, 2); /* ResType */
893 put_word(res, curg->ncursor);
894 #if 0
895 for(cur = curg->cursorlist; cur; cur = cur->next)
896 #else
897 cur = curg->cursorlist;
898 while(cur->next)
899 cur = cur->next;
900 for(; cur; cur = cur->prev)
901 #endif
903 put_word(res, cur->width);
904 /* FIXME: The height of a cursor is half the size of
905 * the bitmap's height. BRC puts the height from the
906 * BITMAPINFOHEADER here instead of the cursorfile's
907 * height. MS doesn't seem to care...
909 put_word(res, cur->height);
910 /* FIXME: The next two are reversed in BRC and I don't
911 * know why. Probably a bug. But, we can safely ignore
912 * it because win16 does not support color cursors.
913 * A warning should have been generated by the parser.
915 put_word(res, cur->planes);
916 put_word(res, cur->bits);
917 /* FIXME: The +4 is the hotspot in the cursor resource.
918 * However, I cound not find this in the documentation.
919 * The hotspot bytes must either be included or MS
920 * doesn't care.
922 put_dword(res, cur->data->size +4);
923 put_word(res, cur->id);
926 SetResSize(res, restag); /* Set ResourceSize */
927 if(win32)
928 put_pad(res);
930 return res;
934 *****************************************************************************
935 * Function : cursor2res
936 * Syntax : res_t *cursor2res(cursor_t *cur)
937 * Input :
938 * cur - The cursor descriptor
939 * Output : New .res format structure
940 * Description :
941 * Remarks :
942 *****************************************************************************
944 res_t *cursor2res(cursor_t *cur)
946 int restag;
947 res_t *res;
948 name_id_t name;
950 assert(cur != NULL);
952 res = new_res();
953 name.type = name_ord;
954 name.name.i_name = cur->id;
955 restag = put_res_header(res, WRC_RT_CURSOR, NULL, &name, WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE, &(cur->lvc));
956 put_word(res, cur->xhot);
957 put_word(res, cur->yhot);
958 put_raw_data(res, cur->data, 0);
960 SetResSize(res, restag); /* Set ResourceSize */
961 if(win32)
962 put_pad(res);
964 return res;
968 *****************************************************************************
969 * Function : icongroup2res
970 * Syntax : res_t *icongroup2res(name_id_t *name, icon_group_t *icog)
971 * Input :
972 * name - Name/ordinal of the resource
973 * icog - The icon group descriptor
974 * Output : New .res format structure
975 * Description :
976 * Remarks :
977 *****************************************************************************
979 res_t *icongroup2res(name_id_t *name, icon_group_t *icog)
981 int restag;
982 res_t *res;
983 icon_t *ico;
984 assert(name != NULL);
985 assert(icog != NULL);
987 res = new_res();
988 restag = put_res_header(res, WRC_RT_GROUP_ICON, NULL, name, icog->memopt, &(icog->lvc));
989 if(win32)
991 put_word(res, 0); /* Reserved */
992 /* FIXME: The ResType in the NEWHEADER structure should
993 * contain 14 according to the MS win32 doc. This is
994 * not the case with the BRC compiler and I really doubt
995 * the latter. Putting one here is compliant to win16 spec,
996 * but who knows the true value?
998 put_word(res, 1); /* ResType */
999 put_word(res, icog->nicon);
1000 for(ico = icog->iconlist; ico; ico = ico->next)
1002 put_byte(res, ico->width);
1003 put_byte(res, ico->height);
1004 put_byte(res, ico->nclr);
1005 put_byte(res, 0); /* Reserved */
1006 put_word(res, ico->planes);
1007 put_word(res, ico->bits);
1008 put_dword(res, ico->data->size);
1009 put_word(res, ico->id);
1012 else /* win16 */
1014 put_word(res, 0); /* Reserved */
1015 put_word(res, 1); /* ResType */
1016 put_word(res, icog->nicon);
1017 for(ico = icog->iconlist; ico; ico = ico->next)
1019 put_byte(res, ico->width);
1020 put_byte(res, ico->height);
1021 put_byte(res, ico->nclr);
1022 put_byte(res, 0); /* Reserved */
1023 put_word(res, ico->planes);
1024 put_word(res, ico->bits);
1025 put_dword(res, ico->data->size);
1026 put_word(res, ico->id);
1029 SetResSize(res, restag); /* Set ResourceSize */
1030 if(win32)
1031 put_pad(res);
1033 return res;
1037 *****************************************************************************
1038 * Function : icon2res
1039 * Syntax : res_t *icon2res(icon_t *ico)
1040 * Input :
1041 * ico - The icon descriptor
1042 * Output : New .res format structure
1043 * Description :
1044 * Remarks :
1045 *****************************************************************************
1047 res_t *icon2res(icon_t *ico)
1049 int restag;
1050 res_t *res;
1051 name_id_t name;
1053 assert(ico != NULL);
1055 res = new_res();
1056 name.type = name_ord;
1057 name.name.i_name = ico->id;
1058 restag = put_res_header(res, WRC_RT_ICON, NULL, &name, WRC_MO_MOVEABLE | WRC_MO_DISCARDABLE, &(ico->lvc));
1059 put_raw_data(res, ico->data, 0);
1061 SetResSize(res, restag); /* Set ResourceSize */
1062 if(win32)
1063 put_pad(res);
1065 return res;
1069 *****************************************************************************
1070 * Function : bitmap2res
1071 * Syntax : res_t *bitmap2res(name_id_t *name, bitmap_t *bmp)
1072 * Input :
1073 * name - Name/ordinal of the resource
1074 * bmp - The bitmap descriptor
1075 * Output : New .res format structure
1076 * Description :
1077 * Remarks :
1078 *****************************************************************************
1080 res_t *bitmap2res(name_id_t *name, bitmap_t *bmp)
1082 int restag;
1083 res_t *res;
1084 assert(name != NULL);
1085 assert(bmp != NULL);
1087 HEAPCHECK();
1088 res = new_res();
1089 HEAPCHECK();
1090 restag = put_res_header(res, WRC_RT_BITMAP, NULL, name, bmp->memopt, NULL);
1091 HEAPCHECK();
1092 if(bmp->data->data[0] == 'B'
1093 && bmp->data->data[1] == 'M'
1094 && ((BITMAPFILEHEADER *)bmp->data->data)->bfSize == bmp->data->size
1095 && bmp->data->size >= sizeof(BITMAPFILEHEADER))
1097 /* The File header is still attached, don't write it */
1098 put_raw_data(res, bmp->data, sizeof(BITMAPFILEHEADER));
1100 else
1102 put_raw_data(res, bmp->data, 0);
1104 HEAPCHECK();
1105 /* Set ResourceSize */
1106 SetResSize(res, restag);
1107 HEAPCHECK();
1108 if(win32)
1109 put_pad(res);
1110 HEAPCHECK();
1111 return res;
1115 *****************************************************************************
1116 * Function : font2res
1117 * Syntax : res_t *font2res(name_id_t *name, font_t *fnt)
1118 * Input :
1119 * name - Name/ordinal of the resource
1120 * fnt - The font descriptor
1121 * Output : New .res format structure
1122 * Description :
1123 * Remarks :
1124 *****************************************************************************
1126 res_t *font2res(name_id_t *name, font_t *fnt)
1128 assert(name != NULL);
1129 assert(fnt != NULL);
1130 warning("Fonts not yet implemented");
1131 return NULL;
1135 *****************************************************************************
1136 * Function : rcdata2res
1137 * Syntax : res_t *rcdata2res(name_id_t *name, rcdata_t *rdt)
1138 * Input :
1139 * name - Name/ordinal of the resource
1140 * rdt - The rcdata descriptor
1141 * Output : New .res format structure
1142 * Description :
1143 * Remarks :
1144 *****************************************************************************
1146 res_t *rcdata2res(name_id_t *name, rcdata_t *rdt)
1148 int restag;
1149 res_t *res;
1150 assert(name != NULL);
1151 assert(rdt != NULL);
1153 res = new_res();
1154 restag = put_res_header(res, WRC_RT_RCDATA, NULL, name, rdt->memopt, NULL);
1155 put_raw_data(res, rdt->data, 0);
1156 /* Set ResourceSize */
1157 SetResSize(res, restag);
1158 if(win32)
1159 put_pad(res);
1160 return res;
1164 *****************************************************************************
1165 * Function : messagetable2res
1166 * Syntax : res_t *messagetable2res(name_id_t *name, messagetable_t *msg)
1167 * Input :
1168 * name - Name/ordinal of the resource
1169 * msg - The messagetable descriptor
1170 * Output : New .res format structure
1171 * Description :
1172 * Remarks :
1173 *****************************************************************************
1175 res_t *messagetable2res(name_id_t *name, messagetable_t *msg)
1177 assert(name != NULL);
1178 assert(msg != NULL);
1179 warning("Messagetable not yet implemented");
1180 return NULL;
1184 *****************************************************************************
1185 * Function : stringtable2res
1186 * Syntax : res_t *stringtable2res(stringtable_t *stt)
1187 * Input :
1188 * stt - The stringtable descriptor
1189 * Output : New .res format structure
1190 * Description :
1191 * Remarks :
1192 *****************************************************************************
1194 res_t *stringtable2res(stringtable_t *stt)
1196 res_t *res;
1197 name_id_t name;
1198 int i;
1199 int restag;
1200 DWORD lastsize = 0;
1202 assert(stt != NULL);
1203 res = new_res();
1205 for(; stt; stt = stt->next)
1207 if(!stt->nentries)
1209 warning("Empty internal stringtable");
1210 continue;
1212 name.type = name_ord;
1213 name.name.i_name = (stt->idbase >> 4) + 1;
1214 restag = put_res_header(res, WRC_RT_STRING, NULL, &name, stt->memopt, win32 ? &(stt->lvc) : NULL);
1215 for(i = 0; i < stt->nentries; i++)
1217 if(stt->entries[i].str)
1219 if(win32)
1220 put_word(res, stt->entries[i].str->size);
1221 else
1222 put_byte(res, stt->entries[i].str->size);
1223 put_string(res, stt->entries[i].str, win32 ? str_unicode : str_char, FALSE);
1225 else
1227 if(win32)
1228 put_word(res, 0);
1229 else
1230 put_byte(res, 0);
1233 /* Set ResourceSize */
1234 SetResSize(res, restag - lastsize);
1235 if(win32)
1236 put_pad(res);
1237 lastsize = res->size;
1239 return res;
1243 *****************************************************************************
1244 * Function : user2res
1245 * Syntax : res_t *user2res(name_id_t *name, user_t *usr)
1246 * Input :
1247 * name - Name/ordinal of the resource
1248 * usr - The userresource descriptor
1249 * Output : New .res format structure
1250 * Description :
1251 * Remarks :
1252 *****************************************************************************
1254 res_t *user2res(name_id_t *name, user_t *usr)
1256 int restag;
1257 res_t *res;
1258 assert(name != NULL);
1259 assert(usr != NULL);
1261 res = new_res();
1262 restag = put_res_header(res, 0, usr->type, name, usr->memopt, NULL);
1263 put_raw_data(res, usr->data, 0);
1264 /* Set ResourceSize */
1265 SetResSize(res, restag);
1266 if(win32)
1267 put_pad(res);
1268 return res;
1272 *****************************************************************************
1273 * Function : versionblock2res
1274 * Syntax : void versionblock2res(res_t *res, ver_block_t *blk)
1275 * Input :
1276 * res - Binary resource to write to
1277 * blk - The version block to be written
1278 * Output :
1279 * Description :
1280 * Remarks : Self recursive
1281 *****************************************************************************
1283 void versionblock2res(res_t *res, ver_block_t *blk, int level)
1285 ver_value_t *val;
1286 int blksizetag;
1287 int valblksizetag;
1288 int valvalsizetag;
1289 int tag;
1290 int i;
1292 blksizetag = res->size;
1293 put_word(res, 0); /* Will be overwritten later */
1294 put_word(res, 0);
1295 if(win32)
1296 put_word(res, 0); /* level ? */
1297 put_string(res, blk->name, win32 ? str_unicode : str_char, TRUE);
1298 put_pad(res);
1299 for(val = blk->values; val; val = val->next)
1301 if(val->type == val_str)
1303 valblksizetag = res->size;
1304 put_word(res, 0); /* Will be overwritten later */
1305 valvalsizetag = res->size;
1306 put_word(res, 0); /* Will be overwritten later */
1307 if(win32)
1309 put_word(res, level);
1311 put_string(res, val->key, win32 ? str_unicode : str_char, TRUE);
1312 put_pad(res);
1313 tag = res->size;
1314 put_string(res, val->value.str, win32 ? str_unicode : str_char, TRUE);
1315 if(win32)
1316 *(WORD *)&(res->data[valvalsizetag]) = (WORD)((res->size - tag) >> 1);
1317 else
1318 *(WORD *)&(res->data[valvalsizetag]) = (WORD)(res->size - tag);
1319 *(WORD *)&(res->data[valblksizetag]) = (WORD)(res->size - valblksizetag);
1320 put_pad(res);
1322 else if(val->type == val_words)
1324 valblksizetag = res->size;
1325 put_word(res, 0); /* Will be overwritten later */
1326 valvalsizetag = res->size;
1327 put_word(res, 0); /* Will be overwritten later */
1328 if(win32)
1330 put_word(res, level);
1332 put_string(res, val->key, win32 ? str_unicode : str_char, TRUE);
1333 put_pad(res);
1334 tag = res->size;
1335 for(i = 0; i < val->value.words->nwords; i++)
1337 put_word(res, val->value.words->words[i]);
1339 *(WORD *)&(res->data[valvalsizetag]) = (WORD)(res->size - tag);
1340 *(WORD *)&(res->data[valblksizetag]) = (WORD)(res->size - valblksizetag);
1341 put_pad(res);
1343 else if(val->type == val_block)
1345 versionblock2res(res, val->value.block, level+1);
1347 else
1349 internal_error(__FILE__, __LINE__, "Invalid value indicator %d in VERSIONINFO", val->type);
1353 /* Set blocksize */
1354 *(WORD *)&(res->data[blksizetag]) = (WORD)(res->size - blksizetag);
1358 *****************************************************************************
1359 * Function : versioninfo2res
1360 * Syntax : res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver)
1361 * Input :
1362 * name - Name/ordinal of the resource
1363 * ver - The versioninfo descriptor
1364 * Output : New .res format structure
1365 * Description :
1366 * Remarks :
1367 *****************************************************************************
1369 res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver)
1371 int restag;
1372 int rootblocksizetag;
1373 int valsizetag;
1374 int tag;
1375 res_t *res;
1376 string_t vsvi;
1377 ver_block_t *blk;
1379 assert(name != NULL);
1380 assert(ver != NULL);
1382 vsvi.type = str_char;
1383 vsvi.str.cstr = "VS_VERSION_INFO";
1384 vsvi.size = 15; /* Excl. termination */
1386 res = new_res();
1387 restag = put_res_header(res, WRC_RT_VERSION, NULL, name, WRC_MO_MOVEABLE | WRC_MO_PURE, NULL);
1388 rootblocksizetag = res->size;
1389 put_word(res, 0); /* BlockSize filled in later */
1390 valsizetag = res->size;
1391 put_word(res, 0); /* ValueSize filled in later*/
1392 if(win32)
1393 put_word(res, 0); /* Tree-level ? */
1394 put_string(res, &vsvi, win32 ? str_unicode : str_char, TRUE);
1395 if(win32)
1396 put_pad(res);
1397 tag = res->size;
1398 put_dword(res, VS_FFI_SIGNATURE);
1399 put_dword(res, VS_FFI_STRUCVERSION);
1400 put_dword(res, (ver->filever_maj1 << 16) + (ver->filever_maj2 & 0xffff));
1401 put_dword(res, (ver->filever_min1 << 16) + (ver->filever_min2 & 0xffff));
1402 put_dword(res, (ver->prodver_maj1 << 16) + (ver->prodver_maj2 & 0xffff));
1403 put_dword(res, (ver->prodver_min1 << 16) + (ver->prodver_min2 & 0xffff));
1404 put_dword(res, ver->fileflagsmask);
1405 put_dword(res, ver->fileflags);
1406 put_dword(res, ver->fileos);
1407 put_dword(res, ver->filetype);
1408 put_dword(res, ver->filesubtype);
1409 put_dword(res, 0); /* FileDateMS */
1410 put_dword(res, 0); /* FileDateLS */
1411 /* Set ValueSize */
1412 *(WORD *)&(res->data[valsizetag]) = (WORD)(res->size - tag);
1413 /* Descend into the blocks */
1414 for(blk = ver->blocks; blk; blk = blk->next)
1415 versionblock2res(res, blk, 0);
1416 /* Set root block's size */
1417 *(WORD *)&(res->data[rootblocksizetag]) = (WORD)(res->size - rootblocksizetag);
1419 SetResSize(res, restag);
1420 if(win32)
1421 put_pad(res);
1423 return res;
1427 *****************************************************************************
1428 * Function : prep_nid_for_label
1429 * Syntax : char *prep_nid_for_label(name_id_t *nid)
1430 * Input :
1431 * Output :
1432 * Description : Converts a resource name into the first 32 (or less)
1433 * characters of the name with conversions.
1434 * Remarks :
1435 *****************************************************************************
1437 #define MAXNAMELEN 32
1438 char *prep_nid_for_label(name_id_t *nid)
1440 static char buf[MAXNAMELEN+1];
1442 assert(nid != NULL);
1444 if(nid->type == name_str && nid->name.s_name->type == str_unicode)
1446 short *sptr;
1447 int i;
1448 sptr = nid->name.s_name->str.wstr;
1449 buf[0] = '\0';
1450 for(i = 0; *sptr && i < MAXNAMELEN; i++)
1452 if((unsigned)*sptr < 0x80 && isprint((char)*sptr))
1453 buf[i] = *sptr++;
1454 else
1455 warning("Resourcename (str_unicode) contain unprintable characters or invalid translation, ignored");
1457 buf[i] = '\0';
1459 else if(nid->type == name_str && nid->name.s_name->type == str_char)
1461 char *cptr;
1462 int i;
1463 cptr = nid->name.s_name->str.cstr;
1464 buf[0] = '\0';
1465 for(i = 0; *cptr && i < MAXNAMELEN; i++)
1467 if((unsigned)*cptr < 0x80 && isprint(*cptr))
1468 buf[i] = *cptr++;
1469 else
1470 warning("Resourcename (str_char) contain unprintable characters, ignored");
1472 buf[i] = '\0';
1474 else if(nid->type == name_ord)
1476 sprintf(buf, "%u", nid->name.i_name);
1478 else
1480 internal_error(__FILE__, __LINE__, "Resource name_id with invalid type %d", nid->type);
1482 return buf;
1484 #undef MAXNAMELEN
1487 *****************************************************************************
1488 * Function : make_c_name
1489 * Syntax : char *make_c_name(char *base, name_id_t *nid, language_t *lan)
1490 * Input :
1491 * Output :
1492 * Description : Converts a resource name into a valid c-identifier in the
1493 * form "_base_nid".
1494 * Remarks :
1495 *****************************************************************************
1497 char *make_c_name(char *base, name_id_t *nid, language_t *lan)
1499 int nlen;
1500 char *buf;
1501 char *ret;
1502 char lanbuf[6];
1504 sprintf(lanbuf, "%d", lan ? MAKELANGID(lan->id, lan->sub) : 0);
1505 buf = prep_nid_for_label(nid);
1506 nlen = strlen(buf) + strlen(lanbuf);
1507 nlen += strlen(base) + 4; /* three time '_' and '\0' */
1508 ret = (char *)xmalloc(nlen);
1509 strcpy(ret, "_");
1510 strcat(ret, base);
1511 strcat(ret, "_");
1512 strcat(ret, buf);
1513 strcat(ret, "_");
1514 strcat(ret, lanbuf);
1515 return ret;
1519 *****************************************************************************
1520 * Function : get_c_typename
1521 * Syntax : char *get_c_typename(enum res_e type)
1522 * Input :
1523 * Output :
1524 * Description : Convert resource enum to char string to be used in c-name
1525 * creation.
1526 * Remarks :
1527 *****************************************************************************
1529 char *get_c_typename(enum res_e type)
1531 switch(type)
1533 case res_acc: return "Acc";
1534 case res_bmp: return "Bmp";
1535 case res_cur: return "Cur";
1536 case res_curg: return "CurGrp";
1537 case res_dlg:
1538 case res_dlgex: return "Dlg";
1539 case res_fnt: return "Fnt";
1540 case res_ico: return "Ico";
1541 case res_icog: return "IcoGrp";
1542 case res_men:
1543 case res_menex: return "Men";
1544 case res_rdt: return "RCDat";
1545 case res_stt: return "StrTab";
1546 case res_usr: return "Usr";
1547 case res_msg: return "MsgTab";
1548 case res_ver: return "VerInf";
1549 default: return "Oops";
1554 *****************************************************************************
1555 * Function : resources2res
1556 * Syntax : void resources2res(resource_t *top)
1557 * Input :
1558 * top - The resource-tree to convert
1559 * Output :
1560 * Description : Convert logical resource descriptors into binary data
1561 * Remarks :
1562 *****************************************************************************
1564 void resources2res(resource_t *top)
1566 while(top)
1568 switch(top->type)
1570 case res_acc:
1571 if(!top->binres)
1572 top->binres = accelerator2res(top->name, top->res.acc);
1573 break;
1574 case res_bmp:
1575 if(!top->binres)
1576 top->binres = bitmap2res(top->name, top->res.bmp);
1577 break;
1578 case res_cur:
1579 if(!top->binres)
1580 top->binres = cursor2res(top->res.cur);
1581 break;
1582 case res_curg:
1583 if(!top->binres)
1584 top->binres = cursorgroup2res(top->name, top->res.curg);
1585 break;
1586 case res_dlg:
1587 if(!top->binres)
1588 top->binres = dialog2res(top->name, top->res.dlg);
1589 break;
1590 case res_dlgex:
1591 if(!top->binres)
1592 top->binres = dialogex2res(top->name, top->res.dlgex);
1593 break;
1594 case res_fnt:
1595 if(!top->binres)
1596 top->binres = font2res(top->name, top->res.fnt);
1597 break;
1598 case res_ico:
1599 if(!top->binres)
1600 top->binres = icon2res(top->res.ico);
1601 break;
1602 case res_icog:
1603 if(!top->binres)
1604 top->binres = icongroup2res(top->name, top->res.icog);
1605 break;
1606 case res_men:
1607 if(!top->binres)
1608 top->binres = menu2res(top->name, top->res.men);
1609 break;
1610 case res_menex:
1611 if(!top->binres)
1612 top->binres = menuex2res(top->name, top->res.menex);
1613 break;
1614 case res_rdt:
1615 if(!top->binres)
1616 top->binres = rcdata2res(top->name, top->res.rdt);
1617 break;
1618 case res_stt:
1619 if(!top->binres)
1620 top->binres = stringtable2res(top->res.stt);
1621 break;
1622 case res_usr:
1623 if(!top->binres)
1624 top->binres = user2res(top->name, top->res.usr);
1625 break;
1626 case res_msg:
1627 if(!top->binres)
1628 top->binres = messagetable2res(top->name, top->res.msg);
1629 break;
1630 case res_ver:
1631 if(!top->binres)
1632 top->binres = versioninfo2res(top->name, top->res.ver);
1633 break;
1634 default:
1635 internal_error(__FILE__, __LINE__, "Unknown resource type encountered %d in binary res generation", top->type);
1637 top->c_name = make_c_name(get_c_typename(top->type), top->name, top->lan);
1638 top = top->next;