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