msvcrt: Swap the threadlocinfo pointers in setlocale().

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>
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Chip Davis 2020-11-18 17:26:24 +01:00 committed by Alexandre Julliard
parent 5d07f809a0
commit f248221870
2 changed files with 161 additions and 353 deletions

View File

@ -2002,20 +2002,18 @@ static void test__get_current_locale(void)
return;
}
todo_wine {
ok(!strcmp(l->locinfo->lc_category[LC_COLLATE].locale, "C"),
"LC_COLLATE = \"%s\"\n", l->locinfo->lc_category[LC_COLLATE].locale);
ok(!strcmp(l->locinfo->lc_category[LC_CTYPE].locale, "C"),
"LC_CTYPE = \"%s\"\n", l->locinfo->lc_category[LC_CTYPE].locale);
ok(!strcmp(l->locinfo->lc_category[LC_MONETARY].locale, "C"),
"LC_MONETARY = \"%s\"\n", l->locinfo->lc_category[LC_MONETARY].locale);
ok(!strcmp(l->locinfo->lc_category[LC_NUMERIC].locale, "C"),
"LC_NUMERIC = \"%s\"\n", l->locinfo->lc_category[LC_NUMERIC].locale);
ok(!strcmp(l->locinfo->lc_category[LC_TIME].locale, "C"),
"LC_TIME = \"%s\"\n", l->locinfo->lc_category[LC_TIME].locale);
}
ok(!strcmp(l->locinfo->lc_category[LC_COLLATE].locale, "C"),
"LC_COLLATE = \"%s\"\n", l->locinfo->lc_category[LC_COLLATE].locale);
ok(!strcmp(l->locinfo->lc_category[LC_CTYPE].locale, "C"),
"LC_CTYPE = \"%s\"\n", l->locinfo->lc_category[LC_CTYPE].locale);
ok(!strcmp(l->locinfo->lc_category[LC_MONETARY].locale, "C"),
"LC_MONETARY = \"%s\"\n", l->locinfo->lc_category[LC_MONETARY].locale);
ok(!strcmp(l->locinfo->lc_category[LC_NUMERIC].locale, "C"),
"LC_NUMERIC = \"%s\"\n", l->locinfo->lc_category[LC_NUMERIC].locale);
ok(!strcmp(l->locinfo->lc_category[LC_TIME].locale, "C"),
"LC_TIME = \"%s\"\n", l->locinfo->lc_category[LC_TIME].locale);
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");
@ -2026,19 +2024,15 @@ 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(*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].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");
todo_wine 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);
for(i = LC_CTYPE; i <= LC_MAX; i++) {
@ -2050,7 +2044,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",
@ -2092,20 +2086,16 @@ 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(*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].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);
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[i].refcount == 1, "refcount = %d for category %d\n",
*l->locinfo->lc_category[i].refcount, i);
}
@ -2118,26 +2108,21 @@ 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_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n",
l->locinfo->lc_codepage, l2->locinfo->lc_codepage);
todo_wine 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);
}
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");
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");
@ -2164,23 +2149,21 @@ static void test__get_current_locale(void)
p__free_locale(l2);
p_setlocale(LC_MONETARY, "C");
trace("before: %s\n", p_setlocale(LC_ALL, NULL));
trace("current locale is: %s\n", p_setlocale(LC_MONETARY, "C"));
trace("after: %s\n", p_setlocale(LC_ALL, NULL));
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(*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].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);
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[i].refcount == 1, "refcount = %d for category %d\n",
*l->locinfo->lc_category[i].refcount, i);
}
@ -2193,32 +2176,25 @@ 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_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n",
l->locinfo->lc_codepage, l2->locinfo->lc_codepage);
todo_wine 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);
}
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");
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 != 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");
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");
@ -2227,16 +2203,12 @@ static void test__get_current_locale(void)
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");
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);
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, "null refcount pointer in non-C locale\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");
@ -2248,20 +2220,16 @@ 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(*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].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);
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[i].refcount == 1, "refcount = %d for category %d\n",
*l->locinfo->lc_category[i].refcount, i);
}
@ -2272,53 +2240,39 @@ 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_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n",
l->locinfo->lc_codepage, l2->locinfo->lc_codepage);
todo_wine 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);
}
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");
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, "null refcount pointer in non-C locale\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, "null refcount pointer in non-C locale\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, "null refcount pointer in non-C locale\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");
@ -2330,76 +2284,58 @@ 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(*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].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);
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[i].refcount == 1, "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_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_codepage != l2->locinfo->lc_codepage, "same lc_codepages %u, %u\n",
l->locinfo->lc_codepage, l2->locinfo->lc_codepage);
todo_wine 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);
}
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");
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, "null refcount pointer in non-C locale\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, "null refcount pointer in non-C locale\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, "null refcount pointer in non-C locale\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);

View File

@ -585,26 +585,21 @@ static BOOL update_threadlocinfo_category(LCID lcid, unsigned short cp,
return TRUE;
}
/* INTERNAL: swap pointers values */
static inline void swap_pointers(void **p1, void **p2) {
void *hlp;
hlp = *p1;
*p1 = *p2;
*p2 = hlp;
}
/* INTERNAL: returns pthreadlocinfo struct */
MSVCRT_pthreadlocinfo CDECL get_locinfo(void) {
static MSVCRT_pthreadlocinfo* CDECL 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 pthreadlocinfo struct */
/* INTERNAL: returns threadlocinfo struct */
MSVCRT_pthreadlocinfo CDECL get_locinfo(void) {
return *get_locinfo_ptr();
}
/* INTERNAL: returns pthreadmbcinfo struct */
MSVCRT_pthreadmbcinfo CDECL get_mbcinfo(void) {
thread_data_t *data = msvcrt_get_thread_data();
@ -1996,8 +1991,8 @@ MSVCRT__locale_t CDECL MSVCRT__wcreate_locale(int category, const MSVCRT_wchar_t
*/
char* CDECL MSVCRT_setlocale(int category, const char* locale)
{
MSVCRT_pthreadlocinfo locinfo = get_locinfo();
MSVCRT_pthreadlocinfo newlocinfo;
MSVCRT_pthreadlocinfo *plocinfo = get_locinfo_ptr();
MSVCRT_pthreadlocinfo locinfo = *plocinfo, newlocinfo;
if(category<MSVCRT_LC_MIN || category>MSVCRT_LC_MAX)
return NULL;
@ -2015,152 +2010,29 @@ char* CDECL MSVCRT_setlocale(int category, const char* locale)
return NULL;
}
_lock_locales();
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];
swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_COLLATE].wrefcount,
(void**)&newlocinfo->lc_category[MSVCRT_LC_COLLATE].wrefcount);
#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);
swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_CTYPE].wrefcount,
(void**)&newlocinfo->lc_category[MSVCRT_LC_CTYPE].wrefcount);
#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(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->lc_category[MSVCRT_LC_MONETARY].wrefcount,
(void**)&newlocinfo->lc_category[MSVCRT_LC_MONETARY].wrefcount);
#if _MSVCR_VER >= 110
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];
swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_NUMERIC].wrefcount,
(void**)&newlocinfo->lc_category[MSVCRT_LC_NUMERIC].wrefcount);
#if _MSVCR_VER >= 110
swap_pointers((void**)&locinfo->lc_name[MSVCRT_LC_NUMERIC],
(void**)&newlocinfo->lc_name[MSVCRT_LC_NUMERIC]);
#endif
}
swap_pointers((void**)&locinfo->lconv, (void**)&newlocinfo->lconv);
swap_pointers((void**)&locinfo->lconv_num_refcount, (void**)&newlocinfo->lconv_num_refcount);
swap_pointers((void**)&locinfo->lconv_mon_refcount, (void**)&newlocinfo->lconv_mon_refcount);
swap_pointers((void**)&locinfo->lconv_intl_refcount, (void**)&newlocinfo->lconv_intl_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_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);
swap_pointers((void**)&locinfo->lc_category[MSVCRT_LC_TIME].wrefcount,
(void**)&newlocinfo->lc_category[MSVCRT_LC_TIME].wrefcount);
#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);
}
free_locinfo(newlocinfo);
_lock_locales();
free_locinfo(locinfo);
*plocinfo = newlocinfo;
_unlock_locales();
if(locinfo == MSVCRT_locale->locinfo) {
if(newlocinfo == MSVCRT_locale->locinfo) {
int i;
MSVCRT___lc_codepage = locinfo->lc_codepage;
MSVCRT___lc_collate_cp = locinfo->lc_collate_cp;
MSVCRT___mb_cur_max = locinfo->mb_cur_max;
MSVCRT__pctype = locinfo->pctype;
MSVCRT___lc_codepage = newlocinfo->lc_codepage;
MSVCRT___lc_collate_cp = newlocinfo->lc_collate_cp;
MSVCRT___mb_cur_max = newlocinfo->mb_cur_max;
MSVCRT__pctype = newlocinfo->pctype;
for(i=MSVCRT_LC_MIN; i<=MSVCRT_LC_MAX; i++)
MSVCRT___lc_handle[i] = MSVCRT_locale->locinfo->lc_handle[i];
}
if(category == MSVCRT_LC_ALL)
return construct_lc_all(locinfo);
return construct_lc_all(newlocinfo);
return locinfo->lc_category[category].locale;
return newlocinfo->lc_category[category].locale;
}
/*********************************************************************