Commit 71580499 authored by Alexandre Julliard's avatar Alexandre Julliard

winebuild: Added output() function to properly deal with write errors.

parent 05001b1c
......@@ -154,11 +154,13 @@ extern void error( const char *msg, ... )
__attribute__ ((__format__ (__printf__, 1, 2)));
extern void warning( const char *msg, ... )
__attribute__ ((__format__ (__printf__, 1, 2)));
extern int output( const char *format, ... )
__attribute__ ((__format__ (__printf__, 1, 2)));
extern char *get_temp_file_name( const char *prefix, const char *suffix );
extern void output_standard_file_header( FILE *outfile );
extern void output_standard_file_header(void);
extern FILE *open_input_file( const char *srcdir, const char *name );
extern void close_input_file( FILE *file );
extern void dump_bytes( FILE *outfile, const void *buffer, unsigned int size );
extern void dump_bytes( const void *buffer, unsigned int size );
extern int remove_stdcall_decoration( char *name );
extern void assemble_file( const char *src_file, const char *obj_file );
extern DLLSPEC *alloc_dll_spec(void);
......@@ -176,8 +178,8 @@ extern const char *get_asm_string_keyword(void);
extern const char *get_asm_short_keyword(void);
extern const char *get_asm_rodata_section(void);
extern const char *get_asm_string_section(void);
extern void output_function_size( FILE *outfile, const char *name );
extern void output_gnu_stack_note( FILE *outfile );
extern void output_function_size( const char *name );
extern void output_gnu_stack_note(void);
extern void add_import_dll( const char *name, const char *filename );
extern void add_delayed_import( const char *name );
......@@ -187,20 +189,20 @@ extern void read_undef_symbols( DLLSPEC *spec, char **argv );
extern int resolve_imports( DLLSPEC *spec );
extern int has_imports(void);
extern int has_relays( DLLSPEC *spec );
extern void output_get_pc_thunk( FILE *outfile );
extern void output_stubs( FILE *outfile, DLLSPEC *spec );
extern void output_imports( FILE *outfile, DLLSPEC *spec );
extern void output_get_pc_thunk(void);
extern void output_stubs( DLLSPEC *spec );
extern void output_imports( DLLSPEC *spec );
extern int load_res32_file( const char *name, DLLSPEC *spec );
extern void output_resources( FILE *outfile, DLLSPEC *spec );
extern void output_resources( DLLSPEC *spec );
extern void load_res16_file( const char *name, DLLSPEC *spec );
extern void output_res16_data( FILE *outfile, DLLSPEC *spec );
extern void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_name );
extern void output_res16_data( DLLSPEC *spec );
extern void output_res16_directory( DLLSPEC *spec, const char *header_name );
extern void BuildRelays16( FILE *outfile );
extern void BuildRelays32( 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 BuildRelays16(void);
extern void BuildRelays32(void);
extern void BuildSpec16File( DLLSPEC *spec );
extern void BuildSpec32File( DLLSPEC *spec );
extern void BuildDef32File( DLLSPEC *spec );
extern int parse_spec_file( FILE *file, DLLSPEC *spec );
extern int parse_def_file( FILE *file, DLLSPEC *spec );
......@@ -219,6 +221,7 @@ extern int link_ext_symbols;
extern char *input_file_name;
extern char *spec_file_name;
extern FILE *output_file;
extern const char *output_file_name;
extern char **lib_path;
......
......@@ -75,6 +75,7 @@ char **lib_path = NULL;
char *input_file_name = NULL;
char *spec_file_name = NULL;
FILE *output_file = NULL;
const char *output_file_name = NULL;
static const char *output_file_source_name;
......@@ -82,7 +83,6 @@ char *as_command = NULL;
char *ld_command = NULL;
char *nm_command = NULL;
static FILE *output_file;
static int nb_res_files;
static char **res_files;
......@@ -597,11 +597,11 @@ int main(int argc, char **argv)
case SPEC_WIN16:
if (argv[0])
fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
BuildSpec16File( output_file, spec );
BuildSpec16File( spec );
break;
case SPEC_WIN32:
read_undef_symbols( spec, argv );
BuildSpec32File( output_file, spec );
BuildSpec32File( spec );
break;
default: assert(0);
}
......@@ -613,22 +613,22 @@ int main(int argc, char **argv)
load_import_libs( argv );
if (spec_file_name && !parse_input_file( spec )) break;
read_undef_symbols( spec, argv );
BuildSpec32File( output_file, spec );
BuildSpec32File( spec );
break;
case MODE_DEF:
if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
if (spec->type == SPEC_WIN16) fatal_error( "Cannot yet build .def file for 16-bit dlls\n" );
if (!spec_file_name) fatal_error( "missing .spec file\n" );
if (!parse_input_file( spec )) break;
BuildDef32File( output_file, spec );
BuildDef32File( spec );
break;
case MODE_RELAY16:
if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
BuildRelays16( output_file );
BuildRelays16();
break;
case MODE_RELAY32:
if (argv[0]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[0] );
BuildRelays32( output_file );
BuildRelays32();
break;
default:
usage(1);
......@@ -637,7 +637,7 @@ int main(int argc, char **argv)
if (nb_errors) exit(1);
if (output_file_name)
{
fclose( output_file );
if (fclose( output_file ) < 0) fatal_perror( "fclose" );
if (output_file_source_name) assemble_file( output_file_source_name, output_file_name );
output_file_name = NULL;
}
......
......@@ -242,16 +242,16 @@ static void free_resource_tree( struct res_tree *tree )
}
/* output a string preceded by its length */
static void output_string( FILE *outfile, const char *str )
static void output_string( const char *str )
{
unsigned int i, len = strlen(str);
fprintf( outfile, "\t.byte 0x%02x", len );
for (i = 0; i < len; i++) fprintf( outfile, ",0x%02x", (unsigned char)str[i] );
fprintf( outfile, " /* %s */\n", str );
output( "\t.byte 0x%02x", len );
for (i = 0; i < len; i++) output( ",0x%02x", (unsigned char)str[i] );
output( " /* %s */\n", str );
}
/* output the resource data */
void output_res16_data( FILE *outfile, DLLSPEC *spec )
void output_res16_data( DLLSPEC *spec )
{
const struct resource *res;
unsigned int i;
......@@ -260,14 +260,14 @@ void output_res16_data( FILE *outfile, DLLSPEC *spec )
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
{
fprintf( outfile, ".L__wine_spec_resource_%u:\n", i );
dump_bytes( outfile, res->data, res->data_size );
fprintf( outfile, ".L__wine_spec_resource_%u_end:\n", i );
output( ".L__wine_spec_resource_%u:\n", i );
dump_bytes( res->data, res->data_size );
output( ".L__wine_spec_resource_%u_end:\n", i );
}
}
/* output the resource definitions */
void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_name )
void output_res16_directory( DLLSPEC *spec, const char *header_name )
{
unsigned int i, j;
struct res_tree *tree;
......@@ -276,38 +276,38 @@ void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_na
tree = build_resource_tree( spec );
fprintf( outfile, "\n.L__wine_spec_ne_rsrctab:\n" );
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* alignment */
output( "\n.L__wine_spec_ne_rsrctab:\n" );
output( "\t%s 0\n", get_asm_short_keyword() ); /* alignment */
/* type and name structures */
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
if (type->type->str)
fprintf( outfile, "\t%s .L__wine_spec_restype_%u-.L__wine_spec_ne_rsrctab\n",
output( "\t%s .L__wine_spec_restype_%u-.L__wine_spec_ne_rsrctab\n",
get_asm_short_keyword(), i );
else
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), type->type->id | 0x8000 );
output( "\t%s 0x%04x\n", get_asm_short_keyword(), type->type->id | 0x8000 );
fprintf( outfile, "\t%s %u,0,0\n", get_asm_short_keyword(), type->nb_names );
output( "\t%s %u,0,0\n", get_asm_short_keyword(), type->nb_names );
for (j = 0, res = type->res; j < type->nb_names; j++, res++)
{
fprintf( outfile, "\t%s .L__wine_spec_resource_%u-%s\n",
output( "\t%s .L__wine_spec_resource_%u-%s\n",
get_asm_short_keyword(), res - spec->resources, header_name );
fprintf( outfile, "\t%s .L__wine_spec_resource_%u_end-.L__wine_spec_resource_%u\n",
output( "\t%s .L__wine_spec_resource_%u_end-.L__wine_spec_resource_%u\n",
get_asm_short_keyword(), res - spec->resources, res - spec->resources );
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), res->memopt );
output( "\t%s 0x%04x\n", get_asm_short_keyword(), res->memopt );
if (res->name.str)
fprintf( outfile, "\t%s .L__wine_spec_resname_%u_%u-.L__wine_spec_ne_rsrctab\n",
output( "\t%s .L__wine_spec_resname_%u_%u-.L__wine_spec_ne_rsrctab\n",
get_asm_short_keyword(), i, j );
else
fprintf( outfile, "\t%s 0x%04x\n", get_asm_short_keyword(), res->name.id | 0x8000 );
output( "\t%s 0x%04x\n", get_asm_short_keyword(), res->name.id | 0x8000 );
fprintf( outfile, "\t%s 0,0\n", get_asm_short_keyword() );
output( "\t%s 0,0\n", get_asm_short_keyword() );
}
}
fprintf( outfile, "\t%s 0\n", get_asm_short_keyword() ); /* terminator */
output( "\t%s 0\n", get_asm_short_keyword() ); /* terminator */
/* name strings */
......@@ -315,19 +315,19 @@ void output_res16_directory( FILE *outfile, DLLSPEC *spec, const char *header_na
{
if (type->type->str)
{
fprintf( outfile, ".L__wine_spec_restype_%u:\n", i );
output_string( outfile, type->type->str );
output( ".L__wine_spec_restype_%u:\n", i );
output_string( type->type->str );
}
for (j = 0, res = type->res; j < type->nb_names; j++, res++)
{
if (res->name.str)
{
fprintf( outfile, ".L__wine_spec_resname_%u_%u:\n", i, j );
output_string( outfile, res->name.str );
output( ".L__wine_spec_resname_%u_%u:\n", i, j );
output_string( res->name.str );
}
}
}
fprintf( outfile, "\t.byte 0\n" ); /* names terminator */
output( "\t.byte 0\n" ); /* names terminator */
free_resource_tree( tree );
}
......@@ -316,29 +316,29 @@ static void free_resource_tree( struct res_tree *tree )
}
/* output a Unicode string */
static void output_string( FILE *outfile, const WCHAR *name )
static void output_string( const WCHAR *name )
{
int i, len = strlenW(name);
fprintf( outfile, "\t%s 0x%04x", get_asm_short_keyword(), len );
for (i = 0; i < len; i++) fprintf( outfile, ",0x%04x", name[i] );
fprintf( outfile, " /* " );
for (i = 0; i < len; i++) fprintf( outfile, "%c", isprint((char)name[i]) ? (char)name[i] : '?' );
fprintf( outfile, " */\n" );
output( "\t%s 0x%04x", get_asm_short_keyword(), len );
for (i = 0; i < len; i++) output( ",0x%04x", name[i] );
output( " /* " );
for (i = 0; i < len; i++) output( "%c", isprint((char)name[i]) ? (char)name[i] : '?' );
output( " */\n" );
}
/* output a resource directory */
static inline void output_res_dir( FILE *outfile, unsigned int nb_names, unsigned int nb_ids )
static inline void output_res_dir( unsigned int nb_names, unsigned int nb_ids )
{
fprintf( outfile, "\t.long 0\n" ); /* Characteristics */
fprintf( outfile, "\t.long 0\n" ); /* TimeDateStamp */
fprintf( outfile, "\t%s 0,0\n", /* Major/MinorVersion */
output( "\t.long 0\n" ); /* Characteristics */
output( "\t.long 0\n" ); /* TimeDateStamp */
output( "\t%s 0,0\n", /* Major/MinorVersion */
get_asm_short_keyword() );
fprintf( outfile, "\t%s %u,%u\n", /* NumberOfNamed/IdEntries */
output( "\t%s %u,%u\n", /* NumberOfNamed/IdEntries */
get_asm_short_keyword(), nb_names, nb_ids );
}
/* output the resource definitions */
void output_resources( FILE *outfile, DLLSPEC *spec )
void output_resources( DLLSPEC *spec )
{
int k, nb_id_types;
unsigned int i, n, offset, data_offset;
......@@ -388,19 +388,19 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
/* output the resource directories */
fprintf( outfile, "\n/* resources */\n\n" );
fprintf( outfile, "\t.data\n" );
fprintf( outfile, "\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, ".L__wine_spec_resources:\n" );
output( "\n/* resources */\n\n" );
output( "\t.data\n" );
output( "\t.align %d\n", get_alignment(get_ptr_size()) );
output( ".L__wine_spec_resources:\n" );
output_res_dir( outfile, tree->nb_types - nb_id_types, nb_id_types );
output_res_dir( tree->nb_types - nb_id_types, nb_id_types );
/* dump the type directory */
offset = RESDIR_SIZE( tree->nb_types );
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
fprintf( outfile, "\t.long 0x%08x,0x%08x\n",
output( "\t.long 0x%08x,0x%08x\n",
type->name_offset, offset | 0x80000000 );
offset += RESDIR_SIZE( type->nb_names );
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
......@@ -414,22 +414,22 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
output_res_dir( outfile, type->nb_names - type->nb_id_names, type->nb_id_names );
output_res_dir( type->nb_names - type->nb_id_names, type->nb_id_names );
offset += RESDIR_SIZE( type->nb_names );
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
{
fprintf( outfile, "\t.long 0x%08x,0x%08x\n",
output( "\t.long 0x%08x,0x%08x\n",
name->name_offset, offset | 0x80000000 );
offset += RESDIR_SIZE( name->nb_languages );
}
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
{
output_res_dir( outfile, 0, name->nb_languages );
output_res_dir( 0, name->nb_languages );
for (k = 0, res = name->res; k < name->nb_languages; k++, res++)
{
unsigned int entry_offset = (res - spec->resources) * sizeof(IMAGE_RESOURCE_DATA_ENTRY);
fprintf( outfile, "\t.long 0x%08x,0x%08x\n", res->lang, data_offset + entry_offset );
output( "\t.long 0x%08x,0x%08x\n", res->lang, data_offset + entry_offset );
}
}
}
......@@ -437,28 +437,28 @@ void output_resources( FILE *outfile, DLLSPEC *spec )
/* dump the resource data entries */
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
fprintf( outfile, "\t.long .L__wine_spec_res_%d-.L__wine_spec_rva_base,%u,0,0\n",
output( "\t.long .L__wine_spec_res_%d-.L__wine_spec_rva_base,%u,0,0\n",
i, res->data_size );
/* dump the name strings */
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
if (type->type->str) output_string( outfile, type->type->str );
if (type->type->str) output_string( type->type->str );
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
if (name->name->str) output_string( outfile, name->name->str );
if (name->name->str) output_string( name->name->str );
}
/* resource data */
for (i = 0, res = spec->resources; i < spec->nb_resources; i++, res++)
{
fprintf( outfile, "\n\t.align %d\n", get_alignment(get_ptr_size()) );
fprintf( outfile, ".L__wine_spec_res_%d:\n", i );
dump_bytes( outfile, res->data, res->data_size );
output( "\n\t.align %d\n", get_alignment(get_ptr_size()) );
output( ".L__wine_spec_res_%d:\n", i );
dump_bytes( res->data, res->data_size );
}
fprintf( outfile, ".L__wine_spec_resources_end:\n" );
fprintf( outfile, "\t.byte 0\n" );
output( ".L__wine_spec_resources_end:\n" );
output( "\t.byte 0\n" );
free_resource_tree( tree );
}
......@@ -162,6 +162,18 @@ void warning( const char *msg, ... )
va_end( valist );
}
int output( const char *format, ... )
{
int ret;
va_list valist;
va_start( valist, format );
ret = vfprintf( output_file, format, valist );
va_end( valist );
if (ret < 0) fatal_perror( "Output error" );
return ret;
}
/* get a name for a temp file, automatically cleaned up on exit */
char *get_temp_file_name( const char *prefix, const char *suffix )
{
......@@ -193,31 +205,29 @@ char *get_temp_file_name( const char *prefix, const char *suffix )
}
/* output a standard header for generated files */
void output_standard_file_header( FILE *outfile )
void output_standard_file_header(void)
{
if (spec_file_name)
fprintf( outfile, "/* File generated automatically from %s; do not edit! */\n",
spec_file_name );
output( "/* File generated automatically from %s; do not edit! */\n", spec_file_name );
else
fprintf( outfile, "/* File generated automatically; do not edit! */\n" );
fprintf( outfile,
"/* This file can be copied, modified and distributed without restriction. */\n\n" );
output( "/* File generated automatically; do not edit! */\n" );
output( "/* This file can be copied, modified and distributed without restriction. */\n\n" );
}
/* dump a byte stream into the assembly code */
void dump_bytes( FILE *outfile, const void *buffer, unsigned int size )
void dump_bytes( const void *buffer, unsigned int size )
{
unsigned int i;
const unsigned char *ptr = buffer;
if (!size) return;
fprintf( outfile, "\t.byte " );
output( "\t.byte " );
for (i = 0; i < size - 1; i++, ptr++)
{
if ((i % 16) == 15) fprintf( outfile, "0x%02x\n\t.byte ", *ptr );
else fprintf( outfile, "0x%02x,", *ptr );
if ((i % 16) == 15) output( "0x%02x\n\t.byte ", *ptr );
else output( "0x%02x,", *ptr );
}
fprintf( outfile, "0x%02x\n", *ptr );
output( "0x%02x\n", *ptr );
}
......@@ -520,7 +530,7 @@ const char *func_declaration( const char *func )
}
/* output a size declaration for an assembly function */
void output_function_size( FILE *outfile, const char *name )
void output_function_size( const char *name )
{
switch (target_platform)
{
......@@ -528,13 +538,13 @@ void output_function_size( FILE *outfile, const char *name )
case PLATFORM_WINDOWS:
break;
default:
fprintf( outfile, "\t.size %s, .-%s\n", name, name );
output( "\t.size %s, .-%s\n", name, name );
break;
}
}
/* output the GNU note for non-exec stack */
void output_gnu_stack_note( FILE *outfile )
void output_gnu_stack_note(void)
{
switch (target_platform)
{
......@@ -542,7 +552,7 @@ void output_gnu_stack_note( FILE *outfile )
case PLATFORM_APPLE:
break;
default:
fprintf( outfile, "\t.section .note.GNU-stack,\"\",@progbits\n" );
output( "\t.section .note.GNU-stack,\"\",@progbits\n" );
break;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment