Release 20020509.
[wine] / tools / wrc / dumpres.c
1 /*
2  * Copyright 1998 Bertho A. Stultiens (BS)
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 #include "config.h"
20
21 #include <assert.h>
22 #include <stdio.h>
23 #include <ctype.h>
24
25 #include "wrc.h"
26 #include "dumpres.h"
27
28 /*
29  *****************************************************************************
30  * Function     : get_typename
31  * Syntax       : char *get_typename(resource_t* r)
32  * Input        :
33  *      r       - Resource description
34  * Output       : A pointer to a string representing the resource type
35  * Description  :
36  * Remarks      :
37  *****************************************************************************
38 */
39 char *get_typename(resource_t* r)
40 {
41         switch(r->type){
42         case res_acc:   return "ACCELERATOR";
43         case res_bmp:   return "BITMAP";
44         case res_cur:   return "CURSOR";
45         case res_curg:  return "GROUP_CURSOR";
46         case res_dlg:   return "DIALOG";
47         case res_dlgex: return "DIALOGEX";
48         case res_fnt:   return "FONT";
49         case res_ico:   return "ICON";
50         case res_icog:  return "GROUP_ICON";
51         case res_men:   return "MENU";
52         case res_menex: return "MENUEX";
53         case res_rdt:   return "RCDATA";
54         case res_stt:   return "STRINGTABLE";
55         case res_usr:   return "UserResource";
56         case res_msg:   return "MESSAGETABLE";
57         case res_ver:   return "VERSIONINFO";
58         case res_dlginit: return "DLGINIT";
59         case res_toolbar: return "TOOLBAR";
60         case res_anicur:  return "CURSOR (animated)";
61         case res_aniico:  return "ICON (animated)";
62         default:        return "Unknown";
63         }
64 }
65
66 /*
67  *****************************************************************************
68  * Function     : strncpyWtoA
69  * Syntax       : char *strncpyWtoA(char *cs, short *ws, int maxlen)
70  * Input        :
71  *      cs      - Pointer to buffer to receive result
72  *      ws      - Source wide-string
73  *      maxlen  - Max chars to copy
74  * Output       : 'cs'
75  * Description  : Copy a unicode string to ascii. Copying stops after the
76  *                first occurring '\0' or when maxlen-1 chars are copied. The
77  *                String is always nul terminated.
78  * Remarks      : No codepage translation is done.
79  *****************************************************************************
80 */
81 char *strncpyWtoA(char *cs, short *ws, int maxlen)
82 {
83         char *cptr = cs;
84         short *wsMax = ws + maxlen;
85         while(ws < wsMax)
86         {
87                 if(*ws < -128 || *ws > 127)
88                         printf("***Warning: Unicode string contains non-printable chars***");
89                 *cptr++ = (char)*ws++;
90                 maxlen--;
91         }
92         *cptr = '\0';
93         return cs;
94 }
95
96 /*
97  *****************************************************************************
98  * Function     : print_string
99  * Syntax       : void print_string(string_t *str)
100  * Input        :
101  * Output       :
102  * Description  :
103  * Remarks      :
104  *****************************************************************************
105 */
106 void print_string(string_t *str)
107 {
108         char buffer[512];
109         if(!str)
110                 printf("<none>");
111         else if(str->type == str_char)
112                 printf("\"%s\"", str->str.cstr);
113         else
114         {
115                 strncpyWtoA(buffer, str->str.wstr, sizeof(buffer));
116                 printf("L\"%s\"", buffer);
117         }
118 }
119
120 /*
121  *****************************************************************************
122  * Function     : get_nameid_str
123  * Syntax       : char *get_nameid_str(name_id_t *n)
124  * Input        :
125  *      n       - nameid to convert to text
126  * Output       : A pointer to the name.
127  * Description  :
128  * Remarks      : Not reentrant because of static buffer
129  *****************************************************************************
130 */
131 char *get_nameid_str(name_id_t *n)
132 {
133         static char buffer[256];
134
135         if(!n)
136                 return "<none>";
137
138         if(n->type == name_ord)
139         {
140                 sprintf(buffer, "%d", n->name.i_name);
141                 return buffer;
142         }
143         else if(n->type == name_str)
144         {
145                 if(n->name.s_name->type == str_char)
146                         return n->name.s_name->str.cstr;
147                 else
148                 {
149                         strncpyWtoA(buffer, n->name.s_name->str.wstr, sizeof(buffer));
150                         return buffer;
151                 }
152         }
153         else
154                 return "Hoooo, report this: wrong type in nameid";
155 }
156
157 /*
158  *****************************************************************************
159  * Function     : dump_memopt
160  * Syntax       : void dump_memopt(DWORD memopt)
161  * Input        :
162  *      memopt  - flag bits of the options set
163  * Output       :
164  * Description  :
165  * Remarks      :
166  *****************************************************************************
167 */
168 static void dump_memopt(DWORD memopt)
169 {
170         printf("Memory/load options: ");
171         if(memopt & 0x0040)
172                 printf("PRELOAD ");
173         else
174                 printf("LOADONCALL ");
175         if(memopt & 0x0010)
176                 printf("MOVEABLE ");
177         else
178                 printf("FIXED ");
179         if(memopt & 0x0020)
180                 printf("PURE ");
181         else
182                 printf("IMPURE ");
183         if(memopt & 0x1000)
184                 printf("DISCARDABLE");
185         printf("\n");
186 }
187
188 /*
189  *****************************************************************************
190  * Function     : dump_lvc
191  * Syntax       : void dump_lvc(lvc_t *l)
192  * Input        :
193  *      l       - pointer to lvc structure
194  * Output       :
195  * Description  : Dump language, version and characteristics
196  * Remarks      :
197  *****************************************************************************
198 */
199 static void dump_lvc(lvc_t *l)
200 {
201         if(l->language)
202                 printf("LANGUAGE %04x, %04x\n", l->language->id, l->language->sub);
203         else
204                 printf("LANGUAGE <not set>\n");
205
206         if(l->version)
207                 printf("VERSION %08lx\n", *(l->version));
208         else
209                 printf("VERSION <not set>\n");
210
211         if(l->characts)
212                 printf("CHARACTERISTICS %08lx\n", *(l->characts));
213         else
214                 printf("CHARACTERISTICS <not set>\n");
215 }
216
217 /*
218  *****************************************************************************
219  * Function     : dump_raw_data
220  * Syntax       : void dump_raw_data(raw_data_t *d)
221  * Input        :
222  *      d       - Raw data descriptor
223  * Output       :
224  * Description  :
225  * Remarks      :
226  *****************************************************************************
227 */
228 static void dump_raw_data(raw_data_t *d)
229 {
230         unsigned int n;
231         int i;
232         int j;
233
234         if(!d)
235         {
236                 printf("<none>");
237                 return;
238         }
239         printf("Rawdata size: %d\n", d->size);
240         if(debuglevel < 2)
241                 return;
242
243         for(n = 0; n < d->size; n++)
244         {
245                 if((n % 16) == 0) 
246                 {
247                         if(n)
248                         {
249                                 printf("- ");
250                                 for(i = 0; i < 16; i++)
251                                         printf("%c", isprint(d->data[n-16+i] & 0xff) ? d->data[n-16+i] : '.');
252                                 printf("\n%08x: ", n);
253                         }
254                         else
255                                 printf("%08x: ", n);
256                 }
257                 printf("%02x ", d->data[n] & 0xff);
258         }
259         printf("- ");
260         j = d->size % 16;
261         if(!j)
262                 j = 16;
263         for(i = 0; i < j; i++)
264                 printf("%c", isprint(d->data[n-j+i] & 0xff) ? d->data[n-j+i] : '.');
265         printf("\n");
266 }
267
268 /*
269  *****************************************************************************
270  * Function     : dump_accelerator
271  * Syntax       : void dump_accelerator(resource_t *acc)
272  * Input        :
273  *      acc     - Accelerator resource descriptor
274  * Output       : nop
275  * Description  :
276  * Remarks      :
277  *****************************************************************************
278 */
279 static void dump_accelerator(accelerator_t *acc)
280 {
281         event_t *ev = acc->events;
282
283         dump_memopt(acc->memopt);
284         dump_lvc(&(acc->lvc));
285
286         printf("Events: %s\n", ev ? "" : "<none>");
287         while(ev)
288         {
289                 printf("Key=");
290                 if(isprint(ev->key))
291                         printf("\"%c\"", ev->key);
292                 else if(iscntrl(ev->key))
293                         printf("\"^%c\"", ev->key +'@');
294                 else
295                         printf("\\x%02x", ev->key & 0xff);
296
297                 printf(" Id=%d flags=%04x\n", ev->id, ev->flags);
298                 ev = ev->next;
299         }
300 }
301
302 /*
303  *****************************************************************************
304  * Function     : dump_cursor
305  * Syntax       : void dump_cursor(cursor_t *cur)
306  * Input        :
307  *      cur     - Cursor resource descriptor
308  * Output       : nop
309  * Description  :
310  * Remarks      :
311  *****************************************************************************
312 */
313 static void dump_cursor(cursor_t *cur)
314 {
315         printf("Id: %d\n", cur->id);
316         printf("Width: %d\n", cur->width);
317         printf("Height: %d\n", cur->height);
318         printf("X Hotspot: %d\n", cur->xhot);
319         printf("Y Hotspot: %d\n", cur->yhot);
320         dump_raw_data(cur->data);
321 }
322
323 /*
324  *****************************************************************************
325  * Function     : dump_cursor_group
326  * Syntax       : void dump_cursor_group(cursor_group_t *cur)
327  * Input        :
328  *      cur     - Cursor group resource descriptor
329  * Output       : nop
330  * Description  :
331  * Remarks      :
332  *****************************************************************************
333 */
334 static void dump_cursor_group(cursor_group_t *curg)
335 {
336         dump_memopt(curg->memopt);
337         printf("There are %d cursors in this group\n", curg->ncursor);
338 }
339
340 /*
341  *****************************************************************************
342  * Function     : dump_icon
343  * Syntax       : void dump_icon(icon_t *ico)
344  * Input        :
345  *      ico     - Icon resource descriptor
346  * Output       : nop
347  * Description  :
348  * Remarks      :
349  *****************************************************************************
350 */
351 static void dump_icon(icon_t *ico)
352 {
353         printf("Id: %d\n", ico->id);
354         printf("Width: %d\n", ico->width);
355         printf("Height: %d\n", ico->height);
356         printf("NColor: %d\n", ico->nclr);
357         printf("NPlanes: %d\n", ico->planes);
358         printf("NBits: %d\n", ico->bits);
359         dump_raw_data(ico->data);
360 }
361
362 /*
363  *****************************************************************************
364  * Function     : dump_icon_group
365  * Syntax       : void dump_icon_group(icon_group_t *ico)
366  * Input        :
367  *      ico     - Icon group resource descriptor
368  * Output       : nop
369  * Description  :
370  * Remarks      :
371  *****************************************************************************
372 */
373 static void dump_icon_group(icon_group_t *icog)
374 {
375         dump_memopt(icog->memopt);
376         printf("There are %d icons in this group\n", icog->nicon);
377 }
378
379 /*
380  *****************************************************************************
381  * Function     : dump_ani_curico
382  * Syntax       : void dump_ani_curico(ani_curico_t *ani)
383  * Input        :
384  *      ani     - Animated object resource descriptor
385  * Output       : nop
386  * Description  :
387  * Remarks      :
388  *****************************************************************************
389 */
390 static void dump_ani_curico(ani_curico_t *ani)
391 {
392         dump_memopt(ani->memopt);
393         dump_lvc(&ani->data->lvc);
394         dump_raw_data(ani->data);
395 }
396
397 /*
398  *****************************************************************************
399  * Function     : dump_font
400  * Syntax       : void dump_font(font_t *fnt)
401  * Input        :
402  *      fnt     - Font resource descriptor
403  * Output       : nop
404  * Description  :
405  * Remarks      :
406  *****************************************************************************
407 */
408 static void dump_font(font_t *fnt)
409 {
410         dump_memopt(fnt->memopt);
411         dump_lvc(&(fnt->data->lvc));
412         dump_raw_data(fnt->data);
413 }
414
415 /*
416  *****************************************************************************
417  * Function     : dump_bitmap
418  * Syntax       : void dump_bitmap(bitmap_t *bmp)
419  * Input        :
420  *      bmp     - Bitmap resource descriptor
421  * Output       : nop
422  * Description  :
423  * Remarks      :
424  *****************************************************************************
425 */
426 static void dump_bitmap(bitmap_t *bmp)
427 {
428         dump_memopt(bmp->memopt);
429         dump_lvc(&(bmp->data->lvc));
430         dump_raw_data(bmp->data);
431 }
432
433 /*
434  *****************************************************************************
435  * Function     : dump_rcdata
436  * Syntax       : void dump_rcdata(rcdata_t *rdt)
437  * Input        :
438  *      rdt     - RCData resource descriptor
439  * Output       : nop
440  * Description  :
441  * Remarks      :
442  *****************************************************************************
443 */
444 static void dump_rcdata(rcdata_t *rdt)
445 {
446         dump_memopt(rdt->memopt);
447         dump_lvc(&(rdt->data->lvc));
448         dump_raw_data(rdt->data);
449 }
450
451 /*
452  *****************************************************************************
453  * Function     : dump_user
454  * Syntax       : void dump_user(user_t *usr)
455  * Input        :
456  *      usr     - User resource descriptor
457  * Output       : nop
458  * Description  :
459  * Remarks      :
460  *****************************************************************************
461 */
462 static void dump_user(user_t *usr)
463 {
464         dump_memopt(usr->memopt);
465         dump_lvc(&(usr->data->lvc));
466         printf("Class %s\n", get_nameid_str(usr->type));
467         dump_raw_data(usr->data);
468 }
469
470 /*
471  *****************************************************************************
472  * Function     : dump_messagetable
473  * Syntax       : void dump_messagetable(messagetable_t *msg)
474  * Input        :
475  *      msg     - Messagetable resource descriptor
476  * Output       : nop
477  * Description  :
478  * Remarks      :
479  *****************************************************************************
480 */
481 static void dump_messagetable(messagetable_t *msg)
482 {
483         dump_memopt(msg->memopt);
484         dump_lvc(&(msg->data->lvc));
485         dump_raw_data(msg->data);
486 }
487
488 /*
489  *****************************************************************************
490  * Function     : dump_stringtable
491  * Syntax       : void dump_stringtable(stringtable_t *stt)
492  * Input        :
493  *      stt     - Stringtable resource descriptor
494  * Output       : nop
495  * Description  :
496  * Remarks      :
497  *****************************************************************************
498 */
499 static void dump_stringtable(stringtable_t *stt)
500 {
501         int i;
502         for(; stt; stt = stt->next)
503         {
504                 printf("{\n");
505                 dump_memopt(stt->memopt);
506                 dump_lvc(&(stt->lvc));
507                 for(i = 0; i < stt->nentries; i++)
508                 {
509                         printf("Id=%-5d (%d) ", stt->idbase+i, stt->entries[i].id);
510                         if(stt->entries[i].str)
511                                 print_string(stt->entries[i].str);
512                         else
513                                 printf("<none>");
514                         printf("\n");
515                 }
516                 printf("}\n");
517         }
518 }
519
520 /*
521  *****************************************************************************
522  * Function     : dump_control
523  * Syntax       : void dump_control(control_t *ctrl)
524  * Input        :
525  *      ctrl    - Control resource descriptor
526  * Output       :
527  * Description  :
528  * Remarks      :
529  *****************************************************************************
530 */
531 static void dump_control(control_t *ctrl)
532 {
533         printf("Control {\n\tClass: %s\n", get_nameid_str(ctrl->ctlclass));
534         printf("\tText: "); get_nameid_str(ctrl->title); printf("\n");
535         printf("\tId: %d\n", ctrl->id);
536         printf("\tx, y, w, h: %d, %d, %d, %d\n", ctrl->x, ctrl->y, ctrl->width, ctrl->height);
537         if(ctrl->gotstyle)
538         {
539                 assert(ctrl->style != NULL);
540                 assert(ctrl->style->and_mask == 0);
541                 printf("\tStyle: %08lx\n", ctrl->style->or_mask);
542         }
543         if(ctrl->gotexstyle)
544         {
545                 assert(ctrl->exstyle != NULL);
546                 assert(ctrl->exstyle->and_mask == 0);
547                 printf("\tExStyle: %08lx\n", ctrl->exstyle->or_mask);
548         }
549         if(ctrl->gothelpid)
550                 printf("\tHelpid: %ld\n", ctrl->helpid);
551         if(ctrl->extra)
552         {
553                 printf("\t");
554                 dump_raw_data(ctrl->extra);
555         }
556         printf("}\n");
557 }
558
559 /*
560  *****************************************************************************
561  * Function     : dump_dialog
562  * Syntax       : void dump_dialog(dialog_t *dlg)
563  * Input        :
564  *      dlg     - Dialog resource descriptor
565  * Output       :
566  * Description  :
567  * Remarks      :
568  *****************************************************************************
569 */
570 static void dump_dialog(dialog_t *dlg)
571 {
572         control_t *c = dlg->controls;
573
574         dump_memopt(dlg->memopt);
575         dump_lvc(&(dlg->lvc));
576         printf("x, y, w, h: %d, %d, %d, %d\n", dlg->x, dlg->y, dlg->width, dlg->height);
577         if(dlg->gotstyle)
578         {
579                 assert(dlg->style != NULL);
580                 assert(dlg->style->and_mask == 0);
581                 printf("Style: %08lx\n", dlg->style->or_mask);
582                 
583         }
584         if(dlg->gotexstyle)
585         {
586                 assert(dlg->exstyle != NULL);
587                 assert(dlg->exstyle->and_mask == 0);
588                 printf("ExStyle: %08lx\n", dlg->exstyle->or_mask);
589         }
590         printf("Menu: %s\n", get_nameid_str(dlg->menu));
591         printf("Class: %s\n", get_nameid_str(dlg->dlgclass));
592         printf("Title: "); print_string(dlg->title); printf("\n");
593         printf("Font: ");
594         if(!dlg->font)
595                 printf("<none>\n");
596         else
597         {
598                 printf("%d, ", dlg->font->size);
599                 print_string(dlg->font->name);
600                 printf("\n");
601         }
602         while(c)
603         {
604                 dump_control(c);
605                 c = c->next;
606         }
607 }
608
609 /*
610  *****************************************************************************
611  * Function     : dump_dialogex
612  * Syntax       : void dump_dialogex(dialogex_t *dlgex)
613  * Input        :
614  *      dlgex   - DialogEx resource descriptor
615  * Output       :
616  * Description  :
617  * Remarks      :
618  *****************************************************************************
619 */
620 static void dump_dialogex(dialogex_t *dlgex)
621 {
622         control_t *c = dlgex->controls;
623
624         dump_memopt(dlgex->memopt);
625         dump_lvc(&(dlgex->lvc));
626         printf("x, y, w, h: %d, %d, %d, %d\n", dlgex->x, dlgex->y, dlgex->width, dlgex->height);
627         if(dlgex->gotstyle)
628         {
629                 assert(dlgex->style != NULL);
630                 assert(dlgex->style->and_mask == 0);
631                 printf("Style: %08lx\n", dlgex->style->or_mask);
632         }
633         if(dlgex->gotexstyle)
634         {
635                 assert(dlgex->exstyle != NULL);
636                 assert(dlgex->exstyle->and_mask == 0);
637                 printf("ExStyle: %08lx\n", dlgex->exstyle->or_mask);
638         }
639         if(dlgex->gothelpid)
640                 printf("Helpid: %ld\n", dlgex->helpid);
641         printf("Menu: %s\n", get_nameid_str(dlgex->menu));
642         printf("Class: %s\n", get_nameid_str(dlgex->dlgclass));
643         printf("Title: "); print_string(dlgex->title); printf("\n");
644         printf("Font: ");
645         if(!dlgex->font)
646                 printf("<none>\n");
647         else
648         {
649                 printf("%d, ", dlgex->font->size);
650                 print_string(dlgex->font->name);
651                 printf(", %d, %d\n", dlgex->font->weight, dlgex->font->italic);
652         }
653         while(c)
654         {
655                 dump_control(c);
656                 c = c->next;
657         }
658 }
659
660 /*
661  *****************************************************************************
662  * Function     : dump_menu_item
663  * Syntax       : void dump_menu_item(menu_item_t *item)
664  * Input        :
665  * Output       :
666  * Description  :
667  * Remarks      :
668  *****************************************************************************
669 */
670 static void dump_menu_item(menu_item_t *item)
671 {
672         while(item)
673         {
674                 if(item->popup)
675                 {
676                         printf("POPUP ");
677                         print_string(item->name);
678                         printf("\n");
679                         dump_menu_item(item->popup);
680                 }
681                 else
682                 {
683                         printf("MENUITEM ");
684                         if(item->name)
685                         {
686                                 print_string(item->name);
687                                 printf(", %d, %08lx", item->id, item->state);
688                         }
689                         else
690                                 printf("SEPARATOR");
691                         printf("\n");
692                 }
693                 item = item->next;
694         }
695 }
696
697 /*
698  *****************************************************************************
699  * Function     : dump_menu
700  * Syntax       : void dump_menu(menu_t *men)
701  * Input        :
702  *      men     - Menu resource descriptor
703  * Output       :
704  * Description  :
705  * Remarks      :
706  *****************************************************************************
707 */
708 static void dump_menu(menu_t *men)
709 {
710         dump_memopt(men->memopt);
711         dump_lvc(&(men->lvc));
712         dump_menu_item(men->items);
713 }
714
715 /*
716  *****************************************************************************
717  * Function     : dump_menuex_item
718  * Syntax       : void dump_menuex_item(menuex_item_t *item)
719  * Input        :
720  * Output       :
721  * Description  :
722  * Remarks      :
723  *****************************************************************************
724 */
725 static void dump_menuex_item(menuex_item_t *item)
726 {
727         while(item)
728         {
729                 if(item->popup)
730                 {
731                         printf("POPUP ");
732                         print_string(item->name);
733                         if(item->gotid)
734                                 printf(", Id=%d", item->id);
735                         if(item->gottype)
736                                 printf(", Type=%ld", item->type);
737                         if(item->gotstate)
738                                 printf(", State=%08lx", item->state);
739                         if(item->gothelpid)
740                                 printf(", HelpId=%d", item->helpid);
741                         printf("\n");
742                         dump_menuex_item(item->popup);
743                 }
744                 else
745                 {
746                         printf("MENUITEM ");
747                         if(item->name)
748                         {
749                                 print_string(item->name);
750                                 if(item->gotid)
751                                         printf(", Id=%d", item->id);
752                                 if(item->gottype)
753                                         printf(", Type=%ld", item->type);
754                                 if(item->gotstate)
755                                         printf(", State=%08lx", item->state);
756                                 if(item->gothelpid)
757                                         printf(", HelpId=%d", item->helpid);
758                         }
759                         else
760                                 printf("SEPARATOR");
761                         printf("\n");
762                 }
763                 item = item->next;
764         }
765 }
766
767 /*
768  *****************************************************************************
769  * Function     : dump_menuex
770  * Syntax       : void dump_menuex(dialogex_t *menex)
771  * Input        :
772  *      menex   - MenuEx resource descriptor
773  * Output       :
774  * Description  :
775  * Remarks      :
776  *****************************************************************************
777 */
778 static void dump_menuex(menuex_t *menex)
779 {
780         dump_memopt(menex->memopt);
781         dump_lvc(&(menex->lvc));
782         dump_menuex_item(menex->items);
783 }
784
785 /*
786  *****************************************************************************
787  * Function     : dump_ver_value
788  * Syntax       : void dump_ver_value(ver_value_t *val)
789  * Input        :
790  * Output       :
791  * Description  :
792  * Remarks      :
793  *****************************************************************************
794 */
795 static void dump_ver_block(ver_block_t *);      /* Forward ref */
796
797 static void dump_ver_value(ver_value_t *val)
798 {
799         if(val->type == val_str)
800         {
801                 printf("VALUE ");
802                 print_string(val->key);
803                 printf(" ");
804                 print_string(val->value.str);
805                 printf("\n");
806         }
807         else if(val->type == val_words)
808         {
809                 int i;
810                 printf("VALUE");
811                 print_string(val->key);
812                 for(i = 0; i < val->value.words->nwords; i++)
813                         printf(" %04x", val->value.words->words[i]);
814                 printf("\n");
815         }
816         else if(val->type == val_block)
817         {
818                 dump_ver_block(val->value.block);
819         }
820 }
821
822 /*
823  *****************************************************************************
824  * Function     : dump_ver_block
825  * Syntax       : void dump_ver_block(ver_block_t *blk)
826  * Input        :
827  * Output       :
828  * Description  :
829  * Remarks      :
830  *****************************************************************************
831 */
832 static void dump_ver_block(ver_block_t *blk)
833 {
834         ver_value_t *val = blk->values;
835         printf("BLOCK ");
836         print_string(blk->name);
837         printf("\n{\n");
838         while(val)
839         {
840                 dump_ver_value(val);
841                 val = val->next;
842         }
843         printf("}\n");
844 }
845
846 /*
847  *****************************************************************************
848  * Function     : dump_versioninfo
849  * Syntax       : void dump_versioninfo(versioninfo_t *ver)
850  * Input        :
851  *      ver     - Versioninfo resource descriptor
852  * Output       :
853  * Description  :
854  * Remarks      :
855  *****************************************************************************
856 */
857 static void dump_versioninfo(versioninfo_t *ver)
858 {
859         ver_block_t *blk = ver->blocks;
860
861         dump_lvc(&(ver->lvc));
862
863         if(ver->gotit.fv)
864                 printf("FILEVERSION %04x, %04x, %04x, %04x\n",
865                         ver->filever_maj1,
866                         ver->filever_maj2,
867                         ver->filever_min1,
868                         ver->filever_min2);
869         if(ver->gotit.pv)
870                 printf("PRODUCTVERSION %04x, %04x, %04x, %04x\n",
871                         ver->prodver_maj1,
872                         ver->prodver_maj2,
873                         ver->prodver_min1,
874                         ver->prodver_min2);
875         if(ver->gotit.fo)
876                 printf("FILEOS %08x\n", ver->fileos);
877         if(ver->gotit.ff)
878                 printf("FILEFLAGS %08x\n", ver->fileflags);
879         if(ver->gotit.ffm)
880                 printf("FILEFLAGSMASK %08x\n", ver->fileflagsmask);
881         if(ver->gotit.ft)
882                 printf("FILETYPE %08x\n", ver->filetype);
883         if(ver->gotit.fst)
884                 printf("FILESUBTYPE %08x\n", ver->filesubtype);
885         while(blk)
886         {
887                 dump_ver_block(blk);
888                 blk = blk->next;
889         }
890 }
891
892 /*
893  *****************************************************************************
894  * Function     : dump_toolbar_item
895  * Syntax       : void dump_toolbar_item(toolbar_item_t *item)
896  * Input        :
897  * Output       :
898  * Description  :
899  * Remarks      :
900  *****************************************************************************
901 */
902 static void dump_toolbar_items(toolbar_item_t *items)
903 {
904         while(items)
905         {
906                 if(items->id)
907                         printf("   BUTTON %d", items->id );
908                 else
909                         printf("   SEPARATOR");
910
911                 printf("\n");
912               
913                 items = items->next;
914         }
915 }
916
917 /*
918  *****************************************************************************
919  * Function     : dump_toolbar
920  * Syntax       : void dump_toolbar(toolbar_t *toolbar)
921  * Input        :
922  *      toolbar - Toolbar resource descriptor
923  * Output       :
924  * Description  :
925  * Remarks      :
926  *****************************************************************************
927 */
928 static void dump_toolbar(toolbar_t *toolbar)
929 {
930         dump_memopt(toolbar->memopt);
931         dump_lvc(&(toolbar->lvc));
932         dump_toolbar_items(toolbar->items);
933 }
934
935 /*
936  *****************************************************************************
937  * Function     : dump_dlginit
938  * Syntax       : void dump_dlginit(dlginit_t *dit)
939  * Input        :
940  *      dit     - DlgInit resource descriptor
941  * Output       :
942  * Description  :
943  * Remarks      :
944  *****************************************************************************
945 */
946 static void dump_dlginit(dlginit_t *dit)
947 {
948         dump_memopt(dit->memopt);
949         dump_lvc(&(dit->data->lvc));
950         dump_raw_data(dit->data);
951 }
952
953 /*
954  *****************************************************************************
955  * Function     :
956  * Syntax       :
957  * Input        :
958  * Output       :
959  * Description  :
960  * Remarks      :
961  *****************************************************************************
962 */
963 /*
964  *****************************************************************************
965  * Function     : dump_resources
966  * Syntax       : void dump_resources(resource_t *top)
967  * Input        :
968  *      top     - Top of the resource tree
969  * Output       :
970  *      nop
971  * Description  : Dump the parsed resource-tree to stdout
972  * Remarks      :
973  *****************************************************************************
974 */
975 void dump_resources(resource_t *top)
976 {
977         printf("Internal resource-tree dump:\n");
978         while(top)
979         {
980                 printf("Resource: %s\nId: %s\n",
981                        get_typename(top),
982                        get_nameid_str(top->name));
983                 switch(top->type)
984                 {
985                 case res_acc:
986                         dump_accelerator(top->res.acc);
987                         break;
988                 case res_bmp:
989                         dump_bitmap(top->res.bmp);
990                         break;
991                 case res_cur:
992                         dump_cursor(top->res.cur);
993                         break;
994                 case res_curg:
995                         dump_cursor_group(top->res.curg);
996                         break;
997                 case res_dlg:
998                         dump_dialog(top->res.dlg);
999                         break;
1000                 case res_dlgex:
1001                         dump_dialogex(top->res.dlgex);
1002                         break;
1003                 case res_fnt:
1004                         dump_font(top->res.fnt);
1005                         break;
1006                 case res_icog:
1007                         dump_icon_group(top->res.icog);
1008                         break;
1009                 case res_ico:
1010                         dump_icon(top->res.ico);
1011                         break;
1012                 case res_men:
1013                         dump_menu(top->res.men);
1014                         break;
1015                 case res_menex:
1016                         dump_menuex(top->res.menex);
1017                         break;
1018                 case res_rdt:
1019                         dump_rcdata(top->res.rdt);
1020                         break;
1021                 case res_stt:
1022                         dump_stringtable(top->res.stt);
1023                         break;
1024                 case res_usr:
1025                         dump_user(top->res.usr);
1026                         break;
1027                 case res_msg:
1028                         dump_messagetable(top->res.msg);
1029                         break;
1030                 case res_ver:
1031                         dump_versioninfo(top->res.ver);
1032                         break;
1033                 case res_dlginit:
1034                         dump_dlginit(top->res.dlgi);
1035                         break;
1036                 case res_toolbar:
1037                         dump_toolbar(top->res.tbt);
1038                         break;
1039                 case res_anicur:
1040                 case res_aniico:
1041                         dump_ani_curico(top->res.ani);
1042                         break;
1043                 default:
1044                         printf("Report this: Unknown resource type parsed %08x\n", top->type);
1045                 }
1046                 printf("\n");
1047                 top = top->next;
1048         }
1049 }
1050