Commit 1d1f5f3e authored by Alexandre Julliard's avatar Alexandre Julliard

Added codepage translation based on the language id (based on a patch

by Junichi Kuchinishi <jkuchi@mahoroba.ne.jp>).
parent c946b1cc
...@@ -3,6 +3,7 @@ TOPSRCDIR = @top_srcdir@ ...@@ -3,6 +3,7 @@ TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../.. TOPOBJDIR = ../..
SRCDIR = @srcdir@ SRCDIR = @srcdir@
VPATH = @srcdir@ VPATH = @srcdir@
LIBEXT = @LIBEXT@
LEXOPT = -Cf #-w -b LEXOPT = -Cf #-w -b
YACCOPT = #-v YACCOPT = #-v
...@@ -29,8 +30,11 @@ depend: y.tab.h ppy.tab.h ...@@ -29,8 +30,11 @@ depend: y.tab.h ppy.tab.h
@MAKE_RULES@ @MAKE_RULES@
wrc: $(OBJS) wrc: $(OBJS) $(TOPOBJDIR)/libwine_unicode.$(LIBEXT)
$(CC) $(CFLAGS) -o wrc $(OBJS) $(LEXLIB) $(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 y.tab.c y.tab.h: parser.y
$(YACC) $(YACCOPT) -d -t $(SRCDIR)/parser.y $(YACC) $(YACCOPT) -d -t $(SRCDIR)/parser.y
......
...@@ -257,7 +257,7 @@ void string_to_upper(string_t *str) ...@@ -257,7 +257,7 @@ void string_to_upper(string_t *str)
* Remarks : * 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 cnt;
int c = !0; int c = !0;
...@@ -269,6 +269,7 @@ void put_string(res_t *res, string_t *str, enum str_e type, int isterm) ...@@ -269,6 +269,7 @@ void put_string(res_t *res, string_t *str, enum str_e type, int isterm)
return; return;
} }
str = convert_string(str, type);
if(str->type == str_unicode && type == str_unicode) if(str->type == str_unicode && type == str_unicode)
{ {
for(cnt = 0; cnt < str->size; cnt++) 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) ...@@ -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))) if(isterm && (str->size == 0 || (cnt == str->size && c)))
put_word(res, 0); put_word(res, 0);
} }
free(str);
} }
/* /*
...@@ -375,6 +377,12 @@ void put_lvc(res_t *res, lvc_t *lvc) ...@@ -375,6 +377,12 @@ void put_lvc(res_t *res, lvc_t *lvc)
put_dword(res, *(lvc->characts)); put_dword(res, *(lvc->characts));
else else
put_dword(res, 0); 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) ...@@ -1418,11 +1426,13 @@ static res_t *stringtable2res(stringtable_t *stt)
{ {
if(stt->entries[i].str && stt->entries[i].str->size) if(stt->entries[i].str && stt->entries[i].str->size)
{ {
string_t *str = convert_string(stt->entries[i].str, win32 ? str_unicode : str_char);
if(win32) if(win32)
put_word(res, stt->entries[i].str->size); put_word(res, str->size);
else else
put_byte(res, stt->entries[i].str->size); put_byte(res, str->size);
put_string(res, stt->entries[i].str, win32 ? str_unicode : str_char, FALSE); put_string(res, str, win32 ? str_unicode : str_char, FALSE);
free(str);
} }
else else
{ {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "config.h" #include "config.h"
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
...@@ -14,6 +15,7 @@ ...@@ -14,6 +15,7 @@
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include "wine/unicode.h"
#include "wrc.h" #include "wrc.h"
#include "utils.h" #include "utils.h"
#include "parser.h" #include "parser.h"
...@@ -21,6 +23,7 @@ ...@@ -21,6 +23,7 @@
/* #define WANT_NEAR_INDICATION */ /* #define WANT_NEAR_INDICATION */
static const union cptable *current_codepage;
#ifdef WANT_NEAR_INDICATION #ifdef WANT_NEAR_INDICATION
void make_print(char *str) void make_print(char *str)
...@@ -208,71 +211,29 @@ char *xstrdup(const char *str) ...@@ -208,71 +211,29 @@ char *xstrdup(const char *str)
return strcpy(s, 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) short *dupcstr2wstr(const char *str)
{ {
int len = strlen(str) + 1; int len;
short *ws = (short *)xmalloc(len*2); WCHAR *ws;
short *wptr;
if (!current_codepage) set_language( LANG_NEUTRAL, SUBLANG_NEUTRAL );
wptr = ws; len = cp_mbstowcs( current_codepage, 0, str, strlen(str), NULL, 0 );
/* FIXME: codepage translation */ ws = xmalloc( sizeof(WCHAR) * (len + 1) );
while(*str) len = cp_mbstowcs( current_codepage, 0, str, strlen(str), ws, len );
*wptr++ = (short)(*str++ & 0xff); ws[len] = 0;
*wptr = 0;
return ws; return ws;
} }
char *dupwstr2cstr(const short *str) char *dupwstr2cstr(const short *str)
{ {
int len = wstrlen(str) + 1; int len;
char *cs = (char *)xmalloc(len); char *cs;
char *cptr;
if (!current_codepage) set_language( LANG_NEUTRAL, SUBLANG_NEUTRAL );
cptr = cs; len = cp_wcstombs( current_codepage, 0, str, strlenW(str), NULL, 0, NULL, NULL );
/* FIXME: codepage translation */ cs = xmalloc( len + 1 );
while(*str) len = cp_wcstombs( current_codepage, 0, str, strlenW(str), cs, len, NULL, NULL );
*cptr++ = (char)*str++; cs[len] = 0;
*cptr = 0;
return cs; return cs;
} }
...@@ -302,7 +263,7 @@ int compare_name_id(name_id_t *n1, name_id_t *n2) ...@@ -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 else if(n1->name.s_name->type == str_unicode
&& n2->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 else
{ {
...@@ -320,3 +281,124 @@ int compare_name_id(name_id_t *n1, name_id_t *n2) ...@@ -320,3 +281,124 @@ int compare_name_id(name_id_t *n1, name_id_t *n2)
return 0; /* Keep the compiler happy */ 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))); ...@@ -28,12 +28,10 @@ void warning(const char *s, ...) __attribute__((format (printf, 1, 2)));
void chat(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); 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); char *dupwstr2cstr(const short *str);
short *dupcstr2wstr(const char *str); short *dupcstr2wstr(const char *str);
int compare_name_id(name_id_t *n1, name_id_t *n2); 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 #endif
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include "wine/unicode.h"
#include "wrc.h" #include "wrc.h"
#include "writeres.h" #include "writeres.h"
#include "genres.h" #include "genres.h"
...@@ -261,7 +262,7 @@ static void write_name_str(FILE *fp, name_id_t *nid) ...@@ -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) 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) if(res.size > 65534)
error("Can't write strings larger than 65534 bytes"); error("Can't write strings larger than 65534 bytes");
if(res.size == 0) if(res.size == 0)
...@@ -269,7 +270,7 @@ static void write_name_str(FILE *fp, name_id_t *nid) ...@@ -269,7 +270,7 @@ static void write_name_str(FILE *fp, name_id_t *nid)
res.dataidx = 0; res.dataidx = 0;
res.data = (char *)xmalloc((res.size + 1) * 2); res.data = (char *)xmalloc((res.size + 1) * 2);
((short *)res.data)[0] = (short)res.size; ((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; /* Function writes bytes, not shorts... */
res.size += 2; /* We need to write the length word as well */ res.size += 2; /* We need to write the length word as well */
write_s_res(fp, &res); write_s_res(fp, &res);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment