From 8611e654fcc5c14ea0618a305d7d7acdb644f62e Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 11 Feb 2004 06:41:01 +0000 Subject: [PATCH] Store all information about the current dll in a structure instead of using global variables to make it easier to reuse the parsing routines. --- tools/winebuild/build.h | 60 ++++++++------- tools/winebuild/import.c | 60 +++++++-------- tools/winebuild/main.c | 124 +++++++++++++++--------------- tools/winebuild/parser.c | 155 ++++++++++++++++++++++++++------------ tools/winebuild/res16.c | 76 +++++++++++-------- tools/winebuild/res32.c | 101 +++++++++++++++---------- tools/winebuild/spec16.c | 74 +++++++++--------- tools/winebuild/spec32.c | 158 ++++++++++++++++----------------------- 8 files changed, 441 insertions(+), 367 deletions(-) diff --git a/tools/winebuild/build.h b/tools/winebuild/build.h index ec350df36c7..afb6fd19cf7 100644 --- a/tools/winebuild/build.h +++ b/tools/winebuild/build.h @@ -94,6 +94,28 @@ typedef struct } u; } ORDDEF; +typedef struct +{ + char *file_name; /* file name of the dll */ + char *dll_name; /* internal name of the dll */ + char *owner_name; /* name of the 32-bit dll owning this one */ + char *init_func; /* initialization routine */ + SPEC_TYPE type; /* type of dll (Win16/Win32) */ + SPEC_MODE mode; /* dll mode (dll/exe/etc.) */ + int base; /* ordinal base */ + int limit; /* ordinal limit */ + int stack_size; /* exe stack size */ + int heap_size; /* exe heap size */ + int nb_entry_points; /* number of used entry points */ + int alloc_entry_points; /* number of allocated entry points */ + int nb_names; /* number of entry points with names */ + int nb_resources; /* number of resources */ + ORDDEF *entry_points; /* dll entry points */ + ORDDEF **names; /* array of entry point names (points into entry_points) */ + ORDDEF **ordinals; /* array of dll ordinals (points into entry_points) */ + struct resource *resources; /* array of dll resources (format differs between Win16/Win32) */ +} DLLSPEC; + /* entry point flags */ #define FLAG_NORELAY 0x01 /* don't use relay debugging for this function */ #define FLAG_NONAME 0x02 /* don't import function by name */ @@ -153,54 +175,38 @@ extern int get_alignment(int alignBoundary); extern void add_import_dll( const char *name, int delay ); extern void add_ignore_symbol( const char *name ); extern void read_undef_symbols( char **argv ); -extern int resolve_imports( void ); -extern int output_imports( FILE *outfile ); -extern int load_res32_file( const char *name ); -extern int output_resources( FILE *outfile ); -extern void load_res16_file( const char *name ); -extern int output_res16_data( FILE *outfile ); -extern int output_res16_directory( unsigned char *buffer ); +extern int resolve_imports( DLLSPEC *spec ); +extern int output_imports( FILE *outfile, DLLSPEC *spec ); +extern int load_res32_file( const char *name, DLLSPEC *spec ); +extern void output_resources( FILE *outfile, DLLSPEC *spec ); +extern void load_res16_file( const char *name, DLLSPEC *spec ); +extern int output_res16_data( FILE *outfile, DLLSPEC *spec ); +extern int output_res16_directory( unsigned char *buffer, DLLSPEC *spec ); extern void output_dll_init( FILE *outfile, const char *constructor, const char *destructor ); extern int parse_debug_channels( const char *srcdir, const char *filename ); extern void BuildRelays16( FILE *outfile ); extern void BuildRelays32( FILE *outfile ); -extern void BuildSpec16File( FILE *outfile ); -extern void BuildSpec32File( FILE *outfile ); -extern void BuildDef32File( FILE *outfile ); +extern void BuildSpec16File( FILE *outfile, DLLSPEC *spec ); +extern void BuildSpec32File( FILE *outfile, DLLSPEC *spec ); +extern void BuildDef32File( FILE *outfile, DLLSPEC *spec ); extern void BuildDebugFile( FILE *outfile, const char *srcdir, char **argv ); -extern int ParseTopLevel( FILE *file ); +extern int ParseTopLevel( FILE *file, DLLSPEC *spec ); /* global variables */ extern int current_line; -extern int nb_entry_points; -extern int nb_names; -extern int Base; -extern int Limit; -extern int DLLHeapSize; extern int UsePIC; extern int debugging; -extern int stack_size; extern int nb_debug_channels; extern int nb_lib_paths; extern int nb_errors; extern int display_warnings; extern int kill_at; -extern char *owner_name; -extern char *dll_name; -extern char *dll_file_name; -extern const char *init_func; extern char *input_file_name; extern const char *output_file_name; extern char **debug_channels; extern char **lib_path; -extern ORDDEF *EntryPoints[MAX_ORDINALS]; -extern ORDDEF *Ordinals[MAX_ORDINALS]; -extern ORDDEF *Names[MAX_ORDINALS]; -extern SPEC_MODE SpecMode; -extern SPEC_TYPE SpecType; - #endif /* __WINE_BUILD_H */ diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index a901d3c6814..023f45c75ed 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -525,16 +525,16 @@ static int remove_symbol_holes(void) } /* add a symbol to the extra list, but only if needed */ -static int add_extra_symbol( const char **extras, int *count, const char *name ) +static int add_extra_symbol( const char **extras, int *count, const char *name, const DLLSPEC *spec ) { int i; if (!find_symbol( name, undef_symbols, nb_undef_symbols )) { /* check if the symbol is being exported by this dll */ - for (i = 0; i < nb_entry_points; i++) + for (i = 0; i < spec->nb_entry_points; i++) { - ORDDEF *odp = EntryPoints[i]; + ORDDEF *odp = &spec->entry_points[i]; if (odp->type == TYPE_STDCALL || odp->type == TYPE_CDECL || odp->type == TYPE_VARARGS || @@ -550,7 +550,7 @@ static int add_extra_symbol( const char **extras, int *count, const char *name ) } /* add the extra undefined symbols that will be contained in the generated spec file itself */ -static void add_extra_undef_symbols(void) +static void add_extra_undef_symbols( const DLLSPEC *spec ) { const char *extras[10]; int i, count = 0, nb_stubs = 0, nb_regs = 0; @@ -558,44 +558,44 @@ static void add_extra_undef_symbols(void) sort_symbols( undef_symbols, nb_undef_symbols ); - for (i = 0; i < nb_entry_points; i++) + for (i = 0; i < spec->nb_entry_points; i++) { - ORDDEF *odp = EntryPoints[i]; + ORDDEF *odp = &spec->entry_points[i]; if (odp->type == TYPE_STUB) nb_stubs++; if (odp->flags & FLAG_REGISTER) nb_regs++; } /* add symbols that will be contained in the spec file itself */ - switch (SpecMode) + switch (spec->mode) { case SPEC_MODE_DLL: break; case SPEC_MODE_GUIEXE: - kernel_imports += add_extra_symbol( extras, &count, "GetCommandLineA" ); - kernel_imports += add_extra_symbol( extras, &count, "GetStartupInfoA" ); - kernel_imports += add_extra_symbol( extras, &count, "GetModuleHandleA" ); + kernel_imports += add_extra_symbol( extras, &count, "GetCommandLineA", spec ); + kernel_imports += add_extra_symbol( extras, &count, "GetStartupInfoA", spec ); + kernel_imports += add_extra_symbol( extras, &count, "GetModuleHandleA", spec ); /* fall through */ case SPEC_MODE_CUIEXE: - kernel_imports += add_extra_symbol( extras, &count, "ExitProcess" ); + kernel_imports += add_extra_symbol( extras, &count, "ExitProcess", spec ); break; case SPEC_MODE_GUIEXE_UNICODE: - kernel_imports += add_extra_symbol( extras, &count, "GetCommandLineA" ); - kernel_imports += add_extra_symbol( extras, &count, "GetStartupInfoA" ); - kernel_imports += add_extra_symbol( extras, &count, "GetModuleHandleA" ); + kernel_imports += add_extra_symbol( extras, &count, "GetCommandLineA", spec ); + kernel_imports += add_extra_symbol( extras, &count, "GetStartupInfoA", spec ); + kernel_imports += add_extra_symbol( extras, &count, "GetModuleHandleA", spec ); /* fall through */ case SPEC_MODE_CUIEXE_UNICODE: - kernel_imports += add_extra_symbol( extras, &count, "ExitProcess" ); + kernel_imports += add_extra_symbol( extras, &count, "ExitProcess", spec ); break; } if (nb_delayed) { - kernel_imports += add_extra_symbol( extras, &count, "LoadLibraryA" ); - kernel_imports += add_extra_symbol( extras, &count, "GetProcAddress" ); + kernel_imports += add_extra_symbol( extras, &count, "LoadLibraryA", spec ); + kernel_imports += add_extra_symbol( extras, &count, "GetProcAddress", spec ); } if (nb_regs) - ntdll_imports += add_extra_symbol( extras, &count, "__wine_call_from_32_regs" ); + ntdll_imports += add_extra_symbol( extras, &count, "__wine_call_from_32_regs", spec ); if (nb_delayed || nb_stubs) - ntdll_imports += add_extra_symbol( extras, &count, "RtlRaiseException" ); + ntdll_imports += add_extra_symbol( extras, &count, "RtlRaiseException", spec ); /* make sure we import the dlls that contain these functions */ if (kernel_imports) add_import_dll( "kernel32", 0 ); @@ -609,16 +609,16 @@ static void add_extra_undef_symbols(void) } /* check if a given imported dll is not needed, taking forwards into account */ -static int check_unused( const struct import* imp ) +static int check_unused( const struct import* imp, const DLLSPEC *spec ) { int i; size_t len = strlen(imp->dll); const char *p = strchr( imp->dll, '.' ); if (p && !strcasecmp( p, ".dll" )) len = p - imp->dll; - for (i = Base; i <= Limit; i++) + for (i = spec->base; i <= spec->limit; i++) { - ORDDEF *odp = Ordinals[i]; + ORDDEF *odp = spec->ordinals[i]; if (!odp || !(odp->flags & FLAG_FORWARD)) continue; if (!strncasecmp( odp->link_name, imp->dll, len ) && odp->link_name[len] == '.') @@ -708,13 +708,13 @@ static void remove_ignored_symbols(void) } /* resolve the imports for a Win32 module */ -int resolve_imports( void ) +int resolve_imports( DLLSPEC *spec ) { int i, j; if (nb_undef_symbols == -1) return 0; /* no symbol file specified */ - add_extra_undef_symbols(); + add_extra_undef_symbols( spec ); remove_ignored_symbols(); for (i = 0; i < nb_imports; i++) @@ -732,7 +732,7 @@ int resolve_imports( void ) } } /* remove all the holes in the undef symbols list */ - if (!remove_symbol_holes() && check_unused( imp )) + if (!remove_symbol_holes() && check_unused( imp, spec )) { /* the dll is not used, get rid of it */ warning( "%s imported but no symbols used\n", imp->dll ); @@ -873,7 +873,7 @@ static int output_immediate_imports( FILE *outfile ) } /* output the delayed import table of a Win32 module */ -static int output_delayed_imports( FILE *outfile ) +static int output_delayed_imports( FILE *outfile, const DLLSPEC *spec ) { int i, idx, j, pos; @@ -941,9 +941,9 @@ static int output_delayed_imports( FILE *outfile ) /* check if there's some stub defined. if so, exception struct * is already defined, so don't emit it twice */ - for (i = 0; i < nb_entry_points; i++) if (EntryPoints[i]->type == TYPE_STUB) break; + for (i = 0; i < spec->nb_entry_points; i++) if (spec->entry_points[i].type == TYPE_STUB) break; - if (i == nb_entry_points) { + if (i == spec->nb_entry_points) { fprintf( outfile, "struct exc_record {\n" ); fprintf( outfile, " unsigned int code, flags;\n" ); fprintf( outfile, " void *rec, *addr;\n" ); @@ -1153,8 +1153,8 @@ static int output_delayed_imports( FILE *outfile ) /* output the import and delayed import tables of a Win32 module * returns number of DLLs exported in 'immediate' mode */ -int output_imports( FILE *outfile ) +int output_imports( FILE *outfile, DLLSPEC *spec ) { - output_delayed_imports( outfile ); + output_delayed_imports( outfile, spec ); return output_immediate_imports( outfile ); } diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c index 3ac191389ca..ce7ff312c8c 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -36,20 +36,7 @@ #include "build.h" -ORDDEF *EntryPoints[MAX_ORDINALS]; -ORDDEF *Ordinals[MAX_ORDINALS]; -ORDDEF *Names[MAX_ORDINALS]; - -SPEC_MODE SpecMode = SPEC_MODE_DLL; -SPEC_TYPE SpecType = SPEC_WIN32; - -int Base = MAX_ORDINALS; -int Limit = 0; -int DLLHeapSize = 0; int UsePIC = 0; -int stack_size = 0; -int nb_entry_points = 0; -int nb_names = 0; int nb_debug_channels = 0; int nb_lib_paths = 0; int nb_errors = 0; @@ -63,10 +50,6 @@ int debugging = 1; int debugging = 0; #endif -char *owner_name = NULL; -char *dll_name = NULL; -char *dll_file_name = NULL; -const char *init_func = NULL; char **debug_channels = NULL; char **lib_path = NULL; @@ -94,18 +77,18 @@ enum exec_mode_values static enum exec_mode_values exec_mode = MODE_NONE; /* set the dll file name from the input file name */ -static void set_dll_file_name( const char *name ) +static void set_dll_file_name( const char *name, DLLSPEC *spec ) { char *p; - if (dll_file_name) return; + if (spec->file_name) return; if ((p = strrchr( name, '\\' ))) name = p + 1; if ((p = strrchr( name, '/' ))) name = p + 1; - dll_file_name = xmalloc( strlen(name) + 5 ); - strcpy( dll_file_name, name ); - if ((p = strrchr( dll_file_name, '.' )) && !strcmp( p, ".spec" )) *p = 0; - if (!strchr( dll_file_name, '.' )) strcat( dll_file_name, ".dll" ); + spec->file_name = xmalloc( strlen(name) + 5 ); + strcpy( spec->file_name, name ); + if ((p = strrchr( spec->file_name, '.' )) && !strcmp( p, ".spec" )) *p = 0; + if (!strchr( spec->file_name, '.' )) strcat( spec->file_name, ".dll" ); } /* cleanup on program exit */ @@ -206,7 +189,7 @@ static void set_exec_mode( enum exec_mode_values mode ) } /* parse options from the argv array and remove all the recognized ones */ -static char **parse_options( int argc, char **argv ) +static char **parse_options( int argc, char **argv, DLLSPEC *spec ) { char *p; int optc; @@ -222,14 +205,14 @@ static char **parse_options( int argc, char **argv ) /* ignored */ break; case 'F': - dll_file_name = xstrdup( optarg ); + spec->file_name = xstrdup( optarg ); break; case 'H': if (!isdigit(optarg[0])) fatal_error( "Expected number argument with -H option instead of '%s'\n", optarg ); - DLLHeapSize = atoi(optarg); - if (DLLHeapSize > 65535) - fatal_error( "Invalid heap size %d, maximum is 65535\n", DLLHeapSize ); + spec->heap_size = atoi(optarg); + if (spec->heap_size > 65535) + fatal_error( "Invalid heap size %d, maximum is 65535\n", spec->heap_size ); break; case 'I': /* ignored */ @@ -242,18 +225,18 @@ static char **parse_options( int argc, char **argv ) lib_path[nb_lib_paths++] = xstrdup( optarg ); break; case 'M': - owner_name = xstrdup( optarg ); - SpecType = SPEC_WIN16; + spec->owner_name = xstrdup( optarg ); + spec->type = SPEC_WIN16; break; case 'N': - dll_name = xstrdup( optarg ); + spec->dll_name = xstrdup( optarg ); break; case 'd': add_import_dll( optarg, 1 ); break; case 'e': - init_func = xstrdup( optarg ); - if ((p = strchr( init_func, '@' ))) *p = 0; /* kill stdcall decoration */ + spec->init_func = xstrdup( optarg ); + if ((p = strchr( spec->init_func, '@' ))) *p = 0; /* kill stdcall decoration */ break; case 'f': if (!strcmp( optarg, "PIC") || !strcmp( optarg, "pic")) UsePIC = 1; @@ -281,10 +264,10 @@ static char **parse_options( int argc, char **argv ) add_import_dll( optarg, 0 ); break; case 'm': - if (!strcmp( optarg, "gui" )) SpecMode = SPEC_MODE_GUIEXE; - else if (!strcmp( optarg, "cui" )) SpecMode = SPEC_MODE_CUIEXE; - else if (!strcmp( optarg, "guiw" )) SpecMode = SPEC_MODE_GUIEXE_UNICODE; - else if (!strcmp( optarg, "cuiw" )) SpecMode = SPEC_MODE_CUIEXE_UNICODE; + if (!strcmp( optarg, "gui" )) spec->mode = SPEC_MODE_GUIEXE; + else if (!strcmp( optarg, "cui" )) spec->mode = SPEC_MODE_CUIEXE; + else if (!strcmp( optarg, "guiw" )) spec->mode = SPEC_MODE_GUIEXE_UNICODE; + else if (!strcmp( optarg, "cuiw" )) spec->mode = SPEC_MODE_CUIEXE_UNICODE; else usage(1); break; case 'o': @@ -305,21 +288,21 @@ static char **parse_options( int argc, char **argv ) case LONG_OPT_SPEC: set_exec_mode( MODE_SPEC ); input_file = open_input_file( NULL, optarg ); - set_dll_file_name( optarg ); + set_dll_file_name( optarg, spec ); break; case LONG_OPT_DEF: set_exec_mode( MODE_DEF ); input_file = open_input_file( NULL, optarg ); - set_dll_file_name( optarg ); + set_dll_file_name( optarg, spec ); break; case LONG_OPT_EXE: set_exec_mode( MODE_EXE ); if ((p = strrchr( optarg, '/' ))) p++; else p = optarg; - dll_file_name = xmalloc( strlen(p) + 5 ); - strcpy( dll_file_name, p ); - if (!strchr( dll_file_name, '.' )) strcat( dll_file_name, ".exe" ); - if (SpecMode == SPEC_MODE_DLL) SpecMode = SPEC_MODE_GUIEXE; + spec->file_name = xmalloc( strlen(p) + 5 ); + strcpy( spec->file_name, p ); + if (!strchr( spec->file_name, '.' )) strcat( spec->file_name, ".exe" ); + if (spec->mode == SPEC_MODE_DLL) spec->mode = SPEC_MODE_GUIEXE; break; case LONG_OPT_DEBUG: set_exec_mode( MODE_DEBUG ); @@ -343,28 +326,28 @@ static char **parse_options( int argc, char **argv ) /* load all specified resource files */ -static void load_resources( char *argv[] ) +static void load_resources( char *argv[], DLLSPEC *spec ) { int i; char **ptr, **last; - switch (SpecType) + switch (spec->type) { case SPEC_WIN16: - for (i = 0; i < nb_res_files; i++) load_res16_file( res_files[i] ); + for (i = 0; i < nb_res_files; i++) load_res16_file( res_files[i], spec ); break; case SPEC_WIN32: for (i = 0; i < nb_res_files; i++) { - if (!load_res32_file( res_files[i] )) + if (!load_res32_file( res_files[i], spec )) fatal_error( "%s is not a valid Win32 resource file\n", res_files[i] ); } /* load any resource file found in the remaining arguments */ for (ptr = last = argv; *ptr; ptr++) { - if (!load_res32_file( *ptr )) + if (!load_res32_file( *ptr, spec )) *last++ = *ptr; /* not a resource file, keep it in the list */ } *last = NULL; @@ -377,39 +360,60 @@ static void load_resources( char *argv[] ) */ int main(int argc, char **argv) { + DLLSPEC spec; + + spec.file_name = NULL; + spec.dll_name = NULL; + spec.owner_name = NULL; + spec.init_func = NULL; + spec.type = SPEC_WIN32; + spec.mode = SPEC_MODE_DLL; + spec.base = MAX_ORDINALS; + spec.limit = 0; + spec.stack_size = 0; + spec.heap_size = 0; + spec.nb_entry_points = 0; + spec.alloc_entry_points = 0; + spec.nb_names = 0; + spec.nb_resources = 0; + spec.entry_points = NULL; + spec.names = NULL; + spec.ordinals = NULL; + spec.resources = NULL; + output_file = stdout; - argv = parse_options( argc, argv ); + argv = parse_options( argc, argv, &spec ); switch(exec_mode) { case MODE_SPEC: - load_resources( argv ); - if (!ParseTopLevel( input_file )) break; - switch (SpecType) + load_resources( argv, &spec ); + if (!ParseTopLevel( input_file, &spec )) break; + switch (spec.type) { case SPEC_WIN16: if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] ); - BuildSpec16File( output_file ); + BuildSpec16File( output_file, &spec ); break; case SPEC_WIN32: read_undef_symbols( argv ); - BuildSpec32File( output_file ); + BuildSpec32File( output_file, &spec ); break; default: assert(0); } break; case MODE_EXE: - if (SpecType == SPEC_WIN16) fatal_error( "Cannot build 16-bit exe files\n" ); - load_resources( argv ); + if (spec.type == SPEC_WIN16) fatal_error( "Cannot build 16-bit exe files\n" ); + load_resources( argv, &spec ); read_undef_symbols( argv ); - BuildSpec32File( output_file ); + BuildSpec32File( output_file, &spec ); break; case MODE_DEF: if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] ); - if (SpecType == SPEC_WIN16) fatal_error( "Cannot yet build .def file for 16-bit dlls\n" ); - if (!ParseTopLevel( input_file )) break; - BuildDef32File( output_file ); + if (spec.type == SPEC_WIN16) fatal_error( "Cannot yet build .def file for 16-bit dlls\n" ); + if (!ParseTopLevel( input_file, &spec )) break; + BuildDef32File( output_file, &spec ); break; case MODE_DEBUG: BuildDebugFile( output_file, current_src_dir, argv ); diff --git a/tools/winebuild/parser.c b/tools/winebuild/parser.c index 135344fe59e..49b42a9d67f 100644 --- a/tools/winebuild/parser.c +++ b/tools/winebuild/parser.c @@ -134,12 +134,23 @@ static const char * GetToken( int allow_eol ) } +static ORDDEF *add_entry_point( DLLSPEC *spec ) +{ + if (spec->nb_entry_points == spec->alloc_entry_points) + { + spec->alloc_entry_points += 128; + spec->entry_points = xrealloc( spec->entry_points, + spec->alloc_entry_points * sizeof(*spec->entry_points) ); + } + return &spec->entry_points[spec->nb_entry_points++]; +} + /******************************************************************* * ParseVariable * * Parse a variable definition. */ -static int ParseVariable( ORDDEF *odp ) +static int ParseVariable( ORDDEF *odp, DLLSPEC *spec ) { char *endptr; int *value_array; @@ -147,7 +158,7 @@ static int ParseVariable( ORDDEF *odp ) int value_array_size; const char *token; - if (SpecType == SPEC_WIN32) + if (spec->type == SPEC_WIN32) { error( "'variable' not supported in Win32, use 'extern' instead\n" ); return 0; @@ -201,12 +212,12 @@ static int ParseVariable( ORDDEF *odp ) * * Parse a function definition. */ -static int ParseExportFunction( ORDDEF *odp ) +static int ParseExportFunction( ORDDEF *odp, DLLSPEC *spec ) { const char *token; unsigned int i; - switch(SpecType) + switch(spec->type) { case SPEC_WIN16: if (odp->type == TYPE_STDCALL) @@ -269,7 +280,7 @@ static int ParseExportFunction( ORDDEF *odp ) return 0; } - if (SpecType == SPEC_WIN32) + if (spec->type == SPEC_WIN32) { if (strcmp(token, "long") && strcmp(token, "ptr") && @@ -306,7 +317,7 @@ static int ParseExportFunction( ORDDEF *odp ) odp->link_name = xstrdup( token ); if (strchr( odp->link_name, '.' )) { - if (SpecType == SPEC_WIN16) + if (spec->type == SPEC_WIN16) { error( "Forwarded functions not supported for Win16\n" ); return 0; @@ -323,13 +334,13 @@ static int ParseExportFunction( ORDDEF *odp ) * * Parse an 'equate' definition. */ -static int ParseEquate( ORDDEF *odp ) +static int ParseEquate( ORDDEF *odp, DLLSPEC *spec ) { char *endptr; int value; const char *token; - if (SpecType == SPEC_WIN32) + if (spec->type == SPEC_WIN32) { error( "'equate' not supported for Win32\n" ); return 0; @@ -351,7 +362,7 @@ static int ParseEquate( ORDDEF *odp ) * * Parse a 'stub' definition. */ -static int ParseStub( ORDDEF *odp ) +static int ParseStub( ORDDEF *odp, DLLSPEC *spec ) { odp->u.func.arg_types[0] = '\0'; odp->link_name = xstrdup(""); @@ -364,11 +375,11 @@ static int ParseStub( ORDDEF *odp ) * * Parse an 'extern' definition. */ -static int ParseExtern( ORDDEF *odp ) +static int ParseExtern( ORDDEF *odp, DLLSPEC *spec ) { const char *token; - if (SpecType == SPEC_WIN16) + if (spec->type == SPEC_WIN16) { error( "'extern' not supported for Win16, use 'variable' instead\n" ); return 0; @@ -437,13 +448,12 @@ static void fix_export_name( char *name ) * * Parse an ordinal definition. */ -static int ParseOrdinal(int ordinal) +static int ParseOrdinal( int ordinal, DLLSPEC *spec ) { const char *token; - ORDDEF *odp = xmalloc( sizeof(*odp) ); + ORDDEF *odp = add_entry_point( spec ); memset( odp, 0, sizeof(*odp) ); - EntryPoints[nb_entry_points++] = odp; if (!(token = GetToken(0))) goto error; @@ -468,22 +478,22 @@ static int ParseOrdinal(int ordinal) switch(odp->type) { case TYPE_VARIABLE: - if (!ParseVariable( odp )) goto error; + if (!ParseVariable( odp, spec )) goto error; break; case TYPE_PASCAL: case TYPE_STDCALL: case TYPE_VARARGS: case TYPE_CDECL: - if (!ParseExportFunction( odp )) goto error; + if (!ParseExportFunction( odp, spec )) goto error; break; case TYPE_ABS: - if (!ParseEquate( odp )) goto error; + if (!ParseEquate( odp, spec )) goto error; break; case TYPE_STUB: - if (!ParseStub( odp )) goto error; + if (!ParseStub( odp, spec )) goto error; break; case TYPE_EXTERN: - if (!ParseExtern( odp )) goto error; + if (!ParseExtern( odp, spec )) goto error; break; default: assert( 0 ); @@ -493,8 +503,7 @@ static int ParseOrdinal(int ordinal) if (odp->flags & FLAG_I386) { /* ignore this entry point on non-Intel archs */ - EntryPoints[--nb_entry_points] = NULL; - free( odp ); + spec->nb_entry_points--; return 1; } #endif @@ -511,15 +520,9 @@ static int ParseOrdinal(int ordinal) error( "Ordinal number %d too large\n", ordinal ); goto error; } - if (ordinal > Limit) Limit = ordinal; - if (ordinal < Base) Base = ordinal; + if (ordinal > spec->limit) spec->limit = ordinal; + if (ordinal < spec->base) spec->base = ordinal; odp->ordinal = ordinal; - if (Ordinals[ordinal]) - { - error( "Duplicate ordinal %d\n", ordinal ); - goto error; - } - Ordinals[ordinal] = odp; } if (!strcmp( odp->name, "@" ) || odp->flags & FLAG_NONAME) @@ -529,7 +532,7 @@ static int ParseOrdinal(int ordinal) error( "Nameless function needs an explicit ordinal number\n" ); goto error; } - if (SpecType != SPEC_WIN32) + if (spec->type != SPEC_WIN32) { error( "Nameless functions not supported for Win16\n" ); goto error; @@ -538,13 +541,11 @@ static int ParseOrdinal(int ordinal) else odp->export_name = odp->name; odp->name = NULL; } - else Names[nb_names++] = odp; return 1; error: - EntryPoints[--nb_entry_points] = NULL; + spec->nb_entry_points--; free( odp->name ); - free( odp ); return 0; } @@ -557,39 +558,94 @@ static int name_compare( const void *name1, const void *name2 ) } /******************************************************************* - * sort_names + * assign_names * - * Sort the name array and catch duplicates. + * Build the name array and catch duplicates. */ -static void sort_names(void) +static void assign_names( DLLSPEC *spec ) { - int i; + int i, j; - if (!nb_names) return; + spec->nb_names = 0; + for (i = 0; i < spec->nb_entry_points; i++) + if (spec->entry_points[i].name) spec->nb_names++; + if (!spec->nb_names) return; + + spec->names = xmalloc( spec->nb_names * sizeof(spec->names[0]) ); + for (i = j = 0; i < spec->nb_entry_points; i++) + if (spec->entry_points[i].name) spec->names[j++] = &spec->entry_points[i]; /* sort the list of names */ - qsort( Names, nb_names, sizeof(Names[0]), name_compare ); + qsort( spec->names, spec->nb_names, sizeof(spec->names[0]), name_compare ); /* check for duplicate names */ - for (i = 0; i < nb_names - 1; i++) + for (i = 0; i < spec->nb_names - 1; i++) { - if (!strcmp( Names[i]->name, Names[i+1]->name )) + if (!strcmp( spec->names[i]->name, spec->names[i+1]->name )) { - current_line = max( Names[i]->lineno, Names[i+1]->lineno ); + current_line = max( spec->names[i]->lineno, spec->names[i+1]->lineno ); error( "'%s' redefined\n%s:%d: First defined here\n", - Names[i]->name, input_file_name, - min( Names[i]->lineno, Names[i+1]->lineno ) ); + spec->names[i]->name, input_file_name, + min( spec->names[i]->lineno, spec->names[i+1]->lineno ) ); } } } +/******************************************************************* + * assign_ordinals + * + * Build the ordinal array. + */ +static void assign_ordinals( DLLSPEC *spec ) +{ + int i, count, ordinal; + + /* start assigning from base, or from 1 if no ordinal defined yet */ + if (spec->base == MAX_ORDINALS) spec->base = 1; + if (spec->limit < spec->base) spec->limit = spec->base; + + count = max( spec->limit + 1, spec->base + spec->nb_entry_points ); + spec->ordinals = xmalloc( count * sizeof(spec->ordinals[0]) ); + memset( spec->ordinals, 0, count * sizeof(spec->ordinals[0]) ); + + /* fill in all explicitly specified ordinals */ + for (i = 0; i < spec->nb_entry_points; i++) + { + ordinal = spec->entry_points[i].ordinal; + if (ordinal == -1) continue; + if (spec->ordinals[ordinal]) + { + current_line = max( spec->entry_points[i].lineno, spec->ordinals[ordinal]->lineno ); + error( "ordinal %d redefined\n%s:%d: First defined here\n", + ordinal, input_file_name, + min( spec->entry_points[i].lineno, spec->ordinals[ordinal]->lineno ) ); + } + else spec->ordinals[ordinal] = &spec->entry_points[i]; + } + + /* now assign ordinals to the rest */ + for (i = 0, ordinal = spec->base; i < spec->nb_names; i++) + { + if (spec->names[i]->ordinal != -1) continue; /* already has an ordinal */ + while (spec->ordinals[ordinal]) ordinal++; + if (ordinal >= MAX_ORDINALS) + { + current_line = spec->names[i]->lineno; + fatal_error( "Too many functions defined (max %d)\n", MAX_ORDINALS ); + } + spec->names[i]->ordinal = ordinal; + spec->ordinals[ordinal] = spec->names[i]; + } + if (ordinal > spec->limit) spec->limit = ordinal; +} + /******************************************************************* * ParseTopLevel * * Parse a spec file. */ -int ParseTopLevel( FILE *file ) +int ParseTopLevel( FILE *file, DLLSPEC *spec ) { const char *token; @@ -601,16 +657,16 @@ int ParseTopLevel( FILE *file ) if (!(token = GetToken(1))) continue; if (strcmp(token, "@") == 0) { - if (SpecType != SPEC_WIN32) + if (spec->type != SPEC_WIN32) { error( "'@' ordinals not supported for Win16\n" ); continue; } - if (!ParseOrdinal( -1 )) continue; + if (!ParseOrdinal( -1, spec )) continue; } else if (IsNumberString(token)) { - if (!ParseOrdinal( atoi(token) )) continue; + if (!ParseOrdinal( atoi(token), spec )) continue; } else { @@ -621,7 +677,8 @@ int ParseTopLevel( FILE *file ) } current_line = 0; /* no longer parsing the input file */ - sort_names(); + assign_names( spec ); + assign_ordinals( spec ); return !nb_errors; } diff --git a/tools/winebuild/res16.c b/tools/winebuild/res16.c index 0c82f602ec8..17ff05f3410 100644 --- a/tools/winebuild/res16.c +++ b/tools/winebuild/res16.c @@ -69,28 +69,29 @@ struct res_type unsigned int nb_names; /* total number of names */ }; -static struct resource *resources; -static int nb_resources; - -static struct res_type *res_types; -static int nb_types; /* total number of types */ +/* top level of the resource tree */ +struct res_tree +{ + struct res_type *types; /* types array */ + unsigned int nb_types; /* total number of types */ +}; static const unsigned char *file_pos; /* current position in resource file */ static const unsigned char *file_end; /* end of resource file */ static const char *file_name; /* current resource file name */ -inline static struct resource *add_resource(void) +inline static struct resource *add_resource( DLLSPEC *spec ) { - resources = xrealloc( resources, (nb_resources + 1) * sizeof(*resources) ); - return &resources[nb_resources++]; + spec->resources = xrealloc( spec->resources, (spec->nb_resources + 1) * sizeof(*spec->resources) ); + return &spec->resources[spec->nb_resources++]; } -static struct res_type *add_type( const struct resource *res ) +static struct res_type *add_type( struct res_tree *tree, const struct resource *res ) { struct res_type *type; - res_types = xrealloc( res_types, (nb_types + 1) * sizeof(*res_types) ); - type = &res_types[nb_types++]; + tree->types = xrealloc( tree->types, (tree->nb_types + 1) * sizeof(*tree->types) ); + type = &tree->types[tree->nb_types++]; type->type = &res->type; type->res = res; type->nb_names = 0; @@ -151,9 +152,9 @@ static void get_string( struct string_id *str ) } /* load the next resource from the current file */ -static void load_next_resource(void) +static void load_next_resource( DLLSPEC *spec ) { - struct resource *res = add_resource(); + struct resource *res = add_resource( spec ); get_string( &res->type ); get_string( &res->name ); @@ -165,7 +166,7 @@ static void load_next_resource(void) } /* load a Win16 .res file */ -void load_res16_file( const char *name ) +void load_res16_file( const char *name, DLLSPEC *spec ) { int fd; void *base; @@ -186,7 +187,7 @@ void load_res16_file( const char *name ) file_name = name; file_pos = base; file_end = file_pos + st.st_size; - while (file_pos < file_end) load_next_resource(); + while (file_pos < file_end) load_next_resource( spec ); } /* compare two strings/ids */ @@ -214,19 +215,32 @@ static int cmp_res( const void *ptr1, const void *ptr2 ) } /* build the 2-level (type,name) resource tree */ -static void build_resource_tree(void) +static struct res_tree *build_resource_tree( DLLSPEC *spec ) { int i; + struct res_tree *tree; struct res_type *type = NULL; - qsort( resources, nb_resources, sizeof(*resources), cmp_res ); + qsort( spec->resources, spec->nb_resources, sizeof(*spec->resources), cmp_res ); - for (i = 0; i < nb_resources; i++) + tree = xmalloc( sizeof(*tree) ); + tree->types = NULL; + tree->nb_types = 0; + + for (i = 0; i < spec->nb_resources; i++) { - if (!i || cmp_string( &resources[i].type, &resources[i-1].type )) /* new type */ - type = add_type( &resources[i] ); + if (!i || cmp_string( &spec->resources[i].type, &spec->resources[i-1].type )) /* new type */ + type = add_type( tree, &spec->resources[i] ); type->nb_names++; } + return tree; +} + +/* free the resource tree */ +static void free_resource_tree( struct res_tree *tree ) +{ + free( tree->types ); + free( tree ); } inline static void put_byte( unsigned char **buffer, unsigned char val ) @@ -254,19 +268,19 @@ static void output_string( unsigned char **buffer, const char *str ) } /* output the resource data */ -int output_res16_data( FILE *outfile ) +int output_res16_data( FILE *outfile, DLLSPEC *spec ) { const struct resource *res; unsigned char *buffer, *p; int i, total; - if (!nb_resources) return 0; + if (!spec->nb_resources) return 0; - for (i = total = 0, res = resources; i < nb_resources; i++, res++) + for (i = total = 0, res = spec->resources; i < spec->nb_resources; i++, res++) total += (res->data_size + ALIGN_MASK) & ~ALIGN_MASK; buffer = p = xmalloc( total ); - for (i = 0, res = resources; i < nb_resources; i++, res++) + for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) { memcpy( p, res->data, res->data_size ); p += res->data_size; @@ -278,25 +292,26 @@ int output_res16_data( FILE *outfile ) } /* output the resource definitions */ -int output_res16_directory( unsigned char *buffer ) +int output_res16_directory( unsigned char *buffer, DLLSPEC *spec ) { int i, offset, res_offset = 0; unsigned int j; + struct res_tree *tree; const struct res_type *type; const struct resource *res; unsigned char *start = buffer; - build_resource_tree(); + tree = build_resource_tree( spec ); offset = 4; /* alignment + terminator */ - offset += nb_types * 8; /* typeinfo structures */ - offset += nb_resources * 12; /* nameinfo structures */ + offset += tree->nb_types * 8; /* typeinfo structures */ + offset += spec->nb_resources * 12; /* nameinfo structures */ put_word( &buffer, ALIGNMENT ); /* type and name structures */ - for (i = 0, type = res_types; i < nb_types; i++, type++) + for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) { if (type->type->str) { @@ -331,7 +346,7 @@ int output_res16_directory( unsigned char *buffer ) /* name strings */ - for (i = 0, type = res_types; i < nb_types; i++, type++) + for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) { if (type->type->str) output_string( &buffer, type->type->str ); for (j = 0, res = type->res; j < type->nb_names; j++, res++) @@ -342,5 +357,6 @@ int output_res16_directory( unsigned char *buffer ) put_byte( &buffer, 0 ); /* names terminator */ if ((buffer - start) & 1) put_byte( &buffer, 0 ); /* align on word boundary */ + free_resource_tree( tree ); return buffer - start; } diff --git a/tools/winebuild/res32.c b/tools/winebuild/res32.c index 73a1f92fc78..5ee54b1e424 100644 --- a/tools/winebuild/res32.c +++ b/tools/winebuild/res32.c @@ -75,22 +75,22 @@ struct res_type unsigned int nb_id_names; /* number of names that have a numeric id */ }; -static struct resource *resources; -static int nb_resources; - -static struct res_type *res_types; -static int nb_types; /* total number of types */ -static int nb_id_types; /* number of types that have a numeric id */ +/* top level of the resource tree */ +struct res_tree +{ + struct res_type *types; /* types array */ + unsigned int nb_types; /* total number of types */ +}; static const unsigned char *file_pos; /* current position in resource file */ static const unsigned char *file_end; /* end of resource file */ static const char *file_name; /* current resource file name */ -inline static struct resource *add_resource(void) +inline static struct resource *add_resource( DLLSPEC *spec ) { - resources = xrealloc( resources, (nb_resources + 1) * sizeof(*resources) ); - return &resources[nb_resources++]; + spec->resources = xrealloc( spec->resources, (spec->nb_resources + 1) * sizeof(spec->resources[0]) ); + return &spec->resources[spec->nb_resources++]; } static inline unsigned int strlenW( const WCHAR *str ) @@ -118,16 +118,15 @@ static struct res_name *add_name( struct res_type *type, const struct resource * return name; } -static struct res_type *add_type( const struct resource *res ) +static struct res_type *add_type( struct res_tree *tree, const struct resource *res ) { struct res_type *type; - res_types = xrealloc( res_types, (nb_types + 1) * sizeof(*res_types) ); - type = &res_types[nb_types++]; + tree->types = xrealloc( tree->types, (tree->nb_types + 1) * sizeof(*tree->types) ); + type = &tree->types[tree->nb_types++]; type->type = &res->type; type->names = NULL; type->nb_names = 0; type->nb_id_names = 0; - if (!type->type->str) nb_id_types++; return type; } @@ -184,10 +183,10 @@ static int check_header(void) } /* load the next resource from the current file */ -static void load_next_resource(void) +static void load_next_resource( DLLSPEC *spec ) { DWORD hdr_size; - struct resource *res = add_resource(); + struct resource *res = add_resource( spec ); res->data_size = (get_dword() + 3) & ~3; hdr_size = get_dword(); @@ -208,7 +207,7 @@ static void load_next_resource(void) } /* load a Win32 .res file */ -int load_res32_file( const char *name ) +int load_res32_file( const char *name, DLLSPEC *spec ) { int fd, ret; void *base; @@ -231,7 +230,7 @@ int load_res32_file( const char *name ) file_end = file_pos + st.st_size; if ((ret = check_header())) { - while (file_pos < file_end) load_next_resource(); + while (file_pos < file_end) load_next_resource( spec ); } close( fd ); return ret; @@ -263,27 +262,43 @@ static int cmp_res( const void *ptr1, const void *ptr2 ) } /* build the 3-level (type,name,language) resource tree */ -static void build_resource_tree(void) +static struct res_tree *build_resource_tree( DLLSPEC *spec ) { int i; + struct res_tree *tree; struct res_type *type = NULL; struct res_name *name = NULL; - qsort( resources, nb_resources, sizeof(*resources), cmp_res ); + qsort( spec->resources, spec->nb_resources, sizeof(*spec->resources), cmp_res ); - for (i = 0; i < nb_resources; i++) + tree = xmalloc( sizeof(*tree) ); + tree->types = NULL; + tree->nb_types = 0; + + for (i = 0; i < spec->nb_resources; i++) { - if (!i || cmp_string( &resources[i].type, &resources[i-1].type )) /* new type */ + if (!i || cmp_string( &spec->resources[i].type, &spec->resources[i-1].type )) /* new type */ { - type = add_type( &resources[i] ); - name = add_name( type, &resources[i] ); + type = add_type( tree, &spec->resources[i] ); + name = add_name( type, &spec->resources[i] ); } - else if (cmp_string( &resources[i].name, &resources[i-1].name )) /* new name */ + else if (cmp_string( &spec->resources[i].name, &spec->resources[i-1].name )) /* new name */ { - name = add_name( type, &resources[i] ); + name = add_name( type, &spec->resources[i] ); } else name->nb_languages++; } + return tree; +} + +/* free the resource tree */ +static void free_resource_tree( struct res_tree *tree ) +{ + int i; + + for (i = 0; i < tree->nb_types; i++) free( tree->types[i].names ); + free( tree->types ); + free( tree ); } /* output a Unicode string */ @@ -298,21 +313,22 @@ static void output_string( FILE *outfile, const WCHAR *name ) } /* output the resource definitions */ -int output_resources( FILE *outfile ) +void output_resources( FILE *outfile, DLLSPEC *spec ) { - int i, j, k; + int i, j, k, nb_id_types; unsigned int n; + struct res_tree *tree; const struct res_type *type; const struct res_name *name; const struct resource *res; - if (!nb_resources) return 0; + if (!spec->nb_resources) return; - build_resource_tree(); + tree = build_resource_tree( spec ); /* resource data */ - for (i = 0, res = resources; i < nb_resources; i++, res++) + for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) { const unsigned int *p = res->data; int size = res->data_size / 4; @@ -347,9 +363,9 @@ int output_resources( FILE *outfile ) fprintf( outfile, "#define OFFSETOF(field) ((char*)&((struct res_struct *)0)->field - (char*)((struct res_struct *) 0))\n" ); fprintf( outfile, "static struct res_struct{\n" ); fprintf( outfile, " struct res_dir type_dir;\n" ); - fprintf( outfile, " struct res_dir_entry type_entries[%d];\n", nb_types ); + fprintf( outfile, " struct res_dir_entry type_entries[%d];\n", tree->nb_types ); - for (i = 0, type = res_types; i < nb_types; i++, type++) + for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) { fprintf( outfile, " struct res_dir name_%d_dir;\n", i ); fprintf( outfile, " struct res_dir_entry name_%d_entries[%d];\n", i, type->nb_names ); @@ -361,13 +377,16 @@ int output_resources( FILE *outfile ) } } - fprintf( outfile, " struct res_data_entry data_entries[%d];\n", nb_resources ); + fprintf( outfile, " struct res_data_entry data_entries[%d];\n", spec->nb_resources ); - for (i = 0, type = res_types; i < nb_types; i++, type++) + for (i = nb_id_types = 0, type = tree->types; i < tree->nb_types; i++, type++) { if (type->type->str) fprintf( outfile, " unsigned short type_%d_name[%d];\n", i, strlenW(type->type->str)+1 ); + else + nb_id_types++; + for (n = 0, name = type->names; n < type->nb_names; n++, name++) { if (name->name->str) @@ -379,11 +398,11 @@ int output_resources( FILE *outfile ) /* resource directory contents */ fprintf( outfile, "} resources = {\n" ); - fprintf( outfile, " { 0, 0, 0, 0, %d, %d },\n", nb_types - nb_id_types, nb_id_types ); + fprintf( outfile, " { 0, 0, 0, 0, %d, %d },\n", tree->nb_types - nb_id_types, nb_id_types ); /* dump the type directory */ fprintf( outfile, " {\n" ); - for (i = 0, type = res_types; i < nb_types; i++, type++) + for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) { if (!type->type->str) fprintf( outfile, " { 0x%04x, OFFSETOF(name_%d_dir) | 0x80000000 },\n", @@ -395,7 +414,7 @@ int output_resources( FILE *outfile ) fprintf( outfile, " },\n" ); /* dump the names and languages directories */ - for (i = 0, type = res_types; i < nb_types; i++, type++) + for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) { fprintf( outfile, " { 0, 0, 0, 0, %d, %d }, /* name_%d_dir */\n {\n", type->nb_names - type->nb_id_names, type->nb_id_names, i ); @@ -417,7 +436,7 @@ int output_resources( FILE *outfile ) for (k = 0, res = name->res; k < name->nb_languages; k++, res++) { fprintf( outfile, " { 0x%04x, OFFSETOF(data_entries[%d]) },\n", - res->lang, res - resources ); + res->lang, res - spec->resources ); } fprintf( outfile, " },\n" ); } @@ -425,13 +444,13 @@ int output_resources( FILE *outfile ) /* dump the resource data entries */ fprintf( outfile, " {\n" ); - for (i = 0, res = resources; i < nb_resources; i++, res++) + for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++) { fprintf( outfile, " { res_%d, sizeof(res_%d), 0, 0 },\n", i, i ); } /* dump the name strings */ - for (i = 0, type = res_types; i < nb_types; i++, type++) + for (i = 0, type = tree->types; i < tree->nb_types; i++, type++) { if (type->type->str) { @@ -448,5 +467,5 @@ int output_resources( FILE *outfile ) } } fprintf( outfile, " }\n};\n#undef OFFSETOF\n\n" ); - return nb_resources; + free_resource_tree( tree ); } diff --git a/tools/winebuild/spec16.c b/tools/winebuild/spec16.c index 43188a85bf3..46c6b5df468 100644 --- a/tools/winebuild/spec16.c +++ b/tools/winebuild/spec16.c @@ -111,7 +111,7 @@ static int StoreVariableCode( unsigned char *buffer, int size, ORDDEF *odp ) * as a byte stream into the assembly code. */ static int BuildModule16( FILE *outfile, int max_code_offset, - int max_data_offset ) + int max_data_offset, DLLSPEC *spec ) { int i; char *buffer; @@ -142,7 +142,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset, pModule->next = 0; pModule->flags = NE_FFLAGS_SINGLEDATA | NE_FFLAGS_BUILTIN | NE_FFLAGS_LIBMODULE; pModule->dgroup = 2; - pModule->heap_size = DLLHeapSize; + pModule->heap_size = spec->heap_size; pModule->stack_size = 0; pModule->ip = 0; pModule->cs = 0; @@ -172,8 +172,8 @@ static int BuildModule16( FILE *outfile, int max_code_offset, pModule->fileinfo = (int)pFileInfo - (int)pModule; memset( pFileInfo, 0, sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName) ); pFileInfo->cBytes = sizeof(*pFileInfo) - sizeof(pFileInfo->szPathName) - + strlen(dll_file_name); - strcpy( pFileInfo->szPathName, dll_file_name ); + + strlen(spec->file_name); + strcpy( pFileInfo->szPathName, spec->file_name ); pstr = (char *)pFileInfo + pFileInfo->cBytes + 1; /* Segment table */ @@ -201,7 +201,7 @@ static int BuildModule16( FILE *outfile, int max_code_offset, pstr = (char *)pSegment; pstr = (char *)(((long)pstr + 3) & ~3); pModule->res_table = (int)pstr - (int)pModule; - pstr += output_res16_directory( pstr ); + pstr += output_res16_directory( pstr, spec ); /* Imported names table */ @@ -215,16 +215,16 @@ static int BuildModule16( FILE *outfile, int max_code_offset, pstr = (char *)(((long)pstr + 3) & ~3); pModule->name_table = (int)pstr - (int)pModule; /* First entry is module name */ - *pstr = strlen( dll_name ); - strcpy( pstr + 1, dll_name ); + *pstr = strlen( spec->dll_name ); + strcpy( pstr + 1, spec->dll_name ); strupper( pstr + 1 ); pstr += *pstr + 1; *pstr++ = 0; *pstr++ = 0; /* Store all ordinals */ - for (i = 1; i <= Limit; i++) + for (i = 1; i <= spec->limit; i++) { - ORDDEF *odp = Ordinals[i]; + ORDDEF *odp = spec->ordinals[i]; WORD ord = i; if (!odp || !odp->name[0]) continue; *pstr = strlen( odp->name ); @@ -240,10 +240,10 @@ static int BuildModule16( FILE *outfile, int max_code_offset, pstr = (char *)(((long)pstr + 3) & ~3); pModule->entry_table = (int)pstr - (int)pModule; - for (i = 1; i <= Limit; i++) + for (i = 1; i <= spec->limit; i++) { int selector = 0; - ORDDEF *odp = Ordinals[i]; + ORDDEF *odp = spec->ordinals[i]; if (!odp) continue; switch (odp->type) @@ -504,14 +504,14 @@ static int Spec16TypeCompare( const void *e1, const void *e2 ) * * Output the functions for stub entry points */ -static void output_stub_funcs( FILE *outfile ) +static void output_stub_funcs( FILE *outfile, const DLLSPEC *spec ) { int i; char *p; - for (i = 0; i <= Limit; i++) + for (i = 0; i <= spec->limit; i++) { - ORDDEF *odp = Ordinals[i]; + ORDDEF *odp = spec->ordinals[i]; if (!odp || odp->type != TYPE_STUB) continue; fprintf( outfile, "#ifdef __GNUC__\n" ); fprintf( outfile, "static void __wine_unimplemented( const char *func ) __attribute__((noreturn));\n" ); @@ -528,7 +528,7 @@ static void output_stub_funcs( FILE *outfile ) fprintf( outfile, " rec.flags = %d;\n", EH_NONCONTINUABLE ); fprintf( outfile, " rec.rec = 0;\n" ); fprintf( outfile, " rec.params = 2;\n" ); - fprintf( outfile, " rec.info[0] = \"%s\";\n", dll_file_name ); + fprintf( outfile, " rec.info[0] = \"%s\";\n", spec->file_name ); fprintf( outfile, " rec.info[1] = func;\n" ); fprintf( outfile, "#ifdef __GNUC__\n" ); fprintf( outfile, " rec.addr = __builtin_return_address(1);\n" ); @@ -538,9 +538,9 @@ static void output_stub_funcs( FILE *outfile ) fprintf( outfile, " for (;;) RtlRaiseException( &rec );\n}\n\n" ); break; } - for (i = 0; i <= Limit; i++) + for (i = 0; i <= spec->limit; i++) { - ORDDEF *odp = Ordinals[i]; + ORDDEF *odp = spec->ordinals[i]; if (!odp || odp->type != TYPE_STUB) continue; odp->link_name = xrealloc( odp->link_name, strlen(odp->name) + 13 ); strcpy( odp->link_name, "__wine_stub_" ); @@ -557,7 +557,7 @@ static void output_stub_funcs( FILE *outfile ) * * Build a Win16 assembly file from a spec file. */ -void BuildSpec16File( FILE *outfile ) +void BuildSpec16File( FILE *outfile, DLLSPEC *spec ) { ORDDEF **type, **typelist; int i, nFuncs, nTypes; @@ -580,22 +580,22 @@ void BuildSpec16File( FILE *outfile ) memset( data, 0, 16 ); data_offset = 16; - if (!dll_name) /* set default name from file name */ + if (!spec->dll_name) /* set default name from file name */ { char *p; - dll_name = xstrdup( dll_file_name ); - if ((p = strrchr( dll_name, '.' ))) *p = 0; + spec->dll_name = xstrdup( spec->file_name ); + if ((p = strrchr( spec->dll_name, '.' ))) *p = 0; } - output_stub_funcs( outfile ); + output_stub_funcs( outfile, spec ); /* Build sorted list of all argument types, without duplicates */ - typelist = (ORDDEF **)calloc( Limit+1, sizeof(ORDDEF *) ); + typelist = (ORDDEF **)calloc( spec->limit+1, sizeof(ORDDEF *) ); - for (i = nFuncs = 0; i <= Limit; i++) + for (i = nFuncs = 0; i <= spec->limit; i++) { - ORDDEF *odp = Ordinals[i]; + ORDDEF *odp = spec->ordinals[i]; if (!odp) continue; switch (odp->type) { @@ -627,15 +627,15 @@ void BuildSpec16File( FILE *outfile ) char profile[101]; strcpy( profile, get_function_name( typelist[i] )); - BuildCallFrom16Func( outfile, profile, dll_file_name ); + BuildCallFrom16Func( outfile, profile, spec->file_name ); } #endif /* Output the DLL functions prototypes */ - for (i = 0; i <= Limit; i++) + for (i = 0; i <= spec->limit; i++) { - ORDDEF *odp = Ordinals[i]; + ORDDEF *odp = spec->ordinals[i]; if (!odp) continue; switch(odp->type) { @@ -724,7 +724,7 @@ void BuildSpec16File( FILE *outfile ) #ifdef __i386__ fprintf( outfile, " { 0x68, __wine_%s_CallFrom16_%s, 0x9a, __wine_call_from_16_%s,\n", - make_c_identifier(dll_file_name), profile, + make_c_identifier(spec->file_name), profile, (typelist[i]->flags & (FLAG_REGISTER|FLAG_INTERRUPT)) ? "regs": (typelist[i]->flags & FLAG_RET16) ? "word" : "long" ); if (argsize) @@ -745,9 +745,9 @@ void BuildSpec16File( FILE *outfile ) } fprintf( outfile, " },\n {\n" ); - for (i = 0; i <= Limit; i++) + for (i = 0; i <= spec->limit; i++) { - ORDDEF *odp = Ordinals[i]; + ORDDEF *odp = spec->ordinals[i]; if (!odp) continue; switch (odp->type) { @@ -767,7 +767,7 @@ void BuildSpec16File( FILE *outfile ) type = bsearch( &odp, typelist, nTypes, sizeof(ORDDEF *), Spec16TypeCompare ); assert( type ); - fprintf( outfile, " /* %s.%d */ ", dll_name, i ); + fprintf( outfile, " /* %s.%d */ ", spec->dll_name, i ); #ifdef __i386__ fprintf( outfile, "{ 0x5566, 0x68, %s, 0xe866, %d /* %s */ },\n", #else @@ -797,8 +797,8 @@ void BuildSpec16File( FILE *outfile ) /* Build the module */ - module_size = BuildModule16( outfile, code_offset, data_offset ); - res_size = output_res16_data( outfile ); + module_size = BuildModule16( outfile, code_offset, data_offset, spec ); + res_size = output_res16_data( outfile, spec ); /* Output the DLL descriptor */ @@ -816,14 +816,14 @@ void BuildSpec16File( FILE *outfile ) fprintf( outfile, " sizeof(Module),\n" ); fprintf( outfile, " &code_segment,\n" ); fprintf( outfile, " Data_Segment,\n" ); - fprintf( outfile, " \"%s\",\n", owner_name ); + fprintf( outfile, " \"%s\",\n", spec->owner_name ); fprintf( outfile, " %s\n", res_size ? "resource_data" : "0" ); fprintf( outfile, "};\n" ); /* Output the DLL constructor */ - sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(dll_file_name) ); - sprintf( destructor, "__wine_spec_%s_fini", make_c_identifier(dll_file_name) ); + sprintf( constructor, "__wine_spec_%s_init", make_c_identifier(spec->file_name) ); + sprintf( destructor, "__wine_spec_%s_fini", make_c_identifier(spec->file_name) ); output_dll_init( outfile, constructor, destructor ); fprintf( outfile, diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 3a037fb7ece..8588e720676 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -55,51 +55,22 @@ static int string_compare( const void *ptr1, const void *ptr2 ) * * Generate an internal name for an entry point. Used for stubs etc. */ -static const char *make_internal_name( const ORDDEF *odp, const char *prefix ) +static const char *make_internal_name( const ORDDEF *odp, DLLSPEC *spec, const char *prefix ) { static char buffer[256]; if (odp->name || odp->export_name) { char *p; - sprintf( buffer, "__wine_%s_%s_%s", prefix, dll_file_name, + sprintf( buffer, "__wine_%s_%s_%s", prefix, spec->file_name, odp->name ? odp->name : odp->export_name ); /* make sure name is a legal C identifier */ for (p = buffer; *p; p++) if (!isalnum(*p) && *p != '_') break; if (!*p) return buffer; } - sprintf( buffer, "__wine_%s_%s_%d", prefix, make_c_identifier(dll_file_name), odp->ordinal ); + sprintf( buffer, "__wine_%s_%s_%d", prefix, make_c_identifier(spec->file_name), odp->ordinal ); return buffer; } -/******************************************************************* - * AssignOrdinals - * - * Assign ordinals to all entry points. - */ -static void AssignOrdinals(void) -{ - int i, ordinal; - - if ( !nb_names ) return; - - /* start assigning from Base, or from 1 if no ordinal defined yet */ - if (Base == MAX_ORDINALS) Base = 1; - for (i = 0, ordinal = Base; i < nb_names; i++) - { - if (Names[i]->ordinal != -1) continue; /* already has an ordinal */ - while (Ordinals[ordinal]) ordinal++; - if (ordinal >= MAX_ORDINALS) - { - current_line = Names[i]->lineno; - fatal_error( "Too many functions defined (max %d)\n", MAX_ORDINALS ); - } - Names[i]->ordinal = ordinal; - Ordinals[ordinal] = Names[i]; - } - if (ordinal > Limit) Limit = ordinal; -} - - /******************************************************************* * output_debug * @@ -134,7 +105,7 @@ static int output_debug( FILE *outfile ) * * Output the export table for a Win32 module. */ -static int output_exports( FILE *outfile, int nr_exports ) +static int output_exports( FILE *outfile, int nr_exports, DLLSPEC *spec ) { int i, fwd_size = 0, total_size = 0; @@ -150,11 +121,11 @@ static int output_exports( FILE *outfile, int nr_exports ) fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* TimeDateStamp */ fprintf( outfile, " \"\\t.long 0\\n\"\n" ); /* MajorVersion/MinorVersion */ fprintf( outfile, " \"\\t.long __wine_spec_exp_names\\n\"\n" ); /* Name */ - fprintf( outfile, " \"\\t.long %d\\n\"\n", Base ); /* Base */ - fprintf( outfile, " \"\\t.long %d\\n\"\n", nr_exports ); /* NumberOfFunctions */ - fprintf( outfile, " \"\\t.long %d\\n\"\n", nb_names ); /* NumberOfNames */ + fprintf( outfile, " \"\\t.long %d\\n\"\n", spec->base ); /* Base */ + fprintf( outfile, " \"\\t.long %d\\n\"\n", nr_exports ); /* NumberOfFunctions */ + fprintf( outfile, " \"\\t.long %d\\n\"\n", spec->nb_names ); /* NumberOfNames */ fprintf( outfile, " \"\\t.long __wine_spec_exports_funcs\\n\"\n" ); /* AddressOfFunctions */ - if (nb_names) + if (spec->nb_names) { fprintf( outfile, " \"\\t.long __wine_spec_exp_name_ptrs\\n\"\n" ); /* AddressOfNames */ fprintf( outfile, " \"\\t.long __wine_spec_exp_ordinals\\n\"\n" ); /* AddressOfNameOrdinals */ @@ -169,9 +140,9 @@ static int output_exports( FILE *outfile, int nr_exports ) /* output the function pointers */ fprintf( outfile, " \"__wine_spec_exports_funcs:\\n\"\n" ); - for (i = Base; i <= Limit; i++) + for (i = spec->base; i <= spec->limit; i++) { - ORDDEF *odp = Ordinals[i]; + ORDDEF *odp = spec->ordinals[i]; if (!odp) fprintf( outfile, " \"\\t.long 0\\n\"\n" ); else switch(odp->type) { @@ -182,7 +153,8 @@ static int output_exports( FILE *outfile, int nr_exports ) if (!(odp->flags & FLAG_FORWARD)) { fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n", - (odp->flags & FLAG_REGISTER) ? make_internal_name(odp,"regs") : odp->link_name ); + (odp->flags & FLAG_REGISTER) ? make_internal_name( odp, spec, "regs" ) + : odp->link_name ); } else { @@ -191,49 +163,51 @@ static int output_exports( FILE *outfile, int nr_exports ) } break; case TYPE_STUB: - fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n", make_internal_name( odp, "stub" ) ); + fprintf( outfile, " \"\\t.long " __ASM_NAME("%s") "\\n\"\n", + make_internal_name( odp, spec, "stub" ) ); break; default: assert(0); } } - total_size += (Limit - Base + 1) * sizeof(int); + total_size += (spec->limit - spec->base + 1) * sizeof(int); - if (nb_names) + if (spec->nb_names) { /* output the function name pointers */ - int namepos = strlen(dll_file_name) + 1; + int namepos = strlen(spec->file_name) + 1; fprintf( outfile, " \"__wine_spec_exp_name_ptrs:\\n\"\n" ); - for (i = 0; i < nb_names; i++) + for (i = 0; i < spec->nb_names; i++) { fprintf( outfile, " \"\\t.long __wine_spec_exp_names+%d\\n\"\n", namepos ); - namepos += strlen(Names[i]->name) + 1; + namepos += strlen(spec->names[i]->name) + 1; } - total_size += nb_names * sizeof(int); + total_size += spec->nb_names * sizeof(int); } /* output the function names */ fprintf( outfile, " \"\\t.text\\n\"\n" ); fprintf( outfile, " \"__wine_spec_exp_names:\\n\"\n" ); - fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", dll_file_name ); - for (i = 0; i < nb_names; i++) - fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", Names[i]->name ); + fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", spec->file_name ); + for (i = 0; i < spec->nb_names; i++) + fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", spec->names[i]->name ); fprintf( outfile, " \"\\t.data\\n\"\n" ); - if (nb_names) + if (spec->nb_names) { /* output the function ordinals */ fprintf( outfile, " \"__wine_spec_exp_ordinals:\\n\"\n" ); - for (i = 0; i < nb_names; i++) + for (i = 0; i < spec->nb_names; i++) { - fprintf( outfile, " \"\\t" __ASM_SHORT " %d\\n\"\n", Names[i]->ordinal - Base ); + fprintf( outfile, " \"\\t" __ASM_SHORT " %d\\n\"\n", + spec->names[i]->ordinal - spec->base ); } - total_size += nb_names * sizeof(short); - if (nb_names % 2) + total_size += spec->nb_names * sizeof(short); + if (spec->nb_names % 2) { fprintf( outfile, " \"\\t" __ASM_SHORT " 0\\n\"\n" ); total_size += sizeof(short); @@ -245,9 +219,9 @@ static int output_exports( FILE *outfile, int nr_exports ) if (fwd_size) { fprintf( outfile, " \"__wine_spec_forwards:\\n\"\n" ); - for (i = Base; i <= Limit; i++) + for (i = spec->base; i <= spec->limit; i++) { - ORDDEF *odp = Ordinals[i]; + ORDDEF *odp = spec->ordinals[i]; if (odp && (odp->flags & FLAG_FORWARD)) fprintf( outfile, " \"\\t" __ASM_STRING " \\\"%s\\\"\\n\"\n", odp->link_name ); } @@ -259,9 +233,9 @@ static int output_exports( FILE *outfile, int nr_exports ) if (debugging) { - for (i = Base; i <= Limit; i++) + for (i = spec->base; i <= spec->limit; i++) { - ORDDEF *odp = Ordinals[i]; + ORDDEF *odp = spec->ordinals[i]; unsigned int j, args, mask = 0; const char *name; @@ -281,7 +255,7 @@ static int output_exports( FILE *outfile, int nr_exports ) name = odp->link_name; args = strlen(odp->u.func.arg_types) * sizeof(int); - if (odp->flags & FLAG_REGISTER) name = make_internal_name( odp, "regs" ); + if (odp->flags & FLAG_REGISTER) name = make_internal_name( odp, spec, "regs" ); switch(odp->type) { @@ -319,13 +293,13 @@ static int output_exports( FILE *outfile, int nr_exports ) * * Output the functions for stub entry points */ -static void output_stub_funcs( FILE *outfile ) +static void output_stub_funcs( FILE *outfile, DLLSPEC *spec ) { int i; - for (i = 0; i < nb_entry_points; i++) + for (i = 0; i < spec->nb_entry_points; i++) { - ORDDEF *odp = EntryPoints[i]; + ORDDEF *odp = &spec->entry_points[i]; if (odp->type != TYPE_STUB) continue; fprintf( outfile, "#ifdef __GNUC__\n" ); fprintf( outfile, "static void __wine_unimplemented( const char *func ) __attribute__((noreturn));\n" ); @@ -343,7 +317,7 @@ static void output_stub_funcs( FILE *outfile ) fprintf( outfile, " rec.flags = %d;\n", EH_NONCONTINUABLE ); fprintf( outfile, " rec.rec = 0;\n" ); fprintf( outfile, " rec.params = 2;\n" ); - fprintf( outfile, " rec.info[0] = \"%s\";\n", dll_file_name ); + fprintf( outfile, " rec.info[0] = \"%s\";\n", spec->file_name ); fprintf( outfile, " rec.info[1] = func;\n" ); fprintf( outfile, "#ifdef __GNUC__\n" ); fprintf( outfile, " rec.addr = __builtin_return_address(1);\n" ); @@ -354,11 +328,11 @@ static void output_stub_funcs( FILE *outfile ) break; } - for (i = 0; i < nb_entry_points; i++) + for (i = 0; i < spec->nb_entry_points; i++) { - ORDDEF *odp = EntryPoints[i]; + const ORDDEF *odp = &spec->entry_points[i]; if (odp->type != TYPE_STUB) continue; - fprintf( outfile, "void %s(void) ", make_internal_name( odp, "stub" ) ); + fprintf( outfile, "void %s(void) ", make_internal_name( odp, spec, "stub" ) ); if (odp->name) fprintf( outfile, "{ __wine_unimplemented(\"%s\"); }\n", odp->name ); else if (odp->export_name) @@ -374,18 +348,18 @@ static void output_stub_funcs( FILE *outfile ) * * Output the functions for register entry points */ -static void output_register_funcs( FILE *outfile ) +static void output_register_funcs( FILE *outfile, DLLSPEC *spec ) { const char *name; int i; - for (i = 0; i < nb_entry_points; i++) + for (i = 0; i < spec->nb_entry_points; i++) { - ORDDEF *odp = EntryPoints[i]; + const ORDDEF *odp = &spec->entry_points[i]; if (odp->type != TYPE_STDCALL && odp->type != TYPE_CDECL) continue; if (!(odp->flags & FLAG_REGISTER)) continue; if (odp->flags & FLAG_FORWARD) continue; - name = make_internal_name( odp, "regs" ); + name = make_internal_name( odp, spec, "regs" ); fprintf( outfile, "asm(\".align %d\\n\\t\"\n" " \"" __ASM_FUNC("%s") "\\n\\t\"\n" @@ -485,12 +459,13 @@ void output_dll_init( FILE *outfile, const char *constructor, const char *destru * * Build a Win32 C file from a spec file. */ -void BuildSpec32File( FILE *outfile ) +void BuildSpec32File( FILE *outfile, DLLSPEC *spec ) { int exports_size = 0; - int nr_exports, nr_imports, nr_resources; + int nr_exports, nr_imports; int characteristics, subsystem; DWORD page_size; + const char *init_func = spec->init_func; #ifdef HAVE_GETPAGESIZE page_size = getpagesize(); @@ -506,10 +481,8 @@ void BuildSpec32File( FILE *outfile ) # error Cannot get the page size on this platform #endif - AssignOrdinals(); - nr_exports = Base <= Limit ? Limit - Base + 1 : 0; - - resolve_imports(); + nr_exports = spec->base <= spec->limit ? spec->limit - spec->base + 1 : 0; + resolve_imports( spec ); output_standard_file_header( outfile ); /* Reserve some space for the PE header */ @@ -541,7 +514,7 @@ void BuildSpec32File( FILE *outfile ) { /* Output the stub functions */ - output_stub_funcs( outfile ); + output_stub_funcs( outfile, spec ); fprintf( outfile, "#ifndef __GNUC__\n" ); fprintf( outfile, "static void __asm__dummy(void) {\n" ); @@ -549,11 +522,11 @@ void BuildSpec32File( FILE *outfile ) /* Output code for all register functions */ - output_register_funcs( outfile ); + output_register_funcs( outfile, spec ); /* Output the exports and relay entry points */ - exports_size = output_exports( outfile, nr_exports ); + exports_size = output_exports( outfile, nr_exports, spec ); fprintf( outfile, "#ifndef __GNUC__\n" ); fprintf( outfile, "}\n" ); @@ -562,11 +535,11 @@ void BuildSpec32File( FILE *outfile ) /* Output the DLL imports */ - nr_imports = output_imports( outfile ); + nr_imports = output_imports( outfile, spec ); /* Output the resources */ - nr_resources = output_resources( outfile ); + output_resources( outfile, spec ); /* Output the entry point function */ @@ -579,7 +552,7 @@ void BuildSpec32File( FILE *outfile ) fprintf( outfile, "extern void _fini();\n" ); characteristics = subsystem = 0; - switch(SpecMode) + switch(spec->mode) { case SPEC_MODE_DLL: if (init_func) @@ -772,9 +745,9 @@ void BuildSpec32File( FILE *outfile ) fprintf( outfile, " 0x%04x,\n", subsystem ); /* Subsystem */ fprintf( outfile, " 0,\n" ); /* DllCharacteristics */ fprintf( outfile, " %d, %ld,\n", /* SizeOfStackReserve/Commit */ - (stack_size ? stack_size : 1024) * 1024, page_size ); + (spec->stack_size ? spec->stack_size : 1024) * 1024, page_size ); fprintf( outfile, " %d, %ld,\n", /* SizeOfHeapReserve/Commit */ - (DLLHeapSize ? DLLHeapSize : 1024) * 1024, page_size ); + (spec->heap_size ? spec->heap_size : 1024) * 1024, page_size ); fprintf( outfile, " 0,\n" ); /* LoaderFlags */ fprintf( outfile, " %d,\n", IMAGE_NUMBEROF_DIRECTORY_ENTRIES ); /* NumberOfRvaAndSizes */ fprintf( outfile, " {\n" ); @@ -783,7 +756,8 @@ void BuildSpec32File( FILE *outfile ) fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_IMPORT */ nr_imports ? "&imports" : "0", nr_imports ? "sizeof(imports)" : "0" ); fprintf( outfile, " { %s, %s },\n", /* IMAGE_DIRECTORY_ENTRY_RESOURCE */ - nr_resources ? "&resources" : "0", nr_resources ? "sizeof(resources)" : "0" ); + spec->nb_resources ? "&resources" : "0", + spec->nb_resources ? "sizeof(resources)" : "0" ); fprintf( outfile, " }\n }\n};\n\n" ); /* Output the DLL constructor */ @@ -795,7 +769,7 @@ void BuildSpec32File( FILE *outfile ) " __wine_spec_init_state = 1;\n" " __wine_dll_register( &nt_header, \"%s\" );\n" "}\n\n", - dll_file_name ); + spec->file_name ); output_dll_init( outfile, "__wine_spec_init_ctor", NULL ); fprintf( outfile, @@ -813,25 +787,23 @@ void BuildSpec32File( FILE *outfile ) * * Build a Win32 def file from a spec file. */ -void BuildDef32File(FILE *outfile) +void BuildDef32File( FILE *outfile, DLLSPEC *spec ) { const char *name; int i; - AssignOrdinals(); - fprintf(outfile, "; File generated automatically from %s; do not edit!\n\n", input_file_name ); - fprintf(outfile, "LIBRARY %s\n\n", dll_file_name); + fprintf(outfile, "LIBRARY %s\n\n", spec->file_name); fprintf(outfile, "EXPORTS\n"); /* Output the exports and relay entry points */ - for(i = 0; i < nb_entry_points; i++) + for(i = 0; i < spec->nb_entry_points; i++) { - ORDDEF *odp = EntryPoints[i]; + const ORDDEF *odp = &spec->entry_points[i]; int is_data = 0; if (!odp) continue;