msvcrt: Don't overwrite threadmbcinfostruct structure in _setmbcp.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e84394764a
commit
35a8f15361
|
@ -130,6 +130,7 @@ static int (__cdecl *p_fflush_nolock)(FILE*);
|
|||
static size_t (__cdecl *p_mbstowcs)(wchar_t*, const char*, size_t);
|
||||
static size_t (__cdecl *p_wcstombs)(char*, const wchar_t*, size_t);
|
||||
static char* (__cdecl *p_setlocale)(int, const char*);
|
||||
static int (__cdecl *p__setmbcp)(int);
|
||||
static int (__cdecl *p__fpieee_flt)(ULONG, EXCEPTION_POINTERS*, int (__cdecl *handler)(_FPIEEE_RECORD*));
|
||||
static int (__cdecl *p__memicmp)(const char*, const char*, size_t);
|
||||
static int (__cdecl *p__memicmp_l)(const char*, const char*, size_t, _locale_t);
|
||||
|
@ -160,6 +161,16 @@ struct __lc_time_data {
|
|||
#undef errno
|
||||
#define errno (*p_errno())
|
||||
|
||||
typedef struct threadmbcinfostruct {
|
||||
int refcount;
|
||||
int mbcodepage;
|
||||
int ismbcodepage;
|
||||
int mblcid;
|
||||
unsigned short mbulinfo[6];
|
||||
unsigned char mbctype[257];
|
||||
unsigned char mbcasemap[256];
|
||||
} threadmbcinfo;
|
||||
|
||||
/* type info */
|
||||
typedef struct __type_info
|
||||
{
|
||||
|
@ -415,6 +426,7 @@ static BOOL init(void)
|
|||
SET(p_mbstowcs, "mbstowcs");
|
||||
SET(p_wcstombs, "wcstombs");
|
||||
SET(p_setlocale, "setlocale");
|
||||
SET(p__setmbcp, "_setmbcp");
|
||||
SET(p__fpieee_flt, "_fpieee_flt");
|
||||
SET(p__memicmp, "_memicmp");
|
||||
SET(p__memicmp_l, "_memicmp_l");
|
||||
|
@ -1979,9 +1991,13 @@ static void test____mb_cur_max_l_func(void)
|
|||
|
||||
static void test__get_current_locale(void)
|
||||
{
|
||||
_locale_t l = p__get_current_locale(), l2 = p__get_current_locale();
|
||||
_locale_t l, l2;
|
||||
int i;
|
||||
|
||||
ok(!p__setmbcp(1252), "_setmbcp failed\n");
|
||||
l = p__get_current_locale();
|
||||
l2 = p__get_current_locale();
|
||||
|
||||
ok(!strcmp(l->locinfo->lc_category[LC_COLLATE].locale, "C"),
|
||||
"LC_COLLATE = \"%s\"\n", l->locinfo->lc_category[LC_COLLATE].locale);
|
||||
ok(!strcmp(l->locinfo->lc_category[LC_CTYPE].locale, "C"),
|
||||
|
@ -1992,6 +2008,7 @@ static void test__get_current_locale(void)
|
|||
"LC_NUMERIC = \"%s\"\n", l->locinfo->lc_category[LC_NUMERIC].locale);
|
||||
ok(!strcmp(l->locinfo->lc_category[LC_TIME].locale, "C"),
|
||||
"LC_TIME = \"%s\"\n", l->locinfo->lc_category[LC_TIME].locale);
|
||||
ok(l->mbcinfo->mbcodepage == 1252, "mbcodepage = %d\n", l->mbcinfo->mbcodepage);
|
||||
|
||||
ok(l->locinfo->refcount == 3, "refcount = %d\n", l->locinfo->refcount);
|
||||
|
||||
|
@ -2001,6 +2018,7 @@ static void test__get_current_locale(void)
|
|||
p__free_locale(l2);
|
||||
return;
|
||||
}
|
||||
ok(!p__setmbcp(932), "_setmbcp failed\n");
|
||||
|
||||
ok(!strcmp(l->locinfo->lc_category[LC_COLLATE].locale, "C"),
|
||||
"LC_COLLATE = \"%s\"\n", l->locinfo->lc_category[LC_COLLATE].locale);
|
||||
|
@ -2012,6 +2030,7 @@ static void test__get_current_locale(void)
|
|||
"LC_NUMERIC = \"%s\"\n", l->locinfo->lc_category[LC_NUMERIC].locale);
|
||||
ok(!strcmp(l->locinfo->lc_category[LC_TIME].locale, "C"),
|
||||
"LC_TIME = \"%s\"\n", l->locinfo->lc_category[LC_TIME].locale);
|
||||
ok(l->mbcinfo->mbcodepage == 1252, "mbcodepage = %d\n", l->mbcinfo->mbcodepage);
|
||||
|
||||
ok(l->locinfo->refcount == 2, "refcount = %d\n", l->locinfo->refcount);
|
||||
ok(l->locinfo == l2->locinfo, "different locinfo pointers\n");
|
||||
|
@ -2143,9 +2162,7 @@ static void test__get_current_locale(void)
|
|||
|
||||
p__free_locale(l2);
|
||||
|
||||
trace("before: %s\n", p_setlocale(LC_ALL, NULL));
|
||||
trace("current locale is: %s\n", p_setlocale(LC_MONETARY, "C"));
|
||||
trace("after: %s\n", p_setlocale(LC_ALL, NULL));
|
||||
p_setlocale(LC_MONETARY, "C");
|
||||
l2 = p__get_current_locale();
|
||||
|
||||
ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount);
|
||||
|
|
|
@ -597,14 +597,18 @@ MSVCRT_pthreadlocinfo CDECL get_locinfo(void) {
|
|||
return *get_locinfo_ptr();
|
||||
}
|
||||
|
||||
/* INTERNAL: returns pthreadmbcinfo struct */
|
||||
MSVCRT_pthreadmbcinfo CDECL get_mbcinfo(void) {
|
||||
MSVCRT_pthreadmbcinfo* CDECL get_mbcinfo_ptr(void) {
|
||||
thread_data_t *data = msvcrt_get_thread_data();
|
||||
|
||||
if(!data || !data->have_locale)
|
||||
return MSVCRT_locale->mbcinfo;
|
||||
return &MSVCRT_locale->mbcinfo;
|
||||
|
||||
return data->mbcinfo;
|
||||
return &data->mbcinfo;
|
||||
}
|
||||
|
||||
/* INTERNAL: returns pthreadmbcinfo struct */
|
||||
MSVCRT_pthreadmbcinfo CDECL get_mbcinfo(void) {
|
||||
return *get_mbcinfo_ptr();
|
||||
}
|
||||
|
||||
/* INTERNAL: constructs string returned by setlocale */
|
||||
|
@ -1964,16 +1968,13 @@ MSVCRT__locale_t CDECL MSVCRT__create_locale(int category, const char *locale)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
loc->mbcinfo = MSVCRT_malloc(sizeof(MSVCRT_threadmbcinfo));
|
||||
loc->mbcinfo = create_mbcinfo(loc->locinfo->lc_id[MSVCRT_LC_CTYPE].wCodePage,
|
||||
loc->locinfo->lc_handle[MSVCRT_LC_CTYPE], NULL);
|
||||
if(!loc->mbcinfo) {
|
||||
free_locinfo(loc->locinfo);
|
||||
MSVCRT_free(loc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
loc->mbcinfo->refcount = 1;
|
||||
_setmbcp_l(loc->locinfo->lc_id[MSVCRT_LC_CTYPE].wCodePage,
|
||||
loc->locinfo->lc_handle[MSVCRT_LC_CTYPE], loc->mbcinfo);
|
||||
return loc;
|
||||
}
|
||||
|
||||
|
|
|
@ -211,10 +211,9 @@ int CDECL ___mb_cur_max_l_func(MSVCRT__locale_t locale)
|
|||
/*********************************************************************
|
||||
* INTERNAL: _setmbcp_l
|
||||
*/
|
||||
int _setmbcp_l(int cp, LCID lcid, MSVCRT_pthreadmbcinfo mbcinfo)
|
||||
MSVCRT_threadmbcinfo* create_mbcinfo(int cp, LCID lcid, MSVCRT_threadmbcinfo *old_mbcinfo)
|
||||
{
|
||||
const char format[] = ".%d";
|
||||
|
||||
MSVCRT_threadmbcinfo *mbcinfo;
|
||||
int newcp;
|
||||
CPINFO cpi;
|
||||
BYTE *bytes;
|
||||
|
@ -225,8 +224,16 @@ int _setmbcp_l(int cp, LCID lcid, MSVCRT_pthreadmbcinfo mbcinfo)
|
|||
int ret;
|
||||
int i;
|
||||
|
||||
if(old_mbcinfo && cp==old_mbcinfo->mbcodepage
|
||||
&& (lcid==-1 || lcid==old_mbcinfo->mblcid)) {
|
||||
InterlockedIncrement(&old_mbcinfo->refcount);
|
||||
return old_mbcinfo;
|
||||
}
|
||||
|
||||
mbcinfo = MSVCRT_malloc(sizeof(MSVCRT_threadmbcinfo));
|
||||
if(!mbcinfo)
|
||||
mbcinfo = get_mbcinfo();
|
||||
return NULL;
|
||||
mbcinfo->refcount = 1;
|
||||
|
||||
switch (cp)
|
||||
{
|
||||
|
@ -250,7 +257,7 @@ int _setmbcp_l(int cp, LCID lcid, MSVCRT_pthreadmbcinfo mbcinfo)
|
|||
}
|
||||
|
||||
if(lcid == -1) {
|
||||
MSVCRT_sprintf(bufA, format, newcp);
|
||||
MSVCRT_sprintf(bufA, ".%d", newcp);
|
||||
mbcinfo->mblcid = MSVCRT_locale_to_LCID(bufA, NULL, NULL);
|
||||
} else {
|
||||
mbcinfo->mblcid = lcid;
|
||||
|
@ -265,8 +272,8 @@ int _setmbcp_l(int cp, LCID lcid, MSVCRT_pthreadmbcinfo mbcinfo)
|
|||
if (!GetCPInfo(newcp, &cpi))
|
||||
{
|
||||
WARN("Codepage %d not found\n", newcp);
|
||||
*MSVCRT__errno() = MSVCRT_EINVAL;
|
||||
return -1;
|
||||
MSVCRT_free(mbcinfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* setup the _mbctype */
|
||||
|
@ -370,10 +377,7 @@ int _setmbcp_l(int cp, LCID lcid, MSVCRT_pthreadmbcinfo mbcinfo)
|
|||
}
|
||||
|
||||
mbcinfo->mbcodepage = newcp;
|
||||
if(MSVCRT_locale && mbcinfo == MSVCRT_locale->mbcinfo)
|
||||
memcpy(MSVCRT_mbctype, MSVCRT_locale->mbcinfo->mbctype, sizeof(MSVCRT_mbctype));
|
||||
|
||||
return 0;
|
||||
return mbcinfo;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
@ -381,7 +385,21 @@ int _setmbcp_l(int cp, LCID lcid, MSVCRT_pthreadmbcinfo mbcinfo)
|
|||
*/
|
||||
int CDECL _setmbcp(int cp)
|
||||
{
|
||||
return _setmbcp_l(cp, -1, NULL);
|
||||
MSVCRT_threadmbcinfo **old_mbcinfo = get_mbcinfo_ptr();
|
||||
MSVCRT_threadmbcinfo *mbcinfo;
|
||||
|
||||
mbcinfo = create_mbcinfo(cp, -1, *old_mbcinfo);
|
||||
if(!mbcinfo) {
|
||||
*MSVCRT__errno() = MSVCRT_EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
free_mbcinfo(*old_mbcinfo);
|
||||
*old_mbcinfo = mbcinfo;
|
||||
|
||||
if(mbcinfo == MSVCRT_locale->mbcinfo)
|
||||
memcpy(MSVCRT_mbctype, MSVCRT_locale->mbcinfo->mbctype, sizeof(MSVCRT_mbctype));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
|
|
@ -1136,10 +1136,11 @@ MSVCRT__locale_t CDECL get_current_locale_noalloc(MSVCRT__locale_t locale) DECLS
|
|||
void CDECL free_locale_noalloc(MSVCRT__locale_t locale) DECLSPEC_HIDDEN;
|
||||
MSVCRT_pthreadlocinfo CDECL get_locinfo(void) DECLSPEC_HIDDEN;
|
||||
MSVCRT_pthreadmbcinfo CDECL get_mbcinfo(void) DECLSPEC_HIDDEN;
|
||||
MSVCRT_pthreadmbcinfo* CDECL get_mbcinfo_ptr(void) DECLSPEC_HIDDEN;
|
||||
void __cdecl MSVCRT__free_locale(MSVCRT__locale_t);
|
||||
MSVCRT_threadmbcinfo* create_mbcinfo(int, LCID, MSVCRT_threadmbcinfo*) DECLSPEC_HIDDEN;
|
||||
void free_locinfo(MSVCRT_pthreadlocinfo) DECLSPEC_HIDDEN;
|
||||
void free_mbcinfo(MSVCRT_pthreadmbcinfo) DECLSPEC_HIDDEN;
|
||||
int _setmbcp_l(int, LCID, MSVCRT_pthreadmbcinfo) DECLSPEC_HIDDEN;
|
||||
int __cdecl __crtLCMapStringA(LCID, DWORD, const char*, int, char*, int, unsigned int, int) DECLSPEC_HIDDEN;
|
||||
|
||||
#ifndef __WINE_MSVCRT_TEST
|
||||
|
|
Loading…
Reference in New Issue