wrc: Avoid using wine/unicode.h on Windows.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
stable
Alexandre Julliard 2019-04-12 12:59:59 +02:00
parent cd37201517
commit ab6e4c8b73
7 changed files with 94 additions and 63 deletions

View File

@ -376,7 +376,7 @@ static unsigned long xstrtoul(const char *nptr, char **endptr, int base)
yy_pop_state(); yy_pop_state();
while (*p < '0' || *p > '9') p++; while (*p < '0' || *p > '9') p++;
current_codepage = strtol( p, NULL, 10 ); current_codepage = strtol( p, NULL, 10 );
if (current_codepage != CP_UTF8 && !wine_cp_get_table( current_codepage )) if (!is_valid_codepage( current_codepage ))
{ {
parser_error("Codepage %d not supported", current_codepage); parser_error("Codepage %d not supported", current_codepage);
current_codepage = 0; current_codepage = 0;

View File

@ -2557,35 +2557,41 @@ static toolbar_item_t *get_tlbr_buttons_head(toolbar_item_t *p, int *nitems)
static string_t *make_filename(string_t *str) static string_t *make_filename(string_t *str)
{ {
int i;
if(str->type == str_char) if(str->type == str_char)
{ {
char *cptr; char *dst = str->str.cstr;
/* Remove escaped backslash and convert to forward */ /* Remove escaped backslash and convert to forward */
for(cptr = str->str.cstr; (cptr = strchr(cptr, '\\')) != NULL; cptr++) for (i = 0; i < str->size; i++)
{ {
if(cptr[1] == '\\') if (str->str.cstr[i] == '\\')
{ {
memmove(cptr, cptr+1, strlen(cptr)); if (i < str->size - 1 && str->str.cstr[i + 1] == '\\') i++;
str->size--; *dst++ = '/';
} }
*cptr = '/'; else *dst++ = str->str.cstr[i];
} }
*dst = 0;
str->size = dst - str->str.cstr;
} }
else else
{ {
WCHAR *wptr; WCHAR *dst = str->str.wstr;
/* Remove escaped backslash and convert to forward */ /* Remove escaped backslash and convert to forward */
for(wptr = str->str.wstr; (wptr = strchrW(wptr, '\\')) != NULL; wptr++) for (i = 0; i < str->size; i++)
{ {
if(wptr[1] == '\\') if (str->str.wstr[i] == '\\')
{ {
memmove(wptr, wptr+1, strlenW(wptr)); if (i < str->size - 1 && str->str.wstr[i + 1] == '\\') i++;
str->size--; *dst++ = '/';
} }
*wptr = '/'; else *dst++ = str->str.wstr[i];
} }
*dst = 0;
str->size = dst - str->str.wstr;
} }
return str; return str;
} }

View File

@ -555,14 +555,12 @@ static void po_xerror2( int severity, po_message_t message1,
static const struct po_xerror_handler po_xerror_handler = { po_xerror, po_xerror2 }; static const struct po_xerror_handler po_xerror_handler = { po_xerror, po_xerror2 };
static char *convert_string_utf8( const string_t *str, int codepage ) static string_t *convert_string_utf8( const string_t *str, int codepage )
{ {
string_t *newstr = convert_string( str, str_unicode, codepage ); string_t *wstr = convert_string( str, str_unicode, codepage );
char *buffer = xmalloc( newstr->size * 4 + 1 ); string_t *ustr = convert_string( wstr, str_char, CP_UTF8 );
int len = wine_utf8_wcstombs( 0, newstr->str.wstr, newstr->size, buffer, newstr->size * 4 ); free_string( wstr );
buffer[len] = 0; return ustr;
free_string( newstr );
return buffer;
} }
static po_message_t find_message( po_file_t po, const char *msgid, const char *msgctxt, static po_message_t find_message( po_file_t po, const char *msgid, const char *msgctxt,
@ -589,7 +587,8 @@ static void add_po_string( po_file_t po, const string_t *msgid, const string_t *
po_message_t msg; po_message_t msg;
po_message_iterator_t iterator; po_message_iterator_t iterator;
int codepage; int codepage;
char *id, *id_buffer, *context, *str = NULL, *str_buffer = NULL; string_t *str_buffer = NULL;
char *id, *id_buffer, *context, *str = NULL;
if (!msgid->size) return; if (!msgid->size) return;
@ -607,7 +606,8 @@ static void add_po_string( po_file_t po, const string_t *msgid, const string_t *
if (lang) codepage = get_language_codepage( lang->id, lang->sub ); if (lang) codepage = get_language_codepage( lang->id, lang->sub );
else codepage = get_language_codepage( 0, 0 ); else codepage = get_language_codepage( 0, 0 );
assert( codepage != -1 ); assert( codepage != -1 );
str_buffer = str = convert_string_utf8( msgstr, codepage ); str_buffer = convert_string_utf8( msgstr, codepage );
str = str_buffer->str.cstr;
if (is_english( lang )) get_message_context( &str ); if (is_english( lang )) get_message_context( &str );
} }
if (!(msg = find_message( po, id, context, &iterator ))) if (!(msg = find_message( po, id, context, &iterator )))
@ -621,7 +621,7 @@ static void add_po_string( po_file_t po, const string_t *msgid, const string_t *
if (msgid->loc.file) po_message_add_filepos( msg, msgid->loc.file, msgid->loc.line ); if (msgid->loc.file) po_message_add_filepos( msg, msgid->loc.file, msgid->loc.line );
po_message_iterator_free( iterator ); po_message_iterator_free( iterator );
free( id_buffer ); free( id_buffer );
free( str_buffer ); if (str_buffer) free_string( str_buffer );
} }
struct po_file_lang struct po_file_lang
@ -1208,9 +1208,8 @@ static const char *get_msgstr( const char *msgid, const char *context, int *foun
static string_t *translate_string( string_t *str, int *found ) static string_t *translate_string( string_t *str, int *found )
{ {
string_t *new; string_t ustr, *new;
const char *transl; const char *transl;
int res;
char *buffer, *msgid, *context; char *buffer, *msgid, *context;
if (!str->size || !(buffer = convert_msgid_ascii( str, 0 ))) if (!str->size || !(buffer = convert_msgid_ascii( str, 0 )))
@ -1220,14 +1219,12 @@ static string_t *translate_string( string_t *str, int *found )
context = get_message_context( &msgid ); context = get_message_context( &msgid );
transl = get_msgstr( msgid, context, found ); transl = get_msgstr( msgid, context, found );
new = xmalloc( sizeof(*new) ); ustr.type = str_char;
new->type = str_unicode; ustr.size = strlen( transl );
new->size = wine_utf8_mbstowcs( 0, transl, strlen(transl), NULL, 0 ); ustr.str.cstr = (char *)transl;
new->str.wstr = xmalloc( (new->size+1) * sizeof(WCHAR) ); ustr.loc = str->loc;
res = wine_utf8_mbstowcs( MB_ERR_INVALID_CHARS, transl, strlen(transl), new->str.wstr, new->size );
if (res == -2) new = convert_string( &ustr, str_unicode, CP_UTF8 );
error( "Invalid utf-8 character in string '%s'\n", transl );
new->str.wstr[new->size] = 0;
free( buffer ); free( buffer );
return new; return new;
} }

View File

@ -289,9 +289,48 @@ int compare_name_id(const name_id_t *n1, const name_id_t *n2)
return 0; /* Keep the compiler happy */ return 0; /* Keep the compiler happy */
} }
#ifdef _WIN32
int is_valid_codepage(int id)
{
return IsValidCodePage( id );
}
int wrc_mbstowcs( int codepage, int flags, const char *src, int srclen, WCHAR *dst, int dstlen )
{
return MultiByteToWideChar( codepage, flags, src, srclen, dst, dstlen );
}
int wrc_wcstombs( int codepage, int flags, const WCHAR *src, int srclen, char *dst, int dstlen )
{
return WideCharToMultiByte( codepage, flags, src, srclen, dst, dstlen, NULL, NULL );
}
#else /* _WIN32 */
#include "wine/unicode.h"
int is_valid_codepage(int cp)
{
return cp == CP_UTF8 || wine_cp_get_table(cp);
}
int wrc_mbstowcs( int codepage, int flags, const char *src, int srclen, WCHAR *dst, int dstlen )
{
if (codepage == CP_UTF8) return wine_utf8_mbstowcs( flags, src, srclen, dst, dstlen );
return wine_cp_mbstowcs( wine_cp_get_table( codepage ), flags, src, srclen, dst, dstlen );
}
int wrc_wcstombs( int codepage, int flags, const WCHAR *src, int srclen, char *dst, int dstlen )
{
if (codepage == CP_UTF8) return wine_utf8_wcstombs( flags, src, srclen, dst, dstlen );
return wine_cp_wcstombs( wine_cp_get_table( codepage ), flags, src, srclen, dst, dstlen, NULL, NULL );
}
#endif /* _WIN32 */
string_t *convert_string(const string_t *str, enum str_e type, int codepage) string_t *convert_string(const string_t *str, enum str_e type, int codepage)
{ {
const union cptable *cptable = codepage ? wine_cp_get_table( codepage ) : NULL;
string_t *ret = xmalloc(sizeof(*ret)); string_t *ret = xmalloc(sizeof(*ret));
int res; int res;
@ -303,15 +342,10 @@ string_t *convert_string(const string_t *str, enum str_e type, int codepage)
if((str->type == str_char) && (type == str_unicode)) if((str->type == str_char) && (type == str_unicode))
{ {
ret->type = str_unicode; ret->type = str_unicode;
ret->size = cptable ? wine_cp_mbstowcs( cptable, 0, str->str.cstr, str->size, NULL, 0 ) ret->size = wrc_mbstowcs( codepage, 0, str->str.cstr, str->size, NULL, 0 );
: wine_utf8_mbstowcs( 0, str->str.cstr, str->size, NULL, 0 );
ret->str.wstr = xmalloc( (ret->size+1) * sizeof(WCHAR) ); ret->str.wstr = xmalloc( (ret->size+1) * sizeof(WCHAR) );
if (cptable) res = wrc_mbstowcs( codepage, MB_ERR_INVALID_CHARS, str->str.cstr, str->size,
res = wine_cp_mbstowcs( cptable, MB_ERR_INVALID_CHARS, str->str.cstr, str->size, ret->str.wstr, ret->size );
ret->str.wstr, ret->size );
else
res = wine_utf8_mbstowcs( MB_ERR_INVALID_CHARS, str->str.cstr, str->size,
ret->str.wstr, ret->size );
if (res == -2) if (res == -2)
parser_error( "Invalid character in string '%.*s' for codepage %u", parser_error( "Invalid character in string '%.*s' for codepage %u",
str->size, str->str.cstr, codepage ); str->size, str->str.cstr, codepage );
@ -320,13 +354,9 @@ string_t *convert_string(const string_t *str, enum str_e type, int codepage)
else if((str->type == str_unicode) && (type == str_char)) else if((str->type == str_unicode) && (type == str_char))
{ {
ret->type = str_char; ret->type = str_char;
ret->size = cptable ? wine_cp_wcstombs( cptable, 0, str->str.wstr, str->size, NULL, 0, NULL, NULL ) ret->size = wrc_wcstombs( codepage, 0, str->str.wstr, str->size, NULL, 0 );
: wine_utf8_wcstombs( 0, str->str.wstr, str->size, NULL, 0 );
ret->str.cstr = xmalloc( ret->size + 1 ); ret->str.cstr = xmalloc( ret->size + 1 );
if (cptable) wrc_wcstombs( codepage, 0, str->str.wstr, str->size, ret->str.cstr, ret->size );
wine_cp_wcstombs( cptable, 0, str->str.wstr, str->size, ret->str.cstr, ret->size, NULL, NULL );
else
wine_utf8_wcstombs( 0, str->str.wstr, str->size, ret->str.cstr, ret->size );
ret->str.cstr[ret->size] = 0; ret->str.cstr[ret->size] = 0;
} }
else if(str->type == str_unicode) else if(str->type == str_unicode)
@ -363,7 +393,8 @@ int check_valid_utf8( const string_t *str, int codepage )
if (!check_utf8) return 0; if (!check_utf8) return 0;
if (!codepage) return 0; if (!codepage) return 0;
if (!wine_cp_get_table( codepage )) return 0; if (codepage == CP_UTF8) return 0;
if (!is_valid_codepage( codepage )) return 0;
for (i = 0; i < str->size; i++) for (i = 0; i < str->size; i++)
{ {
@ -373,7 +404,7 @@ int check_valid_utf8( const string_t *str, int codepage )
} }
if (i == str->size) return 0; /* no 8-bit chars at all */ if (i == str->size) return 0; /* no 8-bit chars at all */
if (wine_utf8_mbstowcs( MB_ERR_INVALID_CHARS, str->str.cstr, str->size, NULL, 0 ) >= 0) return 1; if (wrc_mbstowcs( CP_UTF8, MB_ERR_INVALID_CHARS, str->str.cstr, str->size, NULL, 0 ) >= 0) return 1;
done: done:
check_utf8 = 0; /* at least one 8-bit non-utf8 string found, stop checking */ check_utf8 = 0; /* at least one 8-bit non-utf8 string found, stop checking */
@ -577,6 +608,6 @@ int get_language_codepage( unsigned short lang, unsigned short sublang )
} }
if (cp == -1) cp = defcp; if (cp == -1) cp = defcp;
assert( cp <= 0 || wine_cp_get_table(cp) ); assert( cp <= 0 || is_valid_codepage(cp) );
return cp; return cp;
} }

View File

@ -51,5 +51,6 @@ void free_string( string_t *str );
int check_valid_utf8( const string_t *str, int codepage ); int check_valid_utf8( const string_t *str, int codepage );
int check_unicode_conversion( const string_t *str_a, const string_t *str_w, int codepage ); int check_unicode_conversion( const string_t *str_a, const string_t *str_w, int codepage );
int get_language_codepage( unsigned short lang, unsigned short sublang ); int get_language_codepage( unsigned short lang, unsigned short sublang );
int is_valid_codepage(int cp);
#endif #endif

View File

@ -21,7 +21,6 @@
#ifndef __WRC_WRC_H #ifndef __WRC_WRC_H
#define __WRC_WRC_H #define __WRC_WRC_H
#include "wine/unicode.h"
#include "wrctypes.h" #include "wrctypes.h"
/* From wrc.c */ /* From wrc.c */

View File

@ -24,10 +24,7 @@
#include <stdarg.h> #include <stdarg.h>
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#ifndef MAKELANGID
#include "winnls.h" #include "winnls.h"
#endif
#ifndef VS_FFI_SIGNATURE #ifndef VS_FFI_SIGNATURE
#include "winver.h" #include "winver.h"