2 * Write .res, .s and .h file(s) from a resource-tree
4 * Copyright 1998 Bertho A. Stultiens
21 #ifdef NEED_UNDERSCORE_PREFIX
22 char Underscore[] = "_";
24 char Underscore[] = "";
27 static char s_file_head_str[] =
28 "/* This file is generated with wrc version " WRC_FULLVERSION ". Do not edit! */\n"
37 static char s_file_tail_str[] =
42 static char s_file_autoreg_str[] =
46 #ifdef NEED_UNDERSCORE_PREFIX
47 "\tcall\t_LIBRES_RegisterResources\n"
49 "\tcall\tLIBRES_RegisterResources\n"
54 ".stabs \"___CTOR_LIST__\",22,0,0,.LAuto_Register\n\n"
56 "\t.section .ctors,\"aw\"\n"
57 "\t.long\t.LAuto_Register\n\n"
61 static char h_file_head_str[] =
63 " * This file is generated with wrc version " WRC_FULLVERSION ". Do not edit!\n"
69 "#ifndef __%08lx_H\n" /* This becomes the date of compile */
72 "#include <wrc_rsc.h>\n"
76 static char h_file_tail_str[] =
81 char _NEResTab[] = "_NEResTab";
82 char _PEResTab[] = "_PEResTab";
83 char _ResTable[] = "_ResTable";
85 /* Variables used for resource sorting */
86 res_count_t *rcarray = NULL; /* Type-level count array */
87 int rccount = 0; /* Nr of entries in the type-level array */
88 int n_id_entries = 0; /* win32 only: Nr of unique ids in the type-level array */
89 int n_name_entries = 0; /* win32 only: Nr of unique namess in the type-level array */
91 static int direntries; /* win32 only: Total number of unique resources */
94 *****************************************************************************
95 * Function : write_resfile
96 * Syntax : void write_resfile(char *outname, resource_t *top)
98 * outname - Filename to write to
99 * top - The resource-tree to convert
103 *****************************************************************************
105 void write_resfile(char *outname, resource_t *top)
109 char zeros[3] = {0, 0, 0};
111 fo = fopen(outname, "wb");
114 error("Could not open %s\n", outname);
119 /* Put an empty resource first to signal win32 format */
120 res_t *res = new_res();
121 put_dword(res, 0); /* ResSize */
122 put_dword(res, 0x00000020); /* HeaderSize */
123 put_word(res, 0xffff); /* ResType */
125 put_word(res, 0xffff); /* ResName */
127 put_dword(res, 0); /* DataVersion */
128 put_word(res, 0); /* Memory options */
129 put_word(res, 0); /* Language */
130 put_dword(res, 0); /* Version */
131 put_dword(res, 0); /* Charateristics */
132 ret = fwrite(res->data, 1, res->size, fo);
136 error("Error writing %s", outname);
141 for(; top; top = top->next)
146 ret = fwrite(top->binres->data, 1, top->binres->size, fo);
147 if(ret != top->binres->size)
150 error("Error writing %s", outname);
152 if(win32 && (top->binres->size & 0x03))
155 ret = fwrite(zeros, 1, 4 - (top->binres->size & 0x03), fo);
156 if(ret != 4 - (top->binres->size & 0x03))
159 error("Error writing %s", outname);
167 *****************************************************************************
168 * Function : write_s_res
169 * Syntax : void write_s_res(FILE *fp, res_t *res)
174 *****************************************************************************
176 #define BYTESPERLINE 8
177 static void write_s_res(FILE *fp, res_t *res)
179 int idx = res->dataidx;
181 int rest = (end - idx) % BYTESPERLINE;
182 int lines = (end - idx) / BYTESPERLINE;
185 for(i = 0 ; i < lines; i++)
187 fprintf(fp, "\t.byte\t");
188 for(j = 0; j < BYTESPERLINE; j++, idx++)
190 fprintf(fp, "0x%02x%s", res->data[idx] & 0xff,
191 j == BYTESPERLINE-1 ? "" : ", ");
197 fprintf(fp, "\t.byte\t");
198 for(j = 0; j < rest; j++, idx++)
200 fprintf(fp, "0x%02x%s", res->data[idx] & 0xff,
201 j == rest-1 ? "" : ", ");
209 *****************************************************************************
210 * Function : write_name_str
211 * Syntax : void write_name_str(FILE *fp, name_id_t *nid)
215 * Remarks : One level self recursive for string type conversion
216 *****************************************************************************
218 static void write_name_str(FILE *fp, name_id_t *nid)
221 assert(nid->type == name_str);
223 if(!win32 && nid->name.s_name->type == str_char)
225 res.size = strlen(nid->name.s_name->str.cstr);
227 error("Can't write strings larger than 254 bytes");
229 internal_error(__FILE__, __LINE__, "Attempt to write empty string");
231 res.data = (char *)xmalloc(res.size + 1);
232 res.data[0] = (char)res.size;
233 res.size++; /* We need to write the length byte as well */
234 strcpy(res.data+1, nid->name.s_name->str.cstr);
235 write_s_res(fp, &res);
238 else if(!win32 && nid->name.s_name->type == str_unicode)
243 lnid.type = name_str;
244 lnid.name.s_name = &str;
246 str.str.cstr = dupwstr2cstr(nid->name.s_name->str.wstr);
247 write_name_str(fp, &lnid);
250 else if(win32 && nid->name.s_name->type == str_char)
255 lnid.type = name_str;
256 lnid.name.s_name = &str;
257 str.type = str_unicode;
258 str.str.wstr = dupcstr2wstr(nid->name.s_name->str.cstr);
259 write_name_str(fp, &lnid);
262 else if(win32 && nid->name.s_name->type == str_unicode)
264 res.size = wstrlen(nid->name.s_name->str.wstr);
266 error("Can't write strings larger than 65534 bytes");
268 internal_error(__FILE__, __LINE__, "Attempt to write empty string");
270 res.data = (char *)xmalloc((res.size + 1) * 2);
271 ((short *)res.data)[0] = (short)res.size;
272 wstrcpy((short *)(res.data+2), nid->name.s_name->str.wstr);
273 res.size *= 2; /* Function writes bytes, not shorts... */
274 res.size += 2; /* We need to write the length word as well */
275 write_s_res(fp, &res);
280 internal_error(__FILE__, __LINE__, "Hmm, requested to write a string of unknown type %d",
281 nid->name.s_name->type);
286 *****************************************************************************
287 * Function : find_counter
288 * Syntax : res_count_t *find_counter(name_id_t *type)
293 *****************************************************************************
295 static res_count_t *find_counter(name_id_t *type)
298 for(i = 0; i < rccount; i++)
300 if(!compare_name_id(type, &(rcarray[i].type)))
307 *****************************************************************************
308 * Function : count_resources
309 * Syntax : res_count_t *count_resources(resource_t *top)
313 * Remarks : The whole lot is converted into arrays because they are
314 * easy sortable. Makes the lot almost unreadable, but it
315 * works (I hope). Basically you have to keep in mind that
316 * the lot is a three-dimensional structure for win32 and a
317 * two-dimensional structure for win16.
318 *****************************************************************************
320 #define RCT(v) (*((resource_t **)(v)))
321 /* qsort sorting function */
322 static int sort_name_id(const void *e1, const void *e2)
324 return compare_name_id(RCT(e1)->name, RCT(e2)->name);
327 static int sort_language(const void *e1, const void *e2)
329 assert((RCT(e1)->lan) != NULL);
330 assert((RCT(e2)->lan) != NULL);
332 return MAKELANGID(RCT(e1)->lan->id, RCT(e1)->lan->sub)
333 - MAKELANGID(RCT(e2)->lan->id, RCT(e2)->lan->sub);
336 #define RCT(v) ((res_count_t *)(v))
337 static int sort_type(const void *e1, const void *e2)
339 return compare_name_id(&(RCT(e1)->type), &(RCT(e2)->type));
343 static void count_resources(resource_t *top)
350 for(rsc = top; rsc; rsc = rsc->next)
357 nid.name.i_name = WRC_RT_DIALOG;
361 nid.name.i_name = WRC_RT_MENU;
365 nid = *(rsc->res.usr->type);
368 nid.name.i_name = rsc->type;
372 if((rcp = find_counter(&nid)) == NULL)
374 /* Count the number of uniq ids and names */
376 if(nid.type == name_ord)
383 rcarray = (res_count_t *)xmalloc(sizeof(res_count_t));
385 rcarray[0].count = 1;
386 rcarray[0].type = nid;
387 rcarray[0].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));
388 rcarray[0].rscarray[0] = rsc;
393 rcarray = (res_count_t *)xrealloc(rcarray, rccount * sizeof(res_count_t));
394 rcarray[rccount-1].count = 1;
395 rcarray[rccount-1].type = nid;
396 rcarray[rccount-1].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));
397 rcarray[rccount-1].rscarray[0] = rsc;
403 rcp->rscarray = (resource_t **)xrealloc(rcp->rscarray, rcp->count * sizeof(resource_t *));
404 rcp->rscarray[rcp->count-1] = rsc;
410 /* We're done, win16 requires no special sorting */
414 /* We now have a unsorted list of types with an array of res_count_t
415 * in rcarray[0..rccount-1]. And we have names of one type in the
416 * rcarray[x].rsc[0..rcarray[x].count-1] arrays.
417 * The list needs to be sorted for win32's top level tree structure.
422 qsort(rcarray, rccount, sizeof(rcarray[0]), sort_type);
424 /* Now sort the name-id arrays */
425 for(i = 0; i < rccount; i++)
427 if(rcarray[i].count > 1)
428 qsort(rcarray[i].rscarray, rcarray[i].count, sizeof(rcarray[0].rscarray[0]), sort_name_id);
431 /* Now split the name-id arrays into name/language
432 * subs. Don't look at the awfull expressions...
433 * We do this by taking the array elements out of rscarray and putting
434 * together a new array in rsc32array.
436 for(i = 0; i < rccount; i++)
440 assert(rcarray[i].count >= 1);
442 /* rcap points to the current type we are dealing with */
443 rcap = &(rcarray[i]);
445 /* Insert the first name-id */
446 rcap->rsc32array = (res32_count_t *)xmalloc(sizeof(res32_count_t));
448 rcap->rsc32array[0].rsc = (resource_t **)xmalloc(sizeof(resource_t *));
449 rcap->rsc32array[0].count = 1;
450 rcap->rsc32array[0].rsc[0] = rcap->rscarray[0];
451 if(rcap->rscarray[0]->name->type == name_ord)
453 rcap->n_id_entries = 1;
454 rcap->n_name_entries = 0;
458 rcap->n_id_entries = 0;
459 rcap->n_name_entries = 1;
462 /* Now loop over the resting resources of the current type
463 * to find duplicate names (which should have different
466 for(j = 1; j < rcap->count; j++)
468 res32_count_t *r32cp;
470 /* r32cp points to the current res32_count structure
471 * that holds the resource name we are processing.
473 r32cp = &(rcap->rsc32array[rcap->count32-1]);
475 if(!compare_name_id(r32cp->rsc[0]->name, rcarray[i].rscarray[j]->name))
477 /* Names are the same, add to list */
479 r32cp->rsc = (resource_t **)xrealloc(r32cp->rsc, r32cp->count * sizeof(resource_t *));
480 r32cp->rsc[r32cp->count-1] = rcap->rscarray[j];
484 /* New name-id, sort the old one by
485 * language and create new list
488 qsort(r32cp->rsc, r32cp->count, sizeof(r32cp->rsc[0]), sort_language);
490 rcap->rsc32array = (res32_count_t*)xrealloc(rcap->rsc32array, rcap->count32 * sizeof(res32_count_t));
491 rcap->rsc32array[rcap->count32-1].rsc = (resource_t **)xmalloc(sizeof(resource_t *));
492 rcap->rsc32array[rcap->count32-1].count = 1;
493 rcap->rsc32array[rcap->count32-1].rsc[0] = rcap->rscarray[j];
495 if(rcap->rscarray[j]->name->type == name_ord)
496 rcap->n_id_entries++;
498 rcap->n_name_entries++;
501 /* Also sort the languages of the last name group */
502 if(rcap->rsc32array[rcap->count32-1].count > 1)
503 qsort(rcap->rsc32array[rcap->count32-1].rsc,
504 rcap->rsc32array[rcap->count32-1].count,
505 sizeof(rcap->rsc32array[rcap->count32-1].rsc[0]),
511 *****************************************************************************
512 * Function : write_pe_segment
513 * Syntax : void write_pe_segment(FILE *fp, resource_t *top)
518 *****************************************************************************
520 static void write_pe_segment(FILE *fp, resource_t *top)
524 fprintf(fp, "\t.align\t4\n");
525 fprintf(fp, "%s%s:\n", prefix, _PEResTab);
526 fprintf(fp, "\t.globl\t%s%s\n", prefix, _PEResTab);
528 fprintf(fp, "\t.long\t0\n");
529 /* Time/Date stamp */
530 fprintf(fp, "\t.long\t0x%08lx\n", (long)now);
532 fprintf(fp, "\t.long\t0\n"); /* FIXME: must version be filled out? */
533 /* # of id entries, # of name entries */
534 fprintf(fp, "\t.short\t%d, %d\n", n_name_entries, n_id_entries);
536 /* Write the type level of the tree */
537 for(i = 0; i < rccount; i++)
545 if(rcp->type.type == name_ord)
546 fprintf(fp, "\t.long\t%d\n", rcp->type.name.i_name);
549 char *name = prep_nid_for_label(&(rcp->type));
550 fprintf(fp, "\t.long\t(%s_%s_typename - %s%s) | 0x80000000\n",
557 label = prep_nid_for_label(&(rcp->type));
558 fprintf(fp, "\t.long\t(.L%s - %s%s) | 0x80000000\n",
564 /* Write the name level of the tree */
566 for(i = 0; i < rccount; i++)
575 typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
576 fprintf(fp, ".L%s:\n", typelabel);
578 fprintf(fp, "\t.long\t0\n"); /* Flags */
579 fprintf(fp, "\t.long\t0x%08lx\n", (long)now); /* TimeDate */
580 fprintf(fp, "\t.long\t0\n"); /* FIXME: must version be filled out? */
581 fprintf(fp, "\t.short\t%d, %d\n", rcp->n_name_entries, rcp->n_id_entries);
582 for(j = 0; j < rcp->count32; j++)
584 resource_t *rsc = rcp->rsc32array[j].rsc[0];
586 if(rsc->name->type == name_ord)
587 fprintf(fp, "\t.long\t%d\n", rsc->name->name.i_name);
590 fprintf(fp, "\t.long\t(%s%s_name - %s%s) | 0x80000000\n",
596 /* Maybe FIXME: Unescape the tree (ommit 0x80000000) and
597 * put the offset to the resource data entry.
598 * ?? Is unescaping worth while ??
601 namelabel = prep_nid_for_label(rsc->name);
602 fprintf(fp, "\t.long\t(.L%s_%s - %s%s) | 0x80000000\n",
611 /* Write the language level of the tree */
613 for(i = 0; i < rccount; i++)
621 typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
623 for(j = 0; j < rcp->count32; j++)
625 res32_count_t *r32cp = &(rcp->rsc32array[j]);
628 namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));
629 fprintf(fp, ".L%s_%s:\n", typelabel, namelabel);
631 fprintf(fp, "\t.long\t0\n"); /* Flags */
632 fprintf(fp, "\t.long\t0x%08lx\n", (long)now); /* TimeDate */
633 fprintf(fp, "\t.long\t0\n"); /* FIXME: must version be filled out? */
634 fprintf(fp, "\t.short\t0, %d\n", r32cp->count);
636 for(k = 0; k < r32cp->count; k++)
638 resource_t *rsc = r32cp->rsc[k];
639 assert(rsc->lan != NULL);
641 fprintf(fp, "\t.long\t0x%08x\n", rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);
643 fprintf(fp, "\t.long\t.L%s_%s_%d - %s%s\n",
646 rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0,
655 /* Write the resource table itself */
656 fprintf(fp, "%s_ResourceDirectory:\n", prefix);
657 fprintf(fp, "\t.globl\t%s_ResourceDirectory\n", prefix);
660 for(i = 0; i < rccount; i++)
668 typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
670 for(j = 0; j < rcp->count32; j++)
672 res32_count_t *r32cp = &(rcp->rsc32array[j]);
675 namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));
677 for(k = 0; k < r32cp->count; k++)
679 resource_t *rsc = r32cp->rsc[k];
681 assert(rsc->lan != NULL);
683 fprintf(fp, ".L%s_%s_%d:\n",
686 rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);
689 fprintf(fp, "\t.long\t%s%s_data - %s%s\n",
695 fprintf(fp, "\t.long\t%d\n",
696 rsc->binres->size - rsc->binres->dataidx);
698 fprintf(fp, "\t.long\t%ld\n", codepage);
700 fprintf(fp, "\t.long\t0\n");
711 *****************************************************************************
712 * Function : write_ne_segment
713 * Syntax : void write_ne_segment(FILE *fp, resource_t *top)
718 *****************************************************************************
720 static void write_ne_segment(FILE *fp, resource_t *top)
724 fprintf(fp, "\t.align\t4\n");
725 fprintf(fp, "%s%s:\n", prefix, _NEResTab);
726 fprintf(fp, "\t.globl\t%s%s\n", prefix, _NEResTab);
729 fprintf(fp, "\t.short\t%d\n", alignment_pwr);
732 for(i = 0; i < rccount; i++)
734 res_count_t *rcp = &rcarray[i];
737 if(rcp->type.type == name_ord)
738 fprintf(fp, "\t.short\t0x%04x\n", rcp->type.name.i_name | 0x8000);
740 fprintf(fp, "\t.short\t%s_%s_typename - %s%s\n",
742 rcp->type.name.s_name->str.cstr,
746 fprintf(fp, "\t.short\t%d\n", rcp->count);
748 fprintf(fp, "\t.long\t0\n");
750 for(j = 0; j < rcp->count; j++)
754 * The offset is relative to the beginning of the NE resource segment
755 * and _NOT_ to the file-beginning. This is because we do not have a
756 * file based resource, but a simulated NE segment. The offset _is_
757 * scaled by the AlignShift field.
758 * All other things are as the MS doc describes (alignment etc.)
761 fprintf(fp, "\t.short\t(%s%s_data - %s%s) >> %d\n",
763 rcp->rscarray[j]->c_name,
768 fprintf(fp, "\t.short\t%d\n",
769 rcp->rscarray[j]->binres->size - rcp->rscarray[j]->binres->dataidx);
771 fprintf(fp, "\t.short\t0x%04x\n", (WORD)rcp->rscarray[j]->memopt);
773 if(rcp->rscarray[j]->name->type == name_ord)
774 fprintf(fp, "\t.short\t0x%04x\n", rcp->rscarray[j]->name->name.i_name | 0x8000);
776 fprintf(fp, "\t.short\t%s%s_name - %s%s\n",
778 rcp->rscarray[j]->c_name,
781 /* Handle and Usage */
782 fprintf(fp, "\t.short\t0, 0\n");
786 fprintf(fp, "\t.short\t0\n");
790 *****************************************************************************
791 * Function : write_rsc_names
792 * Syntax : void write_rsc_names(FILE *fp, resource_t *top)
797 *****************************************************************************
799 static void write_rsc_names(FILE *fp, resource_t *top)
805 /* Write the names */
807 for(i = 0; i < rccount; i++)
813 if(rcp->type.type == name_str)
815 char *name = prep_nid_for_label(&(rcp->type));
816 fprintf(fp, "%s_%s_typename:\n",
819 write_name_str(fp, &(rcp->type));
822 for(j = 0; j < rcp->count32; j++)
824 resource_t *rsc = rcp->rsc32array[j].rsc[0];
826 if(rsc->name->type == name_str)
828 fprintf(fp, "%s%s_name:\n",
831 write_name_str(fp, rsc->name);
839 for(i = 0; i < rccount; i++)
841 res_count_t *rcp = &rcarray[i];
843 for(j = 0; j < rcp->count; j++)
845 if(rcp->type.type == name_str)
847 fprintf(fp, "%s_%s_typename:\n",
849 rcp->type.name.s_name->str.cstr);
850 write_name_str(fp, &(rcp->type));
852 if(rcp->rscarray[j]->name->type == name_str)
854 fprintf(fp, "%s%s_name:\n",
856 rcp->rscarray[j]->c_name);
857 write_name_str(fp, rcp->rscarray[j]->name);
863 /* This is to end the NE resource table */
865 fprintf(fp, "\t.byte\t0\n");
872 *****************************************************************************
873 * Function : write_s_file
874 * Syntax : void write_s_file(char *outname, resource_t *top)
876 * outname - Filename to write to
877 * top - The resource-tree to convert
881 *****************************************************************************
883 void write_s_file(char *outname, resource_t *top)
888 fo = fopen(outname, "wt");
891 error("Could not open %s\n", outname);
900 fprintf(fo, s_file_head_str, input_name ? input_name : "stdin",
904 /* Get an idea how many we have and restructure the tables */
905 count_resources(top);
907 /* First write the segment tables */
911 write_pe_segment(fo, top);
913 write_ne_segment(fo, top);
917 write_rsc_names(fo, top);
920 fprintf(fo, ".LResTabEnd:\n");
924 /* Write the resource data */
925 fprintf(fo, "\n/* Resource binary data */\n\n");
926 for(rsc = top; rsc; rsc = rsc->next)
931 fprintf(fo, "\t.align\t%d\n", win32 ? 4 : alignment);
932 fprintf(fo, "%s%s_data:\n", prefix, rsc->c_name);
934 fprintf(fo, "\t.globl\t%s%s_data\n", prefix, rsc->c_name);
936 write_s_res(fo, rsc->binres);
943 /* Add a resource descriptor for built-in and elf-dlls */
944 fprintf(fo, "\t.align\t4\n");
945 fprintf(fo, "%s_ResourceDescriptor:\n", prefix);
946 fprintf(fo, "\t.globl\t%s_ResourceDescriptor\n", prefix);
947 fprintf(fo, "%s_ResourceTable:\n", prefix);
949 fprintf(fo, "\t.globl\t%s_ResourceTable\n", prefix);
950 fprintf(fo, "\t.long\t%s%s\n", prefix, win32 ? _PEResTab : _NEResTab);
951 fprintf(fo, "%s_NumberOfResources:\n", prefix);
953 fprintf(fo, "\t.globl\t%s_NumberOfResources\n", prefix);
954 fprintf(fo, "\t.long\t%d\n", direntries);
955 fprintf(fo, "%s_ResourceSectionSize:\n", prefix);
957 fprintf(fo, "\t.globl\t%s_ResourceSectionSize\n", prefix);
958 fprintf(fo, "\t.long\t.LResTabEnd - %s%s\n", prefix, win32 ? _PEResTab : _NEResTab);
961 fprintf(fo, "%s_ResourcesEntries:\n", prefix);
963 fprintf(fo, "\t.globl\t%s_ResourcesEntries\n", prefix);
964 fprintf(fo, "\t.long\t%s_ResourceDirectory\n", prefix);
971 /* Write the indirection structures */
972 fprintf(fo, "\n/* Resource indirection structures */\n\n");
973 fprintf(fo, "\t.align\t4\n");
974 for(rsc = top; rsc; rsc = rsc->next)
977 char *type_name = NULL;
988 type = WRC_RT_DIALOG;
991 assert(rsc->res.usr->type != NULL);
992 type_name = prep_nid_for_label(rsc->res.usr->type);
1000 * This follows a structure like:
1001 * struct wrc_resource {
1005 * RSCNAME *typename;
1009 * The 'RSCNAME' is a pascal-style string where the
1010 * first byte/word denotes the size and the rest the string
1013 fprintf(fo, "%s%s:\n", prefix, rsc->c_name);
1015 fprintf(fo, "\t.globl\t%s%s\n", prefix, rsc->c_name);
1016 fprintf(fo, "\t.long\t%d, %s%s%s, %d, %s%s%s%s, %s%s_data, %d\n",
1017 rsc->name->type == name_ord ? rsc->name->name.i_name : 0,
1018 rsc->name->type == name_ord ? "0" : prefix,
1019 rsc->name->type == name_ord ? "" : rsc->c_name,
1020 rsc->name->type == name_ord ? "" : "_name",
1022 type ? "0" : prefix,
1024 type ? "" : type_name,
1025 type ? "" : "_typename",
1028 rsc->binres->size - rsc->binres->dataidx);
1033 /* Write the indirection table */
1034 fprintf(fo, "/* Resource indirection table */\n\n");
1035 fprintf(fo, "\t.align\t4\n");
1036 fprintf(fo, "%s%s:\n", prefix, _ResTable);
1037 fprintf(fo, "\t.globl\t%s%s\n", prefix, _ResTable);
1038 for(rsc = top; rsc; rsc = rsc->next)
1040 fprintf(fo, "\t.long\t%s%s\n", prefix, rsc->c_name);
1042 fprintf(fo, "\t.long\t0\n");
1047 fprintf(fo, s_file_autoreg_str, prefix, _ResTable);
1049 fprintf(fo, s_file_tail_str);
1054 *****************************************************************************
1055 * Function : write_h_file
1056 * Syntax : void write_h_file(char *outname, resource_t *top)
1058 * outname - Filename to write to
1059 * top - The resource-tree to convert
1063 *****************************************************************************
1065 void write_h_file(char *outname, resource_t *top)
1071 #ifdef NEED_UNDERSCORE_PREFIX
1072 h_prefix = prefix + 1;
1077 fo = fopen(outname, "wt");
1080 error("Could not open %s\n", outname);
1083 fprintf(fo, h_file_head_str, input_name ? input_name : "stdin",
1084 cmdline, ctime(&now), (long)now, (long)now);
1086 /* First write the segment tables reference */
1089 fprintf(fo, "extern %schar %s%s[];\n\n",
1090 constant ? "const " : "",
1092 win32 ? _PEResTab : _NEResTab);
1095 /* Write the resource data */
1096 for(rsc = top; global && rsc; rsc = rsc->next)
1101 fprintf(fo, "extern %schar %s%s_data[];\n",
1102 constant ? "const " : "",
1112 /* Write the indirection structures */
1113 for(rsc = top; global && rsc; rsc = rsc->next)
1115 fprintf(fo, "extern %swrc_resource%d_t %s%s;\n",
1116 constant ? "const " : "",
1125 /* Write the indirection table */
1126 fprintf(fo, "extern %swrc_resource%d_t %s%s[];\n\n",
1127 constant ? "const " : "",
1133 fprintf(fo, h_file_tail_str);