Module: wine Branch: master Commit: 36e73eb3fb689bce0de79c022a417d4e52e229a5 URL: http://source.winehq.org/git/wine.git/?a=commit;h=36e73eb3fb689bce0de79c022a...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Aug 1 21:29:35 2011 +0200
widl: Add helper functions for outputting resource files.
---
tools/widl/register.c | 48 +------------------------ tools/widl/utils.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ tools/widl/utils.h | 2 + 3 files changed, 98 insertions(+), 46 deletions(-)
diff --git a/tools/widl/register.c b/tools/widl/register.c index f18e810..ec573be 100644 --- a/tools/widl/register.c +++ b/tools/widl/register.c @@ -208,17 +208,6 @@ static void write_progids( const statement_list_t *stmts ) } }
-/* put a string into the resource file */ -static inline void put_string( const char *str ) -{ - while (*str) - { - unsigned char ch = *str++; - put_word( toupper(ch) ); - } - put_word( 0 ); -} - void write_regscript( const statement_list_t *stmts ) { const type_t *ps_factory; @@ -247,41 +236,8 @@ void write_regscript( const statement_list_t *stmts )
if (strendswith( regscript_name, ".res" )) /* create a binary resource file */ { - unsigned char *data = output_buffer; - size_t data_size = output_buffer_pos; - size_t header_size = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short); - - header_size += (strlen(regscript_token) + strlen("WINE_REGISTRY") + 2) * sizeof(unsigned short); - - init_output_buffer(); - - put_dword( 0 ); /* ResSize */ - put_dword( 32 ); /* HeaderSize */ - put_word( 0xffff ); /* ResType */ - put_word( 0x0000 ); - put_word( 0xffff ); /* ResName */ - put_word( 0x0000 ); - put_dword( 0 ); /* DataVersion */ - put_word( 0 ); /* Memory options */ - put_word( 0 ); /* Language */ - put_dword( 0 ); /* Version */ - put_dword( 0 ); /* Characteristics */ - - put_dword( data_size ); /* ResSize */ - put_dword( (header_size + 3) & ~3 ); /* HeaderSize */ - put_string( "WINE_REGISTRY" ); /* ResType */ - put_string( regscript_token ); /* ResName */ - align_output( 4 ); - put_dword( 0 ); /* DataVersion */ - put_word( 0 ); /* Memory options */ - put_word( 0 ); /* Language */ - put_dword( 0 ); /* Version */ - put_dword( 0 ); /* Characteristics */ - - put_data( data, data_size ); - free( data ); - align_output( 4 ); - flush_output_buffer( regscript_name ); + add_output_to_resources( "WINE_REGISTRY", regscript_token ); + flush_output_resources( regscript_name ); } else { diff --git a/tools/widl/utils.c b/tools/widl/utils.c index b025c9a..dc77ae8 100644 --- a/tools/widl/utils.c +++ b/tools/widl/utils.c @@ -253,6 +253,13 @@ unsigned char *output_buffer; size_t output_buffer_pos; size_t output_buffer_size;
+static struct resource +{ + unsigned char *data; + size_t size; +} resources[16]; +static unsigned int nb_resources; + static void check_output_buffer_space( size_t size ) { if (output_buffer_pos + size >= output_buffer_size) @@ -279,6 +286,93 @@ void flush_output_buffer( const char *name ) free( output_buffer ); }
+static inline void put_resource_id( const char *str ) +{ + if (str[0] != '#') + { + while (*str) + { + unsigned char ch = *str++; + put_word( toupper(ch) ); + } + put_word( 0 ); + } + else + { + put_word( 0xffff ); + put_word( atoi( str + 1 )); + } +} + +void add_output_to_resources( const char *type, const char *name ) +{ + size_t data_size = output_buffer_pos; + size_t header_size = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short); + + assert( nb_resources < sizeof(resources)/sizeof(resources[0]) ); + + if (type[0] != '#') header_size += (strlen( type ) + 1) * sizeof(unsigned short); + else header_size += 2 * sizeof(unsigned short); + if (name[0] != '#') header_size += (strlen( name ) + 1) * sizeof(unsigned short); + else header_size += 2 * sizeof(unsigned short); + + header_size = (header_size + 3) & ~3; + align_output( 4 ); + check_output_buffer_space( header_size ); + resources[nb_resources].size = header_size + output_buffer_pos; + memmove( output_buffer + header_size, output_buffer, output_buffer_pos ); + + output_buffer_pos = 0; + put_dword( data_size ); /* ResSize */ + put_dword( header_size ); /* HeaderSize */ + put_resource_id( type ); /* ResType */ + put_resource_id( name ); /* ResName */ + align_output( 4 ); + put_dword( 0 ); /* DataVersion */ + put_word( 0 ); /* Memory options */ + put_word( 0 ); /* Language */ + put_dword( 0 ); /* Version */ + put_dword( 0 ); /* Characteristics */ + + resources[nb_resources++].data = output_buffer; + init_output_buffer(); +} + +void flush_output_resources( const char *name ) +{ + int fd; + unsigned int i; + + /* all output must have been saved with add_output_to_resources() first */ + assert( !output_buffer_pos ); + + put_dword( 0 ); /* ResSize */ + put_dword( 32 ); /* HeaderSize */ + put_word( 0xffff ); /* ResType */ + put_word( 0x0000 ); + put_word( 0xffff ); /* ResName */ + put_word( 0x0000 ); + put_dword( 0 ); /* DataVersion */ + put_word( 0 ); /* Memory options */ + put_word( 0 ); /* Language */ + put_dword( 0 ); /* Version */ + put_dword( 0 ); /* Characteristics */ + + fd = open( name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666 ); + if (fd == -1) error( "Error creating %s\n", name ); + if (write( fd, output_buffer, output_buffer_pos ) != output_buffer_pos) + error( "Error writing to %s\n", name ); + for (i = 0; i < nb_resources; i++) + { + if (write( fd, resources[i].data, resources[i].size ) != resources[i].size) + error( "Error writing to %s\n", name ); + free( resources[i].data ); + } + close( fd ); + nb_resources = 0; + free( output_buffer ); +} + void put_data( const void *data, size_t size ) { check_output_buffer_space( size ); diff --git a/tools/widl/utils.h b/tools/widl/utils.h index 5b44aac..ec02fc7 100644 --- a/tools/widl/utils.h +++ b/tools/widl/utils.h @@ -58,6 +58,8 @@ extern size_t output_buffer_size;
extern void init_output_buffer(void); extern void flush_output_buffer( const char *name ); +extern void add_output_to_resources( const char *type, const char *name ); +extern void flush_output_resources( const char *name ); extern void put_data( const void *data, size_t size ); extern void put_byte( unsigned char val ); extern void put_word( unsigned short val );