Signed-off-by: Chip Davis cdavis@codeweavers.com --- v3: Fix implicit pointer-to-int cast warnings, because we haven't adopted the C99 _Bool type yet. --- dlls/msvcr90/tests/msvcr90.c | 466 +++++++++++++++++++++++++++++++++++ 1 file changed, 466 insertions(+)
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c index c8a49f25492d..d51e3c985d63 100644 --- a/dlls/msvcr90/tests/msvcr90.c +++ b/dlls/msvcr90/tests/msvcr90.c @@ -139,6 +139,22 @@ static int (__cdecl *p_swscanf)(const wchar_t *str, const wchar_t* format, ...); static int (__cdecl *p____mb_cur_max_l_func)(_locale_t locale); static _locale_t (__cdecl *p__create_locale)(int, const char*); static void (__cdecl *p__free_locale)(_locale_t); +static _locale_t (__cdecl *p__get_current_locale)(void); + +struct __lc_time_data { + const char *short_wday[7]; + const char *wday[7]; + const char *short_mon[12]; + const char *mon[12]; + const char *am; + const char *pm; + const char *short_date; + const char *date; + const char *time; + LCID lcid; + int unk; + int refcount; +};
/* make sure we use the correct errno */ #undef errno @@ -408,6 +424,7 @@ static BOOL init(void) SET(p____mb_cur_max_l_func, "___mb_cur_max_l_func"); SET(p__create_locale, "_create_locale"); SET(p__free_locale, "_free_locale"); + SET(p__get_current_locale, "_get_current_locale");
if (sizeof(void *) == 8) { @@ -1961,6 +1978,454 @@ static void test____mb_cur_max_l_func(void) p__free_locale(l); }
+static void test__get_current_locale(void) +{ + _locale_t l = p__get_current_locale(), l2 = p__get_current_locale(); + int i; +#define lc_str(lc, s) \ + ok(!strcmp(l->locinfo->lc_category[lc].locale, s), #lc " = "%s"\n", \ + l->locinfo->lc_category[lc].locale) + lc_str(LC_COLLATE, "C"); + lc_str(LC_CTYPE, "C"); + lc_str(LC_MONETARY, "C"); + lc_str(LC_NUMERIC, "C"); + lc_str(LC_TIME, "C"); + + ok(l->locinfo->refcount == 3, "refcount = %d\n", l->locinfo->refcount); + + if(!p_setlocale(LC_ALL, "english")) { + win_skip("English locale not available\n"); + p__free_locale(l); + p__free_locale(l2); + return; + } + + todo_wine { + lc_str(LC_COLLATE, "C"); + lc_str(LC_CTYPE, "C"); + lc_str(LC_MONETARY, "C"); + lc_str(LC_NUMERIC, "C"); + lc_str(LC_TIME, "C"); + } +#undef lc_str + + todo_wine ok(l->locinfo->refcount == 2, "refcount = %d\n", l->locinfo->refcount); + ok(l->locinfo == l2->locinfo, "different locinfo pointers\n"); + ok(l->mbcinfo == l2->mbcinfo, "different mbcinfo pointers\n"); + + p__free_locale(l); + p__free_locale(l2); + + l = p__get_current_locale(); + p_setlocale(LC_COLLATE, "C"); + l2 = p__get_current_locale(); + + todo_wine { + ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); + ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount); + } + + todo_wine { + ok(l->locinfo->lc_category[LC_COLLATE].locale != l2->locinfo->lc_category[LC_COLLATE].locale, + "same locale name pointers for LC_COLLATE\n"); + ok(l->locinfo->lc_category[LC_COLLATE].refcount != l2->locinfo->lc_category[LC_COLLATE].refcount, + "same refcount pointers for LC_COLLATE\n"); + ok(!!l->locinfo->lc_category[LC_COLLATE].refcount, "null refcount pointer for LC_COLLATE\n"); + if(l->locinfo->lc_category[LC_COLLATE].refcount) + ok(*l->locinfo->lc_category[LC_COLLATE].refcount == 1, "refcount = %d\n", + *l->locinfo->lc_category[LC_COLLATE].refcount); + ok(!!l2->locinfo->lc_category[LC_COLLATE].refcount, "null refcount pointer for LC_COLLATE\n"); + if(l2->locinfo->lc_category[LC_COLLATE].refcount) + ok(*l2->locinfo->lc_category[LC_COLLATE].refcount == 2, "refcount = %d\n", + *l2->locinfo->lc_category[LC_COLLATE].refcount); + } + for(i = LC_CTYPE; i <= LC_MAX; i++) { + ok(l->locinfo->lc_category[i].locale == l2->locinfo->lc_category[i].locale, + "different locale name pointers for category %d\n", i); + ok(l->locinfo->lc_category[i].refcount == l2->locinfo->lc_category[i].refcount, + "different refcount pointers for category %d\n", i); + todo_wine ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n", + *l->locinfo->lc_category[i].refcount, i); + } + + todo_wine ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", + l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp); + + ok(l->locinfo->lc_codepage == l2->locinfo->lc_codepage, "different lc_codepages %u, %u\n", + l->locinfo->lc_codepage, l2->locinfo->lc_codepage); + ok(l->locinfo->lc_clike == l2->locinfo->lc_clike, "different lc_clike values %d, %d\n", + l->locinfo->lc_clike, l2->locinfo->lc_clike); + /* The meaning of this member seems to be reversed--go figure */ + ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); + ok(l->locinfo->ctype1 == l2->locinfo->ctype1, "different ctype1 pointers\n"); + ok(l->locinfo->pclmap == l2->locinfo->pclmap, "different clmap pointers\n"); + ok(l->locinfo->pcumap == l2->locinfo->pcumap, "different cumap pointers\n"); + ok(l->locinfo->ctype1_refcount == l2->locinfo->ctype1_refcount, "different ctype1_refcount pointers\n"); + todo_wine ok(*l->locinfo->ctype1_refcount == 3, "refcount = %d\n", *l->locinfo->ctype1_refcount); + + ok(l->locinfo->lconv == l2->locinfo->lconv, "different lconv pointers\n"); + ok(l->locinfo->lconv_intl_refcount == l2->locinfo->lconv_intl_refcount, "different lconv_intl_refcount pointers\n"); + todo_wine ok(!!l->locinfo->lconv_intl_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_intl_refcount) + todo_wine ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); + + ok(l->locinfo->lconv->decimal_point == l2->locinfo->lconv->decimal_point, "different LC_NUMERIC pointers\n"); + ok(l->locinfo->lconv_num_refcount == l2->locinfo->lconv_num_refcount, "different lconv_num_refcount pointers\n"); + todo_wine ok(!!l->locinfo->lconv_num_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_num_refcount) + todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount); + + ok(l->locinfo->lconv->currency_symbol == l2->locinfo->lconv->currency_symbol, "different LC_MONETARY pointers\n"); + ok(l->locinfo->lconv_mon_refcount == l2->locinfo->lconv_mon_refcount, "different lconv_mon_refcount pointers\n"); + todo_wine ok(!!l->locinfo->lconv_mon_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_mon_refcount) + todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); + + ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); + todo_wine ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); + todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount); + + p__free_locale(l2); + + p_setlocale(LC_CTYPE, "C"); + l2 = p__get_current_locale(); + + todo_wine { + ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); + ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount); + } + + for(i = LC_COLLATE; i < LC_MONETARY; i++) { + todo_wine { + ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale, + "same locale name pointers for category %d\n", i); + ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, + "same refcount pointers for category %d\n", i); + ok(!!l->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); + if(l->locinfo->lc_category[i].refcount) + ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", + *l->locinfo->lc_category[i].refcount, i); + ok(!!l2->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); + if(l2->locinfo->lc_category[i].refcount) + ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", + *l2->locinfo->lc_category[i].refcount, i); + } + } + for(i = LC_MONETARY; i <= LC_MAX; i++) { + ok(l->locinfo->lc_category[i].locale == l2->locinfo->lc_category[i].locale, + "different locale name pointers for category %d\n", i); + ok(l->locinfo->lc_category[i].refcount == l2->locinfo->lc_category[i].refcount, + "different refcount pointers for category %d\n", i); + todo_wine ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n", + *l->locinfo->lc_category[i].refcount, i); + } + + todo_wine { + ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", + l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp); + + ok(l->locinfo->lc_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n", + l->locinfo->lc_codepage, l2->locinfo->lc_codepage); + ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", + l->locinfo->lc_clike, l2->locinfo->lc_clike); + } + ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); + todo_wine { + ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); + ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); + ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); + ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); + ok(l->locinfo->ctype1_refcount != l2->locinfo->ctype1_refcount, "same ctype1_refcount pointers\n"); + ok(!!l->locinfo->ctype1_refcount, "null refcount pointer for non-C locale\n"); + if(l->locinfo->ctype1_refcount) + ok(*l->locinfo->ctype1_refcount == 1, "refcount = %d\n", *l->locinfo->ctype1_refcount); + } + ok(!l2->locinfo->ctype1_refcount, "nonnull refcount pointer for C locale\n"); + + ok(l->locinfo->lconv == l2->locinfo->lconv, "different lconv pointers\n"); + ok(l->locinfo->lconv_intl_refcount == l2->locinfo->lconv_intl_refcount, "different lconv_intl_refcount pointers\n"); + todo_wine ok(!!l->locinfo->lconv_intl_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_intl_refcount) + todo_wine ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); + + ok(l->locinfo->lconv->decimal_point == l2->locinfo->lconv->decimal_point, "different LC_NUMERIC pointers\n"); + ok(l->locinfo->lconv_num_refcount == l2->locinfo->lconv_num_refcount, "different lconv_num_refcount pointers\n"); + todo_wine ok(!!l->locinfo->lconv_num_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_num_refcount) + todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount); + + ok(l->locinfo->lconv->currency_symbol == l2->locinfo->lconv->currency_symbol, "different LC_MONETARY pointers\n"); + ok(l->locinfo->lconv_mon_refcount == l2->locinfo->lconv_mon_refcount, "different lconv_mon_refcount pointers\n"); + todo_wine ok(!!l->locinfo->lconv_mon_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_mon_refcount) + todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); + + ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); + todo_wine ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); + todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount); + + p__free_locale(l2); + + p_setlocale(LC_MONETARY, "C"); + l2 = p__get_current_locale(); + + todo_wine { + ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); + ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount); + } + + for(i = LC_COLLATE; i <= LC_MONETARY; i++) { + todo_wine { + ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale, + "same locale name pointers for category %d\n", i); + ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, + "same refcount pointers for category %d\n", i); + ok(!!l->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); + if(l->locinfo->lc_category[i].refcount) + ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", + *l->locinfo->lc_category[i].refcount, i); + ok(!!l2->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); + if(l2->locinfo->lc_category[i].refcount) + ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", + *l2->locinfo->lc_category[i].refcount, i); + } + } + for(i = LC_NUMERIC; i <= LC_MAX; i++) { + ok(l->locinfo->lc_category[i].locale == l2->locinfo->lc_category[i].locale, + "different locale name pointers for category %d\n", i); + ok(l->locinfo->lc_category[i].refcount == l2->locinfo->lc_category[i].refcount, + "different refcount pointers for category %d\n", i); + todo_wine ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n", + *l->locinfo->lc_category[i].refcount, i); + } + + todo_wine { + ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", + l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp); + + ok(l->locinfo->lc_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n", + l->locinfo->lc_codepage, l2->locinfo->lc_codepage); + ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", + l->locinfo->lc_clike, l2->locinfo->lc_clike); + } + ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); + todo_wine { + ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); + ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); + ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); + ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); + ok(l->locinfo->ctype1_refcount != l2->locinfo->ctype1_refcount, "same ctype1_refcount pointers\n"); + ok(!!l->locinfo->ctype1_refcount, "null refcount pointer for non-C locale\n"); + if(l->locinfo->ctype1_refcount) + ok(*l->locinfo->ctype1_refcount == 1, "refcount = %d\n", *l->locinfo->ctype1_refcount); + } + ok(!l2->locinfo->ctype1_refcount, "nonnull refcount pointer for C locale\n"); + + todo_wine { + ok(l->locinfo->lconv != l2->locinfo->lconv, "same lconv pointers\n"); + ok(l->locinfo->lconv_intl_refcount != l2->locinfo->lconv_intl_refcount, "same lconv_intl_refcount pointers\n"); + ok(!!l->locinfo->lconv_intl_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_intl_refcount) + ok(*l->locinfo->lconv_intl_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); + ok(!!l2->locinfo->lconv_intl_refcount, "null refcount pointer for C locale\n"); + if(l2->locinfo->lconv_intl_refcount) + ok(*l2->locinfo->lconv_intl_refcount == 2, "refcount = %d\n", *l2->locinfo->lconv_intl_refcount); + } + + ok(l->locinfo->lconv->decimal_point == l2->locinfo->lconv->decimal_point, "different LC_NUMERIC pointers\n"); + ok(l->locinfo->lconv_num_refcount == l2->locinfo->lconv_num_refcount, "different lconv_num_refcount pointers\n"); + todo_wine ok(!!l->locinfo->lconv_num_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_num_refcount) + todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount); + + todo_wine { + ok(l->locinfo->lconv->currency_symbol != l2->locinfo->lconv->currency_symbol, "same LC_MONETARY pointers\n"); + ok(l->locinfo->lconv_mon_refcount != l2->locinfo->lconv_mon_refcount, "same lconv_mon_refcount pointers\n"); + ok(!!l->locinfo->lconv_mon_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_mon_refcount) + ok(*l->locinfo->lconv_mon_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); + } + ok(!l2->locinfo->lconv_mon_refcount, "nonnull refcount pointer for C locale\n"); + + ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); + todo_wine ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); + todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount); + + p__free_locale(l2); + + p_setlocale(LC_NUMERIC, "C"); + l2 = p__get_current_locale(); + + todo_wine { + ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); + ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount); + } + + for(i = LC_COLLATE; i <= LC_NUMERIC; i++) { + todo_wine { + ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale, + "same locale name pointers for category %d\n", i); + ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, + "same refcount pointers for category %d\n", i); + ok(!!l->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); + if(l->locinfo->lc_category[i].refcount) + ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", + *l->locinfo->lc_category[i].refcount, i); + ok(!!l2->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); + if(l2->locinfo->lc_category[i].refcount) + ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", + *l2->locinfo->lc_category[i].refcount, i); + } + } + ok(l->locinfo->lc_category[LC_TIME].locale == l2->locinfo->lc_category[LC_TIME].locale, + "different locale name pointers for LC_TIME\n"); + ok(l->locinfo->lc_category[LC_TIME].refcount == l2->locinfo->lc_category[LC_TIME].refcount, + "different refcount pointers for LC_TIME\n"); + todo_wine ok(*l->locinfo->lc_category[LC_TIME].refcount == 3, "refcount = %d\n", + *l->locinfo->lc_category[LC_TIME].refcount); + + todo_wine { + ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", + l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp); + + ok(l->locinfo->lc_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n", + l->locinfo->lc_codepage, l2->locinfo->lc_codepage); + ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", + l->locinfo->lc_clike, l2->locinfo->lc_clike); + } + ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); + todo_wine { + ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); + ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); + ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); + ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); + ok(l->locinfo->ctype1_refcount != l2->locinfo->ctype1_refcount, "same ctype1_refcount pointers\n"); + ok(!!l->locinfo->ctype1_refcount, "null refcount pointer for non-C locale\n"); + if(l->locinfo->ctype1_refcount) + ok(*l->locinfo->ctype1_refcount == 1, "refcount = %d\n", *l->locinfo->ctype1_refcount); + } + ok(!l2->locinfo->ctype1_refcount, "nonnull refcount pointer for C locale\n"); + + todo_wine { + ok(l->locinfo->lconv != l2->locinfo->lconv, "same lconv pointers\n"); + ok(l->locinfo->lconv_intl_refcount != l2->locinfo->lconv_intl_refcount, "same lconv_intl_refcount pointers\n"); + ok(!!l->locinfo->lconv_intl_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_intl_refcount) + ok(*l->locinfo->lconv_intl_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); + } + ok(!l2->locinfo->lconv_intl_refcount, "nonnull refcount pointer for C locale\n"); + + todo_wine { + ok(l->locinfo->lconv->decimal_point != l2->locinfo->lconv->decimal_point, "same LC_NUMERIC pointers\n"); + ok(l->locinfo->lconv_num_refcount != l2->locinfo->lconv_num_refcount, "same lconv_num_refcount pointers\n"); + ok(!!l->locinfo->lconv_num_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_num_refcount) + ok(*l->locinfo->lconv_num_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_num_refcount); + } + ok(!l2->locinfo->lconv_num_refcount, "nonnull refcount pointer for C locale\n"); + + todo_wine { + ok(l->locinfo->lconv->currency_symbol != l2->locinfo->lconv->currency_symbol, "same LC_MONETARY pointers\n"); + ok(l->locinfo->lconv_mon_refcount != l2->locinfo->lconv_mon_refcount, "same lconv_mon_refcount pointers\n"); + ok(!!l->locinfo->lconv_mon_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_mon_refcount) + ok(*l->locinfo->lconv_mon_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); + } + ok(!l2->locinfo->lconv_mon_refcount, "nonnull refcount pointer for C locale\n"); + + ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); + todo_wine ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); + todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount); + + p__free_locale(l2); + + p_setlocale(LC_TIME, "C"); + l2 = p__get_current_locale(); + + todo_wine { + ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); + ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount); + } + + todo_wine { + for(i = LC_MIN+1; i <= LC_MAX; i++) { + ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale, + "same locale name pointers for category %d\n", i); + ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, + "same refcount pointers for category %d\n", i); + ok(!!l->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); + if(l->locinfo->lc_category[i].refcount) + ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", + *l->locinfo->lc_category[i].refcount, i); + ok(!!l2->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); + if(l2->locinfo->lc_category[i].refcount) + ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", + *l2->locinfo->lc_category[i].refcount, i); + } + } + + todo_wine { + ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", + l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp); + + ok(l->locinfo->lc_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n", + l->locinfo->lc_codepage, l2->locinfo->lc_codepage); + ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", + l->locinfo->lc_clike, l2->locinfo->lc_clike); + } + ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); + todo_wine { + ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); + ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); + ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); + ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); + ok(l->locinfo->ctype1_refcount != l2->locinfo->ctype1_refcount, "same ctype1_refcount pointers\n"); + ok(!!l->locinfo->ctype1_refcount, "null refcount pointer for non-C locale\n"); + if(l->locinfo->ctype1_refcount) + ok(*l->locinfo->ctype1_refcount == 1, "refcount = %d\n", *l->locinfo->ctype1_refcount); + } + ok(!l2->locinfo->ctype1_refcount, "nonnull refcount pointer for C locale\n"); + + todo_wine { + ok(l->locinfo->lconv != l2->locinfo->lconv, "same lconv pointers\n"); + ok(l->locinfo->lconv_intl_refcount != l2->locinfo->lconv_intl_refcount, "same lconv_intl_refcount pointers\n"); + ok(!!l->locinfo->lconv_intl_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_intl_refcount) + ok(*l->locinfo->lconv_intl_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); + } + ok(!l2->locinfo->lconv_intl_refcount, "nonnull refcount pointer for C locale\n"); + + todo_wine { + ok(l->locinfo->lconv->decimal_point != l2->locinfo->lconv->decimal_point, "same LC_NUMERIC pointers\n"); + ok(l->locinfo->lconv_num_refcount != l2->locinfo->lconv_num_refcount, "same lconv_num_refcount pointers\n"); + ok(!!l->locinfo->lconv_num_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_num_refcount) + ok(*l->locinfo->lconv_num_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_num_refcount); + } + ok(!l2->locinfo->lconv_num_refcount, "nonnull refcount pointer for C locale\n"); + + todo_wine { + ok(l->locinfo->lconv->currency_symbol != l2->locinfo->lconv->currency_symbol, "same LC_MONETARY pointers\n"); + ok(l->locinfo->lconv_mon_refcount != l2->locinfo->lconv_mon_refcount, "same lconv_mon_refcount pointers\n"); + ok(!!l->locinfo->lconv_mon_refcount, "null refcount pointer in non-C locale\n"); + if(l->locinfo->lconv_mon_refcount) + ok(*l->locinfo->lconv_mon_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); + } + ok(!l2->locinfo->lconv_mon_refcount, "nonnull refcount pointer for C locale\n"); + + todo_wine ok(l->locinfo->lc_time_curr != l2->locinfo->lc_time_curr, "same lc_time_curr pointers\n"); + ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); + todo_wine ok(l->locinfo->lc_time_curr->refcount == 1, "refcount = %d\n", l->locinfo->lc_time_curr->refcount); + ok(l2->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l2->locinfo->lc_time_curr->unk); + todo_wine ok(l2->locinfo->lc_time_curr->refcount == 3 || broken(l2->locinfo->lc_time_curr->refcount == 2), + "refcount = %d\n", l2->locinfo->lc_time_curr->refcount); + + p__free_locale(l2); + + p__free_locale(l); + p_setlocale(LC_ALL, "C"); +} + START_TEST(msvcr90) { if(!init()) @@ -2001,4 +2466,5 @@ START_TEST(msvcr90) test___strncnt(); test_swscanf(); test____mb_cur_max_l_func(); + test__get_current_locale(); }
Signed-off-by: Chip Davis cdavis@codeweavers.com --- v4: Update for changes in patch 1. --- dlls/msvcr90/tests/msvcr90.c | 64 ++++++++++------------------ dlls/msvcrt/locale.c | 81 ++++++++++++++++++++++++++++-------- 2 files changed, 85 insertions(+), 60 deletions(-)
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c index d51e3c985d63..693b8a30c5c1 100644 --- a/dlls/msvcr90/tests/msvcr90.c +++ b/dlls/msvcr90/tests/msvcr90.c @@ -2030,15 +2030,11 @@ static void test__get_current_locale(void) "same locale name pointers for LC_COLLATE\n"); ok(l->locinfo->lc_category[LC_COLLATE].refcount != l2->locinfo->lc_category[LC_COLLATE].refcount, "same refcount pointers for LC_COLLATE\n"); - ok(!!l->locinfo->lc_category[LC_COLLATE].refcount, "null refcount pointer for LC_COLLATE\n"); - if(l->locinfo->lc_category[LC_COLLATE].refcount) - ok(*l->locinfo->lc_category[LC_COLLATE].refcount == 1, "refcount = %d\n", - *l->locinfo->lc_category[LC_COLLATE].refcount); - ok(!!l2->locinfo->lc_category[LC_COLLATE].refcount, "null refcount pointer for LC_COLLATE\n"); - if(l2->locinfo->lc_category[LC_COLLATE].refcount) - ok(*l2->locinfo->lc_category[LC_COLLATE].refcount == 2, "refcount = %d\n", - *l2->locinfo->lc_category[LC_COLLATE].refcount); } + ok(*l->locinfo->lc_category[LC_COLLATE].refcount == 1, "refcount = %d\n", + *l->locinfo->lc_category[LC_COLLATE].refcount); + todo_wine ok(*l2->locinfo->lc_category[LC_COLLATE].refcount == 2, "refcount = %d\n", + *l2->locinfo->lc_category[LC_COLLATE].refcount); for(i = LC_CTYPE; i <= LC_MAX; i++) { ok(l->locinfo->lc_category[i].locale == l2->locinfo->lc_category[i].locale, "different locale name pointers for category %d\n", i); @@ -2101,15 +2097,11 @@ static void test__get_current_locale(void) "same locale name pointers for category %d\n", i); ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, "same refcount pointers for category %d\n", i); - ok(!!l->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); - if(l->locinfo->lc_category[i].refcount) - ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", - *l->locinfo->lc_category[i].refcount, i); - ok(!!l2->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); - if(l2->locinfo->lc_category[i].refcount) - ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", - *l2->locinfo->lc_category[i].refcount, i); } + ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", + *l->locinfo->lc_category[i].refcount, i); + todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", + *l2->locinfo->lc_category[i].refcount, i); } for(i = LC_MONETARY; i <= LC_MAX; i++) { ok(l->locinfo->lc_category[i].locale == l2->locinfo->lc_category[i].locale, @@ -2180,15 +2172,11 @@ static void test__get_current_locale(void) "same locale name pointers for category %d\n", i); ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, "same refcount pointers for category %d\n", i); - ok(!!l->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); - if(l->locinfo->lc_category[i].refcount) - ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", - *l->locinfo->lc_category[i].refcount, i); - ok(!!l2->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); - if(l2->locinfo->lc_category[i].refcount) - ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", - *l2->locinfo->lc_category[i].refcount, i); } + ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", + *l->locinfo->lc_category[i].refcount, i); + todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", + *l2->locinfo->lc_category[i].refcount, i); } for(i = LC_NUMERIC; i <= LC_MAX; i++) { ok(l->locinfo->lc_category[i].locale == l2->locinfo->lc_category[i].locale, @@ -2267,15 +2255,11 @@ static void test__get_current_locale(void) "same locale name pointers for category %d\n", i); ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, "same refcount pointers for category %d\n", i); - ok(!!l->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); - if(l->locinfo->lc_category[i].refcount) - ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", - *l->locinfo->lc_category[i].refcount, i); - ok(!!l2->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); - if(l2->locinfo->lc_category[i].refcount) - ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", - *l2->locinfo->lc_category[i].refcount, i); } + ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", + *l->locinfo->lc_category[i].refcount, i); + todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", + *l2->locinfo->lc_category[i].refcount, i); } ok(l->locinfo->lc_category[LC_TIME].locale == l2->locinfo->lc_category[LC_TIME].locale, "different locale name pointers for LC_TIME\n"); @@ -2347,21 +2331,17 @@ static void test__get_current_locale(void) ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount); }
- todo_wine { - for(i = LC_MIN+1; i <= LC_MAX; i++) { + for(i = LC_MIN+1; i <= LC_MAX; i++) { + todo_wine { ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale, "same locale name pointers for category %d\n", i); ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, "same refcount pointers for category %d\n", i); - ok(!!l->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); - if(l->locinfo->lc_category[i].refcount) - ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", - *l->locinfo->lc_category[i].refcount, i); - ok(!!l2->locinfo->lc_category[i].refcount, "null refcount pointer for category %d\n", i); - if(l2->locinfo->lc_category[i].refcount) - ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", - *l2->locinfo->lc_category[i].refcount, i); } + ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", + *l->locinfo->lc_category[i].refcount, i); + todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", + *l2->locinfo->lc_category[i].refcount, i); }
todo_wine { diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index f6e7631b4f50..20004648ca79 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -418,6 +418,17 @@ static BOOL init_category_name(const char *name, int len, return TRUE; }
+/* INTERNAL: Copy lc_handle, lc_id, and lc_category from one threadlocinfo to another */ +static void copy_threadlocinfo_category(MSVCRT_pthreadlocinfo locinfo, MSVCRT_pthreadlocinfo old_locinfo, int category) +{ + locinfo->lc_handle[category] = old_locinfo->lc_handle[category]; + locinfo->lc_id[category] = old_locinfo->lc_id[category]; + if(!locinfo->lc_category[category].locale) { + locinfo->lc_category[category] = old_locinfo->lc_category[category]; + InterlockedIncrement(locinfo->lc_category[category].refcount); + } +} + /* INTERNAL: Set lc_handle, lc_id and lc_category in threadlocinfo struct */ static BOOL update_threadlocinfo_category(LCID lcid, unsigned short cp, MSVCRT_pthreadlocinfo locinfo, int category) @@ -878,11 +889,14 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo) return;
for(i=MSVCRT_LC_MIN+1; i<=MSVCRT_LC_MAX; i++) { - MSVCRT_free(locinfo->lc_category[i].locale); - MSVCRT_free(locinfo->lc_category[i].refcount); #if _MSVCR_VER >= 110 MSVCRT_free(locinfo->lc_name[i]); #endif + if(!locinfo->lc_category[i].refcount + || InterlockedDecrement(locinfo->lc_category[i].refcount)) + continue; + MSVCRT_free(locinfo->lc_category[i].locale); + MSVCRT_free(locinfo->lc_category[i].refcount); }
if(locinfo->lconv) { @@ -1200,8 +1214,11 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
if(!category_needs_update(MSVCRT_LC_COLLATE, category, old_locinfo, lcid[MSVCRT_LC_COLLATE], cp[MSVCRT_LC_COLLATE])) { - locinfo->lc_handle[MSVCRT_LC_COLLATE] = old_locinfo->lc_handle[MSVCRT_LC_COLLATE]; - locinfo->lc_id[MSVCRT_LC_COLLATE].wCodePage = old_locinfo->lc_id[MSVCRT_LC_COLLATE].wCodePage; + copy_threadlocinfo_category(locinfo, old_locinfo, MSVCRT_LC_COLLATE); + if(!set_lc_locale_name(locinfo, MSVCRT_LC_COLLATE)) { + free_locinfo(locinfo); + return NULL; + } } else if(lcid[MSVCRT_LC_COLLATE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_COLLATE)) { if(!update_threadlocinfo_category(lcid[MSVCRT_LC_COLLATE], cp[MSVCRT_LC_COLLATE], locinfo, MSVCRT_LC_COLLATE)) { @@ -1215,8 +1232,12 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, free_locinfo(locinfo); return NULL; } - } else - locinfo->lc_category[MSVCRT_LC_COLLATE].locale = MSVCRT__strdup("C"); + } else { + if(!init_category_name("C", 1, locinfo, MSVCRT_LC_COLLATE)) { + free_locinfo(locinfo); + return NULL; + } + }
if(locale_name[MSVCRT_LC_CTYPE] && !init_category_name(locale_name[MSVCRT_LC_CTYPE], @@ -1227,8 +1248,11 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
if(!category_needs_update(MSVCRT_LC_CTYPE, category, old_locinfo, lcid[MSVCRT_LC_CTYPE], cp[MSVCRT_LC_CTYPE])) { - locinfo->lc_handle[MSVCRT_LC_CTYPE] = old_locinfo->lc_handle[MSVCRT_LC_CTYPE]; - locinfo->lc_id[MSVCRT_LC_CTYPE].wCodePage = old_locinfo->lc_id[MSVCRT_LC_CTYPE].wCodePage; + copy_threadlocinfo_category(locinfo, old_locinfo, MSVCRT_LC_CTYPE); + if(!set_lc_locale_name(locinfo, MSVCRT_LC_CTYPE)) { + free_locinfo(locinfo); + return NULL; + } } else if(lcid[MSVCRT_LC_CTYPE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_CTYPE)) { CPINFO cp_info; int j; @@ -1293,7 +1317,10 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, locinfo->lc_clike = 1; locinfo->mb_cur_max = 1; locinfo->pctype = MSVCRT__ctype+1; - locinfo->lc_category[MSVCRT_LC_CTYPE].locale = MSVCRT__strdup("C"); + if(!init_category_name("C", 1, locinfo, MSVCRT_LC_CTYPE)) { + free_locinfo(locinfo); + return NULL; + }
for(i=0; i<256; i++) { if(locinfo->pctype[i] & MSVCRT__LEADBYTE) @@ -1317,8 +1344,11 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
if(!category_needs_update(MSVCRT_LC_MONETARY, category, old_locinfo, lcid[MSVCRT_LC_MONETARY], cp[MSVCRT_LC_MONETARY])) { - locinfo->lc_handle[MSVCRT_LC_MONETARY] = old_locinfo->lc_handle[MSVCRT_LC_MONETARY]; - locinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage = old_locinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage; + copy_threadlocinfo_category(locinfo, old_locinfo, MSVCRT_LC_MONETARY); + if(!set_lc_locale_name(locinfo, MSVCRT_LC_MONETARY)) { + free_locinfo(locinfo); + return NULL; + } } else if(lcid[MSVCRT_LC_MONETARY] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_MONETARY)) { if(!update_threadlocinfo_category(lcid[MSVCRT_LC_MONETARY], cp[MSVCRT_LC_MONETARY], locinfo, MSVCRT_LC_MONETARY)) { @@ -1585,7 +1615,10 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, locinfo->lconv->_W_negative_sign[0] = '\0'; #endif
- locinfo->lc_category[MSVCRT_LC_MONETARY].locale = MSVCRT__strdup("C"); + if(!init_category_name("C", 1, locinfo, MSVCRT_LC_MONETARY)) { + free_locinfo(locinfo); + return NULL; + } }
if(locale_name[MSVCRT_LC_NUMERIC] && @@ -1597,8 +1630,11 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
if(!category_needs_update(MSVCRT_LC_NUMERIC, category, old_locinfo, lcid[MSVCRT_LC_NUMERIC], cp[MSVCRT_LC_NUMERIC])) { - locinfo->lc_handle[MSVCRT_LC_NUMERIC] = old_locinfo->lc_handle[MSVCRT_LC_NUMERIC]; - locinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage = old_locinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage; + copy_threadlocinfo_category(locinfo, old_locinfo, MSVCRT_LC_NUMERIC); + if(!set_lc_locale_name(locinfo, MSVCRT_LC_NUMERIC)) { + free_locinfo(locinfo); + return NULL; + } } else if(lcid[MSVCRT_LC_NUMERIC] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_NUMERIC)) { if(!update_threadlocinfo_category(lcid[MSVCRT_LC_NUMERIC], cp[MSVCRT_LC_NUMERIC], locinfo, MSVCRT_LC_NUMERIC)) { @@ -1703,7 +1739,10 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, locinfo->lconv->_W_thousands_sep[0] = '\0'; #endif
- locinfo->lc_category[MSVCRT_LC_NUMERIC].locale = MSVCRT__strdup("C"); + if (!init_category_name("C", 1, locinfo, MSVCRT_LC_NUMERIC)) { + free_locinfo(locinfo); + return NULL; + } }
if(locale_name[MSVCRT_LC_TIME] && @@ -1715,8 +1754,11 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
if(!category_needs_update(MSVCRT_LC_TIME, category, old_locinfo, lcid[MSVCRT_LC_TIME], cp[MSVCRT_LC_TIME])) { - locinfo->lc_handle[MSVCRT_LC_TIME] = old_locinfo->lc_handle[MSVCRT_LC_TIME]; - locinfo->lc_id[MSVCRT_LC_TIME].wCodePage = old_locinfo->lc_id[MSVCRT_LC_TIME].wCodePage; + copy_threadlocinfo_category(locinfo, old_locinfo, MSVCRT_LC_TIME); + if(!set_lc_locale_name(locinfo, MSVCRT_LC_TIME)) { + free_locinfo(locinfo); + return NULL; + } } else if(lcid[MSVCRT_LC_TIME] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_TIME)) { if(!update_threadlocinfo_category(lcid[MSVCRT_LC_TIME], cp[MSVCRT_LC_TIME], locinfo, MSVCRT_LC_TIME)) { @@ -1735,7 +1777,10 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, return NULL; } } else { - locinfo->lc_category[MSVCRT_LC_TIME].locale = MSVCRT__strdup("C"); + if(!init_category_name("C", 1, locinfo, MSVCRT_LC_TIME)) { + free_locinfo(locinfo); + return NULL; + } locinfo->lc_time_curr = &cloc_time_data; }
Signed-off-by: Chip Davis cdavis@codeweavers.com --- dlls/msvcrt/locale.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index 20004648ca79..3723c14d483b 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -1219,6 +1219,7 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, free_locinfo(locinfo); return NULL; } + locinfo->lc_collate_cp = old_locinfo->lc_collate_cp; } else if(lcid[MSVCRT_LC_COLLATE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_COLLATE)) { if(!update_threadlocinfo_category(lcid[MSVCRT_LC_COLLATE], cp[MSVCRT_LC_COLLATE], locinfo, MSVCRT_LC_COLLATE)) {
Signed-off-by: Chip Davis cdavis@codeweavers.com --- v3: Fix a naive attempt at modifying a patch immediately before sending. --- dlls/msvcr90/tests/msvcr90.c | 16 +++++----- dlls/msvcrt/locale.c | 62 +++++++++++++++++++++--------------- 2 files changed, 45 insertions(+), 33 deletions(-)
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c index 693b8a30c5c1..038e16a1d326 100644 --- a/dlls/msvcr90/tests/msvcr90.c +++ b/dlls/msvcr90/tests/msvcr90.c @@ -2120,10 +2120,10 @@ static void test__get_current_locale(void) l->locinfo->lc_codepage, l2->locinfo->lc_codepage); ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", l->locinfo->lc_clike, l2->locinfo->lc_clike); + ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); } - ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); + ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); todo_wine { - ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); @@ -2195,10 +2195,10 @@ static void test__get_current_locale(void) l->locinfo->lc_codepage, l2->locinfo->lc_codepage); ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", l->locinfo->lc_clike, l2->locinfo->lc_clike); + ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); } - ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); + ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); todo_wine { - ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); @@ -2276,10 +2276,10 @@ static void test__get_current_locale(void) l->locinfo->lc_codepage, l2->locinfo->lc_codepage); ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", l->locinfo->lc_clike, l2->locinfo->lc_clike); + ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); } - ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); + ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); todo_wine { - ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); @@ -2352,10 +2352,10 @@ static void test__get_current_locale(void) l->locinfo->lc_codepage, l2->locinfo->lc_codepage); ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", l->locinfo->lc_clike, l2->locinfo->lc_clike); + ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); } - ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); + ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); todo_wine { - ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index 3723c14d483b..47f7c60a445c 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -55,6 +55,9 @@ BOOL initial_locale = TRUE; #define MSVCRT_LEADBYTE 0x8000 #define MSVCRT_C1_DEFINED 0x200
+static unsigned char cloc_clmap[256]; +static unsigned char cloc_cumap[256]; + static const MSVCRT_wchar_t sun[] = {'S','u','n',0}; static const MSVCRT_wchar_t mon[] = {'M','o','n',0}; static const MSVCRT_wchar_t tue[] = {'T','u','e',0}; @@ -163,6 +166,16 @@ static const char * const _country_synonyms[] = "spanish-modern", "esn" };
+static BOOL WINAPI init_cloc_casemap(PINIT_ONCE once, void *param, void **context) +{ + int i; + for(i=0; i<256; i++) { + cloc_clmap[i] = (i>='A' && i<='Z' ? i-'A'+'a' : i); + cloc_cumap[i] = (i>='a' && i<='z' ? i-'a'+'A' : i); + } + return TRUE; +} + /* INTERNAL: Map a synonym to an ISO code */ static void remap_synonym(char *name) { @@ -926,11 +939,13 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo) MSVCRT_free(locinfo->lconv_mon_refcount); MSVCRT_free(locinfo->lconv);
- MSVCRT_free(locinfo->ctype1_refcount); - MSVCRT_free(locinfo->ctype1); - - MSVCRT_free(locinfo->pclmap); - MSVCRT_free(locinfo->pcumap); + if(locinfo->ctype1_refcount + && !InterlockedDecrement(locinfo->ctype1_refcount)) { + MSVCRT_free(locinfo->ctype1_refcount); + MSVCRT_free(locinfo->ctype1); + MSVCRT_free(locinfo->pclmap); + MSVCRT_free(locinfo->pcumap); + }
if(locinfo->lc_time_curr != &cloc_time_data) MSVCRT_free(locinfo->lc_time_curr); @@ -1198,13 +1213,6 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, } memset(locinfo->lconv, 0, sizeof(struct MSVCRT_lconv));
- locinfo->pclmap = MSVCRT_malloc(sizeof(char[256])); - locinfo->pcumap = MSVCRT_malloc(sizeof(char[256])); - if(!locinfo->pclmap || !locinfo->pcumap) { - free_locinfo(locinfo); - return NULL; - } - if(locale_name[MSVCRT_LC_COLLATE] && !init_category_name(locale_name[MSVCRT_LC_COLLATE], locale_len[MSVCRT_LC_COLLATE], locinfo, MSVCRT_LC_COLLATE)) { @@ -1254,6 +1262,16 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, free_locinfo(locinfo); return NULL; } + locinfo->lc_codepage = old_locinfo->lc_codepage; + locinfo->lc_clike = old_locinfo->lc_clike; + locinfo->mb_cur_max = old_locinfo->mb_cur_max; + locinfo->ctype1 = old_locinfo->ctype1; + locinfo->ctype1_refcount = old_locinfo->ctype1_refcount; + locinfo->pctype = old_locinfo->pctype; + locinfo->pclmap = old_locinfo->pclmap; + locinfo->pcumap = old_locinfo->pcumap; + if(locinfo->ctype1_refcount) + InterlockedIncrement(locinfo->ctype1_refcount); } else if(lcid[MSVCRT_LC_CTYPE] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_CTYPE)) { CPINFO cp_info; int j; @@ -1274,7 +1292,9 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
locinfo->ctype1_refcount = MSVCRT_malloc(sizeof(int)); locinfo->ctype1 = MSVCRT_malloc(sizeof(short[257])); - if(!locinfo->ctype1_refcount || !locinfo->ctype1) { + locinfo->pclmap = MSVCRT_malloc(sizeof(char[256])); + locinfo->pcumap = MSVCRT_malloc(sizeof(char[256])); + if(!locinfo->ctype1_refcount || !locinfo->ctype1 || !locinfo->pclmap || !locinfo->pcumap) { free_locinfo(locinfo); return NULL; } @@ -1315,7 +1335,7 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, LCMapStringA(lcid[MSVCRT_LC_CTYPE], LCMAP_UPPERCASE, buf, 256, (char*)locinfo->pcumap, 256); } else { - locinfo->lc_clike = 1; + static INIT_ONCE once = INIT_ONCE_STATIC_INIT; locinfo->mb_cur_max = 1; locinfo->pctype = MSVCRT__ctype+1; if(!init_category_name("C", 1, locinfo, MSVCRT_LC_CTYPE)) { @@ -1323,17 +1343,9 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, return NULL; }
- for(i=0; i<256; i++) { - if(locinfo->pctype[i] & MSVCRT__LEADBYTE) - buf[i] = ' '; - else - buf[i] = i; - } - - for(i=0; i<256; i++) { - locinfo->pclmap[i] = (i>='A' && i<='Z' ? i-'A'+'a' : i); - locinfo->pcumap[i] = (i>='a' && i<='z' ? i-'a'+'A' : i); - } + InitOnceExecuteOnce(&once, init_cloc_casemap, NULL, NULL); + locinfo->pclmap = cloc_clmap; + locinfo->pcumap = cloc_cumap; }
if(locale_name[MSVCRT_LC_MONETARY] &&
Signed-off-by: Chip Davis cdavis@codeweavers.com --- v4: Fix const-mismatch warnings. --- dlls/msvcrt/locale.c | 441 +++++++++++++++++++++++++------------------ 1 file changed, 260 insertions(+), 181 deletions(-)
diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index 47f7c60a445c..cbb30b4c0da0 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -58,6 +58,24 @@ BOOL initial_locale = TRUE; static unsigned char cloc_clmap[256]; static unsigned char cloc_cumap[256];
+static char empty[] = ""; +static char cloc_dec_point[] = "."; +#if _MSVCR_VER >= 100 +static MSVCRT_wchar_t emptyW[] = {0}; +static MSVCRT_wchar_t cloc_dec_pointW[] = {'.', 0}; +#endif +static struct MSVCRT_lconv cloc_lconv = +{ + cloc_dec_point, empty, empty, + empty, empty, empty, empty, empty, empty, empty, + CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX, CHAR_MAX +#if _MSVCR_VER >= 100 + , + cloc_dec_pointW, emptyW, + emptyW, emptyW, emptyW, emptyW, emptyW, emptyW +#endif +}; + static const MSVCRT_wchar_t sun[] = {'S','u','n',0}; static const MSVCRT_wchar_t mon[] = {'M','o','n',0}; static const MSVCRT_wchar_t tue[] = {'T','u','e',0}; @@ -853,6 +871,14 @@ int CDECL __lconv_init(void) { /* this is used to make chars unsigned */ charmax = 255; + cloc_lconv.int_frac_digits = charmax; + cloc_lconv.frac_digits = charmax; + cloc_lconv.p_cs_precedes = charmax; + cloc_lconv.p_sep_by_space = charmax; + cloc_lconv.n_cs_precedes = charmax; + cloc_lconv.n_sep_by_space = charmax; + cloc_lconv.p_sign_posn = charmax; + cloc_lconv.n_sign_posn = charmax; return 0; }
@@ -913,31 +939,42 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo) }
if(locinfo->lconv) { - MSVCRT_free(locinfo->lconv->decimal_point); - MSVCRT_free(locinfo->lconv->thousands_sep); - MSVCRT_free(locinfo->lconv->grouping); - MSVCRT_free(locinfo->lconv->int_curr_symbol); - MSVCRT_free(locinfo->lconv->currency_symbol); - MSVCRT_free(locinfo->lconv->mon_decimal_point); - MSVCRT_free(locinfo->lconv->mon_thousands_sep); - MSVCRT_free(locinfo->lconv->mon_grouping); - MSVCRT_free(locinfo->lconv->positive_sign); - MSVCRT_free(locinfo->lconv->negative_sign); + if(locinfo->lconv_num_refcount + && !InterlockedDecrement(locinfo->lconv_num_refcount)) { + MSVCRT_free(locinfo->lconv->decimal_point); + MSVCRT_free(locinfo->lconv->thousands_sep); + MSVCRT_free(locinfo->lconv->grouping); #if _MSVCR_VER >= 100 - MSVCRT_free(locinfo->lconv->_W_decimal_point); - MSVCRT_free(locinfo->lconv->_W_thousands_sep); - MSVCRT_free(locinfo->lconv->_W_int_curr_symbol); - MSVCRT_free(locinfo->lconv->_W_currency_symbol); - MSVCRT_free(locinfo->lconv->_W_mon_decimal_point); - MSVCRT_free(locinfo->lconv->_W_mon_thousands_sep); - MSVCRT_free(locinfo->lconv->_W_positive_sign); - MSVCRT_free(locinfo->lconv->_W_negative_sign); + MSVCRT_free(locinfo->lconv->_W_decimal_point); + MSVCRT_free(locinfo->lconv->_W_thousands_sep); #endif + MSVCRT_free(locinfo->lconv_num_refcount); + } + if(locinfo->lconv_mon_refcount + && !InterlockedDecrement(locinfo->lconv_mon_refcount)) { + MSVCRT_free(locinfo->lconv->int_curr_symbol); + MSVCRT_free(locinfo->lconv->currency_symbol); + MSVCRT_free(locinfo->lconv->mon_decimal_point); + MSVCRT_free(locinfo->lconv->mon_thousands_sep); + MSVCRT_free(locinfo->lconv->mon_grouping); + MSVCRT_free(locinfo->lconv->positive_sign); + MSVCRT_free(locinfo->lconv->negative_sign); +#if _MSVCR_VER >= 100 + MSVCRT_free(locinfo->lconv->_W_int_curr_symbol); + MSVCRT_free(locinfo->lconv->_W_currency_symbol); + MSVCRT_free(locinfo->lconv->_W_mon_decimal_point); + MSVCRT_free(locinfo->lconv->_W_mon_thousands_sep); + MSVCRT_free(locinfo->lconv->_W_positive_sign); + MSVCRT_free(locinfo->lconv->_W_negative_sign); +#endif + MSVCRT_free(locinfo->lconv_mon_refcount); + } + if(locinfo->lconv_intl_refcount + && !InterlockedDecrement(locinfo->lconv_intl_refcount)) { + MSVCRT_free(locinfo->lconv_intl_refcount); + MSVCRT_free(locinfo->lconv); + } } - MSVCRT_free(locinfo->lconv_intl_refcount); - MSVCRT_free(locinfo->lconv_num_refcount); - MSVCRT_free(locinfo->lconv_mon_refcount); - MSVCRT_free(locinfo->lconv);
if(locinfo->ctype1_refcount && !InterlockedDecrement(locinfo->ctype1_refcount)) { @@ -1206,13 +1243,6 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, memset(locinfo, 0, sizeof(MSVCRT_threadlocinfo)); locinfo->refcount = 1;
- locinfo->lconv = MSVCRT_malloc(sizeof(struct MSVCRT_lconv)); - if(!locinfo->lconv) { - free_locinfo(locinfo); - return NULL; - } - memset(locinfo->lconv, 0, sizeof(struct MSVCRT_lconv)); - if(locale_name[MSVCRT_LC_COLLATE] && !init_category_name(locale_name[MSVCRT_LC_COLLATE], locale_len[MSVCRT_LC_COLLATE], locinfo, MSVCRT_LC_COLLATE)) { @@ -1348,6 +1378,38 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, locinfo->pcumap = cloc_cumap; }
+ if(!category_needs_update(MSVCRT_LC_MONETARY, category, old_locinfo, + lcid[MSVCRT_LC_MONETARY], cp[MSVCRT_LC_MONETARY]) + && !category_needs_update(MSVCRT_LC_NUMERIC, category, old_locinfo, + lcid[MSVCRT_LC_NUMERIC], cp[MSVCRT_LC_NUMERIC])) { + locinfo->lconv = old_locinfo->lconv; + locinfo->lconv_intl_refcount = old_locinfo->lconv_intl_refcount; + if(locinfo->lconv_intl_refcount) + InterlockedIncrement(locinfo->lconv_intl_refcount); + } else if((lcid[MSVCRT_LC_MONETARY] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_MONETARY)) + || (lcid[MSVCRT_LC_NUMERIC] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_NUMERIC)) + || (!category_needs_update(MSVCRT_LC_MONETARY, category, old_locinfo, + lcid[MSVCRT_LC_MONETARY], cp[MSVCRT_LC_MONETARY]) + && old_locinfo->lc_handle[MSVCRT_LC_MONETARY]) + || (!category_needs_update(MSVCRT_LC_NUMERIC, category, old_locinfo, + lcid[MSVCRT_LC_NUMERIC], cp[MSVCRT_LC_NUMERIC]) + && old_locinfo->lc_handle[MSVCRT_LC_NUMERIC])) { + locinfo->lconv = MSVCRT_malloc(sizeof(struct MSVCRT_lconv)); + locinfo->lconv_intl_refcount = MSVCRT_malloc(sizeof(int)); + if(!locinfo->lconv || !locinfo->lconv_intl_refcount) { + MSVCRT_free(locinfo->lconv); + MSVCRT_free(locinfo->lconv_intl_refcount); + locinfo->lconv = NULL; + locinfo->lconv_intl_refcount = NULL; + free_locinfo(locinfo); + return NULL; + } + memset(locinfo->lconv, 0, sizeof(struct MSVCRT_lconv)); + *locinfo->lconv_intl_refcount = 1; + } else { + locinfo->lconv = &cloc_lconv; + } + if(locale_name[MSVCRT_LC_MONETARY] && !init_category_name(locale_name[MSVCRT_LC_MONETARY], locale_len[MSVCRT_LC_MONETARY], locinfo, MSVCRT_LC_MONETARY)) { @@ -1362,6 +1424,35 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, free_locinfo(locinfo); return NULL; } + locinfo->lconv_mon_refcount = old_locinfo->lconv_mon_refcount; + if(locinfo->lconv_mon_refcount) + InterlockedIncrement(locinfo->lconv_mon_refcount); + if(category_needs_update(MSVCRT_LC_NUMERIC, category, old_locinfo, + lcid[MSVCRT_LC_NUMERIC], cp[MSVCRT_LC_NUMERIC])) { + locinfo->lconv->int_curr_symbol = old_locinfo->lconv->int_curr_symbol; + locinfo->lconv->currency_symbol = old_locinfo->lconv->currency_symbol; + locinfo->lconv->mon_decimal_point = old_locinfo->lconv->mon_decimal_point; + locinfo->lconv->mon_thousands_sep = old_locinfo->lconv->mon_thousands_sep; + locinfo->lconv->mon_grouping = old_locinfo->lconv->mon_grouping; + locinfo->lconv->positive_sign = old_locinfo->lconv->positive_sign; + locinfo->lconv->negative_sign = old_locinfo->lconv->negative_sign; + locinfo->lconv->int_frac_digits = old_locinfo->lconv->int_frac_digits; + locinfo->lconv->frac_digits = old_locinfo->lconv->frac_digits; + locinfo->lconv->p_cs_precedes = old_locinfo->lconv->p_cs_precedes; + locinfo->lconv->p_sep_by_space = old_locinfo->lconv->p_sep_by_space; + locinfo->lconv->n_cs_precedes = old_locinfo->lconv->n_cs_precedes; + locinfo->lconv->n_sep_by_space = old_locinfo->lconv->n_sep_by_space; + locinfo->lconv->p_sign_posn = old_locinfo->lconv->p_sign_posn; + locinfo->lconv->n_sign_posn = old_locinfo->lconv->n_sign_posn; +#if _MSVCR_VER >= 100 + locinfo->lconv->_W_int_curr_symbol = old_locinfo->lconv->_W_int_curr_symbol; + locinfo->lconv->_W_currency_symbol = old_locinfo->lconv->_W_currency_symbol; + locinfo->lconv->_W_mon_decimal_point = old_locinfo->lconv->_W_mon_decimal_point; + locinfo->lconv->_W_mon_thousands_sep = old_locinfo->lconv->_W_mon_thousands_sep; + locinfo->lconv->_W_positive_sign = old_locinfo->lconv->_W_positive_sign; + locinfo->lconv->_W_negative_sign = old_locinfo->lconv->_W_negative_sign; +#endif + } } else if(lcid[MSVCRT_LC_MONETARY] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_MONETARY)) { if(!update_threadlocinfo_category(lcid[MSVCRT_LC_MONETARY], cp[MSVCRT_LC_MONETARY], locinfo, MSVCRT_LC_MONETARY)) { @@ -1369,14 +1460,12 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, return NULL; }
- locinfo->lconv_intl_refcount = MSVCRT_malloc(sizeof(int)); locinfo->lconv_mon_refcount = MSVCRT_malloc(sizeof(int)); - if(!locinfo->lconv_intl_refcount || !locinfo->lconv_mon_refcount) { + if(!locinfo->lconv_mon_refcount) { free_locinfo(locinfo); return NULL; }
- *locinfo->lconv_intl_refcount = 1; *locinfo->lconv_mon_refcount = 1;
i = GetLocaleInfoA(lcid[MSVCRT_LC_MONETARY], LOCALE_SINTLSYMBOL @@ -1573,60 +1662,33 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, return NULL; } } else { - locinfo->lconv->int_curr_symbol = MSVCRT_malloc(sizeof(char)); - locinfo->lconv->currency_symbol = MSVCRT_malloc(sizeof(char)); - locinfo->lconv->mon_decimal_point = MSVCRT_malloc(sizeof(char)); - locinfo->lconv->mon_thousands_sep = MSVCRT_malloc(sizeof(char)); - locinfo->lconv->mon_grouping = MSVCRT_malloc(sizeof(char)); - locinfo->lconv->positive_sign = MSVCRT_malloc(sizeof(char)); - locinfo->lconv->negative_sign = MSVCRT_malloc(sizeof(char)); - - if(!locinfo->lconv->int_curr_symbol || !locinfo->lconv->currency_symbol - || !locinfo->lconv->mon_decimal_point || !locinfo->lconv->mon_thousands_sep - || !locinfo->lconv->mon_grouping || !locinfo->lconv->positive_sign - || !locinfo->lconv->negative_sign) { - free_locinfo(locinfo); - return NULL; - } - - locinfo->lconv->int_curr_symbol[0] = '\0'; - locinfo->lconv->currency_symbol[0] = '\0'; - locinfo->lconv->mon_decimal_point[0] = '\0'; - locinfo->lconv->mon_thousands_sep[0] = '\0'; - locinfo->lconv->mon_grouping[0] = '\0'; - locinfo->lconv->positive_sign[0] = '\0'; - locinfo->lconv->negative_sign[0] = '\0'; - locinfo->lconv->int_frac_digits = charmax; - locinfo->lconv->frac_digits = charmax; - locinfo->lconv->p_cs_precedes = charmax; - locinfo->lconv->p_sep_by_space = charmax; - locinfo->lconv->n_cs_precedes = charmax; - locinfo->lconv->n_sep_by_space = charmax; - locinfo->lconv->p_sign_posn = charmax; - locinfo->lconv->n_sign_posn = charmax; + if(!category_needs_update(MSVCRT_LC_NUMERIC, category, old_locinfo, + lcid[MSVCRT_LC_NUMERIC], cp[MSVCRT_LC_NUMERIC])) { + locinfo->lconv->int_curr_symbol = empty; + locinfo->lconv->currency_symbol = empty; + locinfo->lconv->mon_decimal_point = empty; + locinfo->lconv->mon_thousands_sep = empty; + locinfo->lconv->mon_grouping = empty; + locinfo->lconv->positive_sign = empty; + locinfo->lconv->negative_sign = empty; + locinfo->lconv->int_frac_digits = charmax; + locinfo->lconv->frac_digits = charmax; + locinfo->lconv->p_cs_precedes = charmax; + locinfo->lconv->p_sep_by_space = charmax; + locinfo->lconv->n_cs_precedes = charmax; + locinfo->lconv->n_sep_by_space = charmax; + locinfo->lconv->p_sign_posn = charmax; + locinfo->lconv->n_sign_posn = charmax;
#if _MSVCR_VER >= 100 - locinfo->lconv->_W_int_curr_symbol = MSVCRT_malloc(sizeof(MSVCRT_wchar_t)); - locinfo->lconv->_W_currency_symbol = MSVCRT_malloc(sizeof(MSVCRT_wchar_t)); - locinfo->lconv->_W_mon_decimal_point = MSVCRT_malloc(sizeof(MSVCRT_wchar_t)); - locinfo->lconv->_W_mon_thousands_sep = MSVCRT_malloc(sizeof(MSVCRT_wchar_t)); - locinfo->lconv->_W_positive_sign = MSVCRT_malloc(sizeof(MSVCRT_wchar_t)); - locinfo->lconv->_W_negative_sign = MSVCRT_malloc(sizeof(MSVCRT_wchar_t)); - - if(!locinfo->lconv->_W_int_curr_symbol || !locinfo->lconv->_W_currency_symbol - || !locinfo->lconv->_W_mon_decimal_point || !locinfo->lconv->_W_mon_thousands_sep - || !locinfo->lconv->positive_sign || !locinfo->lconv->negative_sign) { - free_locinfo(locinfo); - return NULL; - } - - locinfo->lconv->_W_int_curr_symbol[0] = '\0'; - locinfo->lconv->_W_currency_symbol[0] = '\0'; - locinfo->lconv->_W_mon_decimal_point[0] = '\0'; - locinfo->lconv->_W_mon_thousands_sep[0] = '\0'; - locinfo->lconv->_W_positive_sign[0] = '\0'; - locinfo->lconv->_W_negative_sign[0] = '\0'; + locinfo->lconv->_W_int_curr_symbol = emptyW; + locinfo->lconv->_W_currency_symbol = emptyW; + locinfo->lconv->_W_mon_decimal_point = emptyW; + locinfo->lconv->_W_mon_thousands_sep = emptyW; + locinfo->lconv->_W_positive_sign = emptyW; + locinfo->lconv->_W_negative_sign = emptyW; #endif + }
if(!init_category_name("C", 1, locinfo, MSVCRT_LC_MONETARY)) { free_locinfo(locinfo); @@ -1648,6 +1710,19 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, free_locinfo(locinfo); return NULL; } + locinfo->lconv_num_refcount = old_locinfo->lconv_num_refcount; + if(locinfo->lconv_num_refcount) + InterlockedIncrement(locinfo->lconv_num_refcount); + if(category_needs_update(MSVCRT_LC_MONETARY, category, old_locinfo, + lcid[MSVCRT_LC_MONETARY], cp[MSVCRT_LC_MONETARY])) { + locinfo->lconv->decimal_point = old_locinfo->lconv->decimal_point; + locinfo->lconv->thousands_sep = old_locinfo->lconv->thousands_sep; + locinfo->lconv->grouping = old_locinfo->lconv->grouping; +#if _MSVCR_VER >= 100 + locinfo->lconv->_W_decimal_point = old_locinfo->lconv->_W_decimal_point; + locinfo->lconv->_W_thousands_sep = old_locinfo->lconv->_W_thousands_sep; +#endif + } } else if(lcid[MSVCRT_LC_NUMERIC] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_NUMERIC)) { if(!update_threadlocinfo_category(lcid[MSVCRT_LC_NUMERIC], cp[MSVCRT_LC_NUMERIC], locinfo, MSVCRT_LC_NUMERIC)) { @@ -1655,15 +1730,12 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, return NULL; }
- if(!locinfo->lconv_intl_refcount) - locinfo->lconv_intl_refcount = MSVCRT_malloc(sizeof(int)); locinfo->lconv_num_refcount = MSVCRT_malloc(sizeof(int)); - if(!locinfo->lconv_intl_refcount || !locinfo->lconv_num_refcount) { + if(!locinfo->lconv_num_refcount) { free_locinfo(locinfo); return NULL; }
- *locinfo->lconv_intl_refcount = 1; *locinfo->lconv_num_refcount = 1;
i = GetLocaleInfoA(lcid[MSVCRT_LC_NUMERIC], LOCALE_SDECIMAL @@ -1724,33 +1796,17 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, return NULL; } } else { - locinfo->lconv->decimal_point = MSVCRT_malloc(sizeof(char[2])); - locinfo->lconv->thousands_sep = MSVCRT_malloc(sizeof(char)); - locinfo->lconv->grouping = MSVCRT_malloc(sizeof(char)); - if(!locinfo->lconv->decimal_point || !locinfo->lconv->thousands_sep - || !locinfo->lconv->grouping) { - free_locinfo(locinfo); - return NULL; - } - - locinfo->lconv->decimal_point[0] = '.'; - locinfo->lconv->decimal_point[1] = '\0'; - locinfo->lconv->thousands_sep[0] = '\0'; - locinfo->lconv->grouping[0] = '\0'; + if(!category_needs_update(MSVCRT_LC_MONETARY, category, old_locinfo, + lcid[MSVCRT_LC_MONETARY], cp[MSVCRT_LC_MONETARY])) { + locinfo->lconv->decimal_point = cloc_dec_point; + locinfo->lconv->thousands_sep = empty; + locinfo->lconv->grouping = empty;
#if _MSVCR_VER >= 100 - locinfo->lconv->_W_decimal_point = MSVCRT_malloc(sizeof(MSVCRT_wchar_t[2])); - locinfo->lconv->_W_thousands_sep = MSVCRT_malloc(sizeof(MSVCRT_wchar_t)); - - if(!locinfo->lconv->_W_decimal_point || !locinfo->lconv->_W_thousands_sep) { - free_locinfo(locinfo); - return NULL; - } - - locinfo->lconv->_W_decimal_point[0] = '.'; - locinfo->lconv->_W_decimal_point[1] = '\0'; - locinfo->lconv->_W_thousands_sep[0] = '\0'; + locinfo->lconv->_W_decimal_point = cloc_dec_pointW; + locinfo->lconv->_W_thousands_sep = emptyW; #endif + }
if (!init_category_name("C", 1, locinfo, MSVCRT_LC_NUMERIC)) { free_locinfo(locinfo); @@ -1952,95 +2008,118 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale) (void**)&newlocinfo->lc_category[MSVCRT_LC_CTYPE].refcount); }
- if(locinfo->lc_handle[MSVCRT_LC_MONETARY]!=newlocinfo->lc_handle[MSVCRT_LC_MONETARY] - || locinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage!=newlocinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage) { + if(newlocinfo->lc_category[MSVCRT_LC_MONETARY].locale) { + swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_MONETARY].locale, + (void**)&newlocinfo->lc_category[MSVCRT_LC_MONETARY].locale); + swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_MONETARY].refcount, + (void**)&newlocinfo->lc_category[MSVCRT_LC_MONETARY].refcount); + } + + if(newlocinfo->lc_category[MSVCRT_LC_NUMERIC].locale) { + swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_NUMERIC].locale, + (void**)&newlocinfo->lc_category[MSVCRT_LC_NUMERIC].locale); + swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_NUMERIC].refcount, + (void**)&newlocinfo->lc_category[MSVCRT_LC_NUMERIC].refcount); + } + + if((locinfo->lc_handle[MSVCRT_LC_MONETARY]!=newlocinfo->lc_handle[MSVCRT_LC_MONETARY] + || locinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage!=newlocinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage) + && (locinfo->lc_handle[MSVCRT_LC_NUMERIC]!=newlocinfo->lc_handle[MSVCRT_LC_NUMERIC] + || locinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage!=newlocinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage)) { locinfo->lc_handle[MSVCRT_LC_MONETARY] = newlocinfo->lc_handle[MSVCRT_LC_MONETARY]; locinfo->lc_id[MSVCRT_LC_MONETARY] = newlocinfo->lc_id[MSVCRT_LC_MONETARY]; - - swap_pointers((void**)&locinfo->lconv->int_curr_symbol, - (void**)&newlocinfo->lconv->int_curr_symbol); - swap_pointers((void**)&locinfo->lconv->currency_symbol, - (void**)&newlocinfo->lconv->currency_symbol); - swap_pointers((void**)&locinfo->lconv->mon_decimal_point, - (void**)&newlocinfo->lconv->mon_decimal_point); - swap_pointers((void**)&locinfo->lconv->mon_thousands_sep, - (void**)&newlocinfo->lconv->mon_thousands_sep); - swap_pointers((void**)&locinfo->lconv->mon_grouping, - (void**)&newlocinfo->lconv->mon_grouping); - swap_pointers((void**)&locinfo->lconv->positive_sign, - (void**)&newlocinfo->lconv->positive_sign); - swap_pointers((void**)&locinfo->lconv->negative_sign, - (void**)&newlocinfo->lconv->negative_sign); + locinfo->lc_handle[MSVCRT_LC_NUMERIC] = + newlocinfo->lc_handle[MSVCRT_LC_NUMERIC]; + locinfo->lc_id[MSVCRT_LC_NUMERIC] = + newlocinfo->lc_id[MSVCRT_LC_NUMERIC]; + swap_pointers((void**)&locinfo->lconv, (void**)&newlocinfo->lconv); +#if _MSVCR_VER >= 110 + swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_MONETARY], + (void**)&newlocinfo->lc_name[MSVCRT_LC_MONETARY]); + swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_NUMERIC], + (void**)&newlocinfo->lc_name[MSVCRT_LC_NUMERIC]); +#endif + } else { + if(locinfo->lc_handle[MSVCRT_LC_MONETARY]!=newlocinfo->lc_handle[MSVCRT_LC_MONETARY] + || locinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage!=newlocinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage) { + locinfo->lc_handle[MSVCRT_LC_MONETARY] = + newlocinfo->lc_handle[MSVCRT_LC_MONETARY]; + locinfo->lc_id[MSVCRT_LC_MONETARY] = + newlocinfo->lc_id[MSVCRT_LC_MONETARY]; + + swap_pointers((void**)&locinfo->lconv->int_curr_symbol, + (void**)&newlocinfo->lconv->int_curr_symbol); + swap_pointers((void**)&locinfo->lconv->currency_symbol, + (void**)&newlocinfo->lconv->currency_symbol); + swap_pointers((void**)&locinfo->lconv->mon_decimal_point, + (void**)&newlocinfo->lconv->mon_decimal_point); + swap_pointers((void**)&locinfo->lconv->mon_thousands_sep, + (void**)&newlocinfo->lconv->mon_thousands_sep); + swap_pointers((void**)&locinfo->lconv->mon_grouping, + (void**)&newlocinfo->lconv->mon_grouping); + swap_pointers((void**)&locinfo->lconv->positive_sign, + (void**)&newlocinfo->lconv->positive_sign); + swap_pointers((void**)&locinfo->lconv->negative_sign, + (void**)&newlocinfo->lconv->negative_sign);
#if _MSVCR_VER >= 100 - swap_pointers((void**)&locinfo->lconv->_W_int_curr_symbol, - (void**)&newlocinfo->lconv->_W_int_curr_symbol); - swap_pointers((void**)&locinfo->lconv->_W_currency_symbol, - (void**)&newlocinfo->lconv->_W_currency_symbol); - swap_pointers((void**)&locinfo->lconv->_W_mon_decimal_point, - (void**)&newlocinfo->lconv->_W_mon_decimal_point); - swap_pointers((void**)&locinfo->lconv->_W_mon_thousands_sep, - (void**)&newlocinfo->lconv->_W_mon_thousands_sep); - swap_pointers((void**)&locinfo->lconv->_W_positive_sign, - (void**)&newlocinfo->lconv->_W_positive_sign); - swap_pointers((void**)&locinfo->lconv->_W_negative_sign, - (void**)&newlocinfo->lconv->_W_negative_sign); + swap_pointers((void**)&locinfo->lconv->_W_int_curr_symbol, + (void**)&newlocinfo->lconv->_W_int_curr_symbol); + swap_pointers((void**)&locinfo->lconv->_W_currency_symbol, + (void**)&newlocinfo->lconv->_W_currency_symbol); + swap_pointers((void**)&locinfo->lconv->_W_mon_decimal_point, + (void**)&newlocinfo->lconv->_W_mon_decimal_point); + swap_pointers((void**)&locinfo->lconv->_W_mon_thousands_sep, + (void**)&newlocinfo->lconv->_W_mon_thousands_sep); + swap_pointers((void**)&locinfo->lconv->_W_positive_sign, + (void**)&newlocinfo->lconv->_W_positive_sign); + swap_pointers((void**)&locinfo->lconv->_W_negative_sign, + (void**)&newlocinfo->lconv->_W_negative_sign); #endif
- locinfo->lconv->int_frac_digits = newlocinfo->lconv->int_frac_digits; - locinfo->lconv->frac_digits = newlocinfo->lconv->frac_digits; - locinfo->lconv->p_cs_precedes = newlocinfo->lconv->p_cs_precedes; - locinfo->lconv->p_sep_by_space = newlocinfo->lconv->p_sep_by_space; - locinfo->lconv->n_cs_precedes = newlocinfo->lconv->n_cs_precedes; - locinfo->lconv->n_sep_by_space = newlocinfo->lconv->n_sep_by_space; - locinfo->lconv->p_sign_posn = newlocinfo->lconv->p_sign_posn; - locinfo->lconv->n_sign_posn = newlocinfo->lconv->n_sign_posn; + locinfo->lconv->int_frac_digits = newlocinfo->lconv->int_frac_digits; + locinfo->lconv->frac_digits = newlocinfo->lconv->frac_digits; + locinfo->lconv->p_cs_precedes = newlocinfo->lconv->p_cs_precedes; + locinfo->lconv->p_sep_by_space = newlocinfo->lconv->p_sep_by_space; + locinfo->lconv->n_cs_precedes = newlocinfo->lconv->n_cs_precedes; + locinfo->lconv->n_sep_by_space = newlocinfo->lconv->n_sep_by_space; + locinfo->lconv->p_sign_posn = newlocinfo->lconv->p_sign_posn; + locinfo->lconv->n_sign_posn = newlocinfo->lconv->n_sign_posn;
#if _MSVCR_VER >= 110 - swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_MONETARY], - (void**)&newlocinfo->lc_name[MSVCRT_LC_MONETARY]); + swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_MONETARY], + (void**)&newlocinfo->lc_name[MSVCRT_LC_MONETARY]); #endif - } - if(newlocinfo->lc_category[MSVCRT_LC_MONETARY].locale) { - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_MONETARY].locale, - (void**)&newlocinfo->lc_category[MSVCRT_LC_MONETARY].locale); - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_MONETARY].refcount, - (void**)&newlocinfo->lc_category[MSVCRT_LC_MONETARY].refcount); - } + }
- if(locinfo->lc_handle[MSVCRT_LC_NUMERIC]!=newlocinfo->lc_handle[MSVCRT_LC_NUMERIC] - || locinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage!=newlocinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage) { - locinfo->lc_handle[MSVCRT_LC_NUMERIC] = - newlocinfo->lc_handle[MSVCRT_LC_NUMERIC]; - locinfo->lc_id[MSVCRT_LC_NUMERIC] = - newlocinfo->lc_id[MSVCRT_LC_NUMERIC]; + if(locinfo->lc_handle[MSVCRT_LC_NUMERIC]!=newlocinfo->lc_handle[MSVCRT_LC_NUMERIC] + || locinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage!=newlocinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage) { + locinfo->lc_handle[MSVCRT_LC_NUMERIC] = + newlocinfo->lc_handle[MSVCRT_LC_NUMERIC]; + locinfo->lc_id[MSVCRT_LC_NUMERIC] = + newlocinfo->lc_id[MSVCRT_LC_NUMERIC];
- swap_pointers((void**)&locinfo->lconv->decimal_point, - (void**)&newlocinfo->lconv->decimal_point); - swap_pointers((void**)&locinfo->lconv->thousands_sep, - (void**)&newlocinfo->lconv->thousands_sep); - swap_pointers((void**)&locinfo->lconv->grouping, - (void**)&newlocinfo->lconv->grouping); + swap_pointers((void**)&locinfo->lconv->decimal_point, + (void**)&newlocinfo->lconv->decimal_point); + swap_pointers((void**)&locinfo->lconv->thousands_sep, + (void**)&newlocinfo->lconv->thousands_sep); + swap_pointers((void**)&locinfo->lconv->grouping, + (void**)&newlocinfo->lconv->grouping);
#if _MSVCR_VER >= 100 - swap_pointers((void**)&locinfo->lconv->_W_decimal_point, - (void**)&newlocinfo->lconv->_W_decimal_point); - swap_pointers((void**)&locinfo->lconv->_W_thousands_sep, - (void**)&newlocinfo->lconv->_W_thousands_sep); + swap_pointers((void**)&locinfo->lconv->_W_decimal_point, + (void**)&newlocinfo->lconv->_W_decimal_point); + swap_pointers((void**)&locinfo->lconv->_W_thousands_sep, + (void**)&newlocinfo->lconv->_W_thousands_sep); #endif
#if _MSVCR_VER >= 110 - swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_NUMERIC], - (void**)&newlocinfo->lc_name[MSVCRT_LC_NUMERIC]); + swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_NUMERIC], + (void**)&newlocinfo->lc_name[MSVCRT_LC_NUMERIC]); #endif - } - if(newlocinfo->lc_category[MSVCRT_LC_NUMERIC].locale) { - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_NUMERIC].locale, - (void**)&newlocinfo->lc_category[MSVCRT_LC_NUMERIC].locale); - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_NUMERIC].refcount, - (void**)&newlocinfo->lc_category[MSVCRT_LC_NUMERIC].refcount); + } }
if(locinfo->lc_handle[MSVCRT_LC_TIME]!=newlocinfo->lc_handle[MSVCRT_LC_TIME]
My testing shows that unk[1] is some sort of refcount. I've updated a few places with this knowledge.
Signed-off-by: Chip Davis cdavis@codeweavers.com --- v3: Fix a spot I missed. --- dlls/msvcr90/tests/msvcr90.c | 8 ++++---- dlls/msvcrt/locale.c | 10 ++++++++-- dlls/msvcrt/msvcrt.h | 3 ++- dlls/msvcrt/tests/time.c | 7 ++++--- dlls/ucrtbase/tests/misc.c | 5 +++-- 5 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c index 038e16a1d326..18c9c3c15cc3 100644 --- a/dlls/msvcr90/tests/msvcr90.c +++ b/dlls/msvcr90/tests/msvcr90.c @@ -2078,7 +2078,7 @@ static void test__get_current_locale(void) todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount);
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); - todo_wine ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); + ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
p__free_locale(l2); @@ -2153,7 +2153,7 @@ static void test__get_current_locale(void) todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount);
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); - todo_wine ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); + ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
p__free_locale(l2); @@ -2236,7 +2236,7 @@ static void test__get_current_locale(void) ok(!l2->locinfo->lconv_mon_refcount, "nonnull refcount pointer for C locale\n");
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); - todo_wine ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); + ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
p__free_locale(l2); @@ -2318,7 +2318,7 @@ static void test__get_current_locale(void) ok(!l2->locinfo->lconv_mon_refcount, "nonnull refcount pointer for C locale\n");
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); - todo_wine ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); + ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
p__free_locale(l2); diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index cbb30b4c0da0..69748dcca88d 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -134,7 +134,7 @@ MSVCRT___lc_time_data cloc_time_data = #if _MSVCR_VER < 110 MAKELCID(LANG_ENGLISH, SORT_DEFAULT), #endif - {1, 0}, + 1, 0, {{sun, mon, tue, wed, thu, fri, sat, sunday, monday, tuesday, wednesday, thursday, friday, saturday, jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec, @@ -984,7 +984,8 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo) MSVCRT_free(locinfo->pcumap); }
- if(locinfo->lc_time_curr != &cloc_time_data) + if(!InterlockedDecrement(&locinfo->lc_time_curr->refcount) + && locinfo->lc_time_curr != &cloc_time_data) MSVCRT_free(locinfo->lc_time_curr);
MSVCRT_free(locinfo); @@ -1125,6 +1126,8 @@ static MSVCRT___lc_time_data* create_time_data(LCID lcid) #else cur->lcid = lcid; #endif + cur->unk = 1; + cur->refcount = 1;
return cur; } @@ -1828,6 +1831,8 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, free_locinfo(locinfo); return NULL; } + locinfo->lc_time_curr = old_locinfo->lc_time_curr; + InterlockedIncrement(&locinfo->lc_time_curr->refcount); } else if(lcid[MSVCRT_LC_TIME] && (category==MSVCRT_LC_ALL || category==MSVCRT_LC_TIME)) { if(!update_threadlocinfo_category(lcid[MSVCRT_LC_TIME], cp[MSVCRT_LC_TIME], locinfo, MSVCRT_LC_TIME)) { @@ -1851,6 +1856,7 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category, return NULL; } locinfo->lc_time_curr = &cloc_time_data; + InterlockedIncrement(&locinfo->lc_time_curr->refcount); }
return locinfo; diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 244df7d23ccc..e5a22c68ee8b 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -146,7 +146,8 @@ typedef struct { #if _MSVCR_VER < 110 LCID lcid; #endif - int unk[2]; + int unk; + int refcount; union { const MSVCRT_wchar_t *wstr[43]; struct { diff --git a/dlls/msvcrt/tests/time.c b/dlls/msvcrt/tests/time.c index 45ed971ca89a..20212d19bfa5 100644 --- a/dlls/msvcrt/tests/time.c +++ b/dlls/msvcrt/tests/time.c @@ -47,7 +47,8 @@ typedef struct { const char *date; const char *time; LCID lcid; - int unk[2]; + int unk; + int refcount; } __lc_time_data;
static __time32_t (__cdecl *p_mkgmtime32)(struct tm*); @@ -824,8 +825,8 @@ static void test_strftime(void) return; }
- /* TODO: find meaning of unk[0] */ - time_data.unk[0] = 1; + /* TODO: find meaning of unk */ + time_data.unk = 1; for (i=0; i<ARRAY_SIZE(tests_td); i++) { time_data.short_date = tests_td[i].short_date; diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index c9b04b7dd473..280fcc8a829d 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -116,7 +116,8 @@ typedef struct { const char *short_date; const char *date; const char *time; - int unk[2]; + int unk; + int refcount; const wchar_t *short_wdayW[7]; const wchar_t *wdayW[7]; const wchar_t *short_monW[12]; @@ -1154,7 +1155,7 @@ static void test_strftime(void) { "day1", "day2", "day3", "day4", "day5", "day6", "day7" }, { "m1", "m2", "m3", "m4", "m5", "m6", "m7", "m8", "m9", "m10", "m11", "m12" }, { "mon1", "mon2", "mon3", "mon4", "mon5", "mon6", "mon7", "mon8", "mon9", "mon10", "mon11", "mon12" }, - "tam", "tpm", 0, 0, 0, { 1, 0 }, + "tam", "tpm", 0, 0, 0, 1, 0, { L"D1", L"D2", L"D3", L"D4", L"D5", L"D6", L"D7" }, { L"Day1", L"Day2", L"Day3", L"Day4", L"Day5", L"Day6", L"Day7" }, { L"M1", L"M2", L"M3", L"M4", L"M5", L"M6", L"M7", L"M8", L"M9", L"M10", L"M11", L"M12" },
Do this instead of swapping their contents. This way, the result of _get_current_locale(), which references the current threadlocinfo, won't change after a setlocale() call.
Signed-off-by: Chip Davis cdavis@codeweavers.com --- v5: Fix a mismatched pointer types warning. --- dlls/msvcr90/tests/msvcr90.c | 334 +++++++++++++---------------------- dlls/msvcrt/locale.c | 202 ++------------------- 2 files changed, 132 insertions(+), 404 deletions(-)
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c index 18c9c3c15cc3..eda774210c7b 100644 --- a/dlls/msvcr90/tests/msvcr90.c +++ b/dlls/msvcr90/tests/msvcr90.c @@ -2000,16 +2000,14 @@ static void test__get_current_locale(void) return; }
- todo_wine { - lc_str(LC_COLLATE, "C"); - lc_str(LC_CTYPE, "C"); - lc_str(LC_MONETARY, "C"); - lc_str(LC_NUMERIC, "C"); - lc_str(LC_TIME, "C"); - } + lc_str(LC_COLLATE, "C"); + lc_str(LC_CTYPE, "C"); + lc_str(LC_MONETARY, "C"); + lc_str(LC_NUMERIC, "C"); + lc_str(LC_TIME, "C"); #undef lc_str
- todo_wine ok(l->locinfo->refcount == 2, "refcount = %d\n", l->locinfo->refcount); + ok(l->locinfo->refcount == 2, "refcount = %d\n", l->locinfo->refcount); ok(l->locinfo == l2->locinfo, "different locinfo pointers\n"); ok(l->mbcinfo == l2->mbcinfo, "different mbcinfo pointers\n");
@@ -2020,17 +2018,13 @@ static void test__get_current_locale(void) p_setlocale(LC_COLLATE, "C"); l2 = p__get_current_locale();
- todo_wine { - ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); - ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount); - } + ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); + ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount);
- todo_wine { - ok(l->locinfo->lc_category[LC_COLLATE].locale != l2->locinfo->lc_category[LC_COLLATE].locale, - "same locale name pointers for LC_COLLATE\n"); - ok(l->locinfo->lc_category[LC_COLLATE].refcount != l2->locinfo->lc_category[LC_COLLATE].refcount, - "same refcount pointers for LC_COLLATE\n"); - } + ok(l->locinfo->lc_category[LC_COLLATE].locale != l2->locinfo->lc_category[LC_COLLATE].locale, + "same locale name pointers for LC_COLLATE\n"); + ok(l->locinfo->lc_category[LC_COLLATE].refcount != l2->locinfo->lc_category[LC_COLLATE].refcount, + "same refcount pointers for LC_COLLATE\n"); ok(*l->locinfo->lc_category[LC_COLLATE].refcount == 1, "refcount = %d\n", *l->locinfo->lc_category[LC_COLLATE].refcount); todo_wine ok(*l2->locinfo->lc_category[LC_COLLATE].refcount == 2, "refcount = %d\n", @@ -2044,7 +2038,7 @@ static void test__get_current_locale(void) *l->locinfo->lc_category[i].refcount, i); }
- todo_wine ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", + ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp);
ok(l->locinfo->lc_codepage == l2->locinfo->lc_codepage, "different lc_codepages %u, %u\n", @@ -2061,21 +2055,15 @@ static void test__get_current_locale(void)
ok(l->locinfo->lconv == l2->locinfo->lconv, "different lconv pointers\n"); ok(l->locinfo->lconv_intl_refcount == l2->locinfo->lconv_intl_refcount, "different lconv_intl_refcount pointers\n"); - todo_wine ok(!!l->locinfo->lconv_intl_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_intl_refcount) - todo_wine ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); + todo_wine ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount);
ok(l->locinfo->lconv->decimal_point == l2->locinfo->lconv->decimal_point, "different LC_NUMERIC pointers\n"); ok(l->locinfo->lconv_num_refcount == l2->locinfo->lconv_num_refcount, "different lconv_num_refcount pointers\n"); - todo_wine ok(!!l->locinfo->lconv_num_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_num_refcount) - todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount); + todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount);
ok(l->locinfo->lconv->currency_symbol == l2->locinfo->lconv->currency_symbol, "different LC_MONETARY pointers\n"); ok(l->locinfo->lconv_mon_refcount == l2->locinfo->lconv_mon_refcount, "different lconv_mon_refcount pointers\n"); - todo_wine ok(!!l->locinfo->lconv_mon_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_mon_refcount) - todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); + todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount);
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); @@ -2086,18 +2074,14 @@ static void test__get_current_locale(void) p_setlocale(LC_CTYPE, "C"); l2 = p__get_current_locale();
- todo_wine { - ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); - ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount); - } + ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); + ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount);
for(i = LC_COLLATE; i < LC_MONETARY; i++) { - todo_wine { - ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale, - "same locale name pointers for category %d\n", i); - ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, - "same refcount pointers for category %d\n", i); - } + ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale, + "same locale name pointers for category %d\n", i); + ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, + "same refcount pointers for category %d\n", i); ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", *l->locinfo->lc_category[i].refcount, i); todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", @@ -2112,45 +2096,33 @@ static void test__get_current_locale(void) *l->locinfo->lc_category[i].refcount, i); }
- todo_wine { - ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", - l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp); + ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", + l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp);
- ok(l->locinfo->lc_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n", - l->locinfo->lc_codepage, l2->locinfo->lc_codepage); - ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", - l->locinfo->lc_clike, l2->locinfo->lc_clike); - ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); - } + ok(l->locinfo->lc_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n", + l->locinfo->lc_codepage, l2->locinfo->lc_codepage); + ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", + l->locinfo->lc_clike, l2->locinfo->lc_clike); + ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); - todo_wine { - ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); - ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); - ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); - ok(l->locinfo->ctype1_refcount != l2->locinfo->ctype1_refcount, "same ctype1_refcount pointers\n"); - ok(!!l->locinfo->ctype1_refcount, "null refcount pointer for non-C locale\n"); - if(l->locinfo->ctype1_refcount) - ok(*l->locinfo->ctype1_refcount == 1, "refcount = %d\n", *l->locinfo->ctype1_refcount); - } + ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); + ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); + ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); + ok(l->locinfo->ctype1_refcount != l2->locinfo->ctype1_refcount, "same ctype1_refcount pointers\n"); + ok(*l->locinfo->ctype1_refcount == 1, "refcount = %d\n", *l->locinfo->ctype1_refcount); ok(!l2->locinfo->ctype1_refcount, "nonnull refcount pointer for C locale\n");
ok(l->locinfo->lconv == l2->locinfo->lconv, "different lconv pointers\n"); ok(l->locinfo->lconv_intl_refcount == l2->locinfo->lconv_intl_refcount, "different lconv_intl_refcount pointers\n"); - todo_wine ok(!!l->locinfo->lconv_intl_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_intl_refcount) - todo_wine ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); + todo_wine ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount);
ok(l->locinfo->lconv->decimal_point == l2->locinfo->lconv->decimal_point, "different LC_NUMERIC pointers\n"); ok(l->locinfo->lconv_num_refcount == l2->locinfo->lconv_num_refcount, "different lconv_num_refcount pointers\n"); - todo_wine ok(!!l->locinfo->lconv_num_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_num_refcount) - todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount); + todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount);
ok(l->locinfo->lconv->currency_symbol == l2->locinfo->lconv->currency_symbol, "different LC_MONETARY pointers\n"); ok(l->locinfo->lconv_mon_refcount == l2->locinfo->lconv_mon_refcount, "different lconv_mon_refcount pointers\n"); - todo_wine ok(!!l->locinfo->lconv_mon_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_mon_refcount) - todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); + todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount);
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); @@ -2161,18 +2133,14 @@ static void test__get_current_locale(void) p_setlocale(LC_MONETARY, "C"); l2 = p__get_current_locale();
- todo_wine { - ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); - ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount); - } + ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); + ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount);
for(i = LC_COLLATE; i <= LC_MONETARY; i++) { - todo_wine { - ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale, - "same locale name pointers for category %d\n", i); - ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, - "same refcount pointers for category %d\n", i); - } + ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale, + "same locale name pointers for category %d\n", i); + ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, + "same refcount pointers for category %d\n", i); ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", *l->locinfo->lc_category[i].refcount, i); todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", @@ -2187,52 +2155,34 @@ static void test__get_current_locale(void) *l->locinfo->lc_category[i].refcount, i); }
- todo_wine { - ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", - l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp); + ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", + l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp);
- ok(l->locinfo->lc_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n", - l->locinfo->lc_codepage, l2->locinfo->lc_codepage); - ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", - l->locinfo->lc_clike, l2->locinfo->lc_clike); - ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); - } + ok(l->locinfo->lc_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n", + l->locinfo->lc_codepage, l2->locinfo->lc_codepage); + ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", + l->locinfo->lc_clike, l2->locinfo->lc_clike); + ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); - todo_wine { - ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); - ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); - ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); - ok(l->locinfo->ctype1_refcount != l2->locinfo->ctype1_refcount, "same ctype1_refcount pointers\n"); - ok(!!l->locinfo->ctype1_refcount, "null refcount pointer for non-C locale\n"); - if(l->locinfo->ctype1_refcount) - ok(*l->locinfo->ctype1_refcount == 1, "refcount = %d\n", *l->locinfo->ctype1_refcount); - } + ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); + ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); + ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); + ok(l->locinfo->ctype1_refcount != l2->locinfo->ctype1_refcount, "same ctype1_refcount pointers\n"); + ok(*l->locinfo->ctype1_refcount == 1, "refcount = %d\n", *l->locinfo->ctype1_refcount); ok(!l2->locinfo->ctype1_refcount, "nonnull refcount pointer for C locale\n");
- todo_wine { - ok(l->locinfo->lconv != l2->locinfo->lconv, "same lconv pointers\n"); - ok(l->locinfo->lconv_intl_refcount != l2->locinfo->lconv_intl_refcount, "same lconv_intl_refcount pointers\n"); - ok(!!l->locinfo->lconv_intl_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_intl_refcount) - ok(*l->locinfo->lconv_intl_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); - ok(!!l2->locinfo->lconv_intl_refcount, "null refcount pointer for C locale\n"); - if(l2->locinfo->lconv_intl_refcount) - ok(*l2->locinfo->lconv_intl_refcount == 2, "refcount = %d\n", *l2->locinfo->lconv_intl_refcount); - } + ok(l->locinfo->lconv != l2->locinfo->lconv, "same lconv pointers\n"); + ok(l->locinfo->lconv_intl_refcount != l2->locinfo->lconv_intl_refcount, "same lconv_intl_refcount pointers\n"); + ok(*l->locinfo->lconv_intl_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); + todo_wine ok(*l2->locinfo->lconv_intl_refcount == 2, "refcount = %d\n", *l2->locinfo->lconv_intl_refcount);
ok(l->locinfo->lconv->decimal_point == l2->locinfo->lconv->decimal_point, "different LC_NUMERIC pointers\n"); ok(l->locinfo->lconv_num_refcount == l2->locinfo->lconv_num_refcount, "different lconv_num_refcount pointers\n"); - todo_wine ok(!!l->locinfo->lconv_num_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_num_refcount) - todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount); - - todo_wine { - ok(l->locinfo->lconv->currency_symbol != l2->locinfo->lconv->currency_symbol, "same LC_MONETARY pointers\n"); - ok(l->locinfo->lconv_mon_refcount != l2->locinfo->lconv_mon_refcount, "same lconv_mon_refcount pointers\n"); - ok(!!l->locinfo->lconv_mon_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_mon_refcount) - ok(*l->locinfo->lconv_mon_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); - } + todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount); + + ok(l->locinfo->lconv->currency_symbol != l2->locinfo->lconv->currency_symbol, "same LC_MONETARY pointers\n"); + ok(l->locinfo->lconv_mon_refcount != l2->locinfo->lconv_mon_refcount, "same lconv_mon_refcount pointers\n"); + ok(*l->locinfo->lconv_mon_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); ok(!l2->locinfo->lconv_mon_refcount, "nonnull refcount pointer for C locale\n");
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); @@ -2244,18 +2194,14 @@ static void test__get_current_locale(void) p_setlocale(LC_NUMERIC, "C"); l2 = p__get_current_locale();
- todo_wine { - ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); - ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount); - } + ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); + ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount);
for(i = LC_COLLATE; i <= LC_NUMERIC; i++) { - todo_wine { - ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale, - "same locale name pointers for category %d\n", i); - ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, - "same refcount pointers for category %d\n", i); - } + ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale, + "same locale name pointers for category %d\n", i); + ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, + "same refcount pointers for category %d\n", i); ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", *l->locinfo->lc_category[i].refcount, i); todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", @@ -2268,53 +2214,35 @@ static void test__get_current_locale(void) todo_wine ok(*l->locinfo->lc_category[LC_TIME].refcount == 3, "refcount = %d\n", *l->locinfo->lc_category[LC_TIME].refcount);
- todo_wine { - ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", - l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp); + ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", + l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp);
- ok(l->locinfo->lc_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n", - l->locinfo->lc_codepage, l2->locinfo->lc_codepage); - ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", - l->locinfo->lc_clike, l2->locinfo->lc_clike); - ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); - } + ok(l->locinfo->lc_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n", + l->locinfo->lc_codepage, l2->locinfo->lc_codepage); + ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", + l->locinfo->lc_clike, l2->locinfo->lc_clike); + ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); - todo_wine { - ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); - ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); - ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); - ok(l->locinfo->ctype1_refcount != l2->locinfo->ctype1_refcount, "same ctype1_refcount pointers\n"); - ok(!!l->locinfo->ctype1_refcount, "null refcount pointer for non-C locale\n"); - if(l->locinfo->ctype1_refcount) - ok(*l->locinfo->ctype1_refcount == 1, "refcount = %d\n", *l->locinfo->ctype1_refcount); - } + ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); + ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); + ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); + ok(l->locinfo->ctype1_refcount != l2->locinfo->ctype1_refcount, "same ctype1_refcount pointers\n"); + ok(*l->locinfo->ctype1_refcount == 1, "refcount = %d\n", *l->locinfo->ctype1_refcount); ok(!l2->locinfo->ctype1_refcount, "nonnull refcount pointer for C locale\n");
- todo_wine { - ok(l->locinfo->lconv != l2->locinfo->lconv, "same lconv pointers\n"); - ok(l->locinfo->lconv_intl_refcount != l2->locinfo->lconv_intl_refcount, "same lconv_intl_refcount pointers\n"); - ok(!!l->locinfo->lconv_intl_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_intl_refcount) - ok(*l->locinfo->lconv_intl_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); - } + ok(l->locinfo->lconv != l2->locinfo->lconv, "same lconv pointers\n"); + ok(l->locinfo->lconv_intl_refcount != l2->locinfo->lconv_intl_refcount, "same lconv_intl_refcount pointers\n"); + ok(*l->locinfo->lconv_intl_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); ok(!l2->locinfo->lconv_intl_refcount, "nonnull refcount pointer for C locale\n");
- todo_wine { - ok(l->locinfo->lconv->decimal_point != l2->locinfo->lconv->decimal_point, "same LC_NUMERIC pointers\n"); - ok(l->locinfo->lconv_num_refcount != l2->locinfo->lconv_num_refcount, "same lconv_num_refcount pointers\n"); - ok(!!l->locinfo->lconv_num_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_num_refcount) - ok(*l->locinfo->lconv_num_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_num_refcount); - } + ok(l->locinfo->lconv->decimal_point != l2->locinfo->lconv->decimal_point, "same LC_NUMERIC pointers\n"); + ok(l->locinfo->lconv_num_refcount != l2->locinfo->lconv_num_refcount, "same lconv_num_refcount pointers\n"); + ok(*l->locinfo->lconv_num_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_num_refcount); ok(!l2->locinfo->lconv_num_refcount, "nonnull refcount pointer for C locale\n");
- todo_wine { - ok(l->locinfo->lconv->currency_symbol != l2->locinfo->lconv->currency_symbol, "same LC_MONETARY pointers\n"); - ok(l->locinfo->lconv_mon_refcount != l2->locinfo->lconv_mon_refcount, "same lconv_mon_refcount pointers\n"); - ok(!!l->locinfo->lconv_mon_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_mon_refcount) - ok(*l->locinfo->lconv_mon_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); - } + ok(l->locinfo->lconv->currency_symbol != l2->locinfo->lconv->currency_symbol, "same LC_MONETARY pointers\n"); + ok(l->locinfo->lconv_mon_refcount != l2->locinfo->lconv_mon_refcount, "same lconv_mon_refcount pointers\n"); + ok(*l->locinfo->lconv_mon_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); ok(!l2->locinfo->lconv_mon_refcount, "nonnull refcount pointer for C locale\n");
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); @@ -2326,76 +2254,54 @@ static void test__get_current_locale(void) p_setlocale(LC_TIME, "C"); l2 = p__get_current_locale();
- todo_wine { - ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); - ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount); - } + ok(l->locinfo->refcount == 1, "refcount = %d\n", l->locinfo->refcount); + ok(l2->locinfo->refcount == 2, "refcount = %d\n", l2->locinfo->refcount);
for(i = LC_MIN+1; i <= LC_MAX; i++) { - todo_wine { - ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale, - "same locale name pointers for category %d\n", i); - ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, - "same refcount pointers for category %d\n", i); - } + ok(l->locinfo->lc_category[i].locale != l2->locinfo->lc_category[i].locale, + "same locale name pointers for category %d\n", i); + ok(l->locinfo->lc_category[i].refcount != l2->locinfo->lc_category[i].refcount, + "same refcount pointers for category %d\n", i); ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", *l->locinfo->lc_category[i].refcount, i); todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", *l2->locinfo->lc_category[i].refcount, i); }
- todo_wine { - ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", - l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp); + ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", + l->locinfo->lc_collate_cp, l2->locinfo->lc_collate_cp);
- ok(l->locinfo->lc_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n", - l->locinfo->lc_codepage, l2->locinfo->lc_codepage); - ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", - l->locinfo->lc_clike, l2->locinfo->lc_clike); - ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); - } + ok(l->locinfo->lc_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n", + l->locinfo->lc_codepage, l2->locinfo->lc_codepage); + ok(l->locinfo->lc_clike != l2->locinfo->lc_clike, "same lc_clike values %d, %d\n", + l->locinfo->lc_clike, l2->locinfo->lc_clike); + ok(l->locinfo->lc_clike, "non-C locale is C-like\n"); ok(!l2->locinfo->lc_clike, "C locale is not C-like\n"); - todo_wine { - ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); - ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); - ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); - ok(l->locinfo->ctype1_refcount != l2->locinfo->ctype1_refcount, "same ctype1_refcount pointers\n"); - ok(!!l->locinfo->ctype1_refcount, "null refcount pointer for non-C locale\n"); - if(l->locinfo->ctype1_refcount) - ok(*l->locinfo->ctype1_refcount == 1, "refcount = %d\n", *l->locinfo->ctype1_refcount); - } + ok(l->locinfo->ctype1 != l2->locinfo->ctype1, "same ctype1 pointers\n"); + ok(l->locinfo->pclmap != l2->locinfo->pclmap, "same clmap pointers\n"); + ok(l->locinfo->pcumap != l2->locinfo->pcumap, "same cumap pointers\n"); + ok(l->locinfo->ctype1_refcount != l2->locinfo->ctype1_refcount, "same ctype1_refcount pointers\n"); + ok(*l->locinfo->ctype1_refcount == 1, "refcount = %d\n", *l->locinfo->ctype1_refcount); ok(!l2->locinfo->ctype1_refcount, "nonnull refcount pointer for C locale\n");
- todo_wine { - ok(l->locinfo->lconv != l2->locinfo->lconv, "same lconv pointers\n"); - ok(l->locinfo->lconv_intl_refcount != l2->locinfo->lconv_intl_refcount, "same lconv_intl_refcount pointers\n"); - ok(!!l->locinfo->lconv_intl_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_intl_refcount) - ok(*l->locinfo->lconv_intl_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); - } + ok(l->locinfo->lconv != l2->locinfo->lconv, "same lconv pointers\n"); + ok(l->locinfo->lconv_intl_refcount != l2->locinfo->lconv_intl_refcount, "same lconv_intl_refcount pointers\n"); + ok(*l->locinfo->lconv_intl_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); ok(!l2->locinfo->lconv_intl_refcount, "nonnull refcount pointer for C locale\n");
- todo_wine { - ok(l->locinfo->lconv->decimal_point != l2->locinfo->lconv->decimal_point, "same LC_NUMERIC pointers\n"); - ok(l->locinfo->lconv_num_refcount != l2->locinfo->lconv_num_refcount, "same lconv_num_refcount pointers\n"); - ok(!!l->locinfo->lconv_num_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_num_refcount) - ok(*l->locinfo->lconv_num_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_num_refcount); - } + ok(l->locinfo->lconv->decimal_point != l2->locinfo->lconv->decimal_point, "same LC_NUMERIC pointers\n"); + ok(l->locinfo->lconv_num_refcount != l2->locinfo->lconv_num_refcount, "same lconv_num_refcount pointers\n"); + ok(*l->locinfo->lconv_num_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_num_refcount); ok(!l2->locinfo->lconv_num_refcount, "nonnull refcount pointer for C locale\n");
- todo_wine { - ok(l->locinfo->lconv->currency_symbol != l2->locinfo->lconv->currency_symbol, "same LC_MONETARY pointers\n"); - ok(l->locinfo->lconv_mon_refcount != l2->locinfo->lconv_mon_refcount, "same lconv_mon_refcount pointers\n"); - ok(!!l->locinfo->lconv_mon_refcount, "null refcount pointer in non-C locale\n"); - if(l->locinfo->lconv_mon_refcount) - ok(*l->locinfo->lconv_mon_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); - } + ok(l->locinfo->lconv->currency_symbol != l2->locinfo->lconv->currency_symbol, "same LC_MONETARY pointers\n"); + ok(l->locinfo->lconv_mon_refcount != l2->locinfo->lconv_mon_refcount, "same lconv_mon_refcount pointers\n"); + ok(*l->locinfo->lconv_mon_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); ok(!l2->locinfo->lconv_mon_refcount, "nonnull refcount pointer for C locale\n");
- todo_wine ok(l->locinfo->lc_time_curr != l2->locinfo->lc_time_curr, "same lc_time_curr pointers\n"); + ok(l->locinfo->lc_time_curr != l2->locinfo->lc_time_curr, "same lc_time_curr pointers\n"); ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); - todo_wine ok(l->locinfo->lc_time_curr->refcount == 1, "refcount = %d\n", l->locinfo->lc_time_curr->refcount); + ok(l->locinfo->lc_time_curr->refcount == 1, "refcount = %d\n", l->locinfo->lc_time_curr->refcount); ok(l2->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l2->locinfo->lc_time_curr->unk); todo_wine ok(l2->locinfo->lc_time_curr->refcount == 3 || broken(l2->locinfo->lc_time_curr->refcount == 2), "refcount = %d\n", l2->locinfo->lc_time_curr->refcount); diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index 69748dcca88d..a1f269e01cf4 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -516,17 +516,22 @@ static inline void swap_pointers(void **p1, void **p2) { *p2 = hlp; }
-/* INTERNAL: returns pthreadlocinfo struct */ -MSVCRT_pthreadlocinfo get_locinfo(void) { +/* INTERNAL: returns pointer to pointer to threadlocinfo struct */ +static MSVCRT_pthreadlocinfo *get_locinfo_ptr(void) { thread_data_t *data = msvcrt_get_thread_data();
if(!data || !data->have_locale) - return MSVCRT_locale->locinfo; + return &MSVCRT_locale->locinfo; + + return &data->locinfo; +}
- return data->locinfo; +/* INTERNAL: returns threadlocinfo struct */ +MSVCRT_pthreadlocinfo get_locinfo(void) { + return *get_locinfo_ptr(); }
-/* INTERNAL: returns pthreadlocinfo struct */ +/* INTERNAL: returns threadmbcinfo struct */ MSVCRT_pthreadmbcinfo get_mbcinfo(void) { thread_data_t *data = msvcrt_get_thread_data();
@@ -1964,191 +1969,8 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale) if(locale[0] != 'C' || locale[1] != '\0') initial_locale = FALSE;
- if(locinfo->lc_handle[MSVCRT_LC_COLLATE]!=newlocinfo->lc_handle[MSVCRT_LC_COLLATE] - || locinfo->lc_id[MSVCRT_LC_COLLATE].wCodePage!=newlocinfo->lc_id[MSVCRT_LC_COLLATE].wCodePage) { - locinfo->lc_collate_cp = newlocinfo->lc_collate_cp; - locinfo->lc_handle[MSVCRT_LC_COLLATE] = - newlocinfo->lc_handle[MSVCRT_LC_COLLATE]; - locinfo->lc_id[MSVCRT_LC_COLLATE] = - newlocinfo->lc_id[MSVCRT_LC_COLLATE]; - -#if _MSVCR_VER >= 110 - swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_COLLATE], - (void**)&newlocinfo->lc_name[MSVCRT_LC_COLLATE]); -#endif - } - if(newlocinfo->lc_category[MSVCRT_LC_COLLATE].locale) { - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_COLLATE].locale, - (void**)&newlocinfo->lc_category[MSVCRT_LC_COLLATE].locale); - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_COLLATE].refcount, - (void**)&newlocinfo->lc_category[MSVCRT_LC_COLLATE].refcount); - } - - if(locinfo->lc_handle[MSVCRT_LC_CTYPE]!=newlocinfo->lc_handle[MSVCRT_LC_CTYPE] - || locinfo->lc_id[MSVCRT_LC_CTYPE].wCodePage!=newlocinfo->lc_id[MSVCRT_LC_CTYPE].wCodePage) { - locinfo->lc_handle[MSVCRT_LC_CTYPE] = - newlocinfo->lc_handle[MSVCRT_LC_CTYPE]; - locinfo->lc_id[MSVCRT_LC_CTYPE] = - newlocinfo->lc_id[MSVCRT_LC_CTYPE]; - - locinfo->lc_codepage = newlocinfo->lc_codepage; - locinfo->lc_clike = newlocinfo->lc_clike; - locinfo->mb_cur_max = newlocinfo->mb_cur_max; - - swap_pointers((void**)&locinfo->ctype1_refcount, - (void**)&newlocinfo->ctype1_refcount); - swap_pointers((void**)&locinfo->ctype1, (void**)&newlocinfo->ctype1); - swap_pointers((void**)&locinfo->pctype, (void**)&newlocinfo->pctype); - swap_pointers((void**)&locinfo->pclmap, (void**)&newlocinfo->pclmap); - swap_pointers((void**)&locinfo->pcumap, (void**)&newlocinfo->pcumap); - -#if _MSVCR_VER >= 110 - swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_CTYPE], - (void**)&newlocinfo->lc_name[MSVCRT_LC_CTYPE]); -#endif - } - if(newlocinfo->lc_category[MSVCRT_LC_CTYPE].locale) { - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_CTYPE].locale, - (void**)&newlocinfo->lc_category[MSVCRT_LC_CTYPE].locale); - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_CTYPE].refcount, - (void**)&newlocinfo->lc_category[MSVCRT_LC_CTYPE].refcount); - } - - if(newlocinfo->lc_category[MSVCRT_LC_MONETARY].locale) { - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_MONETARY].locale, - (void**)&newlocinfo->lc_category[MSVCRT_LC_MONETARY].locale); - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_MONETARY].refcount, - (void**)&newlocinfo->lc_category[MSVCRT_LC_MONETARY].refcount); - } - - if(newlocinfo->lc_category[MSVCRT_LC_NUMERIC].locale) { - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_NUMERIC].locale, - (void**)&newlocinfo->lc_category[MSVCRT_LC_NUMERIC].locale); - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_NUMERIC].refcount, - (void**)&newlocinfo->lc_category[MSVCRT_LC_NUMERIC].refcount); - } - - if((locinfo->lc_handle[MSVCRT_LC_MONETARY]!=newlocinfo->lc_handle[MSVCRT_LC_MONETARY] - || locinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage!=newlocinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage) - && (locinfo->lc_handle[MSVCRT_LC_NUMERIC]!=newlocinfo->lc_handle[MSVCRT_LC_NUMERIC] - || locinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage!=newlocinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage)) { - locinfo->lc_handle[MSVCRT_LC_MONETARY] = - newlocinfo->lc_handle[MSVCRT_LC_MONETARY]; - locinfo->lc_id[MSVCRT_LC_MONETARY] = - newlocinfo->lc_id[MSVCRT_LC_MONETARY]; - locinfo->lc_handle[MSVCRT_LC_NUMERIC] = - newlocinfo->lc_handle[MSVCRT_LC_NUMERIC]; - locinfo->lc_id[MSVCRT_LC_NUMERIC] = - newlocinfo->lc_id[MSVCRT_LC_NUMERIC]; - swap_pointers((void**)&locinfo->lconv, (void**)&newlocinfo->lconv); -#if _MSVCR_VER >= 110 - swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_MONETARY], - (void**)&newlocinfo->lc_name[MSVCRT_LC_MONETARY]); - swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_NUMERIC], - (void**)&newlocinfo->lc_name[MSVCRT_LC_NUMERIC]); -#endif - } else { - if(locinfo->lc_handle[MSVCRT_LC_MONETARY]!=newlocinfo->lc_handle[MSVCRT_LC_MONETARY] - || locinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage!=newlocinfo->lc_id[MSVCRT_LC_MONETARY].wCodePage) { - locinfo->lc_handle[MSVCRT_LC_MONETARY] = - newlocinfo->lc_handle[MSVCRT_LC_MONETARY]; - locinfo->lc_id[MSVCRT_LC_MONETARY] = - newlocinfo->lc_id[MSVCRT_LC_MONETARY]; - - swap_pointers((void**)&locinfo->lconv->int_curr_symbol, - (void**)&newlocinfo->lconv->int_curr_symbol); - swap_pointers((void**)&locinfo->lconv->currency_symbol, - (void**)&newlocinfo->lconv->currency_symbol); - swap_pointers((void**)&locinfo->lconv->mon_decimal_point, - (void**)&newlocinfo->lconv->mon_decimal_point); - swap_pointers((void**)&locinfo->lconv->mon_thousands_sep, - (void**)&newlocinfo->lconv->mon_thousands_sep); - swap_pointers((void**)&locinfo->lconv->mon_grouping, - (void**)&newlocinfo->lconv->mon_grouping); - swap_pointers((void**)&locinfo->lconv->positive_sign, - (void**)&newlocinfo->lconv->positive_sign); - swap_pointers((void**)&locinfo->lconv->negative_sign, - (void**)&newlocinfo->lconv->negative_sign); - -#if _MSVCR_VER >= 100 - swap_pointers((void**)&locinfo->lconv->_W_int_curr_symbol, - (void**)&newlocinfo->lconv->_W_int_curr_symbol); - swap_pointers((void**)&locinfo->lconv->_W_currency_symbol, - (void**)&newlocinfo->lconv->_W_currency_symbol); - swap_pointers((void**)&locinfo->lconv->_W_mon_decimal_point, - (void**)&newlocinfo->lconv->_W_mon_decimal_point); - swap_pointers((void**)&locinfo->lconv->_W_mon_thousands_sep, - (void**)&newlocinfo->lconv->_W_mon_thousands_sep); - swap_pointers((void**)&locinfo->lconv->_W_positive_sign, - (void**)&newlocinfo->lconv->_W_positive_sign); - swap_pointers((void**)&locinfo->lconv->_W_negative_sign, - (void**)&newlocinfo->lconv->_W_negative_sign); -#endif - - locinfo->lconv->int_frac_digits = newlocinfo->lconv->int_frac_digits; - locinfo->lconv->frac_digits = newlocinfo->lconv->frac_digits; - locinfo->lconv->p_cs_precedes = newlocinfo->lconv->p_cs_precedes; - locinfo->lconv->p_sep_by_space = newlocinfo->lconv->p_sep_by_space; - locinfo->lconv->n_cs_precedes = newlocinfo->lconv->n_cs_precedes; - locinfo->lconv->n_sep_by_space = newlocinfo->lconv->n_sep_by_space; - locinfo->lconv->p_sign_posn = newlocinfo->lconv->p_sign_posn; - locinfo->lconv->n_sign_posn = newlocinfo->lconv->n_sign_posn; - -#if _MSVCR_VER >= 110 - swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_MONETARY], - (void**)&newlocinfo->lc_name[MSVCRT_LC_MONETARY]); -#endif - } - - if(locinfo->lc_handle[MSVCRT_LC_NUMERIC]!=newlocinfo->lc_handle[MSVCRT_LC_NUMERIC] - || locinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage!=newlocinfo->lc_id[MSVCRT_LC_NUMERIC].wCodePage) { - locinfo->lc_handle[MSVCRT_LC_NUMERIC] = - newlocinfo->lc_handle[MSVCRT_LC_NUMERIC]; - locinfo->lc_id[MSVCRT_LC_NUMERIC] = - newlocinfo->lc_id[MSVCRT_LC_NUMERIC]; - - swap_pointers((void**)&locinfo->lconv->decimal_point, - (void**)&newlocinfo->lconv->decimal_point); - swap_pointers((void**)&locinfo->lconv->thousands_sep, - (void**)&newlocinfo->lconv->thousands_sep); - swap_pointers((void**)&locinfo->lconv->grouping, - (void**)&newlocinfo->lconv->grouping); - -#if _MSVCR_VER >= 100 - swap_pointers((void**)&locinfo->lconv->_W_decimal_point, - (void**)&newlocinfo->lconv->_W_decimal_point); - swap_pointers((void**)&locinfo->lconv->_W_thousands_sep, - (void**)&newlocinfo->lconv->_W_thousands_sep); -#endif - -#if _MSVCR_VER >= 110 - swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_NUMERIC], - (void**)&newlocinfo->lc_name[MSVCRT_LC_NUMERIC]); -#endif - } - } - - if(locinfo->lc_handle[MSVCRT_LC_TIME]!=newlocinfo->lc_handle[MSVCRT_LC_TIME] - || locinfo->lc_id[MSVCRT_LC_TIME].wCodePage!=newlocinfo->lc_id[MSVCRT_LC_TIME].wCodePage) { - locinfo->lc_handle[MSVCRT_LC_TIME] = - newlocinfo->lc_handle[MSVCRT_LC_TIME]; - locinfo->lc_id[MSVCRT_LC_TIME] = - newlocinfo->lc_id[MSVCRT_LC_TIME]; - swap_pointers((void**)&locinfo->lc_time_curr, - (void**)&newlocinfo->lc_time_curr); - -#if _MSVCR_VER >= 110 - swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_TIME], - (void**)&newlocinfo->lc_name[MSVCRT_LC_TIME]); -#endif - } - if(newlocinfo->lc_category[MSVCRT_LC_TIME].locale) { - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_TIME].locale, - (void**)&newlocinfo->lc_category[MSVCRT_LC_TIME].locale); - swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_TIME].refcount, - (void**)&newlocinfo->lc_category[MSVCRT_LC_TIME].refcount); - } - + locinfo = newlocinfo; + swap_pointers((void **)get_locinfo_ptr(), (void **)&newlocinfo); free_locinfo(newlocinfo); _unlock_locales();
Signed-off-by: Chip Davis cdavis@codeweavers.com --- v3: Make sure we decrement refcounts, too. --- dlls/msvcr90/tests/msvcr90.c | 46 ++++++++++++++++++------------------ dlls/msvcrt/locale.c | 30 +++++++++++++++++++---- 2 files changed, 48 insertions(+), 28 deletions(-)
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c index eda774210c7b..c2cf14f37e4c 100644 --- a/dlls/msvcr90/tests/msvcr90.c +++ b/dlls/msvcr90/tests/msvcr90.c @@ -2027,14 +2027,14 @@ static void test__get_current_locale(void) "same refcount pointers for LC_COLLATE\n"); ok(*l->locinfo->lc_category[LC_COLLATE].refcount == 1, "refcount = %d\n", *l->locinfo->lc_category[LC_COLLATE].refcount); - todo_wine ok(*l2->locinfo->lc_category[LC_COLLATE].refcount == 2, "refcount = %d\n", + ok(*l2->locinfo->lc_category[LC_COLLATE].refcount == 2, "refcount = %d\n", *l2->locinfo->lc_category[LC_COLLATE].refcount); for(i = LC_CTYPE; i <= LC_MAX; i++) { ok(l->locinfo->lc_category[i].locale == l2->locinfo->lc_category[i].locale, "different locale name pointers for category %d\n", i); ok(l->locinfo->lc_category[i].refcount == l2->locinfo->lc_category[i].refcount, "different refcount pointers for category %d\n", i); - todo_wine ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n", + ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n", *l->locinfo->lc_category[i].refcount, i); }
@@ -2051,23 +2051,23 @@ static void test__get_current_locale(void) ok(l->locinfo->pclmap == l2->locinfo->pclmap, "different clmap pointers\n"); ok(l->locinfo->pcumap == l2->locinfo->pcumap, "different cumap pointers\n"); ok(l->locinfo->ctype1_refcount == l2->locinfo->ctype1_refcount, "different ctype1_refcount pointers\n"); - todo_wine ok(*l->locinfo->ctype1_refcount == 3, "refcount = %d\n", *l->locinfo->ctype1_refcount); + ok(*l->locinfo->ctype1_refcount == 3, "refcount = %d\n", *l->locinfo->ctype1_refcount);
ok(l->locinfo->lconv == l2->locinfo->lconv, "different lconv pointers\n"); ok(l->locinfo->lconv_intl_refcount == l2->locinfo->lconv_intl_refcount, "different lconv_intl_refcount pointers\n"); - todo_wine ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); + ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount);
ok(l->locinfo->lconv->decimal_point == l2->locinfo->lconv->decimal_point, "different LC_NUMERIC pointers\n"); ok(l->locinfo->lconv_num_refcount == l2->locinfo->lconv_num_refcount, "different lconv_num_refcount pointers\n"); - todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount); + ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount);
ok(l->locinfo->lconv->currency_symbol == l2->locinfo->lconv->currency_symbol, "different LC_MONETARY pointers\n"); ok(l->locinfo->lconv_mon_refcount == l2->locinfo->lconv_mon_refcount, "different lconv_mon_refcount pointers\n"); - todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); + ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount);
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); - todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount); + ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
p__free_locale(l2);
@@ -2084,7 +2084,7 @@ static void test__get_current_locale(void) "same refcount pointers for category %d\n", i); ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", *l->locinfo->lc_category[i].refcount, i); - todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", + ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", *l2->locinfo->lc_category[i].refcount, i); } for(i = LC_MONETARY; i <= LC_MAX; i++) { @@ -2092,7 +2092,7 @@ static void test__get_current_locale(void) "different locale name pointers for category %d\n", i); ok(l->locinfo->lc_category[i].refcount == l2->locinfo->lc_category[i].refcount, "different refcount pointers for category %d\n", i); - todo_wine ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n", + ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n", *l->locinfo->lc_category[i].refcount, i); }
@@ -2114,19 +2114,19 @@ static void test__get_current_locale(void)
ok(l->locinfo->lconv == l2->locinfo->lconv, "different lconv pointers\n"); ok(l->locinfo->lconv_intl_refcount == l2->locinfo->lconv_intl_refcount, "different lconv_intl_refcount pointers\n"); - todo_wine ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); + ok(*l->locinfo->lconv_intl_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_intl_refcount);
ok(l->locinfo->lconv->decimal_point == l2->locinfo->lconv->decimal_point, "different LC_NUMERIC pointers\n"); ok(l->locinfo->lconv_num_refcount == l2->locinfo->lconv_num_refcount, "different lconv_num_refcount pointers\n"); - todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount); + ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount);
ok(l->locinfo->lconv->currency_symbol == l2->locinfo->lconv->currency_symbol, "different LC_MONETARY pointers\n"); ok(l->locinfo->lconv_mon_refcount == l2->locinfo->lconv_mon_refcount, "different lconv_mon_refcount pointers\n"); - todo_wine ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount); + ok(*l->locinfo->lconv_mon_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_mon_refcount);
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); - todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount); + ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
p__free_locale(l2);
@@ -2143,7 +2143,7 @@ static void test__get_current_locale(void) "same refcount pointers for category %d\n", i); ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", *l->locinfo->lc_category[i].refcount, i); - todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", + ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", *l2->locinfo->lc_category[i].refcount, i); } for(i = LC_NUMERIC; i <= LC_MAX; i++) { @@ -2151,7 +2151,7 @@ static void test__get_current_locale(void) "different locale name pointers for category %d\n", i); ok(l->locinfo->lc_category[i].refcount == l2->locinfo->lc_category[i].refcount, "different refcount pointers for category %d\n", i); - todo_wine ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n", + ok(*l->locinfo->lc_category[i].refcount == 3, "refcount = %d for category %d\n", *l->locinfo->lc_category[i].refcount, i); }
@@ -2174,11 +2174,11 @@ static void test__get_current_locale(void) ok(l->locinfo->lconv != l2->locinfo->lconv, "same lconv pointers\n"); ok(l->locinfo->lconv_intl_refcount != l2->locinfo->lconv_intl_refcount, "same lconv_intl_refcount pointers\n"); ok(*l->locinfo->lconv_intl_refcount == 1, "refcount = %d\n", *l->locinfo->lconv_intl_refcount); - todo_wine ok(*l2->locinfo->lconv_intl_refcount == 2, "refcount = %d\n", *l2->locinfo->lconv_intl_refcount); + ok(*l2->locinfo->lconv_intl_refcount == 2, "refcount = %d\n", *l2->locinfo->lconv_intl_refcount);
ok(l->locinfo->lconv->decimal_point == l2->locinfo->lconv->decimal_point, "different LC_NUMERIC pointers\n"); ok(l->locinfo->lconv_num_refcount == l2->locinfo->lconv_num_refcount, "different lconv_num_refcount pointers\n"); - todo_wine ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount); + ok(*l->locinfo->lconv_num_refcount == 3, "refcount = %d\n", *l->locinfo->lconv_num_refcount);
ok(l->locinfo->lconv->currency_symbol != l2->locinfo->lconv->currency_symbol, "same LC_MONETARY pointers\n"); ok(l->locinfo->lconv_mon_refcount != l2->locinfo->lconv_mon_refcount, "same lconv_mon_refcount pointers\n"); @@ -2187,7 +2187,7 @@ static void test__get_current_locale(void)
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); - todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount); + ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
p__free_locale(l2);
@@ -2204,14 +2204,14 @@ static void test__get_current_locale(void) "same refcount pointers for category %d\n", i); ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", *l->locinfo->lc_category[i].refcount, i); - todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", + ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", *l2->locinfo->lc_category[i].refcount, i); } ok(l->locinfo->lc_category[LC_TIME].locale == l2->locinfo->lc_category[LC_TIME].locale, "different locale name pointers for LC_TIME\n"); ok(l->locinfo->lc_category[LC_TIME].refcount == l2->locinfo->lc_category[LC_TIME].refcount, "different refcount pointers for LC_TIME\n"); - todo_wine ok(*l->locinfo->lc_category[LC_TIME].refcount == 3, "refcount = %d\n", + ok(*l->locinfo->lc_category[LC_TIME].refcount == 3, "refcount = %d\n", *l->locinfo->lc_category[LC_TIME].refcount);
ok(l->locinfo->lc_collate_cp != l2->locinfo->lc_collate_cp, "same lc_collate_cp %u, %u\n", @@ -2247,7 +2247,7 @@ static void test__get_current_locale(void)
ok(l->locinfo->lc_time_curr == l2->locinfo->lc_time_curr, "different lc_time_curr pointers\n"); ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); - todo_wine ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount); + ok(l->locinfo->lc_time_curr->refcount == 3, "refcount = %d\n", l->locinfo->lc_time_curr->refcount);
p__free_locale(l2);
@@ -2264,7 +2264,7 @@ static void test__get_current_locale(void) "same refcount pointers for category %d\n", i); ok(*l->locinfo->lc_category[i].refcount == 1, "refcount = %d for category %d\n", *l->locinfo->lc_category[i].refcount, i); - todo_wine ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", + ok(*l2->locinfo->lc_category[i].refcount == 2, "refcount = %d for category %d\n", *l2->locinfo->lc_category[i].refcount, i); }
@@ -2303,7 +2303,7 @@ static void test__get_current_locale(void) ok(l->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l->locinfo->lc_time_curr->unk); ok(l->locinfo->lc_time_curr->refcount == 1, "refcount = %d\n", l->locinfo->lc_time_curr->refcount); ok(l2->locinfo->lc_time_curr->unk == 1, "unk = %d\n", l2->locinfo->lc_time_curr->unk); - todo_wine ok(l2->locinfo->lc_time_curr->refcount == 3 || broken(l2->locinfo->lc_time_curr->refcount == 2), + ok(l2->locinfo->lc_time_curr->refcount == 3 || broken(l2->locinfo->lc_time_curr->refcount == 2), "refcount = %d\n", l2->locinfo->lc_time_curr->refcount);
p__free_locale(l2); diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index a1f269e01cf4..b577260edc98 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -921,6 +921,27 @@ int CDECL ___lc_collate_cp_func(void) return get_locinfo()->lc_collate_cp; }
+/* INTERNAL: increases all reference counts in threadlocinfo struct */ +MSVCRT_pthreadlocinfo grab_locinfo(MSVCRT_pthreadlocinfo locinfo) +{ + int i; + + InterlockedIncrement(&locinfo->refcount); + for(i=MSVCRT_LC_MIN+1; i<=MSVCRT_LC_MAX; i++) + InterlockedIncrement(locinfo->lc_category[i].refcount); + if(locinfo->lconv_intl_refcount) + InterlockedIncrement(locinfo->lconv_intl_refcount); + if(locinfo->lconv_num_refcount) + InterlockedIncrement(locinfo->lconv_num_refcount); + if(locinfo->lconv_mon_refcount) + InterlockedIncrement(locinfo->lconv_mon_refcount); + if(locinfo->ctype1_refcount) + InterlockedIncrement(locinfo->ctype1_refcount); + InterlockedIncrement(&locinfo->lc_time_curr->refcount); + + return locinfo; +} + /* INTERNAL: frees MSVCRT_pthreadlocinfo struct */ void free_locinfo(MSVCRT_pthreadlocinfo locinfo) { @@ -929,9 +950,6 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo) if(!locinfo) return;
- if(InterlockedDecrement(&locinfo->refcount)) - return; - for(i=MSVCRT_LC_MIN+1; i<=MSVCRT_LC_MAX; i++) { #if _MSVCR_VER >= 110 MSVCRT_free(locinfo->lc_name[i]); @@ -993,6 +1011,9 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo) && locinfo->lc_time_curr != &cloc_time_data) MSVCRT_free(locinfo->lc_time_curr);
+ if(InterlockedDecrement(&locinfo->refcount)) + return; + MSVCRT_free(locinfo); }
@@ -1017,9 +1038,8 @@ MSVCRT__locale_t CDECL MSVCRT__get_current_locale(void) if(!loc) return NULL;
- loc->locinfo = get_locinfo(); + loc->locinfo = grab_locinfo(get_locinfo()); loc->mbcinfo = get_mbcinfo(); - InterlockedIncrement(&loc->locinfo->refcount); InterlockedIncrement(&loc->mbcinfo->refcount); return loc; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=64525
Your paranoid android.
=== debian10 (32 bit report) ===
msvcrt: Unhandled exception: page fault on write access to 0x82108214 in 32-bit code (0x7bc714dd).
Report errors: msvcrt:locale crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
msvcrt: Unhandled exception: page fault on write access to 0x82108214 in 32-bit code (0x7bc714dd).
Report errors: msvcrt:locale crashed (c0000005)
=== debian10 (32 bit WoW report) ===
msvcrt: Unhandled exception: page fault on write access to 0x82108214 in 32-bit code (0x7bc714dd).
Report errors: msvcrt:locale crashed (c0000005)
=== debian10 (64 bit WoW report) ===
msvcrt: Unhandled exception: page fault on write access to 0x82108214 in 32-bit code (0x7bc714dd).
Report errors: msvcrt:locale crashed (c0000005)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=64524
Your paranoid android.
=== debian10 (32 bit report) ===
msvcrt: Unhandled exception: page fault on write access to 0x82108214 in 32-bit code (0x7bc714dd).
Report errors: msvcrt:locale crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
msvcrt: Unhandled exception: page fault on write access to 0x82108214 in 32-bit code (0x7bc714dd).
Report errors: msvcrt:locale crashed (c0000005)
=== debian10 (32 bit WoW report) ===
msvcrt: Unhandled exception: page fault on write access to 0x82108214 in 32-bit code (0x7bc714dd).
Report errors: msvcrt:locale crashed (c0000005)
=== debian10 (64 bit WoW report) ===
msvcrt: Unhandled exception: page fault on write access to 0x82108214 in 32-bit code (0x7bc714dd).
Report errors: msvcrt:locale crashed (c0000005)
Ugh, heap corruption... which mysteriously vanishes in patch 7. This is gonna be fun to debug. /s
February 4, 2020 12:47 PM, "Marvin" testbot@winehq.org wrote:
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=64524
Your paranoid android.
=== debian10 (32 bit report) ===
msvcrt: Unhandled exception: page fault on write access to 0x82108214 in 32-bit code (0x7bc714dd).
Report errors: msvcrt:locale crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
msvcrt: Unhandled exception: page fault on write access to 0x82108214 in 32-bit code (0x7bc714dd).
Report errors: msvcrt:locale crashed (c0000005)
=== debian10 (32 bit WoW report) ===
msvcrt: Unhandled exception: page fault on write access to 0x82108214 in 32-bit code (0x7bc714dd).
Report errors: msvcrt:locale crashed (c0000005)
=== debian10 (64 bit WoW report) ===
msvcrt: Unhandled exception: page fault on write access to 0x82108214 in 32-bit code (0x7bc714dd).
Report errors: msvcrt:locale crashed (c0000005)
Chip
Hi Chip,
On 2/4/20 9:19 PM, Chip Davis wrote:
Ugh, heap corruption... which mysteriously vanishes in patch 7. This is gonna be fun to debug. /s
Note that patch 7 incorrectly checks if global locale related externs should be updated. I guess it might be related to why it stops crashing with this patch.
Cheers, Piotr