Added codepage translation based on the language id (based on a patch
by Junichi Kuchinishi <jkuchi@mahoroba.ne.jp>).
This commit is contained in:
parent
c946b1cccd
commit
1d1f5f3eed
|
@ -3,6 +3,7 @@ TOPSRCDIR = @top_srcdir@
|
|||
TOPOBJDIR = ../..
|
||||
SRCDIR = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
LIBEXT = @LIBEXT@
|
||||
LEXOPT = -Cf #-w -b
|
||||
YACCOPT = #-v
|
||||
|
||||
|
@ -29,8 +30,11 @@ depend: y.tab.h ppy.tab.h
|
|||
|
||||
@MAKE_RULES@
|
||||
|
||||
wrc: $(OBJS)
|
||||
$(CC) $(CFLAGS) -o wrc $(OBJS) $(LEXLIB)
|
||||
wrc: $(OBJS) $(TOPOBJDIR)/libwine_unicode.$(LIBEXT)
|
||||
$(CC) $(CFLAGS) -o wrc $(OBJS) -L$(TOPOBJDIR) -lwine_unicode $(LEXLIB)
|
||||
|
||||
$(TOPOBJDIR)/libwine_unicode.$(LIBEXT):
|
||||
cd $(TOPOBJDIR) && $(MAKE) libwine_unicode.$(LIBEXT)
|
||||
|
||||
y.tab.c y.tab.h: parser.y
|
||||
$(YACC) $(YACCOPT) -d -t $(SRCDIR)/parser.y
|
||||
|
|
|
@ -257,7 +257,7 @@ void string_to_upper(string_t *str)
|
|||
* Remarks :
|
||||
*****************************************************************************
|
||||
*/
|
||||
void put_string(res_t *res, string_t *str, enum str_e type, int isterm)
|
||||
static void put_string(res_t *res, string_t *str, enum str_e type, int isterm)
|
||||
{
|
||||
int cnt;
|
||||
int c = !0;
|
||||
|
@ -269,6 +269,7 @@ void put_string(res_t *res, string_t *str, enum str_e type, int isterm)
|
|||
return;
|
||||
}
|
||||
|
||||
str = convert_string(str, type);
|
||||
if(str->type == str_unicode && type == str_unicode)
|
||||
{
|
||||
for(cnt = 0; cnt < str->size; cnt++)
|
||||
|
@ -317,6 +318,7 @@ void put_string(res_t *res, string_t *str, enum str_e type, int isterm)
|
|||
if(isterm && (str->size == 0 || (cnt == str->size && c)))
|
||||
put_word(res, 0);
|
||||
}
|
||||
free(str);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -375,6 +377,12 @@ void put_lvc(res_t *res, lvc_t *lvc)
|
|||
put_dword(res, *(lvc->characts));
|
||||
else
|
||||
put_dword(res, 0);
|
||||
if(lvc && lvc->language)
|
||||
set_language( lvc->language->id, lvc->language->sub );
|
||||
else if (currentlanguage)
|
||||
set_language( currentlanguage->id, currentlanguage->sub );
|
||||
else
|
||||
set_language( LANG_NEUTRAL, SUBLANG_NEUTRAL );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1418,11 +1426,13 @@ static res_t *stringtable2res(stringtable_t *stt)
|
|||
{
|
||||
if(stt->entries[i].str && stt->entries[i].str->size)
|
||||
{
|
||||
if(win32)
|
||||
put_word(res, stt->entries[i].str->size);
|
||||
string_t *str = convert_string(stt->entries[i].str, win32 ? str_unicode : str_char);
|
||||
if(win32)
|
||||
put_word(res, str->size);
|
||||
else
|
||||
put_byte(res, stt->entries[i].str->size);
|
||||
put_string(res, stt->entries[i].str, win32 ? str_unicode : str_char, FALSE);
|
||||
put_byte(res, str->size);
|
||||
put_string(res, str, win32 ? str_unicode : str_char, FALSE);
|
||||
free(str);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -14,6 +15,7 @@
|
|||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "wrc.h"
|
||||
#include "utils.h"
|
||||
#include "parser.h"
|
||||
|
@ -21,6 +23,7 @@
|
|||
|
||||
/* #define WANT_NEAR_INDICATION */
|
||||
|
||||
static const union cptable *current_codepage;
|
||||
|
||||
#ifdef WANT_NEAR_INDICATION
|
||||
void make_print(char *str)
|
||||
|
@ -208,71 +211,29 @@ char *xstrdup(const char *str)
|
|||
return strcpy(s, str);
|
||||
}
|
||||
|
||||
int string_compare(const string_t *s1, const string_t *s2)
|
||||
{
|
||||
if(s1->type == str_char && s2->type == str_char)
|
||||
{
|
||||
return strcasecmp(s1->str.cstr, s2->str.cstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
internal_error(__FILE__, __LINE__, "Cannot yet compare unicode strings");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wstrlen(const short *s)
|
||||
{
|
||||
int cnt = 0;
|
||||
while(*s++)
|
||||
cnt++;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
short *wstrcpy(short *dst, const short *src)
|
||||
{
|
||||
short *d = dst;
|
||||
while(*src)
|
||||
*d++ = *src++;
|
||||
return dst;
|
||||
}
|
||||
|
||||
int wstricmp(const short *s1, const short *s2)
|
||||
{
|
||||
char *cs1 = dupwstr2cstr(s1);
|
||||
char *cs2 = dupwstr2cstr(s2);
|
||||
int retval = strcasecmp(cs1, cs2);
|
||||
free(cs1);
|
||||
free(cs2);
|
||||
warning("Comparing unicode strings without case -> converting to ascii");
|
||||
return retval;;
|
||||
}
|
||||
|
||||
short *dupcstr2wstr(const char *str)
|
||||
{
|
||||
int len = strlen(str) + 1;
|
||||
short *ws = (short *)xmalloc(len*2);
|
||||
short *wptr;
|
||||
int len;
|
||||
WCHAR *ws;
|
||||
|
||||
wptr = ws;
|
||||
/* FIXME: codepage translation */
|
||||
while(*str)
|
||||
*wptr++ = (short)(*str++ & 0xff);
|
||||
*wptr = 0;
|
||||
if (!current_codepage) set_language( LANG_NEUTRAL, SUBLANG_NEUTRAL );
|
||||
len = cp_mbstowcs( current_codepage, 0, str, strlen(str), NULL, 0 );
|
||||
ws = xmalloc( sizeof(WCHAR) * (len + 1) );
|
||||
len = cp_mbstowcs( current_codepage, 0, str, strlen(str), ws, len );
|
||||
ws[len] = 0;
|
||||
return ws;
|
||||
}
|
||||
|
||||
char *dupwstr2cstr(const short *str)
|
||||
{
|
||||
int len = wstrlen(str) + 1;
|
||||
char *cs = (char *)xmalloc(len);
|
||||
char *cptr;
|
||||
int len;
|
||||
char *cs;
|
||||
|
||||
cptr = cs;
|
||||
/* FIXME: codepage translation */
|
||||
while(*str)
|
||||
*cptr++ = (char)*str++;
|
||||
*cptr = 0;
|
||||
if (!current_codepage) set_language( LANG_NEUTRAL, SUBLANG_NEUTRAL );
|
||||
len = cp_wcstombs( current_codepage, 0, str, strlenW(str), NULL, 0, NULL, NULL );
|
||||
cs = xmalloc( len + 1 );
|
||||
len = cp_wcstombs( current_codepage, 0, str, strlenW(str), cs, len, NULL, NULL );
|
||||
cs[len] = 0;
|
||||
return cs;
|
||||
}
|
||||
|
||||
|
@ -302,7 +263,7 @@ int compare_name_id(name_id_t *n1, name_id_t *n2)
|
|||
else if(n1->name.s_name->type == str_unicode
|
||||
&& n2->name.s_name->type == str_unicode)
|
||||
{
|
||||
return wstricmp(n1->name.s_name->str.wstr, n2->name.s_name->str.wstr);
|
||||
return strcmpiW(n1->name.s_name->str.wstr, n2->name.s_name->str.wstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -320,3 +281,124 @@ int compare_name_id(name_id_t *n1, name_id_t *n2)
|
|||
return 0; /* Keep the compiler happy */
|
||||
}
|
||||
|
||||
string_t *convert_string(const string_t *str, enum str_e type)
|
||||
{
|
||||
string_t *ret = xmalloc(sizeof(*ret));
|
||||
|
||||
if((str->type == str_char) && (type == str_unicode))
|
||||
{
|
||||
ret->str.wstr = dupcstr2wstr(str->str.cstr);
|
||||
ret->type = str_unicode;
|
||||
ret->size = strlenW(ret->str.wstr);
|
||||
}
|
||||
else if((str->type == str_unicode) && (type == str_char))
|
||||
{
|
||||
ret->str.cstr = dupwstr2cstr(str->str.wstr);
|
||||
ret->type = str_char;
|
||||
ret->size = strlen(ret->str.cstr);
|
||||
}
|
||||
else if(str->type == str_unicode)
|
||||
{
|
||||
ret->type = str_unicode;
|
||||
ret->size = strlenW(str->str.wstr);
|
||||
ret->str.wstr = xmalloc(sizeof(WCHAR)*(ret->size+1));
|
||||
strcpyW(ret->str.wstr, str->str.wstr);
|
||||
}
|
||||
else /* str->type == str_char */
|
||||
{
|
||||
ret->type = str_char;
|
||||
ret->size = strlen(str->str.cstr);
|
||||
ret->str.cstr = xmalloc( ret->size + 1 );
|
||||
strcpy(ret->str.cstr, str->str.cstr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
struct lang2cp
|
||||
{
|
||||
unsigned short lang;
|
||||
unsigned short sublang;
|
||||
unsigned int cp;
|
||||
} lang2cp_t;
|
||||
|
||||
/* language to codepage conversion table */
|
||||
/* specific sublanguages need only be specified if their codepage */
|
||||
/* differs from the default (SUBLANG_NEUTRAL) */
|
||||
static const struct lang2cp lang2cps[] =
|
||||
{
|
||||
/* default code page (LANG_NEUTRAL) must be first entry */
|
||||
{ LANG_NEUTRAL, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_AFRIKAANS, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_ALBANIAN, SUBLANG_NEUTRAL, 1250 },
|
||||
{ LANG_BASQUE, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_BRETON, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_BULGARIAN, SUBLANG_NEUTRAL, 1251 },
|
||||
{ LANG_BYELORUSSIAN, SUBLANG_NEUTRAL, 1251 },
|
||||
{ LANG_CATALAN, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_CORNISH, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_CZECH, SUBLANG_NEUTRAL, 1250 },
|
||||
{ LANG_DANISH, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_DUTCH, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_ENGLISH, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_ESPERANTO, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_ESTONIAN, SUBLANG_NEUTRAL, 1257 },
|
||||
{ LANG_FINNISH, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_FRENCH, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_GAELIC, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_GERMAN, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_GREEK, SUBLANG_NEUTRAL, 1253 },
|
||||
{ LANG_HUNGARIAN, SUBLANG_NEUTRAL, 1250 },
|
||||
{ LANG_ICELANDIC, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_INDONESIAN, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_ITALIAN, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_JAPANESE, SUBLANG_NEUTRAL, 932 },
|
||||
{ LANG_KOREAN, SUBLANG_NEUTRAL, 949 },
|
||||
{ LANG_LATVIAN, SUBLANG_NEUTRAL, 1257 },
|
||||
{ LANG_LITHUANIAN, SUBLANG_NEUTRAL, 1257 },
|
||||
{ LANG_MACEDONIAN, SUBLANG_NEUTRAL, 1251 },
|
||||
{ LANG_NORWEGIAN, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_POLISH, SUBLANG_NEUTRAL, 1250 },
|
||||
{ LANG_PORTUGUESE, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_ROMANIAN, SUBLANG_NEUTRAL, 1250 },
|
||||
{ LANG_RUSSIAN, SUBLANG_NEUTRAL, 1251 },
|
||||
{ LANG_SERBO_CROATIAN, SUBLANG_NEUTRAL, 1250 },
|
||||
{ LANG_SERBO_CROATIAN, SUBLANG_SERBIAN_LATIN, 1251 },
|
||||
{ LANG_SLOVAK, SUBLANG_NEUTRAL, 1250 },
|
||||
{ LANG_SLOVENIAN, SUBLANG_NEUTRAL, 1250 },
|
||||
{ LANG_SPANISH, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_SWEDISH, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_THAI, SUBLANG_NEUTRAL, 874 },
|
||||
{ LANG_TURKISH, SUBLANG_NEUTRAL, 1254 },
|
||||
{ LANG_UKRAINIAN, SUBLANG_NEUTRAL, 1251 },
|
||||
{ LANG_WALON, SUBLANG_NEUTRAL, 1252 },
|
||||
{ LANG_WELSH, SUBLANG_NEUTRAL, 1252 }
|
||||
};
|
||||
|
||||
void set_language( unsigned short lang, unsigned short sublang )
|
||||
{
|
||||
int i;
|
||||
unsigned int cp = 0, defcp = 0;
|
||||
|
||||
for (i = 0; i < sizeof(lang2cps)/sizeof(lang2cps[0]); i++)
|
||||
{
|
||||
if (lang2cps[i].lang != lang) continue;
|
||||
if (lang2cps[i].sublang == sublang)
|
||||
{
|
||||
cp = lang2cps[i].cp;
|
||||
break;
|
||||
}
|
||||
if (lang2cps[i].sublang == SUBLANG_NEUTRAL) defcp = lang2cps[i].cp;
|
||||
}
|
||||
|
||||
if (!cp) cp = defcp;
|
||||
if (!cp) error( "No codepage value for language %04x", MAKELANGID(lang,sublang) );
|
||||
else
|
||||
{
|
||||
if ((current_codepage = cp_get_table( cp ))) return;
|
||||
error( "Bad codepage %d for language %04x", cp, MAKELANGID(lang,sublang) );
|
||||
}
|
||||
/* now find a default code page */
|
||||
current_codepage = cp_get_table( lang2cps[0].cp );
|
||||
assert( current_codepage );
|
||||
}
|
||||
|
|
|
@ -28,12 +28,10 @@ void warning(const char *s, ...) __attribute__((format (printf, 1, 2)));
|
|||
void chat(const char *s, ...) __attribute__((format (printf, 1, 2)));
|
||||
|
||||
char *dup_basename(const char *name, const char *ext);
|
||||
int string_compare(const string_t *s1, const string_t *s2);
|
||||
int wstrlen(const short *s);
|
||||
short *wstrcpy(short *dst, const short *src);
|
||||
int wstricmp(const short *s1, const short *s2);
|
||||
char *dupwstr2cstr(const short *str);
|
||||
short *dupcstr2wstr(const char *str);
|
||||
int compare_name_id(name_id_t *n1, name_id_t *n2);
|
||||
string_t *convert_string(const string_t *str, enum str_e type);
|
||||
void set_language(unsigned short lang, unsigned short sublang);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "wine/unicode.h"
|
||||
#include "wrc.h"
|
||||
#include "writeres.h"
|
||||
#include "genres.h"
|
||||
|
@ -261,7 +262,7 @@ static void write_name_str(FILE *fp, name_id_t *nid)
|
|||
}
|
||||
else if(win32 && nid->name.s_name->type == str_unicode)
|
||||
{
|
||||
res.size = wstrlen(nid->name.s_name->str.wstr);
|
||||
res.size = strlenW(nid->name.s_name->str.wstr);
|
||||
if(res.size > 65534)
|
||||
error("Can't write strings larger than 65534 bytes");
|
||||
if(res.size == 0)
|
||||
|
@ -269,7 +270,7 @@ static void write_name_str(FILE *fp, name_id_t *nid)
|
|||
res.dataidx = 0;
|
||||
res.data = (char *)xmalloc((res.size + 1) * 2);
|
||||
((short *)res.data)[0] = (short)res.size;
|
||||
wstrcpy((short *)(res.data+2), nid->name.s_name->str.wstr);
|
||||
strcpyW((WCHAR *)(res.data+2), nid->name.s_name->str.wstr);
|
||||
res.size *= 2; /* Function writes bytes, not shorts... */
|
||||
res.size += 2; /* We need to write the length word as well */
|
||||
write_s_res(fp, &res);
|
||||
|
|
Loading…
Reference in New Issue