From ab6e4c8b735aa28112fbc6ec876d8881ef6498f0 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 12 Apr 2019 12:59:59 +0200 Subject: [PATCH] wrc: Avoid using wine/unicode.h on Windows. Signed-off-by: Alexandre Julliard --- tools/wrc/parser.l | 2 +- tools/wrc/parser.y | 46 +++++++++++++++++------------- tools/wrc/po.c | 37 +++++++++++------------- tools/wrc/utils.c | 67 ++++++++++++++++++++++++++++++++------------ tools/wrc/utils.h | 1 + tools/wrc/wrc.h | 1 - tools/wrc/wrctypes.h | 3 -- 7 files changed, 94 insertions(+), 63 deletions(-) diff --git a/tools/wrc/parser.l b/tools/wrc/parser.l index 0f46670288c..f456c626d16 100644 --- a/tools/wrc/parser.l +++ b/tools/wrc/parser.l @@ -376,7 +376,7 @@ static unsigned long xstrtoul(const char *nptr, char **endptr, int base) yy_pop_state(); while (*p < '0' || *p > '9') p++; 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); current_codepage = 0; diff --git a/tools/wrc/parser.y b/tools/wrc/parser.y index 8196e9f7faf..4c2f22ac0d3 100644 --- a/tools/wrc/parser.y +++ b/tools/wrc/parser.y @@ -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) { + int i; + if(str->type == str_char) { - char *cptr; + char *dst = str->str.cstr; /* Remove escaped backslash and convert to forward */ - for(cptr = str->str.cstr; (cptr = strchr(cptr, '\\')) != NULL; cptr++) - { - if(cptr[1] == '\\') - { - memmove(cptr, cptr+1, strlen(cptr)); - str->size--; - } - *cptr = '/'; - } + for (i = 0; i < str->size; i++) + { + if (str->str.cstr[i] == '\\') + { + if (i < str->size - 1 && str->str.cstr[i + 1] == '\\') i++; + *dst++ = '/'; + } + else *dst++ = str->str.cstr[i]; + } + *dst = 0; + str->size = dst - str->str.cstr; } else { - WCHAR *wptr; + WCHAR *dst = str->str.wstr; /* Remove escaped backslash and convert to forward */ - for(wptr = str->str.wstr; (wptr = strchrW(wptr, '\\')) != NULL; wptr++) - { - if(wptr[1] == '\\') - { - memmove(wptr, wptr+1, strlenW(wptr)); - str->size--; - } - *wptr = '/'; - } + for (i = 0; i < str->size; i++) + { + if (str->str.wstr[i] == '\\') + { + if (i < str->size - 1 && str->str.wstr[i + 1] == '\\') i++; + *dst++ = '/'; + } + else *dst++ = str->str.wstr[i]; + } + *dst = 0; + str->size = dst - str->str.wstr; } return str; } diff --git a/tools/wrc/po.c b/tools/wrc/po.c index c58c062cbb7..913a918a699 100644 --- a/tools/wrc/po.c +++ b/tools/wrc/po.c @@ -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 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 ); - char *buffer = xmalloc( newstr->size * 4 + 1 ); - int len = wine_utf8_wcstombs( 0, newstr->str.wstr, newstr->size, buffer, newstr->size * 4 ); - buffer[len] = 0; - free_string( newstr ); - return buffer; + string_t *wstr = convert_string( str, str_unicode, codepage ); + string_t *ustr = convert_string( wstr, str_char, CP_UTF8 ); + free_string( wstr ); + return ustr; } 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_iterator_t iterator; 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; @@ -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 ); else codepage = get_language_codepage( 0, 0 ); 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 (!(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 ); po_message_iterator_free( iterator ); free( id_buffer ); - free( str_buffer ); + if (str_buffer) free_string( str_buffer ); } 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 ) { - string_t *new; + string_t ustr, *new; const char *transl; - int res; char *buffer, *msgid, *context; 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 ); transl = get_msgstr( msgid, context, found ); - new = xmalloc( sizeof(*new) ); - new->type = str_unicode; - new->size = wine_utf8_mbstowcs( 0, transl, strlen(transl), NULL, 0 ); - new->str.wstr = xmalloc( (new->size+1) * sizeof(WCHAR) ); - res = wine_utf8_mbstowcs( MB_ERR_INVALID_CHARS, transl, strlen(transl), new->str.wstr, new->size ); - if (res == -2) - error( "Invalid utf-8 character in string '%s'\n", transl ); - new->str.wstr[new->size] = 0; + ustr.type = str_char; + ustr.size = strlen( transl ); + ustr.str.cstr = (char *)transl; + ustr.loc = str->loc; + + new = convert_string( &ustr, str_unicode, CP_UTF8 ); free( buffer ); return new; } diff --git a/tools/wrc/utils.c b/tools/wrc/utils.c index 633ec57d86e..5533a531f17 100644 --- a/tools/wrc/utils.c +++ b/tools/wrc/utils.c @@ -289,9 +289,48 @@ int compare_name_id(const name_id_t *n1, const name_id_t *n2) 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) { - const union cptable *cptable = codepage ? wine_cp_get_table( codepage ) : NULL; string_t *ret = xmalloc(sizeof(*ret)); 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)) { ret->type = str_unicode; - ret->size = cptable ? wine_cp_mbstowcs( cptable, 0, str->str.cstr, str->size, NULL, 0 ) - : wine_utf8_mbstowcs( 0, str->str.cstr, str->size, NULL, 0 ); + ret->size = wrc_mbstowcs( codepage, 0, str->str.cstr, str->size, NULL, 0 ); ret->str.wstr = xmalloc( (ret->size+1) * sizeof(WCHAR) ); - if (cptable) - res = wine_cp_mbstowcs( cptable, MB_ERR_INVALID_CHARS, str->str.cstr, str->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 ); + res = wrc_mbstowcs( codepage, MB_ERR_INVALID_CHARS, str->str.cstr, str->size, + ret->str.wstr, ret->size ); if (res == -2) parser_error( "Invalid character in string '%.*s' for codepage %u", 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)) { ret->type = str_char; - ret->size = cptable ? wine_cp_wcstombs( cptable, 0, str->str.wstr, str->size, NULL, 0, NULL, NULL ) - : wine_utf8_wcstombs( 0, str->str.wstr, str->size, NULL, 0 ); + ret->size = wrc_wcstombs( codepage, 0, str->str.wstr, str->size, NULL, 0 ); ret->str.cstr = xmalloc( ret->size + 1 ); - if (cptable) - 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 ); + wrc_wcstombs( codepage, 0, str->str.wstr, str->size, ret->str.cstr, ret->size ); ret->str.cstr[ret->size] = 0; } 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 (!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++) { @@ -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 (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: 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; - assert( cp <= 0 || wine_cp_get_table(cp) ); + assert( cp <= 0 || is_valid_codepage(cp) ); return cp; } diff --git a/tools/wrc/utils.h b/tools/wrc/utils.h index f0e8cd6175e..15dfacdd47d 100644 --- a/tools/wrc/utils.h +++ b/tools/wrc/utils.h @@ -51,5 +51,6 @@ void free_string( string_t *str ); 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 get_language_codepage( unsigned short lang, unsigned short sublang ); +int is_valid_codepage(int cp); #endif diff --git a/tools/wrc/wrc.h b/tools/wrc/wrc.h index cf8c793eb41..77e3e6942ea 100644 --- a/tools/wrc/wrc.h +++ b/tools/wrc/wrc.h @@ -21,7 +21,6 @@ #ifndef __WRC_WRC_H #define __WRC_WRC_H -#include "wine/unicode.h" #include "wrctypes.h" /* From wrc.c */ diff --git a/tools/wrc/wrctypes.h b/tools/wrc/wrctypes.h index d71c4acf51d..375455ea973 100644 --- a/tools/wrc/wrctypes.h +++ b/tools/wrc/wrctypes.h @@ -24,10 +24,7 @@ #include #include "windef.h" #include "winbase.h" - -#ifndef MAKELANGID #include "winnls.h" -#endif #ifndef VS_FFI_SIGNATURE #include "winver.h"