Changeset 906 for trunk/tools/wrc/writeres.c
- Timestamp:
- Sep 11, 1999, 4:22:44 AM (26 years ago)
- File:
-
- 1 edited
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 79 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; 88 int rccount = 0; 89 int n_id_entries = 0; /* win32 only: Nr of unique ids in the type-level array */90 int n_name_entries = 0; 91 92 static int direntries; 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 99 * Syntax 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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 put_dword(res, 0);/* ResSize */125 put_dword(res, 0x00000020);/* HeaderSize */126 put_word(res, 0xffff);/* ResType */127 128 put_word(res, 0xffff);/* ResName */129 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 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 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 172 * Syntax 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 226 #define BYTESPERLINE 8 180 227 void write_s_res(FILE *fp, res_t *res) 181 228 { 182 183 184 185 186 187 188 189 190 fprintf(fp, "\t.byte\t");191 192 193 fprintf(fp, "0x%02x%s", res->data[idx] & 0xff,194 195 196 197 198 199 200 fprintf(fp, "\t.byte\t");201 202 203 fprintf(fp, "0x%02x%s", res->data[idx] & 0xff,204 205 206 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 213 * Syntax 214 * Input 215 * Output 216 * Description 217 * Remarks 259 * 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 223 224 225 226 227 228 229 230 231 232 233 234 235 res.size++;/* We need to write the lenth byte as well */236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 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 290 * Syntax 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 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 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 334 * Syntax 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 344 345 346 347 348 349 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 355 * Syntax 356 * Input 357 * Output 358 * Description 359 * Remarks 360 * 361 * 362 * 363 * 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) 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 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 376 377 378 379 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) 429 #define RCT(v) ((res_count_t *)(v)) 383 430 int sort_type(const void *e1, const void *e2) 384 431 { 385 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 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 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 559 * Syntax 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 569 570 fprintf(fp, "\t.align\t4\n");571 572 fprintf(fp, "\t.globl\t%s%s\n", prefix, _PEResTab);573 574 fprintf(fp, "\t.long\t0\n");575 576 fprintf(fp, "\t.long\t0x%08lx\n", (long)now);577 578 fprintf(fp, "\t.long\t0\n");/* FIXME: must version be filled out? */579 580 fprintf(fp, "\t.word\t%d, %d\n", n_name_entries, n_id_entries);581 582 583 584 585 586 587 588 589 590 591 592 fprintf(fp, "\t.long\t%d\n", rcp->type.name.i_name);593 594 595 596 fprintf(fp, "\t.long\t(%s_%s_typename - %s%s) | 0x80000000\n",597 598 599 600 601 602 603 604 fprintf(fp, "\t.long\t(.L%s - %s%s) | 0x80000000\n",605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 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 629 630 631 632 633 fprintf(fp, "\t.long\t%d\n", rsc->name->name.i_name);634 635 636 637 fprintf(fp, "\t.long\t(%s_%s_name - %s%s) | 0x80000000\n",638 639 640 641 642 643 644 645 646 647 648 649 fprintf(fp, "\t.long\t(.L%s_%s - %s%s) | 0x80000000\n",650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 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 684 685 686 687 688 fprintf(fp, "\t.long\t0x%08x\n", rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);689 690 fprintf(fp, "\t.long\t.L%s_%s_%d - %s%s\n",691 692 693 694 695 696 697 698 699 700 701 702 703 704 fprintf(fp, "\t.globl\t%s_ResourceDirectory\n", prefix);705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 fprintf(fp, ".L%s_%s_%d:\n",731 732 733 734 735 736 fprintf(fp, "\t.long\t%s%s_data - %s%s\n",737 738 739 740 741 742 fprintf(fp, "\t.long\t%d\n",743 744 745 fprintf(fp, "\t.long\t%ld\n", codepage);746 747 fprintf(fp, "\t.long\t0\n");748 749 750 751 752 753 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 760 * Syntax 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 770 771 fprintf(fp, "\t.align\t4\n");772 773 fprintf(fp, "\t.globl\t%s%s\n", prefix, _NEResTab);774 775 776 fprintf(fp, "\t.word\t%d\n", alignment_pwr);777 778 779 780 781 782 783 784 785 fprintf(fp, "\t.word\t0x%04x\n", rcp->type.name.i_name | 0x8000);786 787 fprintf(fp, "\t.word\t%s_%s_typename - %s%s\n",788 789 790 791 792 793 fprintf(fp, "\t.word\t%d\n", rcp->count);794 795 fprintf(fp, "\t.long\t0\n");796 797 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 808 fprintf(fp, "\t.word\t(%s%s_data - %s%s) >> %d\n",809 810 811 812 813 814 815 fprintf(fp, "\t.word\t%d\n",816 817 818 fprintf(fp, "\t.word\t0x%04x\n", (WORD)rcp->rscarray[j]->memopt);819 820 821 fprintf(fp, "\t.word\t0x%04x\n", rcp->rscarray[j]->name->name.i_name | 0x8000);822 823 fprintf(fp, "\t.word\t%s%s_name - %s%s\n",824 825 826 827 828 829 fprintf(fp, "\t.word\t0, 0\n");830 831 832 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 839 * Syntax 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 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 fprintf(fp, "\t.byte\t0\n");914 915 916 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 922 * Syntax 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 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 fprintf(fo, ".LResTabEnd:\n");970 971 972 973 974 fprintf(fo, "\n/* Resource binary data */\n\n");975 976 977 978 979 980 fprintf(fo, "\t.align\t%d\n", win32 ? 4 : alignment);981 982 983 fprintf(fo, "\t.globl\t%s%s_data\n", prefix, rsc->c_name);984 985 986 987 988 989 990 991 992 993 fprintf(fo, "\t.align\t4\n");994 995 fprintf(fo, "\t.globl\t%s_ResourceDescriptor\n", prefix);996 997 998 fprintf(fo, "\t.globl\t%s_ResourceTable\n", prefix);999 fprintf(fo, "\t.long\t%s%s\n", prefix, win32 ? _PEResTab : _NEResTab);1000 1001 1002 fprintf(fo, "\t.globl\t%s_NumberOfResources\n", prefix);1003 fprintf(fo, "\t.long\t%d\n", direntries);1004 1005 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 1009 1010 1011 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 1019 1020 1021 fprintf(fo, "\n/* Resource indirection structures */\n\n");1022 fprintf(fo, "\t.align\t4\n");1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 * INT32id;1053 * RSCNAME*resname;1054 * INT32restype;1055 * RSCNAME*typename;1056 * void*data;1057 * UINT32datasize;1058 1059 1060 1061 1062 1063 1064 1065 fprintf(fo, "\t.globl\t%s%s\n", prefix, rsc->c_name);1066 1067 fprintf(fo, "\t.long\t%d, %s%s%s%s, %d, %s%s%s%s, %s%s_data, %d\n",1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 fprintf(fo,"/* Resource indirection table */\n\n");1087 fprintf(fo, "\t.align\t4\n");1088 1089 fprintf(fo, "\t.globl\t%s%s\n", prefix, _ResTable);1090 1091 1092 fprintf(fo, "\t.long\t%s%s\n", prefix, rsc->c_name);1093 1094 fprintf(fo, "\t.long\t0\n");1095 1096 1097 1098 1099 1100 1101 1102 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 1108 * Syntax 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 1120 1121 1166 FILE *fo; 1167 resource_t *rsc; 1168 char *h_prefix; 1122 1169 1123 1170 #ifdef NEED_UNDERSCORE_PREFIX 1124 1171 h_prefix = prefix + 1; 1125 1172 #else 1126 1173 h_prefix = prefix; 1127 1174 #endif 1128 1175 1129 1130 1131 1132 1133 1134 1135 1136 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 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 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.