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