diff --git a/tools/wrc/genres.c b/tools/wrc/genres.c index 4e8552fa37d..0950b3e9c3c 100644 --- a/tools/wrc/genres.c +++ b/tools/wrc/genres.c @@ -363,33 +363,21 @@ static int parse_accel_string( const string_t *key, int flags ) static void put_string(res_t *res, const string_t *str, int isterm, const language_t *lang) { int cnt, codepage; - string_t *newstr; - - assert(res != NULL); - assert(str != NULL); - - if (lang) codepage = get_language_codepage( lang->id, lang->sub ); - else codepage = get_language_codepage( 0, 0 ); - - assert( codepage != -1 ); if (win32) { - newstr = convert_string(str, str_unicode, codepage); - if (str->type == str_char) + string_t *newstr; + + if (lang) codepage = get_language_codepage( lang->id, lang->sub ); + else codepage = get_language_codepage( 0, 0 ); + assert( codepage != -1 ); + + newstr = convert_string_unicode( str, codepage ); + if (str->type == str_char && check_valid_utf8( str, codepage )) { - if (!check_unicode_conversion( str, newstr, codepage )) - { - print_location( &str->loc ); - error( "String %s does not convert identically to Unicode and back in codepage %d. " - "Try using a Unicode string instead\n", str->str.cstr, codepage ); - } - if (check_valid_utf8( str, codepage )) - { - print_location( &str->loc ); - warning( "string \"%s\" seems to be UTF-8 but codepage %u is in use.\n", - str->str.cstr, codepage ); - } + print_location( &str->loc ); + warning( "string \"%s\" seems to be UTF-8 but codepage %u is in use, maybe use --utf8?\n", + str->str.cstr, codepage ); } if (!isterm) put_word(res, newstr->size); for(cnt = 0; cnt < newstr->size; cnt++) @@ -399,20 +387,22 @@ static void put_string(res_t *res, const string_t *str, int isterm, const langua put_word(res, c); } if (isterm) put_word(res, 0); + free_string(newstr); } else { - newstr = convert_string(str, str_char, codepage); - if (!isterm) put_byte(res, newstr->size); - for(cnt = 0; cnt < newstr->size; cnt++) + if (str->type == str_unicode) + internal_error(__FILE__, __LINE__, "Unicode string %s in 16-bit\n", + convert_string_utf8( str, 0 )); + if (!isterm) put_byte(res, str->size); + for(cnt = 0; cnt < str->size; cnt++) { - char c = newstr->str.cstr[cnt]; + char c = str->str.cstr[cnt]; if (isterm && !c) break; put_byte(res, c); } if (isterm) put_byte(res, 0); } - free_string(newstr); } /* @@ -1458,21 +1448,15 @@ static void versionblock2res(res_t *res, ver_block_t *blk, int level, const lang */ static res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver) { - int restag; - int rootblocksizetag; - int valsizetag; - int tag; + static const char info[] = "VS_VERSION_INFO"; + unsigned int i; + int restag, rootblocksizetag, valsizetag, tag; res_t *res; - string_t vsvi; ver_block_t *blk; assert(name != NULL); assert(ver != NULL); - vsvi.type = str_char; - vsvi.str.cstr = xstrdup("VS_VERSION_INFO"); - vsvi.size = 15; /* Excl. termination */ - res = new_res(); restag = put_res_header(res, WRC_RT_VERSION, NULL, name, ver->memopt, &(ver->lvc)); rootblocksizetag = res->size; @@ -1480,10 +1464,15 @@ static res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver) valsizetag = res->size; put_word(res, 0); /* ValueSize filled in later*/ if(win32) + { put_word(res, 0); /* Tree-level ? */ - put_string(res, &vsvi, TRUE, NULL); - if(win32) + for (i = 0; i < sizeof(info); i++) put_word(res, info[i]); put_pad(res); + } + else + { + for (i = 0; i < sizeof(info); i++) put_byte(res, info[i]); + } tag = res->size; put_dword(res, VS_FFI_SIGNATURE); put_dword(res, VS_FFI_STRUCVERSION); @@ -1505,8 +1494,6 @@ static res_t *versioninfo2res(name_id_t *name, versioninfo_t *ver) versionblock2res(res, blk, 0, win32 ? ver->lvc.language : NULL); /* Set root block's size */ set_word(res, rootblocksizetag, (WORD)(res->size - rootblocksizetag)); - - free(vsvi.str.cstr); return end_res(res, restag); } diff --git a/tools/wrc/parser.l b/tools/wrc/parser.l index d1e768f72c7..3ee7eb4a96a 100644 --- a/tools/wrc/parser.l +++ b/tools/wrc/parser.l @@ -429,7 +429,7 @@ L\" { yy_push_state(tklstr); wbufidx = 0; if(!win32) - parser_warning("16bit resource contains unicode strings\n"); + parser_error("16bit resource contains unicode strings\n"); } \"{ws}+ | \" { @@ -635,12 +635,9 @@ static string_t *get_buffered_cstring(void) } else /* convert to Unicode before storing */ { - string_t *str_w = convert_string( str, str_unicode, current_codepage ); - if (!check_unicode_conversion( str, str_w, current_codepage )) - parser_error("String %s does not convert identically to Unicode and back in codepage %d. " - "Try using a Unicode string instead", str->str.cstr, current_codepage ); + string_t *str_w = convert_string_unicode( str, current_codepage ); if (check_valid_utf8( str, current_codepage )) - parser_warning( "string \"%s\" seems to be UTF-8 but codepage %u is in use.\n", + parser_warning( "string \"%s\" seems to be UTF-8 but codepage %u is in use, maybe use --utf8?\n", str->str.cstr, current_codepage ); free_string( str ); return str_w; @@ -660,10 +657,13 @@ static string_t *get_buffered_wstring(void) static string_t *make_string(char *s) { - string_t *str = new_string(); + string_t *ret, *str = new_string(); str->size = strlen(s); str->type = str_char; str->str.cstr = xmalloc(str->size+1); memcpy(str->str.cstr, s, str->size+1); - return str; + if (current_codepage <= 0 || !win32) return str; + ret = convert_string_unicode( str, current_codepage ); + free_string( str ); + return ret; } diff --git a/tools/wrc/po.c b/tools/wrc/po.c index 726bed393f5..622d2f7a3ad 100644 --- a/tools/wrc/po.c +++ b/tools/wrc/po.c @@ -97,32 +97,30 @@ static name_id_t *dup_name_id( name_id_t *id ) if (!id || id->type != name_str) return id; new = new_name_id(); *new = *id; - new->name.s_name = convert_string( id->name.s_name, str_unicode, 1252 ); + new->name.s_name = convert_string_unicode( id->name.s_name, 1252 ); return new; } static char *convert_msgid_ascii( const string_t *str, int error_on_invalid_char ) { int i; - string_t *newstr = convert_string( str, str_unicode, 1252 ); - char *buffer = xmalloc( newstr->size + 1 ); + char *buffer = xmalloc( str->size + 1 ); - for (i = 0; i < newstr->size; i++) + for (i = 0; i < str->size; i++) { - buffer[i] = newstr->str.wstr[i]; - if (newstr->str.wstr[i] >= 32 && newstr->str.wstr[i] <= 127) continue; - if (newstr->str.wstr[i] == '\t' || newstr->str.wstr[i] == '\n') continue; + WCHAR ch = (str->type == str_unicode ? str->str.wstr[i] : (unsigned char)str->str.cstr[i]); + buffer[i] = ch; + if (ch >= 32 && ch <= 127) continue; + if (ch == '\t' || ch == '\n') continue; if (error_on_invalid_char) { - print_location( &newstr->loc ); - error( "Invalid character %04x in source string\n", newstr->str.wstr[i] ); + print_location( &str->loc ); + error( "Invalid character %04x in source string\n", ch ); } free( buffer); - free_string( newstr ); return NULL; } buffer[i] = 0; - free_string( newstr ); return buffer; } @@ -1205,7 +1203,7 @@ static string_t *translate_string( string_t *str, int *found ) char *buffer, *msgid, *context; if (!str->size || !(buffer = convert_msgid_ascii( str, 0 ))) - return convert_string( str, str_unicode, 1252 ); + return convert_string_unicode( str, 1252 ); msgid = buffer; context = get_message_context( &msgid ); @@ -1216,7 +1214,7 @@ static string_t *translate_string( string_t *str, int *found ) ustr.str.cstr = (char *)transl; ustr.loc = str->loc; - new = convert_string( &ustr, str_unicode, CP_UTF8 ); + new = convert_string_unicode( &ustr, CP_UTF8 ); free( buffer ); return new; } @@ -1310,7 +1308,7 @@ static void translate_dialog( dialog_t *dlg, dialog_t *new, int *found ) new->font = xmalloc( sizeof(*dlg->font) ); *new->font = *dlg->font; if (uses_larger_font( new->lvc.language )) new->font->size++; - new->font->name = convert_string( dlg->font->name, str_unicode, 1252 ); + new->font->name = convert_string_unicode( dlg->font->name, 1252 ); } new->controls = translate_controls( dlg->controls, found ); } @@ -1383,12 +1381,12 @@ static ver_value_t *translate_stringfileinfo( ver_value_t *val, language_t *lang { if (!strcasecmp( name, english_block_name[i] )) { - string_t *str; - str = new_string(); - str->type = str_char; - str->size = strlen( block_name[i] ) + 1; - str->str.cstr = xstrdup( block_name[i] ); - new_blk->name = str; + string_t str; + str.type = str_char; + str.size = strlen( block_name[i] ) + 1; + str.str.cstr = block_name[i]; + str.loc = blk->name->loc; + new_blk->name = convert_string_unicode( &str, CP_UTF8 ); new_blk->values = translate_langcharset_values( blk->values, lang, found ); } } diff --git a/tools/wrc/utils.c b/tools/wrc/utils.c index 6ec1fe7b66e..9780beb613f 100644 --- a/tools/wrc/utils.c +++ b/tools/wrc/utils.c @@ -301,11 +301,6 @@ static int wrc_mbstowcs( int codepage, int flags, const char *src, int srclen, W return MultiByteToWideChar( codepage, flags, src, srclen, dst, dstlen ); } -static 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" @@ -320,11 +315,6 @@ static int wrc_mbstowcs( int codepage, int flags, const char *src, int srclen, W return wine_cp_mbstowcs( wine_cp_get_table( codepage ), flags, src, srclen, dst, dstlen ); } -static int wrc_wcstombs( int codepage, int flags, const WCHAR *src, int srclen, char *dst, int dstlen ) -{ - return wine_cp_wcstombs( wine_cp_get_table( codepage ), flags, src, srclen, dst, dstlen, NULL, NULL ); -} - #endif /* _WIN32 */ static WCHAR *utf8_to_unicode( const char *src, int srclen, int *dstlen ) @@ -448,19 +438,18 @@ static char *unicode_to_utf8( const WCHAR *src, int srclen, int *dstlen ) return ret; } -string_t *convert_string(const string_t *str, enum str_e type, int codepage) +string_t *convert_string_unicode( const string_t *str, int codepage ) { string_t *ret = xmalloc(sizeof(*ret)); int res; - ret->type = type; + ret->type = str_unicode; ret->loc = str->loc; - if (!codepage && str->type != type) - parser_error( "Current language is Unicode only, cannot convert string" ); - - if((str->type == str_char) && (type == str_unicode)) + if (str->type == str_char) { + if (!codepage) parser_error( "Current language is Unicode only, cannot convert string" ); + if (codepage == CP_UTF8) ret->str.wstr = utf8_to_unicode( str->str.cstr, str->size, &ret->size ); else @@ -475,38 +464,20 @@ string_t *convert_string(const string_t *str, enum str_e type, int codepage) ret->str.wstr[ret->size] = 0; } } - else if((str->type == str_unicode) && (type == str_char)) - { - if (codepage == CP_UTF8) - ret->str.cstr = unicode_to_utf8( str->str.wstr, str->size, &ret->size ); - else - { - ret->str.cstr = xmalloc( str->size * 2 + 1 ); - ret->size = wrc_wcstombs( codepage, 0, str->str.wstr, str->size, ret->str.cstr, str->size * 2 ); - ret->str.cstr[ret->size] = 0; - } - } - else if(str->type == str_unicode) + else { ret->size = str->size; ret->str.wstr = xmalloc(sizeof(WCHAR)*(ret->size+1)); memcpy( ret->str.wstr, str->str.wstr, ret->size * sizeof(WCHAR) ); ret->str.wstr[ret->size] = 0; } - else /* str->type == str_char */ - { - ret->size = str->size; - ret->str.cstr = xmalloc( ret->size + 1 ); - memcpy( ret->str.cstr, str->str.cstr, ret->size ); - ret->str.cstr[ret->size] = 0; - } return ret; } char *convert_string_utf8( const string_t *str, int codepage ) { int len; - string_t *wstr = convert_string( str, str_unicode, codepage ); + string_t *wstr = convert_string_unicode( str, codepage ); char *ret = unicode_to_utf8( wstr->str.wstr, wstr->size, &len ); free_string( wstr ); return ret; @@ -548,32 +519,6 @@ done: return 0; } -int check_unicode_conversion( const string_t *str_a, const string_t *str_w, int codepage ) -{ - int ok; - string_t *teststr = convert_string( str_w, str_char, codepage ); - - ok = (teststr->size == str_a->size && !memcmp( teststr->str.cstr, str_a->str.cstr, str_a->size )); - - if (!ok) - { - int i; - - fprintf( stderr, "Source: %s", str_a->str.cstr ); - for (i = 0; i < str_a->size; i++) - fprintf( stderr, " %02x", (unsigned char)str_a->str.cstr[i] ); - fprintf( stderr, "\nUnicode: " ); - for (i = 0; i < str_w->size; i++) - fprintf( stderr, " %04x", str_w->str.wstr[i] ); - fprintf( stderr, "\nBack: %s", teststr->str.cstr ); - for (i = 0; i < teststr->size; i++) - fprintf( stderr, " %02x", (unsigned char)teststr->str.cstr[i] ); - fprintf( stderr, "\n" ); - } - free_string( teststr ); - return ok; -} - struct lang2cp { diff --git a/tools/wrc/utils.h b/tools/wrc/utils.h index f5d3385c558..aed10b5dea0 100644 --- a/tools/wrc/utils.h +++ b/tools/wrc/utils.h @@ -46,11 +46,10 @@ void chat(const char *s, ...) __attribute__((format (printf, 1, 2))); char *dup_basename(const char *name, const char *ext); int compare_name_id(const name_id_t *n1, const name_id_t *n2); -string_t *convert_string(const string_t *str, enum str_e type, int codepage); +string_t *convert_string_unicode( const string_t *str, int codepage ); char *convert_string_utf8( const string_t *str, int codepage ); 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);