- Timestamp:
- Sep 11, 1999, 4:22:44 AM (26 years ago)
- File:
-
- 1 edited
-
trunk/tools/wrc/writeres.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/wrc/writeres.c
r882 r906 6 6 */ 7 7 8 /******************************************************************************* 9 * Defined Constants And Macros * 10 *******************************************************************************/ 11 #define MASM 1 12 #ifdef MASM 13 #define DIRECTIVE_BYTE "db" 14 #define DIRECTIVE_WORD "dw" 15 #define DIRECTIVE_LONG "dd" 16 #define DIRECTIVE_ALIGN "align" 17 #define DIRECTIVE_GLOBAL "public" 18 #define LOCAL_PREFIX "" 19 #define LONGFRMT "0%08lxh" 20 #define SHORTFRMT "0%04xh" 21 #define BYTEFRMT "0%02xh" 22 #define HEXBIT31 "80000000h" 23 #define COMMENT_LINE ";" 24 #define OR "or" 25 #else 26 #define DIRECTIVE_BYTE ".byte" 27 #define DIRECTIVE_WORD ".word" 28 #define DIRECTIVE_LONG ".long" 29 #define DIRECTIVE_ALIGN ".align" 30 #define DIRECTIVE_GLOBAL ".globl" 31 #define LOCAL_PREFIX "." 32 #define LONGFRMT "0x%08lx" 33 #define SHORTFRMT "0x%04x" 34 #define BYTEFRMT "0x%02x" 35 #define HEXBIT31 "0x80000000" 36 #define COMMENT_LINE 37 #define OR "|" 38 #endif 39 40 /******************************************************************************* 41 * Header Files * 42 *******************************************************************************/ 8 43 #include "config.h" 9 44 … … 27 62 28 63 char s_file_head_str[] = 29 "/* This file is generated with wrc version " WRC_FULLVERSION ". Do not edit! */\n" 30 "/* Source : %s */\n" 31 "/* Cmdline: %s */\n" 32 "/* Date : %s */\n" 64 COMMENT_LINE"/* This file is generated with wrc version " WRC_FULLVERSION ". Do not edit! */\n" 65 COMMENT_LINE"/* Source : %s */\n" 66 COMMENT_LINE"/* Cmdline: %s */\n" 67 COMMENT_LINE"/* Date : %s */\n" 68 "\n" 69 #ifdef MASM 70 "\t.386p\n" 71 "\t.model flat\n" 72 #endif 73 "\t.data\n" 74 "\n" 75 ; 76 77 char s_file_tail_str[] = 78 #ifdef MASM 79 "\tend\n" 80 #else 81 "/* <eof> */\n" 82 "\n" 83 #endif 84 ; 85 86 char s_file_autoreg_str[] = 87 #ifdef MASM 88 "" 89 #else 90 "\t.text\n" 91 LOCAL_PREFIX"LAuto_Register:\n" 92 "\tpushl\t$%s%s\n" 93 #ifdef NEED_UNDERSCORE_PREFIX 94 "\tcall\t_LIBRES_RegisterResources\n" 95 #else 96 "\tcall\tLIBRES_RegisterResources\n" 97 #endif 98 "\taddl\t$4,%%esp\n" 99 "\tret\n\n" 100 #ifdef __NetBSD__ 101 ".stabs \"___CTOR_LIST__\",22,0,0,.LAuto_Register\n\n" 102 #else 103 "\t.section .ctors,\"aw\"\n" 104 "\t"DIRECTIVE_LONG"\t.LAuto_Register\n\n" 105 #endif 106 #endif 107 ; 108 109 char h_file_head_str[] = 110 "/*\n" 111 " * This file is generated with wrc version " WRC_FULLVERSION ". Do not edit!\n" 112 " * Source : %s\n" 113 " * Cmdline: %s\n" 114 " * Date : %s" 115 " */\n" 33 116 "\n" 34 "\t.data\n" 35 "\n" 36 ; 37 38 char s_file_tail_str[] = 39 "/* <eof> */\n" 40 "\n" 41 ; 42 43 char s_file_autoreg_str[] = 44 "\t.text\n" 45 ".LAuto_Register:\n" 46 "\tpushl\t$%s%s\n" 47 #ifdef NEED_UNDERSCORE_PREFIX 48 "\tcall\t_LIBRES_RegisterResources\n" 49 #else 50 "\tcall\tLIBRES_RegisterResources\n" 51 #endif 52 "\taddl\t$4,%%esp\n" 53 "\tret\n\n" 54 #ifdef __NetBSD__ 55 ".stabs \"___CTOR_LIST__\",22,0,0,.LAuto_Register\n\n" 56 #else 57 "\t.section .ctors,\"aw\"\n" 58 "\t.long\t.LAuto_Register\n\n" 59 #endif 60 ; 61 62 char h_file_head_str[] = 63 "/*\n" 64 " * This file is generated with wrc version " WRC_FULLVERSION ". Do not edit!\n" 65 " * Source : %s\n" 66 " * Cmdline: %s\n" 67 " * Date : %s" 68 " */\n" 69 "\n" 70 "#ifndef __%08lx_H\n" /* This becomes the date of compile */ 71 "#define __%08lx_H\n" 72 "\n" 73 "#include <wrc_rsc.h>\n" 74 "\n" 75 ; 117 "#ifndef __%08lx_H\n" /* This becomes the date of compile */ 118 "#define __%08lx_H\n" 119 "\n" 120 "#include <wrc_rsc.h>\n" 121 "\n" 122 ; 76 123 77 124 char h_file_tail_str[] = 78 "#endif\n"79 "/* <eof> */\n\n"80 ;125 "#endif\n" 126 "/* <eof> */\n\n" 127 ; 81 128 82 129 char _NEResTab[] = "_NEResTab"; … … 85 132 86 133 /* Variables used for resource sorting */ 87 res_count_t *rcarray = NULL; /* Type-level count array */88 int rccount = 0; /* Nr of entries in the type-level array */89 int n_id_entries = 0; /* win32 only: Nr of unique ids in the type-level array */90 int n_name_entries = 0; /* win32 only: Nr of unique namess in the type-level array */91 92 static int direntries; /* win32 only: Total number of unique resources */134 res_count_t *rcarray = NULL; /* Type-level count array */ 135 int rccount = 0; /* Nr of entries in the type-level array */ 136 int n_id_entries = 0; /* win32 only: Nr of unique ids in the type-level array */ 137 int n_name_entries = 0; /* win32 only: Nr of unique namess in the type-level array */ 138 139 static int direntries; /* win32 only: Total number of unique resources */ 93 140 94 141 time_t now; … … 96 143 /* 97 144 ***************************************************************************** 98 * Function : write_resfile99 * Syntax : void write_resfile(char *outname, resource_t *top)100 * Input :101 * outname- Filename to write to102 * top- The resource-tree to convert103 * Output :104 * Description :105 * Remarks :145 * Function : write_resfile 146 * Syntax : void write_resfile(char *outname, resource_t *top) 147 * Input : 148 * outname - Filename to write to 149 * top - The resource-tree to convert 150 * Output : 151 * Description : 152 * Remarks : 106 153 ***************************************************************************** 107 154 */ 108 155 void write_resfile(char *outname, resource_t *top) 109 156 { 110 FILE *fo;111 int ret;112 char zeros[3] = {0, 0, 0};113 114 fo = fopen(outname, "wb");115 if(!fo)116 {117 error("Could not open %s\n", outname);118 }119 120 if(win32)121 {122 /* Put an empty resource first to signal win32 format */123 res_t *res = new_res();124 put_dword(res, 0);/* ResSize */125 put_dword(res, 0x00000020);/* HeaderSize */126 put_word(res, 0xffff);/* ResType */127 put_word(res, 0);128 put_word(res, 0xffff);/* ResName */129 put_word(res, 0);130 put_dword(res, 0);/* DataVersion */131 put_word(res, 0);/* Memory options */132 put_word(res, 0);/* Language */133 put_dword(res, 0);/* Version */134 put_dword(res, 0);/* Charateristics */135 ret = fwrite(res->data, 1, res->size, fo);136 if(ret != res->size)137 {138 fclose(fo);139 error("Error writing %s", outname);140 }141 free(res);142 }143 144 for(; top; top = top->next)145 {146 if(!top->binres)147 continue;148 149 ret = fwrite(top->binres->data, 1, top->binres->size, fo);150 if(ret != top->binres->size)151 {152 fclose(fo);153 error("Error writing %s", outname);154 }155 if(win32 && (top->binres->size & 0x03))156 {157 /* Write padding */158 ret = fwrite(zeros, 1, 4 - (top->binres->size & 0x03), fo);159 if(ret != 4 - (top->binres->size & 0x03))160 {161 fclose(fo);162 error("Error writing %s", outname);163 }164 }165 }166 fclose(fo);157 FILE *fo; 158 int ret; 159 char zeros[3] = {0, 0, 0}; 160 161 fo = fopen(outname, "wb"); 162 if(!fo) 163 { 164 error("Could not open %s\n", outname); 165 } 166 167 if(win32) 168 { 169 /* Put an empty resource first to signal win32 format */ 170 res_t *res = new_res(); 171 put_dword(res, 0); /* ResSize */ 172 put_dword(res, 0x00000020); /* HeaderSize */ 173 put_word(res, 0xffff); /* ResType */ 174 put_word(res, 0); 175 put_word(res, 0xffff); /* ResName */ 176 put_word(res, 0); 177 put_dword(res, 0); /* DataVersion */ 178 put_word(res, 0); /* Memory options */ 179 put_word(res, 0); /* Language */ 180 put_dword(res, 0); /* Version */ 181 put_dword(res, 0); /* Charateristics */ 182 ret = fwrite(res->data, 1, res->size, fo); 183 if(ret != res->size) 184 { 185 fclose(fo); 186 error("Error writing %s", outname); 187 } 188 free(res); 189 } 190 191 for(; top; top = top->next) 192 { 193 if(!top->binres) 194 continue; 195 196 ret = fwrite(top->binres->data, 1, top->binres->size, fo); 197 if(ret != top->binres->size) 198 { 199 fclose(fo); 200 error("Error writing %s", outname); 201 } 202 if(win32 && (top->binres->size & 0x03)) 203 { 204 /* Write padding */ 205 ret = fwrite(zeros, 1, 4 - (top->binres->size & 0x03), fo); 206 if(ret != 4 - (top->binres->size & 0x03)) 207 { 208 fclose(fo); 209 error("Error writing %s", outname); 210 } 211 } 212 } 213 fclose(fo); 167 214 } 168 215 169 216 /* 170 217 ***************************************************************************** 171 * Function : write_s_res172 * Syntax : void write_s_res(FILE *fp, res_t *res)173 * Input :174 * Output :175 * Description :176 * Remarks :218 * Function : write_s_res 219 * Syntax : void write_s_res(FILE *fp, res_t *res) 220 * Input : 221 * Output : 222 * Description : 223 * Remarks : 177 224 ***************************************************************************** 178 225 */ 179 #define BYTESPERLINE 8226 #define BYTESPERLINE 8 180 227 void write_s_res(FILE *fp, res_t *res) 181 228 { 182 int idx = res->dataidx;183 int end = res->size;184 int rest = (end - idx) % BYTESPERLINE;185 int lines = (end - idx) / BYTESPERLINE;186 int i, j;187 188 for(i = 0 ; i < lines; i++)189 {190 fprintf(fp, "\t.byte\t");191 for(j = 0; j < BYTESPERLINE; j++, idx++)192 {193 fprintf(fp, "0x%02x%s", res->data[idx] & 0xff,194 j == BYTESPERLINE-1 ? "" : ", ");195 }196 fprintf(fp, "\n");197 }198 if(rest)199 {200 fprintf(fp, "\t.byte\t");201 for(j = 0; j < rest; j++, idx++)202 {203 fprintf(fp, "0x%02x%s", res->data[idx] & 0xff,204 j == rest-1 ? "" : ", ");205 }206 fprintf(fp, "\n");207 }229 int idx = res->dataidx; 230 int end = res->size; 231 int rest = (end - idx) % BYTESPERLINE; 232 int lines = (end - idx) / BYTESPERLINE; 233 int i, j; 234 235 for(i = 0 ; i < lines; i++) 236 { 237 fprintf(fp, "\t"DIRECTIVE_BYTE"\t"); 238 for(j = 0; j < BYTESPERLINE; j++, idx++) 239 { 240 fprintf(fp, BYTEFRMT"%s", res->data[idx] & 0xff, 241 j == BYTESPERLINE-1 ? "" : ", "); 242 } 243 fprintf(fp, "\n"); 244 } 245 if(rest) 246 { 247 fprintf(fp, "\t"DIRECTIVE_BYTE"\t"); 248 for(j = 0; j < rest; j++, idx++) 249 { 250 fprintf(fp, BYTEFRMT"%s", res->data[idx] & 0xff, 251 j == rest-1 ? "" : ", "); 252 } 253 fprintf(fp, "\n"); 254 } 208 255 } 209 256 210 257 /* 211 258 ***************************************************************************** 212 * Function : write_name_str213 * Syntax : void write_name_str(FILE *fp, name_id_t *nid)214 * Input :215 * Output :216 * Description :217 * Remarks : One level self recursive for string type conversion259 * Function : write_name_str 260 * Syntax : void write_name_str(FILE *fp, name_id_t *nid) 261 * Input : 262 * Output : 263 * Description : 264 * Remarks : One level self recursive for string type conversion 218 265 ***************************************************************************** 219 266 */ 220 267 void write_name_str(FILE *fp, name_id_t *nid) 221 268 { 222 res_t res;223 assert(nid->type == name_str);224 225 if(!win32 && nid->name.s_name->type == str_char)226 {227 res.size = strlen(nid->name.s_name->str.cstr);228 if(res.size > 254)229 error("Can't write strings larger than 254 bytes");230 if(res.size == 0)231 internal_error(__FILE__, __LINE__, "Attempt to write empty string");232 res.dataidx = 0;233 res.data = (char *)xmalloc(res.size + 1);234 res.data[0] = (char)res.size;235 res.size++;/* We need to write the lenth byte as well */236 strcpy(res.data+1, nid->name.s_name->str.cstr);237 write_s_res(fp, &res);238 free(res.data);239 }240 else if(!win32 && nid->name.s_name->type == str_unicode)241 {242 name_id_t lnid;243 string_t str;244 245 lnid.type = name_str;246 lnid.name.s_name = &str;247 str.type = str_char;248 str.str.cstr = dupwstr2cstr(nid->name.s_name->str.wstr);249 write_name_str(fp, &lnid);250 free(str.str.cstr);251 }252 else if(win32 && nid->name.s_name->type == str_char)253 {254 name_id_t lnid;255 string_t str;256 257 lnid.type = name_str;258 lnid.name.s_name = &str;259 str.type = str_unicode;260 str.str.wstr = dupcstr2wstr(nid->name.s_name->str.cstr);261 write_name_str(fp, &lnid);262 free(str.str.wstr);263 }264 else if(win32 && nid->name.s_name->type == str_unicode)265 {266 res.size = wstrlen(nid->name.s_name->str.wstr);267 if(res.size > 65534)268 error("Can't write strings larger than 65534 bytes");269 if(res.size == 0)270 internal_error(__FILE__, __LINE__, "Attempt to write empty string");271 res.dataidx = 0;272 res.data = (char *)xmalloc((res.size + 1) * 2);273 ((short *)res.data)[0] = (short)res.size;274 wstrcpy((short *)(res.data+2), nid->name.s_name->str.wstr);275 res.size *= 2; /* Function writes bytes, not shorts... */276 res.size += 2; /* We need to write the length word as well */277 write_s_res(fp, &res);278 free(res.data);279 }280 else281 {282 internal_error(__FILE__, __LINE__, "Hmm, requested to write a string of unknown type %d",283 nid->name.s_name->type);284 }269 res_t res; 270 assert(nid->type == name_str); 271 272 if(!win32 && nid->name.s_name->type == str_char) 273 { 274 res.size = strlen(nid->name.s_name->str.cstr); 275 if(res.size > 254) 276 error("Can't write strings larger than 254 bytes"); 277 if(res.size == 0) 278 internal_error(__FILE__, __LINE__, "Attempt to write empty string"); 279 res.dataidx = 0; 280 res.data = (char *)xmalloc(res.size + 1); 281 res.data[0] = (char)res.size; 282 res.size++; /* We need to write the lenth byte as well */ 283 strcpy(res.data+1, nid->name.s_name->str.cstr); 284 write_s_res(fp, &res); 285 free(res.data); 286 } 287 else if(!win32 && nid->name.s_name->type == str_unicode) 288 { 289 name_id_t lnid; 290 string_t str; 291 292 lnid.type = name_str; 293 lnid.name.s_name = &str; 294 str.type = str_char; 295 str.str.cstr = dupwstr2cstr(nid->name.s_name->str.wstr); 296 write_name_str(fp, &lnid); 297 free(str.str.cstr); 298 } 299 else if(win32 && nid->name.s_name->type == str_char) 300 { 301 name_id_t lnid; 302 string_t str; 303 304 lnid.type = name_str; 305 lnid.name.s_name = &str; 306 str.type = str_unicode; 307 str.str.wstr = dupcstr2wstr(nid->name.s_name->str.cstr); 308 write_name_str(fp, &lnid); 309 free(str.str.wstr); 310 } 311 else if(win32 && nid->name.s_name->type == str_unicode) 312 { 313 res.size = wstrlen(nid->name.s_name->str.wstr); 314 if(res.size > 65534) 315 error("Can't write strings larger than 65534 bytes"); 316 if(res.size == 0) 317 internal_error(__FILE__, __LINE__, "Attempt to write empty string"); 318 res.dataidx = 0; 319 res.data = (char *)xmalloc((res.size + 1) * 2); 320 ((short *)res.data)[0] = (short)res.size; 321 wstrcpy((short *)(res.data+2), nid->name.s_name->str.wstr); 322 res.size *= 2; /* Function writes bytes, not shorts... */ 323 res.size += 2; /* We need to write the length word as well */ 324 write_s_res(fp, &res); 325 free(res.data); 326 } 327 else 328 { 329 internal_error(__FILE__, __LINE__, "Hmm, requested to write a string of unknown type %d", 330 nid->name.s_name->type); 331 } 285 332 } 286 333 287 334 /* 288 335 ***************************************************************************** 289 * Function : compare_name_id290 * Syntax : int compare_name_id(name_id_t *n1, name_id_t *n2)291 * Input :292 * Output :293 * Description :294 * Remarks :336 * Function : compare_name_id 337 * Syntax : int compare_name_id(name_id_t *n1, name_id_t *n2) 338 * Input : 339 * Output : 340 * Description : 341 * Remarks : 295 342 ***************************************************************************** 296 343 */ 297 344 int compare_name_id(name_id_t *n1, name_id_t *n2) 298 345 { 299 if(n1->type == name_ord && n2->type == name_ord)300 {301 return n1->name.i_name - n2->name.i_name;302 }303 else if(n1->type == name_str && n2->type == name_str)304 {305 if(n1->name.s_name->type == str_char306 && n2->name.s_name->type == str_char)307 {308 return strcasecmp(n1->name.s_name->str.cstr, n2->name.s_name->str.cstr);309 }310 else if(n1->name.s_name->type == str_unicode311 && n2->name.s_name->type == str_unicode)312 {313 return wstricmp(n1->name.s_name->str.wstr, n2->name.s_name->str.wstr);314 }315 else316 {317 internal_error(__FILE__, __LINE__, "Can't yet compare strings of mixed type");318 }319 }320 else if(n1->type == name_ord && n2->type == name_str)321 return 1;322 else if(n1->type == name_str && n2->type == name_ord)323 return -1;324 else325 internal_error(__FILE__, __LINE__, "Comparing name-ids with unknown types (%d, %d)",326 n1->type, n2->type);327 328 return 0; /* Keep the compiler happy */346 if(n1->type == name_ord && n2->type == name_ord) 347 { 348 return n1->name.i_name - n2->name.i_name; 349 } 350 else if(n1->type == name_str && n2->type == name_str) 351 { 352 if(n1->name.s_name->type == str_char 353 && n2->name.s_name->type == str_char) 354 { 355 return strcasecmp(n1->name.s_name->str.cstr, n2->name.s_name->str.cstr); 356 } 357 else if(n1->name.s_name->type == str_unicode 358 && n2->name.s_name->type == str_unicode) 359 { 360 return wstricmp(n1->name.s_name->str.wstr, n2->name.s_name->str.wstr); 361 } 362 else 363 { 364 internal_error(__FILE__, __LINE__, "Can't yet compare strings of mixed type"); 365 } 366 } 367 else if(n1->type == name_ord && n2->type == name_str) 368 return 1; 369 else if(n1->type == name_str && n2->type == name_ord) 370 return -1; 371 else 372 internal_error(__FILE__, __LINE__, "Comparing name-ids with unknown types (%d, %d)", 373 n1->type, n2->type); 374 375 return 0; /* Keep the compiler happy */ 329 376 } 330 377 331 378 /* 332 379 ***************************************************************************** 333 * Function : find_counter334 * Syntax : res_count_t *find_counter(name_id_t *type)335 * Input :336 * Output :337 * Description :338 * Remarks :380 * Function : find_counter 381 * Syntax : res_count_t *find_counter(name_id_t *type) 382 * Input : 383 * Output : 384 * Description : 385 * Remarks : 339 386 ***************************************************************************** 340 387 */ 341 388 res_count_t *find_counter(name_id_t *type) 342 389 { 343 int i;344 for(i = 0; i < rccount; i++)345 {346 if(!compare_name_id(type, &(rcarray[i].type)))347 return &rcarray[i];348 }349 return NULL;390 int i; 391 for(i = 0; i < rccount; i++) 392 { 393 if(!compare_name_id(type, &(rcarray[i].type))) 394 return &rcarray[i]; 395 } 396 return NULL; 350 397 } 351 398 352 399 /* 353 400 ***************************************************************************** 354 * Function : count_resources355 * Syntax : res_count_t *count_resources(resource_t *top)356 * Input :357 * Output :358 * Description :359 * Remarks : The whole lot is converted into arrays because they are360 * easy sortable. Makes the lot almost unreadable, but it361 * works (I hope). Basically you have to keep in mind that362 * the lot is a three-dimensional structure for win32 and a363 * two-dimensional structure for win16.401 * Function : count_resources 402 * Syntax : res_count_t *count_resources(resource_t *top) 403 * Input : 404 * Output : 405 * Description : 406 * Remarks : The whole lot is converted into arrays because they are 407 * easy sortable. Makes the lot almost unreadable, but it 408 * works (I hope). Basically you have to keep in mind that 409 * the lot is a three-dimensional structure for win32 and a 410 * two-dimensional structure for win16. 364 411 ***************************************************************************** 365 412 */ 366 #define RCT(v) (*((resource_t **)(v)))413 #define RCT(v) (*((resource_t **)(v))) 367 414 /* qsort sorting function */ 368 415 int sort_name_id(const void *e1, const void *e2) 369 416 { 370 return compare_name_id(RCT(e1)->name, RCT(e2)->name);417 return compare_name_id(RCT(e1)->name, RCT(e2)->name); 371 418 } 372 419 373 420 int sort_language(const void *e1, const void *e2) 374 421 { 375 assert((RCT(e1)->lan) != NULL);376 assert((RCT(e2)->lan) != NULL);377 378 return MAKELANGID(RCT(e1)->lan->id, RCT(e1)->lan->sub)379 - MAKELANGID(RCT(e2)->lan->id, RCT(e2)->lan->sub);422 assert((RCT(e1)->lan) != NULL); 423 assert((RCT(e2)->lan) != NULL); 424 425 return MAKELANGID(RCT(e1)->lan->id, RCT(e1)->lan->sub) 426 - MAKELANGID(RCT(e2)->lan->id, RCT(e2)->lan->sub); 380 427 } 381 428 #undef RCT 382 #define RCT(v) ((res_count_t *)(v))429 #define RCT(v) ((res_count_t *)(v)) 383 430 int sort_type(const void *e1, const void *e2) 384 431 { 385 return compare_name_id(&(RCT(e1)->type), &(RCT(e2)->type));432 return compare_name_id(&(RCT(e1)->type), &(RCT(e2)->type)); 386 433 } 387 434 #undef RCT … … 389 436 void count_resources(resource_t *top) 390 437 { 391 resource_t *rsc;392 res_count_t *rcp;393 name_id_t nid;394 int i, j;395 396 for(rsc = top; rsc; rsc = rsc->next)397 {398 if(!rsc->binres)399 continue;400 switch(rsc->type)401 {402 case res_dlgex:403 nid.name.i_name = WRC_RT_DIALOG;404 nid.type = name_ord;405 break;406 case res_menex:407 nid.name.i_name = WRC_RT_MENU;408 nid.type = name_ord;409 break;410 case res_usr:411 nid = *(rsc->res.usr->type);412 break;413 default:414 nid.name.i_name = rsc->type;415 nid.type = name_ord;416 }417 418 if((rcp = find_counter(&nid)) == NULL)419 {420 /* Count the number of uniq ids and names */421 422 if(nid.type == name_ord)423 n_id_entries++;424 else425 n_name_entries++;426 427 if(!rcarray)428 {429 rcarray = (res_count_t *)xmalloc(sizeof(res_count_t));430 rccount = 1;431 rcarray[0].count = 1;432 rcarray[0].type = nid;433 rcarray[0].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));434 rcarray[0].rscarray[0] = rsc;435 }436 else437 {438 rccount++;439 rcarray = (res_count_t *)xrealloc(rcarray, rccount * sizeof(res_count_t));440 rcarray[rccount-1].count = 1;441 rcarray[rccount-1].type = nid;442 rcarray[rccount-1].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));443 rcarray[rccount-1].rscarray[0] = rsc;444 }445 }446 else447 {448 rcp->count++;449 rcp->rscarray = (resource_t **)xrealloc(rcp->rscarray, rcp->count * sizeof(resource_t *));450 rcp->rscarray[rcp->count-1] = rsc;451 }452 }453 454 if(!win32)455 {456 /* We're done, win16 requires no special sorting */457 return;458 }459 460 /* We now have a unsorted list of types with an array of res_count_t461 * in rcarray[0..rccount-1]. And we have names of one type in the462 * rcarray[x].rsc[0..rcarray[x].count-1] arrays.463 * The list needs to be sorted for win32's top level tree structure.464 */465 466 /* Sort the types */467 if(rccount > 1)468 qsort(rcarray, rccount, sizeof(rcarray[0]), sort_type);469 470 /* Now sort the name-id arrays */471 for(i = 0; i < rccount; i++)472 {473 if(rcarray[i].count > 1)474 qsort(rcarray[i].rscarray, rcarray[i].count, sizeof(rcarray[0].rscarray[0]), sort_name_id);475 }476 477 /* Now split the name-id arrays into name/language478 * subs. Don't look at the awfull expressions...479 * We do this by taking the array elements out of rscarray and putting480 * together a new array in rsc32array.481 */482 for(i = 0; i < rccount; i++)483 {484 res_count_t *rcap;485 486 assert(rcarray[i].count >= 1);487 488 /* rcap points to the current type we are dealing with */489 rcap = &(rcarray[i]);490 491 /* Insert the first name-id */492 rcap->rsc32array = (res32_count_t *)xmalloc(sizeof(res32_count_t));493 rcap->count32 = 1;494 rcap->rsc32array[0].rsc = (resource_t **)xmalloc(sizeof(resource_t *));495 rcap->rsc32array[0].count = 1;496 rcap->rsc32array[0].rsc[0] = rcap->rscarray[0];497 if(rcap->rscarray[0]->name->type == name_ord)498 {499 rcap->n_id_entries = 1;500 rcap->n_name_entries = 0;501 }502 else503 {504 rcap->n_id_entries = 0;505 rcap->n_name_entries = 1;506 }507 508 /* Now loop over the resting resources of the current type509 * to find duplicate names (which should have different510 * languages).511 */512 for(j = 1; j < rcap->count; j++)513 {514 res32_count_t *r32cp;515 516 /* r32cp points to the current res32_count structure517 * that holds the resource name we are processing.518 */519 r32cp = &(rcap->rsc32array[rcap->count32-1]);520 521 if(!compare_name_id(r32cp->rsc[0]->name, rcarray[i].rscarray[j]->name))522 {523 /* Names are the same, add to list */524 r32cp->count++;525 r32cp->rsc = (resource_t **)xrealloc(r32cp->rsc, r32cp->count * sizeof(resource_t *));526 r32cp->rsc[r32cp->count-1] = rcap->rscarray[j];527 }528 else529 {530 /* New name-id, sort the old one by531 * language and create new list532 */533 if(r32cp->count > 1)534 qsort(r32cp->rsc, r32cp->count, sizeof(r32cp->rsc[0]), sort_language);535 rcap->count32++;536 rcap->rsc32array = (res32_count_t*)xrealloc(rcap->rsc32array, rcap->count32 * sizeof(res32_count_t));537 rcap->rsc32array[rcap->count32-1].rsc = (resource_t **)xmalloc(sizeof(resource_t *));538 rcap->rsc32array[rcap->count32-1].count = 1;539 rcap->rsc32array[rcap->count32-1].rsc[0] = rcap->rscarray[j];540 541 if(rcap->rscarray[j]->name->type == name_ord)542 rcap->n_id_entries++;543 else544 rcap->n_name_entries++;545 }546 }547 /* Also sort the languages of the last name group */548 if(rcap->rsc32array[rcap->count32-1].count > 1)549 qsort(rcap->rsc32array[rcap->count32-1].rsc,550 rcap->rsc32array[rcap->count32-1].count,551 sizeof(rcap->rsc32array[rcap->count32-1].rsc[0]),552 sort_language);553 }438 resource_t *rsc; 439 res_count_t *rcp; 440 name_id_t nid; 441 int i, j; 442 443 for(rsc = top; rsc; rsc = rsc->next) 444 { 445 if(!rsc->binres) 446 continue; 447 switch(rsc->type) 448 { 449 case res_dlgex: 450 nid.name.i_name = WRC_RT_DIALOG; 451 nid.type = name_ord; 452 break; 453 case res_menex: 454 nid.name.i_name = WRC_RT_MENU; 455 nid.type = name_ord; 456 break; 457 case res_usr: 458 nid = *(rsc->res.usr->type); 459 break; 460 default: 461 nid.name.i_name = rsc->type; 462 nid.type = name_ord; 463 } 464 465 if((rcp = find_counter(&nid)) == NULL) 466 { 467 /* Count the number of uniq ids and names */ 468 469 if(nid.type == name_ord) 470 n_id_entries++; 471 else 472 n_name_entries++; 473 474 if(!rcarray) 475 { 476 rcarray = (res_count_t *)xmalloc(sizeof(res_count_t)); 477 rccount = 1; 478 rcarray[0].count = 1; 479 rcarray[0].type = nid; 480 rcarray[0].rscarray = (resource_t **)xmalloc(sizeof(resource_t *)); 481 rcarray[0].rscarray[0] = rsc; 482 } 483 else 484 { 485 rccount++; 486 rcarray = (res_count_t *)xrealloc(rcarray, rccount * sizeof(res_count_t)); 487 rcarray[rccount-1].count = 1; 488 rcarray[rccount-1].type = nid; 489 rcarray[rccount-1].rscarray = (resource_t **)xmalloc(sizeof(resource_t *)); 490 rcarray[rccount-1].rscarray[0] = rsc; 491 } 492 } 493 else 494 { 495 rcp->count++; 496 rcp->rscarray = (resource_t **)xrealloc(rcp->rscarray, rcp->count * sizeof(resource_t *)); 497 rcp->rscarray[rcp->count-1] = rsc; 498 } 499 } 500 501 if(!win32) 502 { 503 /* We're done, win16 requires no special sorting */ 504 return; 505 } 506 507 /* We now have a unsorted list of types with an array of res_count_t 508 * in rcarray[0..rccount-1]. And we have names of one type in the 509 * rcarray[x].rsc[0..rcarray[x].count-1] arrays. 510 * The list needs to be sorted for win32's top level tree structure. 511 */ 512 513 /* Sort the types */ 514 if(rccount > 1) 515 qsort(rcarray, rccount, sizeof(rcarray[0]), sort_type); 516 517 /* Now sort the name-id arrays */ 518 for(i = 0; i < rccount; i++) 519 { 520 if(rcarray[i].count > 1) 521 qsort(rcarray[i].rscarray, rcarray[i].count, sizeof(rcarray[0].rscarray[0]), sort_name_id); 522 } 523 524 /* Now split the name-id arrays into name/language 525 * subs. Don't look at the awfull expressions... 526 * We do this by taking the array elements out of rscarray and putting 527 * together a new array in rsc32array. 528 */ 529 for(i = 0; i < rccount; i++) 530 { 531 res_count_t *rcap; 532 533 assert(rcarray[i].count >= 1); 534 535 /* rcap points to the current type we are dealing with */ 536 rcap = &(rcarray[i]); 537 538 /* Insert the first name-id */ 539 rcap->rsc32array = (res32_count_t *)xmalloc(sizeof(res32_count_t)); 540 rcap->count32 = 1; 541 rcap->rsc32array[0].rsc = (resource_t **)xmalloc(sizeof(resource_t *)); 542 rcap->rsc32array[0].count = 1; 543 rcap->rsc32array[0].rsc[0] = rcap->rscarray[0]; 544 if(rcap->rscarray[0]->name->type == name_ord) 545 { 546 rcap->n_id_entries = 1; 547 rcap->n_name_entries = 0; 548 } 549 else 550 { 551 rcap->n_id_entries = 0; 552 rcap->n_name_entries = 1; 553 } 554 555 /* Now loop over the resting resources of the current type 556 * to find duplicate names (which should have different 557 * languages). 558 */ 559 for(j = 1; j < rcap->count; j++) 560 { 561 res32_count_t *r32cp; 562 563 /* r32cp points to the current res32_count structure 564 * that holds the resource name we are processing. 565 */ 566 r32cp = &(rcap->rsc32array[rcap->count32-1]); 567 568 if(!compare_name_id(r32cp->rsc[0]->name, rcarray[i].rscarray[j]->name)) 569 { 570 /* Names are the same, add to list */ 571 r32cp->count++; 572 r32cp->rsc = (resource_t **)xrealloc(r32cp->rsc, r32cp->count * sizeof(resource_t *)); 573 r32cp->rsc[r32cp->count-1] = rcap->rscarray[j]; 574 } 575 else 576 { 577 /* New name-id, sort the old one by 578 * language and create new list 579 */ 580 if(r32cp->count > 1) 581 qsort(r32cp->rsc, r32cp->count, sizeof(r32cp->rsc[0]), sort_language); 582 rcap->count32++; 583 rcap->rsc32array = (res32_count_t*)xrealloc(rcap->rsc32array, rcap->count32 * sizeof(res32_count_t)); 584 rcap->rsc32array[rcap->count32-1].rsc = (resource_t **)xmalloc(sizeof(resource_t *)); 585 rcap->rsc32array[rcap->count32-1].count = 1; 586 rcap->rsc32array[rcap->count32-1].rsc[0] = rcap->rscarray[j]; 587 588 if(rcap->rscarray[j]->name->type == name_ord) 589 rcap->n_id_entries++; 590 else 591 rcap->n_name_entries++; 592 } 593 } 594 /* Also sort the languages of the last name group */ 595 if(rcap->rsc32array[rcap->count32-1].count > 1) 596 qsort(rcap->rsc32array[rcap->count32-1].rsc, 597 rcap->rsc32array[rcap->count32-1].count, 598 sizeof(rcap->rsc32array[rcap->count32-1].rsc[0]), 599 sort_language); 600 } 554 601 } 555 602 556 603 /* 557 604 ***************************************************************************** 558 * Function : write_pe_segment559 * Syntax : void write_pe_segment(FILE *fp, resource_t *top)560 * Input :561 * Output :562 * Description :563 * Remarks :605 * Function : write_pe_segment 606 * Syntax : void write_pe_segment(FILE *fp, resource_t *top) 607 * Input : 608 * Output : 609 * Description : 610 * Remarks : 564 611 ***************************************************************************** 565 612 */ 566 613 void write_pe_segment(FILE *fp, resource_t *top) 567 614 { 568 int i;569 570 fprintf(fp, "\t.align\t4\n");571 fprintf(fp, "%s%s:\n", prefix, _PEResTab);572 fprintf(fp, "\t.globl\t%s%s\n", prefix, _PEResTab);573 /* Flags */574 fprintf(fp, "\t.long\t0\n");575 /* Time/Date stamp */576 fprintf(fp, "\t.long\t0x%08lx\n", (long)now);577 /* Version */578 fprintf(fp, "\t.long\t0\n");/* FIXME: must version be filled out? */579 /* # of id entries, # of name entries */580 fprintf(fp, "\t.word\t%d, %d\n", n_name_entries, n_id_entries);581 582 /* Write the type level of the tree */583 for(i = 0; i < rccount; i++)584 {585 res_count_t *rcp;586 char *label;587 588 rcp = &rcarray[i];589 590 /* TypeId */591 if(rcp->type.type == name_ord)592 fprintf(fp, "\t.long\t%d\n", rcp->type.name.i_name);593 else594 {595 char *name = prep_nid_for_label(&(rcp->type));596 fprintf(fp, "\t.long\t(%s_%s_typename - %s%s) | 0x80000000\n",597 prefix,598 name,599 prefix,600 _PEResTab);601 }602 /* Offset */603 label = prep_nid_for_label(&(rcp->type));604 fprintf(fp, "\t.long\t(.L%s - %s%s) | 0x80000000\n",605 label,606 prefix,607 _PEResTab);608 }609 610 /* Write the name level of the tree */611 612 for(i = 0; i < rccount; i++)613 {614 res_count_t *rcp;615 char *typelabel;616 char *namelabel;617 int j;618 619 rcp = &rcarray[i];620 621 typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));622 fprintf(fp, ".L%s:\n", typelabel);623 624 fprintf(fp, "\t.long\t0\n");/* Flags */625 fprintf(fp, "\t.long\t0x%08lx\n", (long)now);/* TimeDate */626 fprintf(fp, "\t.long\t0\n");/* FIXME: must version be filled out? */627 fprintf(fp, "\t.word\t%d, %d\n", rcp->n_name_entries, rcp->n_id_entries);628 for(j = 0; j < rcp->count32; j++)629 {630 resource_t *rsc = rcp->rsc32array[j].rsc[0];631 /* NameId */632 if(rsc->name->type == name_ord)633 fprintf(fp, "\t.long\t%d\n", rsc->name->name.i_name);634 else635 {636 char *label = prep_nid_for_label(rsc->name);637 fprintf(fp, "\t.long\t(%s_%s_name - %s%s) | 0x80000000\n",638 prefix,639 label,640 prefix,641 _PEResTab);642 }643 /* Maybe FIXME: Unescape the tree (ommit 0x80000000) and644 * put the offset to the resource data entry.645 * ?? Is unescaping worth while ??646 */647 /* Offset */648 namelabel = prep_nid_for_label(rsc->name);649 fprintf(fp, "\t.long\t(.L%s_%s - %s%s) | 0x80000000\n",650 typelabel,651 namelabel,652 prefix,653 _PEResTab);654 }655 free(typelabel);656 }657 658 /* Write the language level of the tree */659 660 for(i = 0; i < rccount; i++)661 {662 res_count_t *rcp;663 char *namelabel;664 char *typelabel;665 int j;666 667 rcp = &rcarray[i];668 typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));669 670 for(j = 0; j < rcp->count32; j++)671 {672 res32_count_t *r32cp = &(rcp->rsc32array[j]);673 int k;674 675 namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));676 fprintf(fp, ".L%s_%s:\n", typelabel, namelabel);677 678 fprintf(fp, "\t.long\t0\n");/* Flags */679 fprintf(fp, "\t.long\t0x%08lx\n", (long)now);/* TimeDate */680 fprintf(fp, "\t.long\t0\n");/* FIXME: must version be filled out? */681 fprintf(fp, "\t.word\t0, %d\n", r32cp->count);682 683 for(k = 0; k < r32cp->count; k++)684 {685 resource_t *rsc = r32cp->rsc[k];686 assert(rsc->lan != NULL);687 /* LanguageId */688 fprintf(fp, "\t.long\t0x%08x\n", rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);689 /* Offset */690 fprintf(fp, "\t.long\t.L%s_%s_%d - %s%s\n",691 typelabel,692 namelabel,693 rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0,694 prefix,695 _PEResTab);696 }697 free(namelabel);698 }699 free(typelabel);700 }701 702 /* Write the resource table itself */703 fprintf(fp, "%s_ResourceDirectory:\n", prefix);704 fprintf(fp, "\t.globl\t%s_ResourceDirectory\n", prefix);705 direntries = 0;706 707 for(i = 0; i < rccount; i++)708 {709 res_count_t *rcp;710 char *namelabel;711 char *typelabel;712 int j;713 714 rcp = &rcarray[i];715 typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));716 717 for(j = 0; j < rcp->count32; j++)718 {719 res32_count_t *r32cp = &(rcp->rsc32array[j]);720 int k;721 722 namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));723 724 for(k = 0; k < r32cp->count; k++)725 {726 resource_t *rsc = r32cp->rsc[k];727 728 assert(rsc->lan != NULL);729 730 fprintf(fp, ".L%s_%s_%d:\n",731 typelabel,732 namelabel,733 rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);734 735 /* Data RVA */736 fprintf(fp, "\t.long\t%s%s_data - %s%s\n",737 prefix,738 rsc->c_name,739 prefix,740 _PEResTab);741 /* Size */742 fprintf(fp, "\t.long\t%d\n",743 rsc->binres->size - rsc->binres->dataidx);744 /* CodePage */745 fprintf(fp, "\t.long\t%ld\n", codepage);746 /* Reserved */747 fprintf(fp, "\t.long\t0\n");748 749 direntries++;750 }751 free(namelabel);752 }753 free(typelabel);754 }615 int i; 616 617 fprintf(fp, "\t"DIRECTIVE_ALIGN"\t4\n"); 618 fprintf(fp, "%s%s:\n", prefix, _PEResTab); 619 fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _PEResTab); 620 /* Flags */ 621 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); 622 /* Time/Date stamp */ 623 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now); 624 /* Version */ 625 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* FIXME: must version be filled out? */ 626 /* # of id entries, # of name entries */ 627 fprintf(fp, "\t"DIRECTIVE_WORD"\t%d, %d\n", n_name_entries, n_id_entries); 628 629 /* Write the type level of the tree */ 630 for(i = 0; i < rccount; i++) 631 { 632 res_count_t *rcp; 633 char *label; 634 635 rcp = &rcarray[i]; 636 637 /* TypeId */ 638 if(rcp->type.type == name_ord) 639 fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n", rcp->type.name.i_name); 640 else 641 { 642 char *name = prep_nid_for_label(&(rcp->type)); 643 fprintf(fp, "\t"DIRECTIVE_LONG"\t(%s_%s_typename - %s%s) "OR" "HEXBIT31"\n", 644 prefix, 645 name, 646 prefix, 647 _PEResTab); 648 } 649 /* Offset */ 650 label = prep_nid_for_label(&(rcp->type)); 651 fprintf(fp, "\t"DIRECTIVE_LONG"\t("LOCAL_PREFIX"L%s - %s%s) "OR" "HEXBIT31"\n", 652 label, 653 prefix, 654 _PEResTab); 655 } 656 657 /* Write the name level of the tree */ 658 659 for(i = 0; i < rccount; i++) 660 { 661 res_count_t *rcp; 662 char *typelabel; 663 char *namelabel; 664 int j; 665 666 rcp = &rcarray[i]; 667 668 typelabel = xstrdup(prep_nid_for_label(&(rcp->type))); 669 fprintf(fp, LOCAL_PREFIX"L%s:\n", typelabel); 670 671 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* Flags */ 672 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now); /* TimeDate */ 673 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* FIXME: must version be filled out? */ 674 fprintf(fp, "\t"DIRECTIVE_WORD"\t%d, %d\n", rcp->n_name_entries, rcp->n_id_entries); 675 for(j = 0; j < rcp->count32; j++) 676 { 677 resource_t *rsc = rcp->rsc32array[j].rsc[0]; 678 /* NameId */ 679 if(rsc->name->type == name_ord) 680 fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n", rsc->name->name.i_name); 681 else 682 { 683 char *label = prep_nid_for_label(rsc->name); 684 fprintf(fp, "\t"DIRECTIVE_LONG"\t(%s_%s_name - %s%s) "OR" "HEXBIT31"\n", 685 prefix, 686 label, 687 prefix, 688 _PEResTab); 689 } 690 /* Maybe FIXME: Unescape the tree (ommit 0x80000000) and 691 * put the offset to the resource data entry. 692 * ?? Is unescaping worth while ?? 693 */ 694 /* Offset */ 695 namelabel = prep_nid_for_label(rsc->name); 696 fprintf(fp, "\t"DIRECTIVE_LONG"\t("LOCAL_PREFIX"L%s_%s - %s%s) "OR" "HEXBIT31"\n", 697 typelabel, 698 namelabel, 699 prefix, 700 _PEResTab); 701 } 702 free(typelabel); 703 } 704 705 /* Write the language level of the tree */ 706 707 for(i = 0; i < rccount; i++) 708 { 709 res_count_t *rcp; 710 char *namelabel; 711 char *typelabel; 712 int j; 713 714 rcp = &rcarray[i]; 715 typelabel = xstrdup(prep_nid_for_label(&(rcp->type))); 716 717 for(j = 0; j < rcp->count32; j++) 718 { 719 res32_count_t *r32cp = &(rcp->rsc32array[j]); 720 int k; 721 722 namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name)); 723 fprintf(fp, LOCAL_PREFIX"L%s_%s:\n", typelabel, namelabel); 724 725 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* Flags */ 726 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now); /* TimeDate */ 727 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* FIXME: must version be filled out? */ 728 fprintf(fp, "\t"DIRECTIVE_WORD"\t0, %d\n", r32cp->count); 729 730 for(k = 0; k < r32cp->count; k++) 731 { 732 resource_t *rsc = r32cp->rsc[k]; 733 assert(rsc->lan != NULL); 734 /* LanguageId */ 735 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0); 736 /* Offset */ 737 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LOCAL_PREFIX"L%s_%s_%d - %s%s\n", 738 typelabel, 739 namelabel, 740 rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0, 741 prefix, 742 _PEResTab); 743 } 744 free(namelabel); 745 } 746 free(typelabel); 747 } 748 749 /* Write the resource table itself */ 750 fprintf(fp, "%s_ResourceDirectory:\n", prefix); 751 fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceDirectory\n", prefix); 752 direntries = 0; 753 754 for(i = 0; i < rccount; i++) 755 { 756 res_count_t *rcp; 757 char *namelabel; 758 char *typelabel; 759 int j; 760 761 rcp = &rcarray[i]; 762 typelabel = xstrdup(prep_nid_for_label(&(rcp->type))); 763 764 for(j = 0; j < rcp->count32; j++) 765 { 766 res32_count_t *r32cp = &(rcp->rsc32array[j]); 767 int k; 768 769 namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name)); 770 771 for(k = 0; k < r32cp->count; k++) 772 { 773 resource_t *rsc = r32cp->rsc[k]; 774 775 assert(rsc->lan != NULL); 776 777 fprintf(fp, LOCAL_PREFIX"L%s_%s_%d:\n", 778 typelabel, 779 namelabel, 780 rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0); 781 782 /* Data RVA */ 783 fprintf(fp, "\t"DIRECTIVE_LONG"\t%s%s_data - %s%s\n", 784 prefix, 785 rsc->c_name, 786 prefix, 787 _PEResTab); 788 /* Size */ 789 fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n", 790 rsc->binres->size - rsc->binres->dataidx); 791 /* CodePage */ 792 fprintf(fp, "\t"DIRECTIVE_LONG"\t%ld\n", codepage); 793 /* Reserved */ 794 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); 795 796 direntries++; 797 } 798 free(namelabel); 799 } 800 free(typelabel); 801 } 755 802 } 756 803 757 804 /* 758 805 ***************************************************************************** 759 * Function : write_ne_segment760 * Syntax : void write_ne_segment(FILE *fp, resource_t *top)761 * Input :762 * Output :763 * Description :764 * Remarks :806 * Function : write_ne_segment 807 * Syntax : void write_ne_segment(FILE *fp, resource_t *top) 808 * Input : 809 * Output : 810 * Description : 811 * Remarks : 765 812 ***************************************************************************** 766 813 */ 767 814 void write_ne_segment(FILE *fp, resource_t *top) 768 815 { 769 int i, j;770 771 fprintf(fp, "\t.align\t4\n");772 fprintf(fp, "%s%s:\n", prefix, _NEResTab);773 fprintf(fp, "\t.globl\t%s%s\n", prefix, _NEResTab);774 775 /* AlignmentShift */776 fprintf(fp, "\t.word\t%d\n", alignment_pwr);777 778 /* TypeInfo */779 for(i = 0; i < rccount; i++)780 {781 res_count_t *rcp = &rcarray[i];782 783 /* TypeId */784 if(rcp->type.type == name_ord)785 fprintf(fp, "\t.word\t0x%04x\n", rcp->type.name.i_name | 0x8000);786 else787 fprintf(fp, "\t.word\t%s_%s_typename - %s%s\n",788 prefix,789 rcp->type.name.s_name->str.cstr,790 prefix,791 _NEResTab);792 /* ResourceCount */793 fprintf(fp, "\t.word\t%d\n", rcp->count);794 /* Reserved */795 fprintf(fp, "\t.long\t0\n");796 /* NameInfo */797 for(j = 0; j < rcp->count; j++)798 {816 int i, j; 817 818 fprintf(fp, "\t"DIRECTIVE_ALIGN"\t4\n"); 819 fprintf(fp, "%s%s:\n", prefix, _NEResTab); 820 fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _NEResTab); 821 822 /* AlignmentShift */ 823 fprintf(fp, "\t"DIRECTIVE_WORD"\t%d\n", alignment_pwr); 824 825 /* TypeInfo */ 826 for(i = 0; i < rccount; i++) 827 { 828 res_count_t *rcp = &rcarray[i]; 829 830 /* TypeId */ 831 if(rcp->type.type == name_ord) 832 fprintf(fp, "\t"DIRECTIVE_WORD"\t"SHORTFRMT"\n", rcp->type.name.i_name | 0x8000); 833 else 834 fprintf(fp, "\t"DIRECTIVE_WORD"\t%s_%s_typename - %s%s\n", 835 prefix, 836 rcp->type.name.s_name->str.cstr, 837 prefix, 838 _NEResTab); 839 /* ResourceCount */ 840 fprintf(fp, "\t"DIRECTIVE_WORD"\t%d\n", rcp->count); 841 /* Reserved */ 842 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); 843 /* NameInfo */ 844 for(j = 0; j < rcp->count; j++) 845 { 799 846 /* 800 847 * VERY IMPORTANT: … … 805 852 * All other things are as the MS doc describes (alignment etc.) 806 853 */ 807 /* Offset */808 fprintf(fp, "\t.word\t(%s%s_data - %s%s) >> %d\n",809 prefix,810 rcp->rscarray[j]->c_name,811 prefix,812 _NEResTab,813 alignment_pwr);814 /* Length */815 fprintf(fp, "\t.word\t%d\n",816 rcp->rscarray[j]->binres->size - rcp->rscarray[j]->binres->dataidx);817 /* Flags */818 fprintf(fp, "\t.word\t0x%04x\n", (WORD)rcp->rscarray[j]->memopt);819 /* Id */820 if(rcp->rscarray[j]->name->type == name_ord)821 fprintf(fp, "\t.word\t0x%04x\n", rcp->rscarray[j]->name->name.i_name | 0x8000);822 else823 fprintf(fp, "\t.word\t%s%s_name - %s%s\n",824 prefix,825 rcp->rscarray[j]->c_name,826 prefix,827 _NEResTab);828 /* Handle and Usage */829 fprintf(fp, "\t.word\t0, 0\n");830 }831 }832 /* EndTypes */833 fprintf(fp, "\t.word\t0\n");854 /* Offset */ 855 fprintf(fp, "\t"DIRECTIVE_WORD"\t(%s%s_data - %s%s) >> %d\n", 856 prefix, 857 rcp->rscarray[j]->c_name, 858 prefix, 859 _NEResTab, 860 alignment_pwr); 861 /* Length */ 862 fprintf(fp, "\t"DIRECTIVE_WORD"\t%d\n", 863 rcp->rscarray[j]->binres->size - rcp->rscarray[j]->binres->dataidx); 864 /* Flags */ 865 fprintf(fp, "\t"DIRECTIVE_WORD"\t"SHORTFRMT"\n", (WORD)rcp->rscarray[j]->memopt); 866 /* Id */ 867 if(rcp->rscarray[j]->name->type == name_ord) 868 fprintf(fp, "\t"DIRECTIVE_WORD"\t"SHORTFRMT"\n", rcp->rscarray[j]->name->name.i_name | 0x8000); 869 else 870 fprintf(fp, "\t"DIRECTIVE_WORD"\t%s%s_name - %s%s\n", 871 prefix, 872 rcp->rscarray[j]->c_name, 873 prefix, 874 _NEResTab); 875 /* Handle and Usage */ 876 fprintf(fp, "\t"DIRECTIVE_WORD"\t0, 0\n"); 877 } 878 } 879 /* EndTypes */ 880 fprintf(fp, "\t"DIRECTIVE_WORD"\t0\n"); 834 881 } 835 882 836 883 /* 837 884 ***************************************************************************** 838 * Function : write_rsc_names839 * Syntax : void write_rsc_names(FILE *fp, resource_t *top)840 * Input :841 * Output :842 * Description :843 * Remarks :885 * Function : write_rsc_names 886 * Syntax : void write_rsc_names(FILE *fp, resource_t *top) 887 * Input : 888 * Output : 889 * Description : 890 * Remarks : 844 891 ***************************************************************************** 845 892 */ 846 893 void write_rsc_names(FILE *fp, resource_t *top) 847 894 { 848 int i, j;849 850 if(win32)851 {852 /* Write the names */853 854 for(i = 0; i < rccount; i++)855 {856 res_count_t *rcp;857 858 rcp = &rcarray[i];859 860 if(rcp->type.type == name_str)861 {862 char *name = prep_nid_for_label(&(rcp->type));863 fprintf(fp, "%s_%s_typename:\n",864 prefix,865 name);866 write_name_str(fp, &(rcp->type));867 }868 869 for(j = 0; j < rcp->count32; j++)870 {871 resource_t *rsc = rcp->rsc32array[j].rsc[0];872 873 if(rsc->name->type == name_str)874 {875 char *name = prep_nid_for_label(rsc->name);876 fprintf(fp, "%s_%s_name:\n",877 prefix,878 name);879 write_name_str(fp, rsc->name);880 }881 }882 }883 }884 else885 {886 /* ResourceNames */887 for(i = 0; i < rccount; i++)888 {889 res_count_t *rcp = &rcarray[i];890 891 for(j = 0; j < rcp->count; j++)892 {893 if(rcp->type.type == name_str)894 {895 fprintf(fp, "%s_%s_typename:\n",896 prefix,897 rcp->type.name.s_name->str.cstr);898 write_name_str(fp, &(rcp->type));899 }900 if(rcp->rscarray[j]->name->type == name_str)901 {902 fprintf(fp, "%s%s_name:\n",903 prefix,904 rcp->rscarray[j]->c_name);905 write_name_str(fp, rcp->rscarray[j]->name);906 }907 }908 }909 /* EndNames */910 911 /* This is to end the NE resource table */912 if(create_dir)913 fprintf(fp, "\t.byte\t0\n");914 }915 916 fprintf(fp, "\n");895 int i, j; 896 897 if(win32) 898 { 899 /* Write the names */ 900 901 for(i = 0; i < rccount; i++) 902 { 903 res_count_t *rcp; 904 905 rcp = &rcarray[i]; 906 907 if(rcp->type.type == name_str) 908 { 909 char *name = prep_nid_for_label(&(rcp->type)); 910 fprintf(fp, "%s_%s_typename:\n", 911 prefix, 912 name); 913 write_name_str(fp, &(rcp->type)); 914 } 915 916 for(j = 0; j < rcp->count32; j++) 917 { 918 resource_t *rsc = rcp->rsc32array[j].rsc[0]; 919 920 if(rsc->name->type == name_str) 921 { 922 char *name = prep_nid_for_label(rsc->name); 923 fprintf(fp, "%s_%s_name:\n", 924 prefix, 925 name); 926 write_name_str(fp, rsc->name); 927 } 928 } 929 } 930 } 931 else 932 { 933 /* ResourceNames */ 934 for(i = 0; i < rccount; i++) 935 { 936 res_count_t *rcp = &rcarray[i]; 937 938 for(j = 0; j < rcp->count; j++) 939 { 940 if(rcp->type.type == name_str) 941 { 942 fprintf(fp, "%s_%s_typename:\n", 943 prefix, 944 rcp->type.name.s_name->str.cstr); 945 write_name_str(fp, &(rcp->type)); 946 } 947 if(rcp->rscarray[j]->name->type == name_str) 948 { 949 fprintf(fp, "%s%s_name:\n", 950 prefix, 951 rcp->rscarray[j]->c_name); 952 write_name_str(fp, rcp->rscarray[j]->name); 953 } 954 } 955 } 956 /* EndNames */ 957 958 /* This is to end the NE resource table */ 959 if(create_dir) 960 fprintf(fp, "\t"DIRECTIVE_BYTE"\t0\n"); 961 } 962 963 fprintf(fp, "\n"); 917 964 } 918 965 919 966 /* 920 967 ***************************************************************************** 921 * Function : write_s_file922 * Syntax : void write_s_file(char *outname, resource_t *top)923 * Input :924 * outname- Filename to write to925 * top- The resource-tree to convert926 * Output :927 * Description :928 * Remarks :968 * Function : write_s_file 969 * Syntax : void write_s_file(char *outname, resource_t *top) 970 * Input : 971 * outname - Filename to write to 972 * top - The resource-tree to convert 973 * Output : 974 * Description : 975 * Remarks : 929 976 ***************************************************************************** 930 977 */ 931 978 void write_s_file(char *outname, resource_t *top) 932 979 { 933 FILE *fo;934 resource_t *rsc;935 936 fo = fopen(outname, "wt");937 if(!fo)938 {939 error("Could not open %s\n", outname);940 return;941 }942 943 {944 char *s, *p;945 now = time(NULL);946 s = ctime(&now);947 p = strchr(s, '\n');948 if(p) *p = '\0';949 fprintf(fo, s_file_head_str, input_name ? input_name : "stdin",950 cmdline, s);951 }952 953 /* Get an idea how many we have and restructure the tables */954 count_resources(top);955 956 /* First write the segment tables */957 if(create_dir)958 {959 if(win32)960 write_pe_segment(fo, top);961 else962 write_ne_segment(fo, top);963 }964 965 /* Dump the names */966 write_rsc_names(fo, top);967 968 if(create_dir)969 fprintf(fo, ".LResTabEnd:\n");970 971 if(!indirect_only)972 {973 /* Write the resource data */974 fprintf(fo, "\n/* Resource binary data */\n\n");975 for(rsc = top; rsc; rsc = rsc->next)976 {977 if(!rsc->binres)978 continue;979 980 fprintf(fo, "\t.align\t%d\n", win32 ? 4 : alignment);981 fprintf(fo, "%s%s_data:\n", prefix, rsc->c_name);982 if(global)983 fprintf(fo, "\t.globl\t%s%s_data\n", prefix, rsc->c_name);984 985 write_s_res(fo, rsc->binres);986 987 fprintf(fo, "\n");988 }989 990 if(create_dir)991 {992 /* Add a resource descriptor for built-in and elf-dlls */993 fprintf(fo, "\t.align\t4\n");994 fprintf(fo, "%s_ResourceDescriptor:\n", prefix);995 fprintf(fo, "\t.globl\t%s_ResourceDescriptor\n", prefix);996 fprintf(fo, "%s_ResourceTable:\n", prefix);997 if(global)998 fprintf(fo, "\t.globl\t%s_ResourceTable\n", prefix);999 fprintf(fo, "\t.long\t%s%s\n", prefix, win32 ? _PEResTab : _NEResTab);1000 fprintf(fo, "%s_NumberOfResources:\n", prefix);1001 if(global)1002 fprintf(fo, "\t.globl\t%s_NumberOfResources\n", prefix);1003 fprintf(fo, "\t.long\t%d\n", direntries);1004 fprintf(fo, "%s_ResourceSectionSize:\n", prefix);1005 if(global)1006 fprintf(fo, "\t.globl\t%s_ResourceSectionSize\n", prefix);1007 fprintf(fo, "\t.long\t.LResTabEnd - %s%s\n", prefix, win32 ? _PEResTab : _NEResTab);1008 if(win32)1009 {1010 fprintf(fo, "%s_ResourcesEntries:\n", prefix);1011 if(global)1012 fprintf(fo, "\t.globl\t%s_ResourcesEntries\n", prefix);1013 fprintf(fo, "\t.long\t%s_ResourceDirectory\n", prefix);1014 }1015 }1016 }1017 1018 if(indirect)1019 {1020 /* Write the indirection structures */1021 fprintf(fo, "\n/* Resource indirection structures */\n\n");1022 fprintf(fo, "\t.align\t4\n");1023 for(rsc = top; rsc; rsc = rsc->next)1024 {1025 int type;1026 char *type_name = NULL;1027 char *label;1028 1029 if(!rsc->binres)1030 continue;1031 1032 switch(rsc->type)1033 {1034 case res_menex:1035 type = WRC_RT_MENU;1036 break;1037 case res_dlgex:1038 type = WRC_RT_DIALOG;1039 break;1040 case res_usr:1041 assert(rsc->res.usr->type != NULL);1042 type_name = prep_nid_for_label(rsc->res.usr->type);1043 type = 0;1044 break;1045 default:1046 type = rsc->type;1047 }1048 1049 /*1050 * This follows a structure like:1051 * struct wrc_resource {1052 * INT32id;1053 * RSCNAME*resname;1054 * INT32restype;1055 * RSCNAME*typename;1056 * void*data;1057 * UINT32datasize;1058 * };1059 * The 'RSCNAME' is a pascal-style string where the1060 * first byte/word denotes the size and the rest the string1061 * itself.1062 */1063 fprintf(fo, "%s%s:\n", prefix, rsc->c_name);1064 if(global)1065 fprintf(fo, "\t.globl\t%s%s\n", prefix, rsc->c_name);1066 label = prep_nid_for_label(rsc->name);1067 fprintf(fo, "\t.long\t%d, %s%s%s%s, %d, %s%s%s%s, %s%s_data, %d\n",1068 rsc->name->type == name_ord ? rsc->name->name.i_name : 0,1069 rsc->name->type == name_ord ? "0" : prefix,1070 rsc->name->type == name_ord ? "" : "_",1071 rsc->name->type == name_ord ? "" : label,1072 rsc->name->type == name_ord ? "" : "_name",1073 type,1074 type ? "0" : prefix,1075 type ? "" : "_",1076 type ? "" : type_name,1077 type ? "" : "_typename",1078 prefix,1079 rsc->c_name,1080 rsc->binres->size - rsc->binres->dataidx);1081 fprintf(fo, "\n");1082 }1083 fprintf(fo, "\n");1084 1085 /* Write the indirection table */1086 fprintf(fo,"/* Resource indirection table */\n\n");1087 fprintf(fo, "\t.align\t4\n");1088 fprintf(fo, "%s%s:\n", prefix, _ResTable);1089 fprintf(fo, "\t.globl\t%s%s\n", prefix, _ResTable);1090 for(rsc = top; rsc; rsc = rsc->next)1091 {1092 fprintf(fo, "\t.long\t%s%s\n", prefix, rsc->c_name);1093 }1094 fprintf(fo, "\t.long\t0\n");1095 fprintf(fo, "\n");1096 }1097 1098 if(auto_register)1099 fprintf(fo, s_file_autoreg_str, prefix, _ResTable);1100 1101 fprintf(fo, s_file_tail_str);1102 fclose(fo);980 FILE *fo; 981 resource_t *rsc; 982 983 fo = fopen(outname, "wt"); 984 if(!fo) 985 { 986 error("Could not open %s\n", outname); 987 return; 988 } 989 990 { 991 char *s, *p; 992 now = time(NULL); 993 s = ctime(&now); 994 p = strchr(s, '\n'); 995 if(p) *p = '\0'; 996 fprintf(fo, s_file_head_str, input_name ? input_name : "stdin", 997 cmdline, s); 998 } 999 1000 /* Get an idea how many we have and restructure the tables */ 1001 count_resources(top); 1002 1003 /* First write the segment tables */ 1004 if(create_dir) 1005 { 1006 if(win32) 1007 write_pe_segment(fo, top); 1008 else 1009 write_ne_segment(fo, top); 1010 } 1011 1012 /* Dump the names */ 1013 write_rsc_names(fo, top); 1014 1015 if(create_dir) 1016 fprintf(fo, LOCAL_PREFIX"LResTabEnd:\n"); 1017 1018 if(!indirect_only) 1019 { 1020 /* Write the resource data */ 1021 fprintf(fo, "\n"COMMENT_LINE"/* Resource binary data */\n\n"); 1022 for(rsc = top; rsc; rsc = rsc->next) 1023 { 1024 if(!rsc->binres) 1025 continue; 1026 1027 fprintf(fo, "\t"DIRECTIVE_ALIGN"\t%d\n", win32 ? 4 : alignment); 1028 fprintf(fo, "%s%s_data:\n", prefix, rsc->c_name); 1029 if(global) 1030 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s_data\n", prefix, rsc->c_name); 1031 1032 write_s_res(fo, rsc->binres); 1033 1034 fprintf(fo, "\n"); 1035 } 1036 1037 if(create_dir) 1038 { 1039 /* Add a resource descriptor for built-in and elf-dlls */ 1040 fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n"); 1041 fprintf(fo, "%s_ResourceDescriptor:\n", prefix); 1042 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceDescriptor\n", prefix); 1043 fprintf(fo, "%s_ResourceTable:\n", prefix); 1044 if(global) 1045 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceTable\n", prefix); 1046 fprintf(fo, "\t"DIRECTIVE_LONG"\t%s%s\n", prefix, win32 ? _PEResTab : _NEResTab); 1047 fprintf(fo, "%s_NumberOfResources:\n", prefix); 1048 if(global) 1049 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_NumberOfResources\n", prefix); 1050 fprintf(fo, "\t"DIRECTIVE_LONG"\t%d\n", direntries); 1051 fprintf(fo, "%s_ResourceSectionSize:\n", prefix); 1052 if(global) 1053 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceSectionSize\n", prefix); 1054 fprintf(fo, "\t"DIRECTIVE_LONG"\t"LOCAL_PREFIX"LResTabEnd - %s%s\n", prefix, win32 ? _PEResTab : _NEResTab); 1055 if(win32) 1056 { 1057 fprintf(fo, "%s_ResourcesEntries:\n", prefix); 1058 if(global) 1059 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourcesEntries\n", prefix); 1060 fprintf(fo, "\t"DIRECTIVE_LONG"\t%s_ResourceDirectory\n", prefix); 1061 } 1062 } 1063 } 1064 1065 if(indirect) 1066 { 1067 /* Write the indirection structures */ 1068 fprintf(fo, "\n"COMMENT_LINE"/* Resource indirection structures */\n\n"); 1069 fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n"); 1070 for(rsc = top; rsc; rsc = rsc->next) 1071 { 1072 int type; 1073 char *type_name = NULL; 1074 char *label; 1075 1076 if(!rsc->binres) 1077 continue; 1078 1079 switch(rsc->type) 1080 { 1081 case res_menex: 1082 type = WRC_RT_MENU; 1083 break; 1084 case res_dlgex: 1085 type = WRC_RT_DIALOG; 1086 break; 1087 case res_usr: 1088 assert(rsc->res.usr->type != NULL); 1089 type_name = prep_nid_for_label(rsc->res.usr->type); 1090 type = 0; 1091 break; 1092 default: 1093 type = rsc->type; 1094 } 1095 1096 /* 1097 * This follows a structure like: 1098 * struct wrc_resource { 1099 * INT32 id; 1100 * RSCNAME *resname; 1101 * INT32 restype; 1102 * RSCNAME *typename; 1103 * void *data; 1104 * UINT32 datasize; 1105 * }; 1106 * The 'RSCNAME' is a pascal-style string where the 1107 * first byte/word denotes the size and the rest the string 1108 * itself. 1109 */ 1110 fprintf(fo, "%s%s:\n", prefix, rsc->c_name); 1111 if(global) 1112 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, rsc->c_name); 1113 label = prep_nid_for_label(rsc->name); 1114 fprintf(fo, "\t"DIRECTIVE_LONG"\t%d, %s%s%s%s, %d, %s%s%s%s, %s%s_data, %d\n", 1115 rsc->name->type == name_ord ? rsc->name->name.i_name : 0, 1116 rsc->name->type == name_ord ? "0" : prefix, 1117 rsc->name->type == name_ord ? "" : "_", 1118 rsc->name->type == name_ord ? "" : label, 1119 rsc->name->type == name_ord ? "" : "_name", 1120 type, 1121 type ? "0" : prefix, 1122 type ? "" : "_", 1123 type ? "" : type_name, 1124 type ? "" : "_typename", 1125 prefix, 1126 rsc->c_name, 1127 rsc->binres->size - rsc->binres->dataidx); 1128 fprintf(fo, "\n"); 1129 } 1130 fprintf(fo, "\n"); 1131 1132 /* Write the indirection table */ 1133 fprintf(fo, COMMENT_LINE"/* Resource indirection table */\n\n"); 1134 fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n"); 1135 fprintf(fo, "%s%s:\n", prefix, _ResTable); 1136 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _ResTable); 1137 for(rsc = top; rsc; rsc = rsc->next) 1138 { 1139 fprintf(fo, "\t"DIRECTIVE_LONG"\t%s%s\n", prefix, rsc->c_name); 1140 } 1141 fprintf(fo, "\t"DIRECTIVE_LONG"\t0\n"); 1142 fprintf(fo, "\n"); 1143 } 1144 1145 if(auto_register) 1146 fprintf(fo, s_file_autoreg_str, prefix, _ResTable); 1147 1148 fprintf(fo, s_file_tail_str); 1149 fclose(fo); 1103 1150 } 1104 1151 1105 1152 /* 1106 1153 ***************************************************************************** 1107 * Function : write_h_file1108 * Syntax : void write_h_file(char *outname, resource_t *top)1109 * Input :1110 * outname- Filename to write to1111 * top- The resource-tree to convert1112 * Output :1113 * Description :1114 * Remarks :1154 * Function : write_h_file 1155 * Syntax : void write_h_file(char *outname, resource_t *top) 1156 * Input : 1157 * outname - Filename to write to 1158 * top - The resource-tree to convert 1159 * Output : 1160 * Description : 1161 * Remarks : 1115 1162 ***************************************************************************** 1116 1163 */ 1117 1164 void write_h_file(char *outname, resource_t *top) 1118 1165 { 1119 FILE *fo;1120 resource_t *rsc;1121 char *h_prefix;1166 FILE *fo; 1167 resource_t *rsc; 1168 char *h_prefix; 1122 1169 1123 1170 #ifdef NEED_UNDERSCORE_PREFIX 1124 h_prefix = prefix + 1;1171 h_prefix = prefix + 1; 1125 1172 #else 1126 h_prefix = prefix;1173 h_prefix = prefix; 1127 1174 #endif 1128 1175 1129 fo = fopen(outname, "wt");1130 if(!fo)1131 {1132 error("Could not open %s\n", outname);1133 }1134 1135 time(&now);1136 fprintf(fo, h_file_head_str, input_name ? input_name : "stdin",1176 fo = fopen(outname, "wt"); 1177 if(!fo) 1178 { 1179 error("Could not open %s\n", outname); 1180 } 1181 1182 time(&now); 1183 fprintf(fo, h_file_head_str, input_name ? input_name : "stdin", 1137 1184 cmdline, ctime(&now), (long)now, (long)now); 1138 1185 1139 /* First write the segment tables reference */1140 if(create_dir)1141 {1142 fprintf(fo, "extern %schar %s%s[];\n\n",1143 constant ? "const " : "",1144 h_prefix,1145 win32 ? _PEResTab : _NEResTab);1146 }1147 1148 /* Write the resource data */1149 for(rsc = top; global && rsc; rsc = rsc->next)1150 {1151 if(!rsc->binres)1152 continue;1153 1154 fprintf(fo, "extern %schar %s%s_data[];\n",1155 constant ? "const " : "",1156 h_prefix,1157 rsc->c_name);1158 }1159 1160 if(indirect)1161 {1162 if(global)1163 fprintf(fo, "\n");1164 1165 /* Write the indirection structures */1166 for(rsc = top; global && rsc; rsc = rsc->next)1167 {1168 fprintf(fo, "extern %swrc_resource%d_t %s%s;\n",1169 constant ? "const " : "",1170 win32 ? 32 : 16,1171 h_prefix,1172 rsc->c_name);1173 }1174 1175 if(global)1176 fprintf(fo, "\n");1177 1178 /* Write the indirection table */1179 fprintf(fo, "extern %swrc_resource%d_t %s%s[];\n\n",1180 constant ? "const " : "",1181 win32 ? 32 : 16,1182 h_prefix,1183 _ResTable);1184 }1185 1186 fprintf(fo, h_file_tail_str);1187 fclose(fo);1188 } 1189 1190 1186 /* First write the segment tables reference */ 1187 if(create_dir) 1188 { 1189 fprintf(fo, "extern %schar %s%s[];\n\n", 1190 constant ? "const " : "", 1191 h_prefix, 1192 win32 ? _PEResTab : _NEResTab); 1193 } 1194 1195 /* Write the resource data */ 1196 for(rsc = top; global && rsc; rsc = rsc->next) 1197 { 1198 if(!rsc->binres) 1199 continue; 1200 1201 fprintf(fo, "extern %schar %s%s_data[];\n", 1202 constant ? "const " : "", 1203 h_prefix, 1204 rsc->c_name); 1205 } 1206 1207 if(indirect) 1208 { 1209 if(global) 1210 fprintf(fo, "\n"); 1211 1212 /* Write the indirection structures */ 1213 for(rsc = top; global && rsc; rsc = rsc->next) 1214 { 1215 fprintf(fo, "extern %swrc_resource%d_t %s%s;\n", 1216 constant ? "const " : "", 1217 win32 ? 32 : 16, 1218 h_prefix, 1219 rsc->c_name); 1220 } 1221 1222 if(global) 1223 fprintf(fo, "\n"); 1224 1225 /* Write the indirection table */ 1226 fprintf(fo, "extern %swrc_resource%d_t %s%s[];\n\n", 1227 constant ? "const " : "", 1228 win32 ? 32 : 16, 1229 h_prefix, 1230 _ResTable); 1231 } 1232 1233 fprintf(fo, h_file_tail_str); 1234 fclose(fo); 1235 } 1236 1237
Note:
See TracChangeset
for help on using the changeset viewer.
