Remove assembly generation from wrc.
This commit is contained in:
parent
f498d4b8fb
commit
deaf02a586
180
tools/wrc/wrc.c
180
tools/wrc/wrc.c
|
@ -65,7 +65,6 @@
|
|||
|
||||
#include "wrc.h"
|
||||
#include "utils.h"
|
||||
#include "writeres.h"
|
||||
#include "readres.h"
|
||||
#include "dumpres.h"
|
||||
#include "genres.h"
|
||||
|
@ -86,7 +85,6 @@
|
|||
static char usage[] =
|
||||
"Usage: wrc [options...] [infile[.rc|.res]] [outfile]\n"
|
||||
" -a n Alignment of resource (win16 only, default is 4)\n"
|
||||
" -b Create an assembly array from a binary .res file\n"
|
||||
" -B x Set output byte-order x={n[ative], l[ittle], b[ig]}\n"
|
||||
" (win32 only; default is " ENDIAN "-endian)\n"
|
||||
" -C cp Set the resource's codepage to cp (default is 0)\n"
|
||||
|
@ -95,18 +93,15 @@ static char usage[] =
|
|||
" -e Disable recognition of win32 keywords in 16bit compile\n"
|
||||
" -E Preprocess only\n"
|
||||
" -F target Ignored for compatibility with windres\n"
|
||||
" -g Add symbols to the global c namespace\n"
|
||||
" -h Prints this summary.\n"
|
||||
" -i file The name of the input file.\n"
|
||||
" -I path Set include search dir to path (multiple -I allowed)\n"
|
||||
" -J Do not search the standard include path\n"
|
||||
" -l lan Set default language to lan (default is neutral {0, 0})\n"
|
||||
" -m Do not remap numerical resource IDs\n"
|
||||
" -o file Output to file (default is infile.[res|s]\n"
|
||||
" -O format The output format: one of `res', 'asm'.\n"
|
||||
" -p prefix Give a prefix for the generated names\n"
|
||||
" -o file Output to file (default is infile.res)\n"
|
||||
" -O format The output format (must be `res').\n"
|
||||
" -P program Specifies the preprocessor to use, including arguments.\n"
|
||||
" -s Add structure with win32/16 (PE/NE) resource directory\n"
|
||||
" -v Enable verbose mode.\n"
|
||||
" -V Print version and exit\n"
|
||||
" -w 16|32 Select win16 or win32 output (default is win32)\n"
|
||||
|
@ -136,7 +131,7 @@ static char usage[] =
|
|||
" * 0x10 Preprocessor lex messages\n"
|
||||
" * 0x20 Preprocessor yacc trace\n"
|
||||
"If no input filename is given and the output name is not overridden\n"
|
||||
"with -o, then the output is written to \"wrc.tab.{s,res}\"\n"
|
||||
"with -o, then the output is written to \"wrc.tab.res\"\n"
|
||||
;
|
||||
|
||||
char version_string[] = "Wine Resource Compiler Version " WRC_FULLVERSION "\n"
|
||||
|
@ -144,21 +139,15 @@ char version_string[] = "Wine Resource Compiler Version " WRC_FULLVERSION "\n"
|
|||
" 1994 Martin von Loewis\n";
|
||||
|
||||
/*
|
||||
* Default prefix for resource names used in the C array.
|
||||
* Option '-p name' sets it to 'name'
|
||||
* External functions
|
||||
*/
|
||||
char *prefix = __ASM_NAME("_Resource");
|
||||
void write_resfile(char *outname, resource_t *top);
|
||||
|
||||
/*
|
||||
* Set if compiling in 32bit mode (default).
|
||||
*/
|
||||
int win32 = 1;
|
||||
|
||||
/*
|
||||
* Output type (default res)
|
||||
*/
|
||||
enum output_t { output_def, output_res, output_asm } output_type = output_def;
|
||||
|
||||
/*
|
||||
* debuglevel == DEBUGLEVEL_NONE Don't bother
|
||||
* debuglevel & DEBUGLEVEL_CHAT Say whats done
|
||||
|
@ -176,22 +165,6 @@ int debuglevel = DEBUGLEVEL_NONE;
|
|||
*/
|
||||
int extensions = 1;
|
||||
|
||||
/*
|
||||
* Set when creating C array from .res file (-b option).
|
||||
*/
|
||||
int binary = 0;
|
||||
|
||||
/*
|
||||
* Set when the NE/PE resource directory should be dumped into
|
||||
* the output file.
|
||||
*/
|
||||
int create_dir = 0;
|
||||
|
||||
/*
|
||||
* Set when all symbols should be added to the global namespace (-g option)
|
||||
*/
|
||||
int global = 0;
|
||||
|
||||
/*
|
||||
* NE segment resource aligment (-a option)
|
||||
*/
|
||||
|
@ -250,7 +223,7 @@ static void rm_tempfile(void);
|
|||
static void segvhandler(int sig);
|
||||
|
||||
static const char* short_options =
|
||||
"a:AbB:cC:d:D:eEF:ghH:i:I:Jl:LmnNo:O:p:P:rstTvVw:W";
|
||||
"a:AB:cC:d:D:eEF:hH:i:I:Jl:LmnNo:O:P:rtTvVw:W";
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static struct option long_options[] = {
|
||||
{ "input", 1, 0, 'i' },
|
||||
|
@ -320,9 +293,6 @@ int main(int argc,char *argv[])
|
|||
case 'a':
|
||||
alignment = atoi(optarg);
|
||||
break;
|
||||
case 'b':
|
||||
binary = 1;
|
||||
break;
|
||||
case 'B':
|
||||
switch(optarg[0])
|
||||
{
|
||||
|
@ -361,9 +331,6 @@ int main(int argc,char *argv[])
|
|||
case 'F':
|
||||
/* ignored for compatibility with windres */
|
||||
break;
|
||||
case 'g':
|
||||
global = 1;
|
||||
break;
|
||||
case 'h':
|
||||
printf(usage);
|
||||
exit(0);
|
||||
|
@ -394,20 +361,13 @@ int main(int argc,char *argv[])
|
|||
else error("Too many output files.\n");
|
||||
break;
|
||||
case 'O':
|
||||
if (strcmp(optarg, "res") == 0) output_type = output_res;
|
||||
else if (strcmp(optarg, "asm") == 0) output_type = output_asm;
|
||||
else error("Output format %s not supported.", optarg);
|
||||
break;
|
||||
case 'p':
|
||||
prefix = xstrdup(optarg);
|
||||
if (strcmp(optarg, "res"))
|
||||
error("Output format %s not supported.", optarg);
|
||||
break;
|
||||
case 'P':
|
||||
if (strcmp(optarg, "cat") == 0) no_preprocess = 1;
|
||||
else fprintf(stderr, "-P option not yet supported, ignored.\n");
|
||||
break;
|
||||
case 's':
|
||||
create_dir = 1;
|
||||
break;
|
||||
case 'v':
|
||||
debuglevel = DEBUGLEVEL_CHAT;
|
||||
break;
|
||||
|
@ -460,19 +420,6 @@ int main(int argc,char *argv[])
|
|||
else error("Too many output files.\n");
|
||||
}
|
||||
|
||||
/* Try to guess the output format based on output name */
|
||||
if (output_type == output_def)
|
||||
{
|
||||
char *dotstr = output_name ? strrchr(output_name, '.') : 0;
|
||||
|
||||
output_type = output_res; /* by default generate .res files */
|
||||
if (dotstr)
|
||||
{
|
||||
if (strcmp(dotstr+1, "s") == 0) output_type = output_asm;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Check the command line options for invalid combinations */
|
||||
if(win32)
|
||||
{
|
||||
|
@ -483,51 +430,6 @@ int main(int argc,char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
if(output_type == output_res)
|
||||
{
|
||||
if(global)
|
||||
{
|
||||
warning("Option -g ignored with compile to .res\n");
|
||||
global = 0;
|
||||
}
|
||||
|
||||
if(create_dir)
|
||||
{
|
||||
error("Option -r and -s cannot be used together\n");
|
||||
}
|
||||
|
||||
if(binary)
|
||||
{
|
||||
error("Option -r and -b cannot be used together\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(byteorder != WRC_BO_NATIVE)
|
||||
{
|
||||
if(binary)
|
||||
error("Forced byteordering not supported for binary resources\n");
|
||||
}
|
||||
|
||||
if(preprocess_only)
|
||||
{
|
||||
if(global)
|
||||
{
|
||||
warning("Option -g ignored with preprocess only\n");
|
||||
global = 0;
|
||||
}
|
||||
|
||||
if(create_dir)
|
||||
{
|
||||
warning("Option -s ignored with preprocess only\n");
|
||||
create_dir = 0;
|
||||
}
|
||||
|
||||
if(binary)
|
||||
{
|
||||
error("Option -E and -b cannot be used together\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Set alignment power */
|
||||
a = alignment;
|
||||
for(alignment_pwr = 0; alignment_pwr < 10 && a > 1; alignment_pwr++)
|
||||
|
@ -575,21 +477,15 @@ int main(int argc,char *argv[])
|
|||
if(!currentlanguage)
|
||||
currentlanguage = new_language(0, 0);
|
||||
|
||||
if(binary && !input_name)
|
||||
{
|
||||
error("Binary mode requires .res file as input\n");
|
||||
}
|
||||
|
||||
/* Generate appropriate outfile names */
|
||||
if(!output_name && !preprocess_only)
|
||||
{
|
||||
output_name = dup_basename(input_name, binary ? ".res" : ".rc");
|
||||
if (output_type == output_res) strcat(output_name, ".res");
|
||||
else if (output_type == output_asm) strcat(output_name, ".s");
|
||||
output_name = dup_basename(input_name, ".rc");
|
||||
strcat(output_name, ".res");
|
||||
}
|
||||
|
||||
/* Run the preprocessor on the input */
|
||||
if(!no_preprocess && !binary)
|
||||
if(!no_preprocess)
|
||||
{
|
||||
/*
|
||||
* Preprocess the input to a temp-file, or stdout if
|
||||
|
@ -626,54 +522,26 @@ int main(int argc,char *argv[])
|
|||
input_name = temp_name;
|
||||
}
|
||||
|
||||
if(!binary)
|
||||
{
|
||||
/* Go from .rc to .res or .s */
|
||||
chat("Starting parse");
|
||||
/* Go from .rc to .res */
|
||||
chat("Starting parse");
|
||||
|
||||
if(!(yyin = fopen(input_name, "rb")))
|
||||
error("Could not open %s for input\n", input_name);
|
||||
if(!(yyin = fopen(input_name, "rb")))
|
||||
error("Could not open %s for input\n", input_name);
|
||||
|
||||
ret = yyparse();
|
||||
ret = yyparse();
|
||||
|
||||
if(input_name)
|
||||
fclose(yyin);
|
||||
if(input_name) fclose(yyin);
|
||||
|
||||
if(ret)
|
||||
{
|
||||
/* Error during parse */
|
||||
exit(1);
|
||||
}
|
||||
if(ret) exit(1); /* Error during parse */
|
||||
|
||||
if(debuglevel & DEBUGLEVEL_DUMP)
|
||||
dump_resources(resource_top);
|
||||
if(debuglevel & DEBUGLEVEL_DUMP)
|
||||
dump_resources(resource_top);
|
||||
|
||||
/* Convert the internal lists to binary data */
|
||||
resources2res(resource_top);
|
||||
/* Convert the internal lists to binary data */
|
||||
resources2res(resource_top);
|
||||
|
||||
if(output_type == output_res)
|
||||
{
|
||||
chat("Writing .res-file");
|
||||
write_resfile(output_name, resource_top);
|
||||
}
|
||||
else if(output_type == output_asm)
|
||||
{
|
||||
chat("Writing .s-file");
|
||||
write_s_file(output_name, resource_top);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Go from .res to .s */
|
||||
chat("Reading .res-file");
|
||||
resource_top = read_resfile(input_name);
|
||||
if(output_type == output_asm)
|
||||
{
|
||||
chat("Writing .s-file");
|
||||
write_s_file(output_name, resource_top);
|
||||
}
|
||||
}
|
||||
chat("Writing .res-file");
|
||||
write_resfile(output_name, resource_top);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -51,9 +51,6 @@ extern int debuglevel;
|
|||
extern int win32;
|
||||
extern int create_res;
|
||||
extern int extensions;
|
||||
extern int binary;
|
||||
extern int create_dir;
|
||||
extern int global;
|
||||
extern int alignment;
|
||||
extern int alignment_pwr;
|
||||
extern int create_s;
|
||||
|
@ -64,7 +61,6 @@ extern int preprocess_only;
|
|||
extern int no_preprocess;
|
||||
extern int remap;
|
||||
|
||||
extern char *prefix;
|
||||
extern char *output_name;
|
||||
extern char *input_name;
|
||||
extern char *cmdline;
|
||||
|
|
|
@ -5,39 +5,25 @@ wrc \- Wine Resource Compiler
|
|||
.BI "wrc " "[options] " "[inputfile]"
|
||||
.SH DESCRIPTION
|
||||
.B wrc
|
||||
compiles resources from
|
||||
.I inputfile
|
||||
into win16 and win32 compatible
|
||||
binary format.
|
||||
.B wrc
|
||||
outputs the binary data either in a standard \fB.res\fR formatted binary
|
||||
file, or an assembly file.
|
||||
.B wrc
|
||||
is also capable of reading \fB.res\fR formatted files and convert them
|
||||
into an assembly file.
|
||||
compiles resources from \fBinputfile\fR
|
||||
into win16 and win32 compatible binary format.
|
||||
.PP
|
||||
The source\-file is preprocessed with a builtin ANSI\-C compatible
|
||||
preprocessor before the resources are compiled. See \fBPREPROCESSOR\fR
|
||||
below.
|
||||
.PP
|
||||
.B wrc
|
||||
takes only one \fBinputfile\fR as argument. The \fBinputfile\fR has
|
||||
extension \fB.rc\fR for resources in source form and \fB.res\fR for
|
||||
binary resources. The resources are read from standard input if no
|
||||
inputfile is given. If the outputfile is not specified with \fI-o\fR,
|
||||
then \fBwrc\fR will write the output to \fBinputfile.{s,res}\fR
|
||||
with \fB.rc\fR stripped, depending on the mode of compilation.
|
||||
The outputfile is named \fBwrc.tab.{s,res}\fR if no inputfile was
|
||||
given.
|
||||
takes only one \fBinputfile\fR as argument. The resources are read from
|
||||
standard input if no inputfile is given. If the output file is not
|
||||
specified with \fI-o\fR, then \fBwrc\fR will write the output to
|
||||
\fBinputfile.res\fR with \fB.rc\fR stripped, or to \fBwrc.tab.res\fR if
|
||||
no inputfile was given.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.I \-a n
|
||||
Win16 only; set the alignment between resources n. The alignment must
|
||||
be a power of 2. The default is 4.
|
||||
.TP
|
||||
.I \-b
|
||||
Create an assembly file from a binary \fB.res\fR file.
|
||||
.TP
|
||||
.I \-B x
|
||||
Win32 only; set output byte\-ordering, where \fIx\fR is one of n[ative],
|
||||
l[ittle] or b[ig]. Only resources in source-form can be reorderd. Native
|
||||
|
@ -68,10 +54,6 @@ Preprocess only. The output is written to standard output if no
|
|||
outputfile was selected. The output is compatible with what gcc would
|
||||
generate.
|
||||
.TP
|
||||
.I \-g
|
||||
Add symbols to the global C namespace. This makes all symbols available
|
||||
for linking by other modules.
|
||||
.TP
|
||||
.I \-h
|
||||
Prints a summary message and exits.
|
||||
.TP
|
||||
|
@ -106,29 +88,20 @@ source\-files that contain overlapping type\-IDs, or when the format of the
|
|||
resource is not 100% compliant.
|
||||
.TP
|
||||
.I \-o file
|
||||
Write output to \fIfile\fR. Default is \fBinputfile.{res,s,h}\fR
|
||||
with \fB.rc\fR stripped or \fBwrc.tab.{s,h,res}\fR, depending on the
|
||||
compilation mode.
|
||||
Write output to \fIfile\fR. Default is \fBinputfile.res\fR
|
||||
with \fB.rc\fR stripped or \fBwrc.tab.res\fR if input is read
|
||||
from standard input.
|
||||
.TP
|
||||
.I \-O format
|
||||
Sets the output format. \fformat\fR can one either 'res' or 'asm'
|
||||
to generate a \fB.res\fR or \fB.s\fR file respectively.
|
||||
If not specified, \fBwrc\fR assumes 'res'.
|
||||
.TP
|
||||
.I \-p prefix
|
||||
Prefix all generated names with \fIprefix\fR. This is only relevant for
|
||||
names in the assembly code and header file. Resource names are not
|
||||
affected.
|
||||
Sets the output format. The only supported \fformat\fR is 'res', which
|
||||
is also the default format if this option is not specified. The option
|
||||
exists mainly for compatibility with \fBwindres\fR.
|
||||
.TP
|
||||
.I \-P program
|
||||
This option may be used to specify the preprocessor to use, including any
|
||||
leading arguments. If not specified, \fBwrc\fR uses its builtin processor.
|
||||
To disable preprocessing, use \fB-P cat\fR.
|
||||
.TP
|
||||
.I \-s
|
||||
Add structure with win32/16 (PE/NE) resource directory to outputfile.
|
||||
This directory is always in native byteorder.
|
||||
.TP
|
||||
.I \-v
|
||||
Turns on verbose mode (equivalent to -d 1).
|
||||
.TP
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Write .res, .s and .h file(s) from a resource-tree
|
||||
* Write .res file from a resource-tree
|
||||
*
|
||||
* Copyright 1998 Bertho A. Stultiens
|
||||
*
|
||||
|
@ -28,38 +28,10 @@
|
|||
|
||||
#include "wine/unicode.h"
|
||||
#include "wrc.h"
|
||||
#include "writeres.h"
|
||||
#include "genres.h"
|
||||
#include "newstruc.h"
|
||||
#include "utils.h"
|
||||
|
||||
static char s_file_head_str[] =
|
||||
"/* This file is generated with wrc version " WRC_FULLVERSION ". Do not edit! */\n"
|
||||
"/* Source : %s */\n"
|
||||
"/* Cmdline: %s */\n"
|
||||
"/* Date : %s */\n"
|
||||
"\n"
|
||||
"\t.data\n"
|
||||
"\n"
|
||||
;
|
||||
|
||||
static char s_file_tail_str[] =
|
||||
"/* <eof> */\n"
|
||||
"\n"
|
||||
;
|
||||
|
||||
char _NEResTab[] = "_NEResTab";
|
||||
char _PEResTab[] = "_PEResTab";
|
||||
char _ResTable[] = "_ResTable";
|
||||
|
||||
/* Variables used for resource sorting */
|
||||
res_count_t *rcarray = NULL; /* Type-level count array */
|
||||
int rccount = 0; /* Nr of entries in the type-level array */
|
||||
int n_id_entries = 0; /* win32 only: Nr of unique ids in the type-level array */
|
||||
int n_name_entries = 0; /* win32 only: Nr of unique namess in the type-level array */
|
||||
|
||||
static int direntries; /* win32 only: Total number of unique resources */
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function : write_resfile
|
||||
|
@ -132,803 +104,3 @@ void write_resfile(char *outname, resource_t *top)
|
|||
}
|
||||
fclose(fo);
|
||||
}
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function : write_s_res
|
||||
* Syntax : void write_s_res(FILE *fp, res_t *res)
|
||||
* Input :
|
||||
* Output :
|
||||
* Description :
|
||||
* Remarks :
|
||||
*****************************************************************************
|
||||
*/
|
||||
#define BYTESPERLINE 8
|
||||
static void write_s_res(FILE *fp, res_t *res)
|
||||
{
|
||||
int idx = res->dataidx;
|
||||
int end = res->size;
|
||||
int rest = (end - idx) % BYTESPERLINE;
|
||||
int lines = (end - idx) / BYTESPERLINE;
|
||||
int i, j;
|
||||
|
||||
for(i = 0 ; i < lines; i++)
|
||||
{
|
||||
fprintf(fp, "\t.byte\t");
|
||||
for(j = 0; j < BYTESPERLINE; j++, idx++)
|
||||
{
|
||||
fprintf(fp, "0x%02x%s", res->data[idx] & 0xff,
|
||||
j == BYTESPERLINE-1 ? "" : ", ");
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
if(rest)
|
||||
{
|
||||
fprintf(fp, "\t.byte\t");
|
||||
for(j = 0; j < rest; j++, idx++)
|
||||
{
|
||||
fprintf(fp, "0x%02x%s", res->data[idx] & 0xff,
|
||||
j == rest-1 ? "" : ", ");
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
}
|
||||
#undef BYTESPERLINE
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function : write_name_str
|
||||
* Syntax : void write_name_str(FILE *fp, name_id_t *nid)
|
||||
* Input :
|
||||
* Output :
|
||||
* Description :
|
||||
* Remarks : One level self recursive for string type conversion
|
||||
*****************************************************************************
|
||||
*/
|
||||
static void write_name_str(FILE *fp, name_id_t *nid)
|
||||
{
|
||||
res_t res;
|
||||
assert(nid->type == name_str);
|
||||
|
||||
if(!win32 && nid->name.s_name->type == str_char)
|
||||
{
|
||||
res.size = strlen(nid->name.s_name->str.cstr);
|
||||
if(res.size > 254)
|
||||
error("Can't write strings larger than 254 bytes");
|
||||
if(res.size == 0)
|
||||
internal_error(__FILE__, __LINE__, "Attempt to write empty string");
|
||||
res.dataidx = 0;
|
||||
res.data = (char *)xmalloc(1 + res.size + 1);
|
||||
res.data[0] = (char)res.size;
|
||||
res.size++; /* We need to write the length byte as well */
|
||||
strcpy(res.data+1, nid->name.s_name->str.cstr);
|
||||
write_s_res(fp, &res);
|
||||
free(res.data);
|
||||
}
|
||||
else if(!win32 && nid->name.s_name->type == str_unicode)
|
||||
{
|
||||
name_id_t lnid;
|
||||
|
||||
lnid.type = name_str;
|
||||
lnid.name.s_name = convert_string( nid->name.s_name, str_char,
|
||||
get_language_codepage(0,0) );
|
||||
write_name_str(fp, &lnid);
|
||||
free_string( lnid.name.s_name );
|
||||
}
|
||||
else if(win32 && nid->name.s_name->type == str_char)
|
||||
{
|
||||
name_id_t lnid;
|
||||
|
||||
lnid.type = name_str;
|
||||
lnid.name.s_name = convert_string( nid->name.s_name, str_unicode,
|
||||
get_language_codepage(0,0) );
|
||||
write_name_str(fp, &lnid);
|
||||
free_string( lnid.name.s_name );
|
||||
}
|
||||
else if(win32 && nid->name.s_name->type == str_unicode)
|
||||
{
|
||||
res.size = strlenW(nid->name.s_name->str.wstr);
|
||||
if(res.size > 65534)
|
||||
error("Can't write strings larger than 65534 characters");
|
||||
if(res.size == 0)
|
||||
internal_error(__FILE__, __LINE__, "Attempt to write empty string");
|
||||
res.dataidx = 0;
|
||||
res.data = (char *)xmalloc(2 + (res.size + 1) * 2);
|
||||
((short *)res.data)[0] = (short)res.size;
|
||||
strcpyW((WCHAR *)(res.data+2), nid->name.s_name->str.wstr);
|
||||
res.size *= 2; /* Function writes bytes, not shorts... */
|
||||
res.size += 2; /* We need to write the length word as well */
|
||||
write_s_res(fp, &res);
|
||||
free(res.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
internal_error(__FILE__, __LINE__, "Hmm, requested to write a string of unknown type %d",
|
||||
nid->name.s_name->type);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function : find_counter
|
||||
* Syntax : res_count_t *find_counter(name_id_t *type)
|
||||
* Input :
|
||||
* Output :
|
||||
* Description :
|
||||
* Remarks :
|
||||
*****************************************************************************
|
||||
*/
|
||||
static res_count_t *find_counter(name_id_t *type)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < rccount; i++)
|
||||
{
|
||||
if(!compare_name_id(type, &(rcarray[i].type)))
|
||||
return &rcarray[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function : count_resources
|
||||
* Syntax : res_count_t *count_resources(resource_t *top)
|
||||
* Input :
|
||||
* Output :
|
||||
* Description :
|
||||
* Remarks : The whole lot is converted into arrays because they are
|
||||
* easy sortable. Makes the lot almost unreadable, but it
|
||||
* works (I hope). Basically you have to keep in mind that
|
||||
* the lot is a three-dimensional structure for win32 and a
|
||||
* two-dimensional structure for win16.
|
||||
*****************************************************************************
|
||||
*/
|
||||
#define RCT(v) (*((resource_t **)(v)))
|
||||
/* qsort sorting function */
|
||||
static int sort_name_id(const void *e1, const void *e2)
|
||||
{
|
||||
return compare_name_id(RCT(e1)->name, RCT(e2)->name);
|
||||
}
|
||||
|
||||
static int sort_language(const void *e1, const void *e2)
|
||||
{
|
||||
assert((RCT(e1)->lan) != NULL);
|
||||
assert((RCT(e2)->lan) != NULL);
|
||||
|
||||
return MAKELANGID(RCT(e1)->lan->id, RCT(e1)->lan->sub)
|
||||
- MAKELANGID(RCT(e2)->lan->id, RCT(e2)->lan->sub);
|
||||
}
|
||||
#undef RCT
|
||||
#define RCT(v) ((res_count_t *)(v))
|
||||
static int sort_type(const void *e1, const void *e2)
|
||||
{
|
||||
return compare_name_id(&(RCT(e1)->type), &(RCT(e2)->type));
|
||||
}
|
||||
#undef RCT
|
||||
|
||||
static void count_resources(resource_t *top)
|
||||
{
|
||||
resource_t *rsc;
|
||||
res_count_t *rcp;
|
||||
name_id_t nid;
|
||||
int i, j;
|
||||
|
||||
for(rsc = top; rsc; rsc = rsc->next)
|
||||
{
|
||||
if(!rsc->binres)
|
||||
continue;
|
||||
switch(rsc->type)
|
||||
{
|
||||
case res_dlgex:
|
||||
nid.name.i_name = WRC_RT_DIALOG;
|
||||
nid.type = name_ord;
|
||||
break;
|
||||
case res_menex:
|
||||
nid.name.i_name = WRC_RT_MENU;
|
||||
nid.type = name_ord;
|
||||
break;
|
||||
case res_usr:
|
||||
nid = *(rsc->res.usr->type);
|
||||
break;
|
||||
default:
|
||||
nid.name.i_name = rsc->type;
|
||||
nid.type = name_ord;
|
||||
}
|
||||
|
||||
if((rcp = find_counter(&nid)) == NULL)
|
||||
{
|
||||
/* Count the number of uniq ids and names */
|
||||
|
||||
if(nid.type == name_ord)
|
||||
n_id_entries++;
|
||||
else
|
||||
n_name_entries++;
|
||||
|
||||
if(!rcarray)
|
||||
{
|
||||
rcarray = (res_count_t *)xmalloc(sizeof(res_count_t));
|
||||
rccount = 1;
|
||||
rcarray[0].count = 1;
|
||||
rcarray[0].type = nid;
|
||||
rcarray[0].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));
|
||||
rcarray[0].rscarray[0] = rsc;
|
||||
}
|
||||
else
|
||||
{
|
||||
rccount++;
|
||||
rcarray = (res_count_t *)xrealloc(rcarray, rccount * sizeof(res_count_t));
|
||||
rcarray[rccount-1].count = 1;
|
||||
rcarray[rccount-1].type = nid;
|
||||
rcarray[rccount-1].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));
|
||||
rcarray[rccount-1].rscarray[0] = rsc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rcp->count++;
|
||||
rcp->rscarray = (resource_t **)xrealloc(rcp->rscarray, rcp->count * sizeof(resource_t *));
|
||||
rcp->rscarray[rcp->count-1] = rsc;
|
||||
}
|
||||
}
|
||||
|
||||
if(!win32)
|
||||
{
|
||||
/* We're done, win16 requires no special sorting */
|
||||
return;
|
||||
}
|
||||
|
||||
/* We now have a unsorted list of types with an array of res_count_t
|
||||
* in rcarray[0..rccount-1]. And we have names of one type in the
|
||||
* rcarray[x].rsc[0..rcarray[x].count-1] arrays.
|
||||
* The list needs to be sorted for win32's top level tree structure.
|
||||
*/
|
||||
|
||||
/* Sort the types */
|
||||
if(rccount > 1)
|
||||
qsort(rcarray, rccount, sizeof(rcarray[0]), sort_type);
|
||||
|
||||
/* Now sort the name-id arrays */
|
||||
for(i = 0; i < rccount; i++)
|
||||
{
|
||||
if(rcarray[i].count > 1)
|
||||
qsort(rcarray[i].rscarray, rcarray[i].count, sizeof(rcarray[0].rscarray[0]), sort_name_id);
|
||||
}
|
||||
|
||||
/* Now split the name-id arrays into name/language
|
||||
* subs. Don't look at the awfull expressions...
|
||||
* We do this by taking the array elements out of rscarray and putting
|
||||
* together a new array in rsc32array.
|
||||
*/
|
||||
for(i = 0; i < rccount; i++)
|
||||
{
|
||||
res_count_t *rcap;
|
||||
|
||||
assert(rcarray[i].count >= 1);
|
||||
|
||||
/* rcap points to the current type we are dealing with */
|
||||
rcap = &(rcarray[i]);
|
||||
|
||||
/* Insert the first name-id */
|
||||
rcap->rsc32array = (res32_count_t *)xmalloc(sizeof(res32_count_t));
|
||||
rcap->count32 = 1;
|
||||
rcap->rsc32array[0].rsc = (resource_t **)xmalloc(sizeof(resource_t *));
|
||||
rcap->rsc32array[0].count = 1;
|
||||
rcap->rsc32array[0].rsc[0] = rcap->rscarray[0];
|
||||
if(rcap->rscarray[0]->name->type == name_ord)
|
||||
{
|
||||
rcap->n_id_entries = 1;
|
||||
rcap->n_name_entries = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rcap->n_id_entries = 0;
|
||||
rcap->n_name_entries = 1;
|
||||
}
|
||||
|
||||
/* Now loop over the resting resources of the current type
|
||||
* to find duplicate names (which should have different
|
||||
* languages).
|
||||
*/
|
||||
for(j = 1; j < rcap->count; j++)
|
||||
{
|
||||
res32_count_t *r32cp;
|
||||
|
||||
/* r32cp points to the current res32_count structure
|
||||
* that holds the resource name we are processing.
|
||||
*/
|
||||
r32cp = &(rcap->rsc32array[rcap->count32-1]);
|
||||
|
||||
if(!compare_name_id(r32cp->rsc[0]->name, rcarray[i].rscarray[j]->name))
|
||||
{
|
||||
/* Names are the same, add to list */
|
||||
r32cp->count++;
|
||||
r32cp->rsc = (resource_t **)xrealloc(r32cp->rsc, r32cp->count * sizeof(resource_t *));
|
||||
r32cp->rsc[r32cp->count-1] = rcap->rscarray[j];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* New name-id, sort the old one by
|
||||
* language and create new list
|
||||
*/
|
||||
if(r32cp->count > 1)
|
||||
qsort(r32cp->rsc, r32cp->count, sizeof(r32cp->rsc[0]), sort_language);
|
||||
rcap->count32++;
|
||||
rcap->rsc32array = (res32_count_t*)xrealloc(rcap->rsc32array, rcap->count32 * sizeof(res32_count_t));
|
||||
rcap->rsc32array[rcap->count32-1].rsc = (resource_t **)xmalloc(sizeof(resource_t *));
|
||||
rcap->rsc32array[rcap->count32-1].count = 1;
|
||||
rcap->rsc32array[rcap->count32-1].rsc[0] = rcap->rscarray[j];
|
||||
|
||||
if(rcap->rscarray[j]->name->type == name_ord)
|
||||
rcap->n_id_entries++;
|
||||
else
|
||||
rcap->n_name_entries++;
|
||||
}
|
||||
}
|
||||
/* Also sort the languages of the last name group */
|
||||
if(rcap->rsc32array[rcap->count32-1].count > 1)
|
||||
qsort(rcap->rsc32array[rcap->count32-1].rsc,
|
||||
rcap->rsc32array[rcap->count32-1].count,
|
||||
sizeof(rcap->rsc32array[rcap->count32-1].rsc[0]),
|
||||
sort_language);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function : write_pe_segment
|
||||
* Syntax : void write_pe_segment(FILE *fp)
|
||||
* Input :
|
||||
* Output :
|
||||
* Description :
|
||||
* Remarks :
|
||||
*****************************************************************************
|
||||
*/
|
||||
static void write_pe_segment(FILE *fp)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf(fp, "\t.align\t4\n");
|
||||
fprintf(fp, __ASM_NAME("%s%s") ":\n", prefix, _PEResTab);
|
||||
fprintf(fp, "\t.globl\t" __ASM_NAME("%s%s") "\n", prefix, _PEResTab);
|
||||
/* Flags */
|
||||
fprintf(fp, "\t.long\t0\n");
|
||||
/* Time/Date stamp */
|
||||
fprintf(fp, "\t.long\t0x%08lx\n", (long)now);
|
||||
/* Version */
|
||||
fprintf(fp, "\t.long\t0\n"); /* FIXME: must version be filled out? */
|
||||
/* # of id entries, # of name entries */
|
||||
fprintf(fp, "\t.short\t%d, %d\n", n_name_entries, n_id_entries);
|
||||
|
||||
/* Write the type level of the tree */
|
||||
for(i = 0; i < rccount; i++)
|
||||
{
|
||||
res_count_t *rcp;
|
||||
char *label;
|
||||
|
||||
rcp = &rcarray[i];
|
||||
|
||||
/* TypeId */
|
||||
if(rcp->type.type == name_ord)
|
||||
fprintf(fp, "\t.long\t%d\n", rcp->type.name.i_name);
|
||||
else
|
||||
{
|
||||
char *name = prep_nid_for_label(&(rcp->type));
|
||||
fprintf(fp, "\t.long\t(" __ASM_NAME("%s_%s_typename") " - " __ASM_NAME("%s%s") ") | 0x80000000\n",
|
||||
prefix,
|
||||
name,
|
||||
prefix,
|
||||
_PEResTab);
|
||||
}
|
||||
/* Offset */
|
||||
label = prep_nid_for_label(&(rcp->type));
|
||||
fprintf(fp, "\t.long\t(.L%s - " __ASM_NAME("%s%s") ") | 0x80000000\n",
|
||||
label,
|
||||
prefix,
|
||||
_PEResTab);
|
||||
}
|
||||
|
||||
/* Write the name level of the tree */
|
||||
|
||||
for(i = 0; i < rccount; i++)
|
||||
{
|
||||
res_count_t *rcp;
|
||||
char *typelabel;
|
||||
char *namelabel;
|
||||
int j;
|
||||
|
||||
rcp = &rcarray[i];
|
||||
|
||||
typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
|
||||
fprintf(fp, ".L%s:\n", typelabel);
|
||||
|
||||
fprintf(fp, "\t.long\t0\n"); /* Flags */
|
||||
fprintf(fp, "\t.long\t0x%08lx\n", (long)now); /* TimeDate */
|
||||
fprintf(fp, "\t.long\t0\n"); /* FIXME: must version be filled out? */
|
||||
fprintf(fp, "\t.short\t%d, %d\n", rcp->n_name_entries, rcp->n_id_entries);
|
||||
for(j = 0; j < rcp->count32; j++)
|
||||
{
|
||||
resource_t *rsc = rcp->rsc32array[j].rsc[0];
|
||||
/* NameId */
|
||||
if(rsc->name->type == name_ord)
|
||||
fprintf(fp, "\t.long\t%d\n", rsc->name->name.i_name);
|
||||
else
|
||||
{
|
||||
fprintf(fp, "\t.long\t(" __ASM_NAME("%s%s_name") " - " __ASM_NAME("%s%s") ") | 0x80000000\n",
|
||||
prefix,
|
||||
rsc->c_name,
|
||||
prefix,
|
||||
_PEResTab);
|
||||
}
|
||||
/* Maybe FIXME: Unescape the tree (ommit 0x80000000) and
|
||||
* put the offset to the resource data entry.
|
||||
* ?? Is unescaping worth while ??
|
||||
*/
|
||||
/* Offset */
|
||||
namelabel = prep_nid_for_label(rsc->name);
|
||||
fprintf(fp, "\t.long\t(.L%s_%s - " __ASM_NAME("%s%s") ") | 0x80000000\n",
|
||||
typelabel,
|
||||
namelabel,
|
||||
prefix,
|
||||
_PEResTab);
|
||||
}
|
||||
free(typelabel);
|
||||
}
|
||||
|
||||
/* Write the language level of the tree */
|
||||
|
||||
for(i = 0; i < rccount; i++)
|
||||
{
|
||||
res_count_t *rcp;
|
||||
char *namelabel;
|
||||
char *typelabel;
|
||||
int j;
|
||||
|
||||
rcp = &rcarray[i];
|
||||
typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
|
||||
|
||||
for(j = 0; j < rcp->count32; j++)
|
||||
{
|
||||
res32_count_t *r32cp = &(rcp->rsc32array[j]);
|
||||
int k;
|
||||
|
||||
namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));
|
||||
fprintf(fp, ".L%s_%s:\n", typelabel, namelabel);
|
||||
|
||||
fprintf(fp, "\t.long\t0\n"); /* Flags */
|
||||
fprintf(fp, "\t.long\t0x%08lx\n", (long)now); /* TimeDate */
|
||||
fprintf(fp, "\t.long\t0\n"); /* FIXME: must version be filled out? */
|
||||
fprintf(fp, "\t.short\t0, %d\n", r32cp->count);
|
||||
|
||||
for(k = 0; k < r32cp->count; k++)
|
||||
{
|
||||
resource_t *rsc = r32cp->rsc[k];
|
||||
assert(rsc->lan != NULL);
|
||||
/* LanguageId */
|
||||
fprintf(fp, "\t.long\t0x%08x\n", rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);
|
||||
/* Offset */
|
||||
fprintf(fp, "\t.long\t.L%s_%s_%d - " __ASM_NAME("%s%s") "\n",
|
||||
typelabel,
|
||||
namelabel,
|
||||
rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0,
|
||||
prefix,
|
||||
_PEResTab);
|
||||
}
|
||||
free(namelabel);
|
||||
}
|
||||
free(typelabel);
|
||||
}
|
||||
|
||||
/* Write the resource table itself */
|
||||
fprintf(fp, __ASM_NAME("%s_ResourceDirectory") ":\n", prefix);
|
||||
fprintf(fp, "\t.globl\t" __ASM_NAME("%s_ResourceDirectory") "\n", prefix);
|
||||
direntries = 0;
|
||||
|
||||
for(i = 0; i < rccount; i++)
|
||||
{
|
||||
res_count_t *rcp;
|
||||
char *namelabel;
|
||||
char *typelabel;
|
||||
int j;
|
||||
|
||||
rcp = &rcarray[i];
|
||||
typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
|
||||
|
||||
for(j = 0; j < rcp->count32; j++)
|
||||
{
|
||||
res32_count_t *r32cp = &(rcp->rsc32array[j]);
|
||||
int k;
|
||||
|
||||
namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));
|
||||
|
||||
for(k = 0; k < r32cp->count; k++)
|
||||
{
|
||||
resource_t *rsc = r32cp->rsc[k];
|
||||
|
||||
assert(rsc->lan != NULL);
|
||||
|
||||
fprintf(fp, ".L%s_%s_%d:\n",
|
||||
typelabel,
|
||||
namelabel,
|
||||
rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);
|
||||
|
||||
/* Data RVA */
|
||||
fprintf(fp, "\t.long\t" __ASM_NAME("%s%s_data") " - " __ASM_NAME("%s%s") "\n",
|
||||
prefix,
|
||||
rsc->c_name,
|
||||
prefix,
|
||||
_PEResTab);
|
||||
/* Size */
|
||||
fprintf(fp, "\t.long\t%d\n",
|
||||
rsc->binres->size - rsc->binres->dataidx);
|
||||
/* CodePage */
|
||||
fprintf(fp, "\t.long\t%ld\n", codepage);
|
||||
/* Reserved */
|
||||
fprintf(fp, "\t.long\t0\n");
|
||||
|
||||
direntries++;
|
||||
}
|
||||
free(namelabel);
|
||||
}
|
||||
free(typelabel);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function : write_ne_segment
|
||||
* Syntax : void write_ne_segment(FILE *fp)
|
||||
* Input :
|
||||
* Output :
|
||||
* Description :
|
||||
* Remarks :
|
||||
*****************************************************************************
|
||||
*/
|
||||
static void write_ne_segment(FILE *fp)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
fprintf(fp, "\t.align\t4\n");
|
||||
fprintf(fp, __ASM_NAME("%s%s") ":\n", prefix, _NEResTab);
|
||||
fprintf(fp, "\t.globl\t" __ASM_NAME("%s%s") "\n", prefix, _NEResTab);
|
||||
|
||||
/* AlignmentShift */
|
||||
fprintf(fp, "\t.short\t%d\n", alignment_pwr);
|
||||
|
||||
/* TypeInfo */
|
||||
for(i = 0; i < rccount; i++)
|
||||
{
|
||||
res_count_t *rcp = &rcarray[i];
|
||||
|
||||
/* TypeId */
|
||||
if(rcp->type.type == name_ord)
|
||||
fprintf(fp, "\t.short\t0x%04x\n", rcp->type.name.i_name | 0x8000);
|
||||
else
|
||||
fprintf(fp, "\t.short\t" __ASM_NAME("%s_%s_typename") " - " __ASM_NAME("%s%s") "\n",
|
||||
prefix,
|
||||
rcp->type.name.s_name->str.cstr,
|
||||
prefix,
|
||||
_NEResTab);
|
||||
/* ResourceCount */
|
||||
fprintf(fp, "\t.short\t%d\n", rcp->count);
|
||||
/* Reserved */
|
||||
fprintf(fp, "\t.long\t0\n");
|
||||
/* NameInfo */
|
||||
for(j = 0; j < rcp->count; j++)
|
||||
{
|
||||
/*
|
||||
* VERY IMPORTANT:
|
||||
* The offset is relative to the beginning of the NE resource segment
|
||||
* and _NOT_ to the file-beginning. This is because we do not have a
|
||||
* file based resource, but a simulated NE segment. The offset _is_
|
||||
* scaled by the AlignShift field.
|
||||
* All other things are as the MS doc describes (alignment etc.)
|
||||
*/
|
||||
/* Offset */
|
||||
fprintf(fp, "\t.short\t(" __ASM_NAME("%s%s_data") " - " __ASM_NAME("%s%s") ") >> %d\n",
|
||||
prefix,
|
||||
rcp->rscarray[j]->c_name,
|
||||
prefix,
|
||||
_NEResTab,
|
||||
alignment_pwr);
|
||||
/* Length */
|
||||
fprintf(fp, "\t.short\t%d\n",
|
||||
(rcp->rscarray[j]->binres->size - rcp->rscarray[j]->binres->dataidx + alignment - 1) >> alignment_pwr);
|
||||
/* Flags */
|
||||
fprintf(fp, "\t.short\t0x%04x\n", (WORD)rcp->rscarray[j]->memopt);
|
||||
/* Id */
|
||||
if(rcp->rscarray[j]->name->type == name_ord)
|
||||
fprintf(fp, "\t.short\t0x%04x\n", rcp->rscarray[j]->name->name.i_name | 0x8000);
|
||||
else
|
||||
fprintf(fp, "\t.short\t" __ASM_NAME("%s%s_name") " - " __ASM_NAME("%s%s") "\n",
|
||||
prefix,
|
||||
rcp->rscarray[j]->c_name,
|
||||
prefix,
|
||||
_NEResTab);
|
||||
/* Handle and Usage */
|
||||
fprintf(fp, "\t.short\t0, 0\n");
|
||||
}
|
||||
}
|
||||
/* EndTypes */
|
||||
fprintf(fp, "\t.short\t0\n");
|
||||
}
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function : write_rsc_names
|
||||
* Syntax : void write_rsc_names(FILE *fp)
|
||||
* Input :
|
||||
* Output :
|
||||
* Description :
|
||||
* Remarks :
|
||||
*****************************************************************************
|
||||
*/
|
||||
static void write_rsc_names(FILE *fp)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if(win32)
|
||||
{
|
||||
/* Write the names */
|
||||
|
||||
for(i = 0; i < rccount; i++)
|
||||
{
|
||||
res_count_t *rcp;
|
||||
|
||||
rcp = &rcarray[i];
|
||||
|
||||
if(rcp->type.type == name_str)
|
||||
{
|
||||
char *name = prep_nid_for_label(&(rcp->type));
|
||||
fprintf(fp, __ASM_NAME("%s_%s_typename") ":\n",
|
||||
prefix,
|
||||
name);
|
||||
write_name_str(fp, &(rcp->type));
|
||||
}
|
||||
|
||||
for(j = 0; j < rcp->count32; j++)
|
||||
{
|
||||
resource_t *rsc = rcp->rsc32array[j].rsc[0];
|
||||
|
||||
if(rsc->name->type == name_str)
|
||||
{
|
||||
fprintf(fp, __ASM_NAME("%s%s_name") ":\n",
|
||||
prefix,
|
||||
rsc->c_name);
|
||||
write_name_str(fp, rsc->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ResourceNames */
|
||||
for(i = 0; i < rccount; i++)
|
||||
{
|
||||
res_count_t *rcp = &rcarray[i];
|
||||
|
||||
if(rcp->type.type == name_str)
|
||||
{
|
||||
fprintf(fp, __ASM_NAME("%s_%s_typename") ":\n",
|
||||
prefix,
|
||||
rcp->type.name.s_name->str.cstr);
|
||||
write_name_str(fp, &(rcp->type));
|
||||
}
|
||||
for(j = 0; j < rcp->count; j++)
|
||||
{
|
||||
if(rcp->rscarray[j]->name->type == name_str)
|
||||
{
|
||||
fprintf(fp, __ASM_NAME("%s%s_name") ":\n",
|
||||
prefix,
|
||||
rcp->rscarray[j]->c_name);
|
||||
write_name_str(fp, rcp->rscarray[j]->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* EndNames */
|
||||
|
||||
/* This is to end the NE resource table */
|
||||
if(create_dir)
|
||||
fprintf(fp, "\t.byte\t0\n");
|
||||
}
|
||||
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
*****************************************************************************
|
||||
* Function : write_s_file
|
||||
* Syntax : void write_s_file(char *outname, resource_t *top)
|
||||
* Input :
|
||||
* outname - Filename to write to
|
||||
* top - The resource-tree to convert
|
||||
* Output :
|
||||
* Description :
|
||||
* Remarks :
|
||||
*****************************************************************************
|
||||
*/
|
||||
void write_s_file(char *outname, resource_t *top)
|
||||
{
|
||||
FILE *fo;
|
||||
resource_t *rsc;
|
||||
|
||||
fo = fopen(outname, "wt");
|
||||
if(!fo)
|
||||
{
|
||||
error("Could not open %s\n", outname);
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
char *s, *p;
|
||||
s = ctime(&now);
|
||||
p = strchr(s, '\n');
|
||||
if(p) *p = '\0';
|
||||
fprintf(fo, s_file_head_str, input_name ? input_name : "stdin",
|
||||
cmdline, s);
|
||||
}
|
||||
|
||||
/* Get an idea how many we have and restructure the tables */
|
||||
count_resources(top);
|
||||
|
||||
/* First write the segment tables */
|
||||
if(create_dir)
|
||||
{
|
||||
if(win32)
|
||||
write_pe_segment(fo);
|
||||
else
|
||||
write_ne_segment(fo);
|
||||
}
|
||||
|
||||
/* Dump the names */
|
||||
write_rsc_names(fo);
|
||||
|
||||
if(create_dir)
|
||||
fprintf(fo, ".LResTabEnd:\n");
|
||||
|
||||
/* Write the resource data */
|
||||
fprintf(fo, "\n/* Resource binary data */\n\n");
|
||||
for(rsc = top; rsc; rsc = rsc->next)
|
||||
{
|
||||
if(!rsc->binres)
|
||||
continue;
|
||||
|
||||
fprintf(fo, "\t.align\t%d\n", win32 ? 4 : alignment);
|
||||
fprintf(fo, __ASM_NAME("%s%s_data") ":\n", prefix, rsc->c_name);
|
||||
if(global)
|
||||
fprintf(fo, "\t.globl\t" __ASM_NAME("%s%s_data") "\n", prefix, rsc->c_name);
|
||||
|
||||
write_s_res(fo, rsc->binres);
|
||||
|
||||
fprintf(fo, "\n");
|
||||
}
|
||||
|
||||
if(create_dir)
|
||||
{
|
||||
/* Add a resource descriptor for built-in and elf-dlls */
|
||||
fprintf(fo, "\t.align\t4\n");
|
||||
fprintf(fo, __ASM_NAME("%s_ResourceDescriptor") ":\n", prefix);
|
||||
fprintf(fo, "\t.globl\t" __ASM_NAME("%s_ResourceDescriptor") "\n", prefix);
|
||||
fprintf(fo, __ASM_NAME("%s_ResourceTable") ":\n", prefix);
|
||||
if(global)
|
||||
fprintf(fo, "\t.globl\t" __ASM_NAME("%s_ResourceTable") "\n", prefix);
|
||||
fprintf(fo, "\t.long\t" __ASM_NAME("%s%s") "\n", prefix, win32 ? _PEResTab : _NEResTab);
|
||||
fprintf(fo, __ASM_NAME("%s_NumberOfResources") ":\n", prefix);
|
||||
if(global)
|
||||
fprintf(fo, "\t.globl\t" __ASM_NAME("%s_NumberOfResources") "\n", prefix);
|
||||
fprintf(fo, "\t.long\t%d\n", direntries);
|
||||
fprintf(fo, __ASM_NAME("%s_ResourceSectionSize") ":\n", prefix);
|
||||
if(global)
|
||||
fprintf(fo, "\t.globl\t" __ASM_NAME("%s_ResourceSectionSize") "\n", prefix);
|
||||
fprintf(fo, "\t.long\t.LResTabEnd - " __ASM_NAME("%s%s") "\n", prefix, win32 ? _PEResTab : _NEResTab);
|
||||
if(win32)
|
||||
{
|
||||
fprintf(fo, __ASM_NAME("%s_ResourcesEntries") ":\n", prefix);
|
||||
if(global)
|
||||
fprintf(fo, "\t.globl\t" __ASM_NAME("%s_ResourcesEntries") "\n", prefix);
|
||||
fprintf(fo, "\t.long\t" __ASM_NAME("%s_ResourceDirectory") "\n", prefix);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fo, s_file_tail_str);
|
||||
fclose(fo);
|
||||
}
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Write resource prototypes
|
||||
*
|
||||
* Copyright 1998 Bertho A. Stultiens (BS)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __WRC_WRITERES_H
|
||||
#define __WRC_WRITERES_H
|
||||
|
||||
#ifndef __WRC_WRCTYPES_H
|
||||
#include "wrctypes.h"
|
||||
#endif
|
||||
|
||||
void write_resfile(char *outname, resource_t *top);
|
||||
void write_s_file(char *outname, resource_t *top);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue