未验证 提交 c1f2352b 编写于 作者: O openharmony_ci 提交者: Gitee

!974 Fix `setlocale` return value to be same as Linux

Merge pull request !974 from zzulilyw/master
...@@ -55,7 +55,7 @@ void duplocale_0200(void) ...@@ -55,7 +55,7 @@ void duplocale_0200(void)
locale_t global = duplocale(LC_GLOBAL_LOCALE); locale_t global = duplocale(LC_GLOBAL_LOCALE);
EXPECT_PTRNE("duplocale_0200", global, NULL); EXPECT_PTRNE("duplocale_0200", global, NULL);
locale_t newlocale_ = newlocale(LC_ALL_MASK, "en-US", NULL); locale_t newlocale_ = newlocale(LC_ALL_MASK, "en_US", NULL);
EXPECT_PTRNE("duplocale_0200", newlocale_, NULL); EXPECT_PTRNE("duplocale_0200", newlocale_, NULL);
locale_t clonelocale = duplocale(newlocale_); locale_t clonelocale = duplocale(newlocale_);
...@@ -70,6 +70,10 @@ void duplocale_0200(void) ...@@ -70,6 +70,10 @@ void duplocale_0200(void)
freelocale(newlocale_); freelocale(newlocale_);
newlocale_ = NULL; newlocale_ = NULL;
} }
if (global) {
freelocale(global);
global = NULL;
}
} }
int main(void) int main(void)
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
/** /**
* @tc.name : langinfo_0100 * @tc.name : langinfo_0100
* @tc.desc : Asserts whether the nl_langinfo function succeeds in reading data * @tc.desc : Asserts whether the nl_langinfo function succeeds in reading data
* from the MUSL_LOCPATH environment variable set to zh_CN. Utf-8 * from the MUSL_LOCPATH environment variable set to zh_CN. Utf-8(There is no file in "/etc/locale" now)
* @tc.level : Level 0 * @tc.level : Level 0
*/ */
void langinfo_0100(void) void langinfo_0100(void)
...@@ -36,8 +36,8 @@ void langinfo_0100(void) ...@@ -36,8 +36,8 @@ void langinfo_0100(void)
return; return;
} }
lo = setlocale(LC_TIME, "zh_CN.UTF-8"); lo = setlocale(LC_TIME, "zh_CN.UTF-8");
if (!lo) { if (lo) {
EXPECT_PTRNE("nl_langinfo_0100", lo, NULL); t_error("nl_langinfo_0100 failed [%s] != NULL\n", lo);
return; return;
} }
char *ptr = nl_langinfo(DAY_2); char *ptr = nl_langinfo(DAY_2);
...@@ -66,7 +66,8 @@ void nl_langinfo_0200() ...@@ -66,7 +66,8 @@ void nl_langinfo_0200()
/** /**
* @tc.name : nl_langinfo_0300 * @tc.name : nl_langinfo_0300
* @tc.desc : Assert whether the LC_TIME data type is set to zh_CN.UTF-8 through setlocale, * @tc.desc : Assert whether the LC_TIME data type is set to zh_CN.UTF-8 through setlocale,
* and whether the return value is empty when the abnormal time data is passed to the nl_langinfo function * and whether the return value is empty when the abnormal time data is passed to the nl_langinfo function.
* MUSL_LOCPATH is `invalid` in system environment so it should be changed to `invalid` check
* @tc.level : Level 2 * @tc.level : Level 2
*/ */
void nl_langinfo_0300() void nl_langinfo_0300()
...@@ -77,8 +78,8 @@ void nl_langinfo_0300() ...@@ -77,8 +78,8 @@ void nl_langinfo_0300()
return; return;
} }
lo = setlocale(LC_TIME, "zh_CN.UTF-8"); lo = setlocale(LC_TIME, "zh_CN.UTF-8");
if (!lo) { if (lo) {
EXPECT_PTRNE("nl_langinfo_0300", lo, NULL); t_error("nl_langinfo_0300 failed [%s] != NULL\n", lo);
return; return;
} }
char *ptr = nl_langinfo(TIME_ERROR_INFO); char *ptr = nl_langinfo(TIME_ERROR_INFO);
...@@ -89,13 +90,14 @@ void nl_langinfo_0300() ...@@ -89,13 +90,14 @@ void nl_langinfo_0300()
* @tc.name : nl_langinfo_0400 * @tc.name : nl_langinfo_0400
* @tc.desc : Assert whether the data type of LC_MESSAGES is set to zh_CN.UTF-8 through setlocale, * @tc.desc : Assert whether the data type of LC_MESSAGES is set to zh_CN.UTF-8 through setlocale,
* and whether the return value is empty when the abnormal time data is passed to the nl_langinfo function * and whether the return value is empty when the abnormal time data is passed to the nl_langinfo function
* MUSL_LOCPATH is `invalid` in system environment so it should be changed to `invalid` check
* @tc.level : Level 2 * @tc.level : Level 2
*/ */
void nl_langinfo_0400() void nl_langinfo_0400()
{ {
char *lo = setlocale(LC_MESSAGES, "zh_CN.UTF-8"); char *lo = setlocale(LC_MESSAGES, "zh_CN.UTF-8");
if (!lo) { if (lo) {
EXPECT_PTRNE("nl_langinfo_0400", lo, NULL); t_error("nl_langinfo_0400 failed [%s] != NULL\n", lo);
return; return;
} }
char *ptr = nl_langinfo(MESSAGES_ERROR_INFO); char *ptr = nl_langinfo(MESSAGES_ERROR_INFO);
......
...@@ -29,7 +29,7 @@ static const int lcMarkArry[] = { ...@@ -29,7 +29,7 @@ static const int lcMarkArry[] = {
/** /**
* @tc.name : newlocale_0100 * @tc.name : newlocale_0100
* @tc.desc : Check whether the LC_ALL type is passed to newlocale to create a custom locale environment * @tc.desc : en-US is a invalid locale. The newlocale should return null
* @tc.level : Level 0 * @tc.level : Level 0
*/ */
void newlocale_0100(void) void newlocale_0100(void)
...@@ -39,7 +39,7 @@ void newlocale_0100(void) ...@@ -39,7 +39,7 @@ void newlocale_0100(void)
EXPECT_PTRNE("newlocale_0100", lo, NULL); EXPECT_PTRNE("newlocale_0100", lo, NULL);
return; return;
} }
locale_t newlocale_ = newlocale(LC_ALL_MASK, "en-US", NULL); locale_t newlocale_ = newlocale(LC_ALL_MASK, "en_US", NULL);
EXPECT_PTRNE("newlocale_0100", newlocale_, NULL); EXPECT_PTRNE("newlocale_0100", newlocale_, NULL);
if (newlocale_) { if (newlocale_) {
...@@ -73,6 +73,7 @@ void newlocale_0200(void) ...@@ -73,6 +73,7 @@ void newlocale_0200(void)
* @tc.name : newlocale_0300 * @tc.name : newlocale_0300
* @tc.desc : Determines whether the custom locale environment is created successfully * @tc.desc : Determines whether the custom locale environment is created successfully
* by passing different LC data types to newlocale * by passing different LC data types to newlocale
* tips: en-US is a invalid locale. The newlocale should return null
* @tc.level : Level 0 * @tc.level : Level 0
*/ */
void newlocale_0300(void) void newlocale_0300(void)
...@@ -83,7 +84,7 @@ void newlocale_0300(void) ...@@ -83,7 +84,7 @@ void newlocale_0300(void)
return; return;
} }
for (int i = 0; i < sizeof(lcMarkArry) / sizeof(lcMarkArry[0]); i++) { for (int i = 0; i < sizeof(lcMarkArry) / sizeof(lcMarkArry[0]); i++) {
locale_t newlocale_ = newlocale(lcMarkArry[i], "en-US", NULL); locale_t newlocale_ = newlocale(lcMarkArry[i], "en_US", NULL);
EXPECT_PTRNE("newlocale_0300", newlocale_, NULL); EXPECT_PTRNE("newlocale_0300", newlocale_, NULL);
if (newlocale_) { if (newlocale_) {
...@@ -93,11 +94,50 @@ void newlocale_0300(void) ...@@ -93,11 +94,50 @@ void newlocale_0300(void)
} }
} }
/**
* @tc.name : newlocale_0400
* @tc.desc : Determines whether the custom locale environment is created successfully
* by passing different LC data types to newlocale
* tips: en-US is a invalid locale. The newlocale should return null
* @tc.level : Level 0
*/
void newlocale_0400(void)
{
for (int i = 0; i < sizeof(lcMarkArry) / sizeof(lcMarkArry[0]); i++) {
locale_t newlocale_ = newlocale(lcMarkArry[i], "C", NULL);
EXPECT_PTRNE("newlocale_0400", newlocale_, NULL);
if (newlocale_) {
freelocale(newlocale_);
newlocale_ = NULL;
}
newlocale_ = newlocale(lcMarkArry[i], "C.UTF-8", NULL);
EXPECT_PTRNE("newlocale_0400", newlocale_, NULL);
if (newlocale_) {
freelocale(newlocale_);
newlocale_ = NULL;
}
}
}
void newlocale_0500(void)
{
locale_t newlocale_ = newlocale(LC_ALL_MASK, "de.UTF-8", NULL);
EXPECT_PTREQ("newlocale_0500", newlocale_, NULL);
if (newlocale_) {
freelocale(newlocale_);
newlocale_ = NULL;
}
}
int main(void) int main(void)
{ {
newlocale_0100(); newlocale_0100();
newlocale_0200(); newlocale_0200();
newlocale_0300(); newlocale_0300();
newlocale_0400();
return t_status; return t_status;
} }
\ No newline at end of file
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <locale.h> #include <locale.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <time.h>
#include <stdio.h>
#include "functionalext.h" #include "functionalext.h"
#define TEST_LC_COUNT 7 #define TEST_LC_COUNT 7
...@@ -111,18 +113,17 @@ void setlocale_0400(void) ...@@ -111,18 +113,17 @@ void setlocale_0400(void)
for (unsigned int i = 0; i < sizeof(envforlocale) / sizeof(envforlocale[0]); i++) { for (unsigned int i = 0; i < sizeof(envforlocale) / sizeof(envforlocale[0]); i++) {
setenv(envforlocale[i], "da_DK", 1); setenv(envforlocale[i], "da_DK", 1);
const char *locale = setlocale(LcArry[i], ""); const char *locale = setlocale(LcArry[i], "");
if (!locale) { if (locale) {
t_error("[%s] failed\n", "setlocale_0400"); t_error("[%s] failed\n", "setlocale_0400");
return; return;
} }
EXPECT_STREQ("SetlocaleTest_0400", locale, "da_DK");
} }
} }
/** /**
* @tc.name : setlocaletest_0500 * @tc.name : setlocaletest_0500
* @tc.desc : Determines whether setlocale returns en_ZA * @tc.desc : Determines whether setlocale returns NULL
* when the character set passed in for different LC data types is set to en_ZA * when the character set passed in for invalid LC data types is set to en_ZA
* @tc.level : Level 0 * @tc.level : Level 0
*/ */
void setlocale_0500(void) void setlocale_0500(void)
...@@ -134,11 +135,10 @@ void setlocale_0500(void) ...@@ -134,11 +135,10 @@ void setlocale_0500(void)
} }
for (unsigned int i = 0; i < sizeof(LcArry) / sizeof(LcArry[0]); i++) { for (unsigned int i = 0; i < sizeof(LcArry) / sizeof(LcArry[0]); i++) {
const char *locale = setlocale(LcArry[i], "en_ZA"); const char *locale = setlocale(LcArry[i], "en_ZA");
if (locale == NULL) { if (locale) {
t_error("[%s] failed\n", "setlocale_0500"); t_error("[%s] failed\n", "setlocale_0500");
return; return;
} }
EXPECT_STREQ("SetlocaleTest_0600", locale, "en_ZA");
} }
} }
...@@ -157,22 +157,18 @@ void setlocale_0600(void) ...@@ -157,22 +157,18 @@ void setlocale_0600(void)
setenv(envforlocale[i], "ar_QA", 1); setenv(envforlocale[i], "ar_QA", 1);
char *locale = setlocale(LC_ALL, ""); char *locale = setlocale(LC_ALL, "");
if (locale == NULL) { if (locale) {
t_error("[%s] failed\n", "setlocale_0600"); t_error("[%s] failed\n", "setlocale_0600");
return; return;
} }
char *token = strtok(locale, flag);
while (token != NULL && count < LC_ALL) {
vec[count] = token;
token = strtok(NULL, flag);
count++;
} }
}
EXPECT_NE("setlocale_0600", count, 0); void setlocale_0700(void)
{
int expectPos = i + TEST_LC_OFFSET; char *str = setlocale(LC_ALL, "sss123456");
EXPECT_STREQ("setlocale_0600", "ar_QA", vec[expectPos]); if (str) {
t_error("setlocale_0700 failed [%s] != NULL\n", str);
} }
} }
...@@ -184,6 +180,7 @@ int main(void) ...@@ -184,6 +180,7 @@ int main(void)
setlocale_0400(); setlocale_0400();
setlocale_0500(); setlocale_0500();
setlocale_0600(); setlocale_0600();
setlocale_0700();
return t_status; return t_status;
} }
...@@ -49,11 +49,13 @@ void uselocale_0200(void) ...@@ -49,11 +49,13 @@ void uselocale_0200(void)
} }
uselocale(NULL); uselocale(NULL);
locale_t newLocale = newlocale(LC_PAPER_MASK, "en_ZA", NULL); locale_t newLocale = newlocale(LC_PAPER_MASK, "en_ZA", NULL);
if (newLocale == NULL) { if (newLocale) {
EXPECT_PTRNE("uselocale_0200", newLocale, NULL); EXPECT_PTREQ("uselocale_0200", newLocale, NULL);
freelocale(newLocale);
newLocale = NULL;
return; return;
} }
newLocale = newlocale(LC_PAPER_MASK, "C.UTF-8", NULL);
locale_t usenow = uselocale(newLocale); locale_t usenow = uselocale(newLocale);
EXPECT_PTREQ("uselocale_0200", usenow, LC_GLOBAL_LOCALE); EXPECT_PTREQ("uselocale_0200", usenow, LC_GLOBAL_LOCALE);
locale_t it = uselocale(NULL); locale_t it = uselocale(NULL);
......
...@@ -55,7 +55,7 @@ void duplocale_0200(void) ...@@ -55,7 +55,7 @@ void duplocale_0200(void)
locale_t global = duplocale(LC_GLOBAL_LOCALE); locale_t global = duplocale(LC_GLOBAL_LOCALE);
EXPECT_PTRNE("duplocale_0200", global, NULL); EXPECT_PTRNE("duplocale_0200", global, NULL);
locale_t newlocale_ = newlocale(LC_ALL_MASK, "en-US", NULL); locale_t newlocale_ = newlocale(LC_ALL_MASK, "en_US", NULL);
EXPECT_PTRNE("duplocale_0200", newlocale_, NULL); EXPECT_PTRNE("duplocale_0200", newlocale_, NULL);
locale_t clonelocale = duplocale(newlocale_); locale_t clonelocale = duplocale(newlocale_);
...@@ -70,6 +70,10 @@ void duplocale_0200(void) ...@@ -70,6 +70,10 @@ void duplocale_0200(void)
freelocale(newlocale_); freelocale(newlocale_);
newlocale_ = NULL; newlocale_ = NULL;
} }
if (global) {
freelocale(global);
global = NULL;
}
} }
int main(void) int main(void)
......
...@@ -36,10 +36,6 @@ void langinfo_0100(void) ...@@ -36,10 +36,6 @@ void langinfo_0100(void)
return; return;
} }
lo = setlocale(LC_TIME, "zh_CN.UTF-8"); lo = setlocale(LC_TIME, "zh_CN.UTF-8");
if (!lo) {
EXPECT_PTRNE("nl_langinfo_0100", lo, NULL);
return;
}
char *ptr = nl_langinfo(DAY_2); char *ptr = nl_langinfo(DAY_2);
EXPECT_STREQ("nl_langinfo_0100", ptr, "Monday"); EXPECT_STREQ("nl_langinfo_0100", ptr, "Monday");
} }
...@@ -77,10 +73,6 @@ void nl_langinfo_0300() ...@@ -77,10 +73,6 @@ void nl_langinfo_0300()
return; return;
} }
lo = setlocale(LC_TIME, "zh_CN.UTF-8"); lo = setlocale(LC_TIME, "zh_CN.UTF-8");
if (!lo) {
EXPECT_PTRNE("nl_langinfo_0300", lo, NULL);
return;
}
char *ptr = nl_langinfo(TIME_ERROR_INFO); char *ptr = nl_langinfo(TIME_ERROR_INFO);
EXPECT_STREQ("nl_langinfo_0300", ptr, ""); EXPECT_STREQ("nl_langinfo_0300", ptr, "");
} }
...@@ -94,8 +86,8 @@ void nl_langinfo_0300() ...@@ -94,8 +86,8 @@ void nl_langinfo_0300()
void nl_langinfo_0400() void nl_langinfo_0400()
{ {
char *lo = setlocale(LC_MESSAGES, "zh_CN.UTF-8"); char *lo = setlocale(LC_MESSAGES, "zh_CN.UTF-8");
if (!lo) { if (lo) {
EXPECT_PTRNE("nl_langinfo_0400", lo, NULL); t_error("nl_langinfo_0400 %s != NULL\n", lo);
return; return;
} }
char *ptr = nl_langinfo(MESSAGES_ERROR_INFO); char *ptr = nl_langinfo(MESSAGES_ERROR_INFO);
......
...@@ -37,7 +37,7 @@ void newlocale_0100(void) ...@@ -37,7 +37,7 @@ void newlocale_0100(void)
EXPECT_PTRNE("newlocale_0100", lo, NULL); EXPECT_PTRNE("newlocale_0100", lo, NULL);
return; return;
} }
locale_t newlocale_ = newlocale(LC_ALL_MASK, "en-US", NULL); locale_t newlocale_ = newlocale(LC_ALL_MASK, "en_US", NULL);
EXPECT_PTRNE("newlocale_0100", newlocale_, NULL); EXPECT_PTRNE("newlocale_0100", newlocale_, NULL);
if (newlocale_) { if (newlocale_) {
...@@ -81,7 +81,7 @@ void newlocale_0300(void) ...@@ -81,7 +81,7 @@ void newlocale_0300(void)
return; return;
} }
for (int i = 0; i < sizeof(lcMarkArry) / sizeof(lcMarkArry[0]); i++) { for (int i = 0; i < sizeof(lcMarkArry) / sizeof(lcMarkArry[0]); i++) {
locale_t newlocale_ = newlocale(lcMarkArry[i], "en-US", NULL); locale_t newlocale_ = newlocale(lcMarkArry[i], "en_US", NULL);
EXPECT_PTRNE("newlocale_0300", newlocale_, NULL); EXPECT_PTRNE("newlocale_0300", newlocale_, NULL);
if (newlocale_) { if (newlocale_) {
......
...@@ -104,11 +104,10 @@ void setlocale_0400(void) ...@@ -104,11 +104,10 @@ void setlocale_0400(void)
for (unsigned int i = 0; i < sizeof(envforlocale) / sizeof(envforlocale[0]); i++) { for (unsigned int i = 0; i < sizeof(envforlocale) / sizeof(envforlocale[0]); i++) {
setenv(envforlocale[i], "da_DK", 1); setenv(envforlocale[i], "da_DK", 1);
const char *locale = setlocale(LcArry[i], ""); const char *locale = setlocale(LcArry[i], "");
if (!locale) { if (locale) {
t_error("[%s] failed\n", "setlocale_0400"); t_error("[%s] failed\n", "setlocale_0400");
return; return;
} }
EXPECT_STREQ("SetlocaleTest_0400", locale, "da_DK");
} }
} }
...@@ -127,11 +126,10 @@ void setlocale_0500(void) ...@@ -127,11 +126,10 @@ void setlocale_0500(void)
} }
for (unsigned int i = 0; i < sizeof(LcArry) / sizeof(LcArry[0]); i++) { for (unsigned int i = 0; i < sizeof(LcArry) / sizeof(LcArry[0]); i++) {
const char *locale = setlocale(LcArry[i], "en_ZA"); const char *locale = setlocale(LcArry[i], "en_ZA");
if (locale == NULL) { if (locale) {
t_error("[%s] failed\n", "setlocale_0500"); t_error("[%s] failed\n", "setlocale_0500");
return; return;
} }
EXPECT_STREQ("SetlocaleTest_0600", locale, "en_ZA");
} }
} }
...@@ -150,22 +148,10 @@ void setlocale_0600(void) ...@@ -150,22 +148,10 @@ void setlocale_0600(void)
setenv(envforlocale[i], "ar_QA", 1); setenv(envforlocale[i], "ar_QA", 1);
char *locale = setlocale(LC_ALL, ""); char *locale = setlocale(LC_ALL, "");
if (locale == NULL) { if (locale) {
t_error("[%s] failed\n", "setlocale_0600"); t_error("[%s] failed\n", "setlocale_0600");
return; return;
} }
char *token = strtok(locale, flag);
while (token != NULL && count < LC_ALL) {
vec[count] = token;
token = strtok(NULL, flag);
count++;
}
EXPECT_NE("setlocale_0600", count, 0);
int expectPos = i + TEST_LC_OFFSET;
EXPECT_STREQ("setlocale_0600", "ar_QA", vec[expectPos]);
} }
} }
......
...@@ -49,11 +49,13 @@ void uselocale_0200(void) ...@@ -49,11 +49,13 @@ void uselocale_0200(void)
} }
uselocale(NULL); uselocale(NULL);
locale_t newLocale = newlocale(LC_PAPER_MASK, "en_ZA", NULL); locale_t newLocale = newlocale(LC_PAPER_MASK, "en_ZA", NULL);
if (newLocale == NULL) { if (newLocale) {
EXPECT_PTRNE("uselocale_0200", newLocale, NULL); EXPECT_PTREQ("uselocale_0200", newLocale, NULL);
freelocale(newLocale);
newLocale = NULL;
return; return;
} }
newLocale = newlocale(LC_PAPER_MASK, "C.UTF-8", NULL);
locale_t usenow = uselocale(newLocale); locale_t usenow = uselocale(newLocale);
EXPECT_PTREQ("uselocale_0200", usenow, LC_GLOBAL_LOCALE); EXPECT_PTREQ("uselocale_0200", usenow, LC_GLOBAL_LOCALE);
locale_t it = uselocale(NULL); locale_t it = uselocale(NULL);
......
...@@ -33,7 +33,7 @@ void wcsftime_l_0100(void) ...@@ -33,7 +33,7 @@ void wcsftime_l_0100(void)
wchar_t buffer[80]; wchar_t buffer[80];
time(&rtime); time(&rtime);
timeinfo = localtime(&rtime); timeinfo = localtime(&rtime);
locale_t newlocale_ = newlocale(LC_ALL_MASK, "en-US", NULL); locale_t newlocale_ = newlocale(LC_ALL_MASK, "en_US", NULL);
size_t result = wcsftime_l(buffer, 80, L"%I:%M%p", timeinfo, newlocale_); size_t result = wcsftime_l(buffer, 80, L"%I:%M%p", timeinfo, newlocale_);
if (!result) { if (!result) {
t_error("%s wcsftime_l failed\n", __func__); t_error("%s wcsftime_l failed\n", __func__);
...@@ -60,7 +60,7 @@ void wcsftime_l_0200(void) ...@@ -60,7 +60,7 @@ void wcsftime_l_0200(void)
.tm_min = 10, .tm_min = 10,
.tm_sec = 20, .tm_sec = 20,
}; };
locale_t newlocale_ = newlocale(LC_ALL_MASK, "en-US", NULL); locale_t newlocale_ = newlocale(LC_ALL_MASK, "en_US", NULL);
size_t result = wcsftime_l(buff, sizeof buff, L"%A %c", &mtime, newlocale_); size_t result = wcsftime_l(buff, sizeof buff, L"%A %c", &mtime, newlocale_);
if (!result) { if (!result) {
t_error("%s wcsftime_l failed\n", __func__); t_error("%s wcsftime_l failed\n", __func__);
......
...@@ -44,7 +44,7 @@ void strftime_l_0100(void) ...@@ -44,7 +44,7 @@ void strftime_l_0100(void)
return; return;
} }
char buffer[gBufferSize]; char buffer[gBufferSize];
locale_t m_locale = newlocale(LC_ALL_MASK, "zh_cn.UTF-8", NULL); locale_t m_locale = newlocale(LC_ALL_MASK, "en_US", NULL);
strftime_l(buffer, sizeof(buffer) - 1, "%c", timeptr, m_locale); strftime_l(buffer, sizeof(buffer) - 1, "%c", timeptr, m_locale);
EXPECT_STREQ("strftime_l_0100", buffer, test_asctime_data[i].result); EXPECT_STREQ("strftime_l_0100", buffer, test_asctime_data[i].result);
} }
......
...@@ -199,6 +199,7 @@ musl_src_file = [ ...@@ -199,6 +199,7 @@ musl_src_file = [
"src/thread/pthread_cond_timedwait_monotonic_np.c", "src/thread/pthread_cond_timedwait_monotonic_np.c",
"src/thread/pthread_cond_timeout_np.c", "src/thread/pthread_cond_timeout_np.c",
"src/internal/pthread_impl.h", "src/internal/pthread_impl.h",
"src/internal/locale_impl.h",
"src/thread/pthread_rwlock_clockrdlock.c", "src/thread/pthread_rwlock_clockrdlock.c",
"src/thread/pthread_rwlock_timedrdlock.c", "src/thread/pthread_rwlock_timedrdlock.c",
"src/thread/pthread_rwlock_timedrdlock_monotonic_np.c", "src/thread/pthread_rwlock_timedrdlock_monotonic_np.c",
...@@ -2084,6 +2085,7 @@ musl_src_porting_file = [ ...@@ -2084,6 +2085,7 @@ musl_src_porting_file = [
"src/env/__init_tls.c", "src/env/__init_tls.c",
"src/env/__libc_start_main.c", "src/env/__libc_start_main.c",
"src/internal/pthread_impl.h", "src/internal/pthread_impl.h",
"src/internal/locale_impl.h",
"src/internal/syscall.h", "src/internal/syscall.h",
"ldso/namespace.h", "ldso/namespace.h",
"ldso/ns_config.h", "ldso/ns_config.h",
...@@ -2159,6 +2161,7 @@ musl_src_porting_file = [ ...@@ -2159,6 +2161,7 @@ musl_src_porting_file = [
"src/locale/dcngettext.c", "src/locale/dcngettext.c",
"src/locale/locale_map.c", "src/locale/locale_map.c",
"src/locale/langinfo.c", "src/locale/langinfo.c",
"src/locale/newlocale.c",
"src/time/__tz.c", "src/time/__tz.c",
"src/time/gmtime_r.c", "src/time/gmtime_r.c",
"src/time/strftime.c", "src/time/strftime.c",
......
#ifndef _LOCALE_IMPL_H
#define _LOCALE_IMPL_H
#include <locale.h>
#include <stdlib.h>
#include "libc.h"
#include "pthread_impl.h"
#define LOCALE_NAME_MAX 23
#define VALID 2
#define INVALID 1
struct __locale_map {
const void *map;
size_t map_size;
char name[LOCALE_NAME_MAX+1];
const struct __locale_map *next;
char flag;
};
extern hidden volatile int __locale_lock[1];
extern hidden const struct __locale_map __c_dot_utf8;
extern hidden const struct __locale_struct __c_locale;
extern hidden const struct __locale_struct __c_dot_utf8_locale;
hidden const struct __locale_map *__get_locale(int, const char *);
hidden const char *__mo_lookup(const void *, size_t, const char *);
hidden const char *__lctrans(const char *, const struct __locale_map *);
hidden const char *__lctrans_cur(const char *);
hidden const char *__lctrans_impl(const char *, const struct __locale_map *);
hidden int __loc_is_allocated(locale_t);
hidden char *__gettextdomain(void);
#define LOC_MAP_FAILED ((const struct __locale_map *)-1)
#define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)])
#define LCTRANS_CUR(msg) __lctrans_cur(msg)
#define C_LOCALE ((locale_t)&__c_locale)
#define UTF8_LOCALE ((locale_t)&__c_dot_utf8_locale)
#define CURRENT_LOCALE (__pthread_self()->locale)
#define CURRENT_UTF8 (!!__pthread_self()->locale->cat[LC_CTYPE])
#undef MB_CUR_MAX
#define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1)
#endif
#include "locale_impl.h"
#include <stdint.h>
static const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 };
const struct __locale_map __c_dot_utf8 = {
.map = empty_mo,
.map_size = sizeof empty_mo,
.name = "C.UTF-8",
.flag = VALID
};
const struct __locale_struct __c_locale = { 0 };
const struct __locale_struct __c_dot_utf8_locale = {
.cat[LC_CTYPE] = &__c_dot_utf8
};
...@@ -60,6 +60,7 @@ const struct __locale_map *__get_locale(int cat, const char *val) ...@@ -60,6 +60,7 @@ const struct __locale_map *__get_locale(int cat, const char *val)
const char *path = 0, *z; const char *path = 0, *z;
char buf[256]; char buf[256];
size_t l, n; size_t l, n;
if (!*val) { if (!*val) {
(val = getenv("LC_ALL")) && *val || (val = getenv("LC_ALL")) && *val ||
(val = getenv(envvars[cat])) && *val || (val = getenv(envvars[cat])) && *val ||
...@@ -73,11 +74,11 @@ const struct __locale_map *__get_locale(int cat, const char *val) ...@@ -73,11 +74,11 @@ const struct __locale_map *__get_locale(int cat, const char *val)
val = "C.UTF-8"; val = "C.UTF-8";
} }
int builtin = (val[0]=='C' && !val[1]) int builtin = (val[0]=='C' && !val[1])
|| !strcmp(val, "C.UTF-8") || !strcmp(val, "POSIX")
|| !strcmp(val, "POSIX"); || !strcmp(val, "en_US");
if (builtin) { if (builtin) {
if (cat == LC_CTYPE && val[1]=='.') if (cat == LC_CTYPE && val[1] == '.')
return (void *)&__c_dot_utf8; return (void *)&__c_dot_utf8;
return 0; return 0;
} }
...@@ -88,12 +89,27 @@ const struct __locale_map *__get_locale(int cat, const char *val) ...@@ -88,12 +89,27 @@ const struct __locale_map *__get_locale(int cat, const char *val)
} }
} }
if (!strcmp(val, "en_US.UTF-8") || !strcmp(val, "C.UTF-8")) {
/* If no locale definition was found, make a locale map
* object anyway to store the name, which is kept for the
* sake of being able to do message translations at the
* application level. */
if (!new && (new = malloc(sizeof *new))) {
new->map = __c_dot_utf8.map;
new->map_size = __c_dot_utf8.map_size;
memcpy(new->name, val, n);
new->name[n] = 0;
new->next = loc_head;
new->flag = VALID;
loc_head = new;
}
}
if (!libc.secure) { if (!libc.secure) {
path = getenv("MUSL_LOCPATH"); path = getenv("MUSL_LOCPATH");
} }
if (path) { if (path) for (; *path; path=z+!!*z) {
for (; *path; path=z+!!*z) {
z = __strchrnul(path, ':'); z = __strchrnul(path, ':');
l = z - path; l = z - path;
if (l >= sizeof buf - n - 2) { if (l >= sizeof buf - n - 2) {
...@@ -116,11 +132,12 @@ const struct __locale_map *__get_locale(int cat, const char *val) ...@@ -116,11 +132,12 @@ const struct __locale_map *__get_locale(int cat, const char *val)
memcpy(new->name, val, n); memcpy(new->name, val, n);
new->name[n] = 0; new->name[n] = 0;
new->next = loc_head; new->next = loc_head;
new->flag = VALID;
loc_head = new; loc_head = new;
break; break;
} }
} }
}
/* If no locale definition was found, make a locale map /* If no locale definition was found, make a locale map
* object anyway to store the name, which is kept for the * object anyway to store the name, which is kept for the
...@@ -132,6 +149,7 @@ const struct __locale_map *__get_locale(int cat, const char *val) ...@@ -132,6 +149,7 @@ const struct __locale_map *__get_locale(int cat, const char *val)
memcpy(new->name, val, n); memcpy(new->name, val, n);
new->name[n] = 0; new->name[n] = 0;
new->next = loc_head; new->next = loc_head;
new->flag = INVALID;
loc_head = new; loc_head = new;
} }
...@@ -141,3 +159,4 @@ const struct __locale_map *__get_locale(int cat, const char *val) ...@@ -141,3 +159,4 @@ const struct __locale_map *__get_locale(int cat, const char *val)
return new; return new;
} }
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "locale_impl.h"
#include "lock.h"
#define malloc __libc_malloc
#define calloc undef
#define realloc undef
#define free undef
static int default_locale_init_done;
static struct __locale_struct default_locale, default_ctype_locale;
int __loc_is_allocated(locale_t loc)
{
return loc && loc != C_LOCALE && loc != UTF8_LOCALE
&& loc != &default_locale && loc != &default_ctype_locale;
}
static locale_t do_newlocale(int mask, const char *name, locale_t loc)
{
struct __locale_struct tmp;
for (int i=0; i<LC_ALL; i++) {
tmp.cat[i] = (!(mask & (1<<i)) && loc) ? loc->cat[i] :
__get_locale(i, (mask & (1<<i)) ? name : "");
if (tmp.cat[i] == LOC_MAP_FAILED || tmp.cat[i] && tmp.cat[i]->flag == INVALID)
return 0;
}
/* For locales with allocated storage, modify in-place. */
if (__loc_is_allocated(loc)) {
*loc = tmp;
return loc;
}
/* Otherwise, first see if we can use one of the builtin locales.
* This makes the common usage case for newlocale, getting a C locale
* with predictable behavior, very fast, and more importantly, fail-safe. */
if (!memcmp(&tmp, C_LOCALE, sizeof tmp)) return C_LOCALE;
if (!memcmp(&tmp, UTF8_LOCALE, sizeof tmp)) return UTF8_LOCALE;
/* And provide builtins for the initial default locale, and a
* variant of the C locale honoring the default locale's encoding. */
if (!default_locale_init_done) {
for (int i=0; i<LC_ALL; i++)
default_locale.cat[i] = __get_locale(i, "");
default_ctype_locale.cat[LC_CTYPE] = default_locale.cat[LC_CTYPE];
default_locale_init_done = 1;
}
if (!memcmp(&tmp, &default_locale, sizeof tmp)) return &default_locale;
if (!memcmp(&tmp, &default_ctype_locale, sizeof tmp))
return &default_ctype_locale;
/* If no builtin locale matched, attempt to allocate and copy. */
if ((loc = malloc(sizeof *loc))) *loc = tmp;
return loc;
}
locale_t __newlocale(int mask, const char *name, locale_t loc)
{
LOCK(__locale_lock);
loc = do_newlocale(mask, name, loc);
UNLOCK(__locale_lock);
return loc;
}
weak_alias(__newlocale, newlocale);
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include "locale_impl.h"
#include "libc.h"
#include "lock.h"
static char buf[LC_ALL*(LOCALE_NAME_MAX+1)];
static inline int Fresh(struct __locale_map *lm)
{
if (lm != NULL) {
return lm->flag;
}
return VALID;
}
char *setlocale(int cat, const char *name)
{
const struct __locale_map *lm;
char flag = VALID;
if ((unsigned)cat > LC_ALL) return 0;
LOCK(__locale_lock);
/* For LC_ALL, setlocale is required to return a string which
* encodes the current setting for all categories. The format of
* this string is unspecified, and only the following code, which
* performs both the serialization and deserialization, depends
* on the format, so it can easily be changed if needed. */
if (cat == LC_ALL) {
int i;
if (name) {
struct __locale_struct tmp_locale;
char part[LOCALE_NAME_MAX+1] = "C.UTF-8";
const char *p = name;
for (i=0; i<LC_ALL; i++) {
const char *z = __strchrnul(p, ';');
if (z-p <= LOCALE_NAME_MAX) {
memcpy(part, p, z-p);
part[z-p] = 0;
if (*z) p = z+1;
}
lm = __get_locale(i, part);
if (lm == LOC_MAP_FAILED) {
UNLOCK(__locale_lock);
return 0;
}
if(Fresh(lm) == INVALID) {
flag = INVALID;
}
tmp_locale.cat[i] = lm;
}
libc.global_locale = tmp_locale;
}
char *s = buf;
const char *part;
int same = 0;
for (i=0; i<LC_ALL; i++) {
const struct __locale_map *lm =
libc.global_locale.cat[i];
if (lm == libc.global_locale.cat[0]) same++;
part = lm ? lm->name : "C";
size_t l = strlen(part);
memcpy(s, part, l);
s[l] = ';';
s += l+1;
}
*--s = 0;
UNLOCK(__locale_lock);
if (flag == INVALID) {
return 0;
}
return same==LC_ALL ? (char *)part : buf;
}
if (name) {
lm = __get_locale(cat, name);
if (lm == LOC_MAP_FAILED) {
UNLOCK(__locale_lock);
return 0;
}
flag = Fresh(lm);
libc.global_locale.cat[cat] = lm;
} else {
lm = libc.global_locale.cat[cat];
}
char *ret = lm ? (char *)lm->name : "C";
UNLOCK(__locale_lock);
if (flag == INVALID) {
return 0;
}
return ret;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册