mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 08:54:05 +00:00
winebuild: Store length of Unicode strings explicitly.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7d3938e811
commit
2c42d8b9a5
|
@ -35,6 +35,7 @@ typedef unsigned short WCHAR;
|
|||
struct string_id
|
||||
{
|
||||
WCHAR *str; /* ptr to Unicode string */
|
||||
unsigned int len; /* len in characters */
|
||||
unsigned short id; /* integer id if str is NULL */
|
||||
};
|
||||
|
||||
|
@ -92,19 +93,6 @@ static inline struct resource *add_resource( DLLSPEC *spec )
|
|||
return &spec->resources[spec->nb_resources++];
|
||||
}
|
||||
|
||||
static inline unsigned int strlenW( const WCHAR *str )
|
||||
{
|
||||
const WCHAR *s = str;
|
||||
while (*s) s++;
|
||||
return s - str;
|
||||
}
|
||||
|
||||
static inline int strcmpW( const WCHAR *str1, const WCHAR *str2 )
|
||||
{
|
||||
while (*str1 && (*str1 == *str2)) { str1++; str2++; }
|
||||
return *str1 - *str2;
|
||||
}
|
||||
|
||||
static struct res_name *add_name( struct res_type *type, struct resource *res )
|
||||
{
|
||||
struct res_name *name;
|
||||
|
@ -132,8 +120,11 @@ static struct res_type *add_type( struct res_tree *tree, struct resource *res )
|
|||
/* get a string from the current resource file */
|
||||
static void get_string( struct string_id *str )
|
||||
{
|
||||
unsigned int i = 0;
|
||||
size_t start_pos = input_buffer_pos;
|
||||
WCHAR wc = get_word();
|
||||
|
||||
str->len = 0;
|
||||
if (wc == 0xffff)
|
||||
{
|
||||
str->str = NULL;
|
||||
|
@ -141,10 +132,11 @@ static void get_string( struct string_id *str )
|
|||
}
|
||||
else
|
||||
{
|
||||
WCHAR *p = xmalloc( (strlenW( (const WCHAR *)(input_buffer + input_buffer_pos) - 1) + 1) * sizeof(WCHAR) );
|
||||
str->str = p;
|
||||
str->id = 0;
|
||||
if ((*p++ = wc)) while ((*p++ = get_word()));
|
||||
input_buffer_pos = start_pos;
|
||||
while (get_word()) str->len++;
|
||||
str->str = xmalloc( str->len * sizeof(WCHAR) );
|
||||
input_buffer_pos = start_pos;
|
||||
while ((wc = get_word())) str->str[i++] = wc;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,8 +145,8 @@ static void put_string( const struct string_id *str )
|
|||
{
|
||||
if (str->str)
|
||||
{
|
||||
const WCHAR *p = str->str;
|
||||
while (*p) put_word( *p++ );
|
||||
unsigned int i;
|
||||
for (i = 0; i < str->len; i++) put_word( str->str[i] );
|
||||
put_word( 0 );
|
||||
}
|
||||
else
|
||||
|
@ -253,13 +245,18 @@ int load_res32_file( const char *name, DLLSPEC *spec )
|
|||
/* compare two unicode strings/ids */
|
||||
static int cmp_string( const struct string_id *str1, const struct string_id *str2 )
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!str1->str)
|
||||
{
|
||||
if (!str2->str) return str1->id - str2->id;
|
||||
return 1; /* an id compares larger than a string */
|
||||
}
|
||||
if (!str2->str) return -1;
|
||||
return strcmpW( str1->str, str2->str );
|
||||
|
||||
for (i = 0; i < str1->len && i < str2->len; i++)
|
||||
if (str1->str[i] != str2->str[i]) return str1->str[i] - str2->str[i];
|
||||
return str1->len - str2->len;
|
||||
}
|
||||
|
||||
/* compare two resources for sorting the resource directory */
|
||||
|
@ -278,11 +275,13 @@ static int cmp_res( const void *ptr1, const void *ptr2 )
|
|||
|
||||
static char *format_res_string( const struct string_id *str )
|
||||
{
|
||||
int i, len = str->str ? strlenW(str->str) + 1 : 5;
|
||||
char *ret = xmalloc( len );
|
||||
unsigned int i;
|
||||
char *ret;
|
||||
|
||||
if (!str->str) sprintf( ret, "%04x", str->id );
|
||||
else for (i = 0; i < len; i++) ret[i] = str->str[i]; /* dumb W->A conversion */
|
||||
if (!str->str) return strmake( "#%04x", str->id );
|
||||
ret = xmalloc( str->len + 1 );
|
||||
for (i = 0; i < str->len; i++) ret[i] = str->str[i]; /* dumb W->A conversion */
|
||||
ret[i] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -365,7 +364,7 @@ static struct res_tree *build_resource_tree( DLLSPEC *spec, unsigned int *dir_si
|
|||
if (type->type->str)
|
||||
{
|
||||
type->name_offset = offset | 0x80000000;
|
||||
offset += (strlenW(type->type->str)+1) * sizeof(WCHAR);
|
||||
offset += (type->type->len + 1) * sizeof(WCHAR);
|
||||
}
|
||||
else type->name_offset = type->type->id;
|
||||
|
||||
|
@ -374,7 +373,7 @@ static struct res_tree *build_resource_tree( DLLSPEC *spec, unsigned int *dir_si
|
|||
if (name->name->str)
|
||||
{
|
||||
name->name_offset = offset | 0x80000000;
|
||||
offset += (strlenW(name->name->str)+1) * sizeof(WCHAR);
|
||||
offset += (name->name->len + 1) * sizeof(WCHAR);
|
||||
}
|
||||
else name->name_offset = name->name->id;
|
||||
for (k = 0, res = name->res; k < name->nb_languages; k++, res++)
|
||||
|
@ -399,13 +398,13 @@ static void free_resource_tree( struct res_tree *tree )
|
|||
}
|
||||
|
||||
/* output a Unicode string */
|
||||
static void output_string( const WCHAR *name )
|
||||
static void output_string( const struct string_id *str )
|
||||
{
|
||||
int i, len = strlenW(name);
|
||||
output( "\t.short 0x%04x", len );
|
||||
for (i = 0; i < len; i++) output( ",0x%04x", name[i] );
|
||||
unsigned int i;
|
||||
output( "\t.short 0x%04x", str->len );
|
||||
for (i = 0; i < str->len; i++) output( ",0x%04x", str->str[i] );
|
||||
output( " /* " );
|
||||
for (i = 0; i < len; i++) output( "%c", isprint((char)name[i]) ? (char)name[i] : '?' );
|
||||
for (i = 0; i < str->len; i++) output( "%c", isprint((char)str->str[i]) ? (char)str->str[i] : '?' );
|
||||
output( " */\n" );
|
||||
}
|
||||
|
||||
|
@ -480,9 +479,9 @@ void output_resources( DLLSPEC *spec )
|
|||
|
||||
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
|
||||
{
|
||||
if (type->type->str) output_string( type->type->str );
|
||||
if (type->type->str) output_string( type->type );
|
||||
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
|
||||
if (name->name->str) output_string( name->name->str );
|
||||
if (name->name->str) output_string( name->name );
|
||||
}
|
||||
|
||||
/* resource data */
|
||||
|
@ -503,11 +502,12 @@ void output_resources( DLLSPEC *spec )
|
|||
}
|
||||
|
||||
/* output a Unicode string in binary format */
|
||||
static void output_bin_string( const WCHAR *name )
|
||||
static void output_bin_string( const struct string_id *str )
|
||||
{
|
||||
int i, len = strlenW(name);
|
||||
put_word( len );
|
||||
for (i = 0; i < len; i++) put_word( name[i] );
|
||||
unsigned int i;
|
||||
|
||||
put_word( str->len );
|
||||
for (i = 0; i < str->len; i++) put_word( str->str[i] );
|
||||
}
|
||||
|
||||
/* output a resource directory in binary format */
|
||||
|
@ -588,9 +588,9 @@ void output_bin_resources( DLLSPEC *spec, unsigned int start_rva )
|
|||
|
||||
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
|
||||
{
|
||||
if (type->type->str) output_bin_string( type->type->str );
|
||||
if (type->type->str) output_bin_string( type->type );
|
||||
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
|
||||
if (name->name->str) output_bin_string( name->name->str );
|
||||
if (name->name->str) output_bin_string( name->name );
|
||||
}
|
||||
|
||||
/* resource data */
|
||||
|
@ -610,10 +610,10 @@ static unsigned int get_resource_header_size( const struct resource *res )
|
|||
unsigned int size = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short);
|
||||
|
||||
if (!res->type.str) size += 2 * sizeof(unsigned short);
|
||||
else size += (strlenW(res->type.str) + 1) * sizeof(WCHAR);
|
||||
else size += (res->type.len + 1) * sizeof(WCHAR);
|
||||
|
||||
if (!res->name.str) size += 2 * sizeof(unsigned short);
|
||||
else size += (strlenW(res->name.str) + 1) * sizeof(WCHAR);
|
||||
else size += (res->name.len + 1) * sizeof(WCHAR);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue