Alexandre Julliard : widl: Add helper functions for outputting resource files.
Alexandre Julliard
julliard at winehq.org
Tue Aug 2 14:18:24 CDT 2011
Module: wine
Branch: master
Commit: 36e73eb3fb689bce0de79c022a417d4e52e229a5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=36e73eb3fb689bce0de79c022a417d4e52e229a5
Author: Alexandre Julliard <julliard at 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 );
More information about the wine-cvs
mailing list