msvcrt: Fixed codepage setting code in create_locale.
This commit is contained in:
parent
b71af96b9c
commit
7afc98a7f7
@ -211,7 +211,7 @@ find_best_locale_proc(HMODULE hModule, LPCSTR type, LPCSTR name, WORD LangID, LO
|
|||||||
extern int atoi(const char *);
|
extern int atoi(const char *);
|
||||||
|
|
||||||
/* Internal: Find the LCID for a locale specification */
|
/* Internal: Find the LCID for a locale specification */
|
||||||
LCID MSVCRT_locale_to_LCID(const char *locale)
|
LCID MSVCRT_locale_to_LCID(const char *locale, unsigned short *codepage)
|
||||||
{
|
{
|
||||||
LCID lcid;
|
LCID lcid;
|
||||||
locale_search_t search;
|
locale_search_t search;
|
||||||
@ -256,7 +256,7 @@ LCID MSVCRT_locale_to_LCID(const char *locale)
|
|||||||
lcid = MAKELCID(search.found_lang_id, SORT_DEFAULT);
|
lcid = MAKELCID(search.found_lang_id, SORT_DEFAULT);
|
||||||
|
|
||||||
/* Populate partial locale, translating LCID to locale string elements */
|
/* Populate partial locale, translating LCID to locale string elements */
|
||||||
if (!search.found_codepage[0]) {
|
if (!(search.match_flags & FOUND_CODEPAGE)) {
|
||||||
/* Even if a codepage is not enumerated for a locale
|
/* Even if a codepage is not enumerated for a locale
|
||||||
* it can be set if valid */
|
* it can be set if valid */
|
||||||
if (search.search_codepage[0]) {
|
if (search.search_codepage[0]) {
|
||||||
@ -264,10 +264,10 @@ LCID MSVCRT_locale_to_LCID(const char *locale)
|
|||||||
memcpy(search.found_codepage,search.search_codepage,MAX_ELEM_LEN);
|
memcpy(search.found_codepage,search.search_codepage,MAX_ELEM_LEN);
|
||||||
else {
|
else {
|
||||||
/* Special codepage values: OEM & ANSI */
|
/* Special codepage values: OEM & ANSI */
|
||||||
if (strcasecmp(search.search_codepage,"OCP")) {
|
if (!strcasecmp(search.search_codepage,"OCP")) {
|
||||||
GetLocaleInfoA(lcid, LOCALE_IDEFAULTCODEPAGE,
|
GetLocaleInfoA(lcid, LOCALE_IDEFAULTCODEPAGE,
|
||||||
search.found_codepage, MAX_ELEM_LEN);
|
search.found_codepage, MAX_ELEM_LEN);
|
||||||
} else if (strcasecmp(search.search_codepage,"ACP")) {
|
} else if (!strcasecmp(search.search_codepage,"ACP")) {
|
||||||
GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE,
|
GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE,
|
||||||
search.found_codepage, MAX_ELEM_LEN);
|
search.found_codepage, MAX_ELEM_LEN);
|
||||||
} else
|
} else
|
||||||
@ -285,12 +285,15 @@ LCID MSVCRT_locale_to_LCID(const char *locale)
|
|||||||
search.found_codepage, MAX_ELEM_LEN);
|
search.found_codepage, MAX_ELEM_LEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (codepage)
|
||||||
|
*codepage = atoi(search.found_codepage);
|
||||||
|
|
||||||
return lcid;
|
return lcid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* INTERNAL: Set lc_handle, lc_id and lc_category in threadlocinfo struct */
|
/* INTERNAL: Set lc_handle, lc_id and lc_category in threadlocinfo struct */
|
||||||
static BOOL update_threadlocinfo_category(LCID lcid, MSVCRT__locale_t loc, int category)
|
static BOOL update_threadlocinfo_category(LCID lcid, unsigned short cp,
|
||||||
|
MSVCRT__locale_t loc, int category)
|
||||||
{
|
{
|
||||||
char buf[256], *p;
|
char buf[256], *p;
|
||||||
int len;
|
int len;
|
||||||
@ -314,9 +317,7 @@ static BOOL update_threadlocinfo_category(LCID lcid, MSVCRT__locale_t loc, int c
|
|||||||
loc->locinfo->lc_id[category].wLanguage;
|
loc->locinfo->lc_id[category].wLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE
|
loc->locinfo->lc_id[category].wCodePage = cp;
|
||||||
|LOCALE_NOUSEROVERRIDE, buf, 256))
|
|
||||||
loc->locinfo->lc_id[category].wCodePage = atoi(buf);
|
|
||||||
|
|
||||||
loc->locinfo->lc_handle[category] = lcid;
|
loc->locinfo->lc_handle[category] = lcid;
|
||||||
|
|
||||||
@ -327,8 +328,8 @@ static BOOL update_threadlocinfo_category(LCID lcid, MSVCRT__locale_t loc, int c
|
|||||||
len += GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY
|
len += GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY
|
||||||
|LOCALE_NOUSEROVERRIDE, &buf[len], 256-len);
|
|LOCALE_NOUSEROVERRIDE, &buf[len], 256-len);
|
||||||
buf[len-1] = '.';
|
buf[len-1] = '.';
|
||||||
len += GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE
|
sprintf(buf+len, "%d", cp);
|
||||||
|LOCALE_NOUSEROVERRIDE, &buf[len], 256-len);
|
len += strlen(buf+len)+1;
|
||||||
|
|
||||||
loc->locinfo->lc_category[category].locale = MSVCRT_malloc(len);
|
loc->locinfo->lc_category[category].locale = MSVCRT_malloc(len);
|
||||||
loc->locinfo->lc_category[category].refcount = MSVCRT_malloc(sizeof(int));
|
loc->locinfo->lc_category[category].refcount = MSVCRT_malloc(sizeof(int));
|
||||||
@ -757,6 +758,7 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
|||||||
|
|
||||||
MSVCRT__locale_t loc;
|
MSVCRT__locale_t loc;
|
||||||
LCID lcid[6] = { 0 }, lcid_tmp;
|
LCID lcid[6] = { 0 }, lcid_tmp;
|
||||||
|
unsigned short cp[6] = { 0 };
|
||||||
char buf[256];
|
char buf[256];
|
||||||
int i, ret, size;
|
int i, ret, size;
|
||||||
|
|
||||||
@ -765,11 +767,20 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
|||||||
if(category<MSVCRT_LC_MIN || category>MSVCRT_LC_MAX || !locale)
|
if(category<MSVCRT_LC_MIN || category>MSVCRT_LC_MAX || !locale)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(locale[0]=='C' && !locale[1])
|
if(locale[0]=='C' && !locale[1]) {
|
||||||
lcid[0] = CP_ACP;
|
lcid[0] = 0;
|
||||||
else if(!locale[0])
|
cp[0] = CP_ACP;
|
||||||
|
} else if(!locale[0]) {
|
||||||
lcid[0] = GetSystemDefaultLCID();
|
lcid[0] = GetSystemDefaultLCID();
|
||||||
else if (locale[0] == 'L' && locale[1] == 'C' && locale[2] == '_') {
|
GetLocaleInfoA(lcid[0], LOCALE_IDEFAULTANSICODEPAGE
|
||||||
|
|LOCALE_NOUSEROVERRIDE, buf, sizeof(buf));
|
||||||
|
cp[0] = atoi(buf);
|
||||||
|
|
||||||
|
for(i=1; i<6; i++) {
|
||||||
|
lcid[i] = lcid[0];
|
||||||
|
cp[i] = cp[0];
|
||||||
|
}
|
||||||
|
} else if (locale[0] == 'L' && locale[1] == 'C' && locale[2] == '_') {
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
@ -793,14 +804,15 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
p = strchr(locale, ';');
|
p = strchr(locale, ';');
|
||||||
if(locale[0]=='C' && (locale[1]==';' || locale[1]=='\0'))
|
if(locale[0]=='C' && (locale[1]==';' || locale[1]=='\0')) {
|
||||||
lcid[i] = 0;
|
lcid[i] = 0;
|
||||||
else if(p) {
|
cp[i] = CP_ACP;
|
||||||
|
} else if(p) {
|
||||||
memcpy(buf, locale, p-locale);
|
memcpy(buf, locale, p-locale);
|
||||||
buf[p-locale] = '\0';
|
buf[p-locale] = '\0';
|
||||||
lcid[i] = MSVCRT_locale_to_LCID(buf);
|
lcid[i] = MSVCRT_locale_to_LCID(buf, &cp[i]);
|
||||||
} else
|
} else
|
||||||
lcid[i] = MSVCRT_locale_to_LCID(locale);
|
lcid[i] = MSVCRT_locale_to_LCID(locale, &cp[i]);
|
||||||
|
|
||||||
if(lcid[i] == -1)
|
if(lcid[i] == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -811,14 +823,14 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
|||||||
locale = p+1;
|
locale = p+1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lcid[0] = MSVCRT_locale_to_LCID(locale);
|
lcid[0] = MSVCRT_locale_to_LCID(locale, &cp[0]);
|
||||||
if(lcid[0] == -1)
|
if(lcid[0] == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
for(i=1; i<6; i++) {
|
for(i=1; i<6; i++) {
|
||||||
if(!lcid[i])
|
|
||||||
lcid[i] = lcid[0];
|
lcid[i] = lcid[0];
|
||||||
|
cp[i] = cp[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loc = MSVCRT_malloc(sizeof(MSVCRT__locale_tstruct));
|
loc = MSVCRT_malloc(sizeof(MSVCRT__locale_tstruct));
|
||||||
@ -857,7 +869,7 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(lcid[MSVCRT_LC_COLLATE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_COLLATE)) {
|
if(lcid[MSVCRT_LC_COLLATE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_COLLATE)) {
|
||||||
if(update_threadlocinfo_category(lcid[MSVCRT_LC_COLLATE], loc, MSVCRT_LC_COLLATE)) {
|
if(update_threadlocinfo_category(lcid[MSVCRT_LC_COLLATE], cp[MSVCRT_LC_COLLATE], loc, MSVCRT_LC_COLLATE)) {
|
||||||
MSVCRT__free_locale(loc);
|
MSVCRT__free_locale(loc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -867,21 +879,21 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
|||||||
loc->locinfo->lc_category[MSVCRT_LC_COLLATE].locale = MSVCRT__strdup("C");
|
loc->locinfo->lc_category[MSVCRT_LC_COLLATE].locale = MSVCRT__strdup("C");
|
||||||
|
|
||||||
if(lcid[MSVCRT_LC_CTYPE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_CTYPE)) {
|
if(lcid[MSVCRT_LC_CTYPE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_CTYPE)) {
|
||||||
CPINFO cp;
|
CPINFO cp_info;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
if(update_threadlocinfo_category(lcid[MSVCRT_LC_CTYPE], loc, MSVCRT_LC_CTYPE)) {
|
if(update_threadlocinfo_category(lcid[MSVCRT_LC_CTYPE], cp[MSVCRT_LC_CTYPE], loc, MSVCRT_LC_CTYPE)) {
|
||||||
MSVCRT__free_locale(loc);
|
MSVCRT__free_locale(loc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
loc->locinfo->lc_codepage = loc->locinfo->lc_id[MSVCRT_LC_CTYPE].wCodePage;
|
loc->locinfo->lc_codepage = loc->locinfo->lc_id[MSVCRT_LC_CTYPE].wCodePage;
|
||||||
loc->locinfo->lc_clike = 1;
|
loc->locinfo->lc_clike = 1;
|
||||||
if(!GetCPInfo(loc->locinfo->lc_codepage, &cp)) {
|
if(!GetCPInfo(loc->locinfo->lc_codepage, &cp_info)) {
|
||||||
MSVCRT__free_locale(loc);
|
MSVCRT__free_locale(loc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
loc->locinfo->mb_cur_max = cp.MaxCharSize;
|
loc->locinfo->mb_cur_max = cp_info.MaxCharSize;
|
||||||
|
|
||||||
loc->locinfo->ctype1_refcount = MSVCRT_malloc(sizeof(int));
|
loc->locinfo->ctype1_refcount = MSVCRT_malloc(sizeof(int));
|
||||||
loc->locinfo->ctype1 = MSVCRT_malloc(sizeof(short[257]));
|
loc->locinfo->ctype1 = MSVCRT_malloc(sizeof(short[257]));
|
||||||
@ -905,8 +917,8 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
|||||||
1, loc->locinfo->ctype1+i);
|
1, loc->locinfo->ctype1+i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i=0; cp.LeadByte[i+1]!=0; i+=2)
|
for(i=0; cp_info.LeadByte[i+1]!=0; i+=2)
|
||||||
for(j=cp.LeadByte[i]; j<=cp.LeadByte[i+1]; j++)
|
for(j=cp_info.LeadByte[i]; j<=cp_info.LeadByte[i+1]; j++)
|
||||||
loc->locinfo->ctype1[j+1] |= MSVCRT__LEADBYTE;
|
loc->locinfo->ctype1[j+1] |= MSVCRT__LEADBYTE;
|
||||||
} else {
|
} else {
|
||||||
loc->locinfo->lc_clike = 1;
|
loc->locinfo->lc_clike = 1;
|
||||||
@ -938,7 +950,7 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
|||||||
_setmbcp_l(loc->locinfo->lc_id[MSVCRT_LC_CTYPE].wCodePage, lcid[MSVCRT_LC_CTYPE], loc->mbcinfo);
|
_setmbcp_l(loc->locinfo->lc_id[MSVCRT_LC_CTYPE].wCodePage, lcid[MSVCRT_LC_CTYPE], loc->mbcinfo);
|
||||||
|
|
||||||
if(lcid[MSVCRT_LC_MONETARY] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_MONETARY)) {
|
if(lcid[MSVCRT_LC_MONETARY] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_MONETARY)) {
|
||||||
if(update_threadlocinfo_category(lcid[MSVCRT_LC_MONETARY], loc, MSVCRT_LC_MONETARY)) {
|
if(update_threadlocinfo_category(lcid[MSVCRT_LC_MONETARY], cp[MSVCRT_LC_MONETARY], loc, MSVCRT_LC_MONETARY)) {
|
||||||
MSVCRT__free_locale(loc);
|
MSVCRT__free_locale(loc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1122,7 +1134,7 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(lcid[MSVCRT_LC_NUMERIC] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_NUMERIC)) {
|
if(lcid[MSVCRT_LC_NUMERIC] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_NUMERIC)) {
|
||||||
if(update_threadlocinfo_category(lcid[MSVCRT_LC_NUMERIC], loc, MSVCRT_LC_NUMERIC)) {
|
if(update_threadlocinfo_category(lcid[MSVCRT_LC_NUMERIC], cp[MSVCRT_LC_NUMERIC], loc, MSVCRT_LC_NUMERIC)) {
|
||||||
MSVCRT__free_locale(loc);
|
MSVCRT__free_locale(loc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1189,7 +1201,7 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(lcid[MSVCRT_LC_TIME] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_TIME)) {
|
if(lcid[MSVCRT_LC_TIME] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_TIME)) {
|
||||||
if(update_threadlocinfo_category(lcid[MSVCRT_LC_TIME], loc, MSVCRT_LC_TIME)) {
|
if(update_threadlocinfo_category(lcid[MSVCRT_LC_TIME], cp[MSVCRT_LC_TIME], loc, MSVCRT_LC_TIME)) {
|
||||||
MSVCRT__free_locale(loc);
|
MSVCRT__free_locale(loc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -245,7 +245,7 @@ int _setmbcp_l(int cp, LCID lcid, MSVCRT_pthreadmbcinfo mbcinfo)
|
|||||||
|
|
||||||
if(lcid == -1) {
|
if(lcid == -1) {
|
||||||
sprintf(bufA, format, newcp);
|
sprintf(bufA, format, newcp);
|
||||||
mbcinfo->mblcid = MSVCRT_locale_to_LCID(bufA);
|
mbcinfo->mblcid = MSVCRT_locale_to_LCID(bufA, NULL);
|
||||||
} else {
|
} else {
|
||||||
mbcinfo->mblcid = lcid;
|
mbcinfo->mblcid = lcid;
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ typedef struct __thread_data thread_data_t;
|
|||||||
|
|
||||||
extern thread_data_t *msvcrt_get_thread_data(void) DECLSPEC_HIDDEN;
|
extern thread_data_t *msvcrt_get_thread_data(void) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
LCID MSVCRT_locale_to_LCID(const char *) DECLSPEC_HIDDEN;
|
LCID MSVCRT_locale_to_LCID(const char*, unsigned short*) DECLSPEC_HIDDEN;
|
||||||
extern MSVCRT__locale_t MSVCRT_locale DECLSPEC_HIDDEN;
|
extern MSVCRT__locale_t MSVCRT_locale DECLSPEC_HIDDEN;
|
||||||
extern unsigned int MSVCRT___lc_codepage;
|
extern unsigned int MSVCRT___lc_codepage;
|
||||||
extern int MSVCRT___lc_collate_cp;
|
extern int MSVCRT___lc_collate_cp;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user