msvcrt: Create global C locale __lc_time_data struct.

Signed-off-by: Jeff Smith <whydoubt@gmail.com>
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jeff Smith 2019-12-04 16:22:14 +01:00 committed by Alexandre Julliard
parent c4b41fd4f1
commit f174eb072d
2 changed files with 97 additions and 62 deletions

View File

@ -53,6 +53,76 @@ BOOL initial_locale = TRUE;
#define MSVCRT_LEADBYTE 0x8000
#define MSVCRT_C1_DEFINED 0x200
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};
static const MSVCRT_wchar_t wed[] = {'W','e','d',0};
static const MSVCRT_wchar_t thu[] = {'T','h','u',0};
static const MSVCRT_wchar_t fri[] = {'F','r','i',0};
static const MSVCRT_wchar_t sat[] = {'S','a','t',0};
static const MSVCRT_wchar_t sunday[] = {'S','u','n','d','a','y',0};
static const MSVCRT_wchar_t monday[] = {'M','o','n','d','a','y',0};
static const MSVCRT_wchar_t tuesday[] = {'T','u','e','s','d','a','y',0};
static const MSVCRT_wchar_t wednesday[] = {'W','e','d','n','e','s','d','a','y',0};
static const MSVCRT_wchar_t thursday[] = {'T','h','u','r','s','d','a','y',0};
static const MSVCRT_wchar_t friday[] = {'F','r','i','d','a','y',0};
static const MSVCRT_wchar_t saturday[] = {'S','a','t','u','r','d','a','y',0};
static const MSVCRT_wchar_t jan[] = {'J','a','n',0};
static const MSVCRT_wchar_t feb[] = {'F','e','b',0};
static const MSVCRT_wchar_t mar[] = {'M','a','r',0};
static const MSVCRT_wchar_t apr[] = {'A','p','r',0};
static const MSVCRT_wchar_t may[] = {'M','a','y',0};
static const MSVCRT_wchar_t jun[] = {'J','u','n',0};
static const MSVCRT_wchar_t jul[] = {'J','u','l',0};
static const MSVCRT_wchar_t aug[] = {'A','u','g',0};
static const MSVCRT_wchar_t sep[] = {'S','e','p',0};
static const MSVCRT_wchar_t oct[] = {'O','c','t',0};
static const MSVCRT_wchar_t nov[] = {'N','o','v',0};
static const MSVCRT_wchar_t dec[] = {'D','e','c',0};
static const MSVCRT_wchar_t january[] = {'J','a','n','u','a','r','y',0};
static const MSVCRT_wchar_t february[] = {'F','e','b','r','u','a','r','y',0};
static const MSVCRT_wchar_t march[] = {'M','a','r','c','h',0};
static const MSVCRT_wchar_t april[] = {'A','p','r','i','l',0};
static const MSVCRT_wchar_t june[] = {'J','u','n','e',0};
static const MSVCRT_wchar_t july[] = {'J','u','l','y',0};
static const MSVCRT_wchar_t august[] = {'A','u','g','u','s','t',0};
static const MSVCRT_wchar_t september[] = {'S','e','p','t','e','m','b','e','r',0};
static const MSVCRT_wchar_t october[] = {'O','c','t','o','b','e','r',0};
static const MSVCRT_wchar_t november[] = {'N','o','v','e','m','b','e','r',0};
static const MSVCRT_wchar_t december[] = {'D','e','c','e','m','b','e','r',0};
static const MSVCRT_wchar_t am[] = {'A','M',0};
static const MSVCRT_wchar_t pm[] = {'P','M',0};
static const MSVCRT_wchar_t cloc_short_date[] = {'M','M','/','d','d','/','y','y',0};
static const MSVCRT_wchar_t cloc_date[] = {'d','d','d','d',',',' ','M','M','M','M',' ','d','d',',',' ','y','y','y','y',0};
static const MSVCRT_wchar_t cloc_time[] = {'H','H',':','m','m',':','s','s',0};
#if _MSVCR_VER >= 110
static const MSVCRT_wchar_t en_us[] = {'e','n','-','U','S',0};
#endif
MSVCRT___lc_time_data cloc_time_data =
{
{{"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",
"January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December",
"AM", "PM", "MM/dd/yy", "dddd, MMMM dd, yyyy", "HH:mm:ss"}},
#if _MSVCR_VER < 110
MAKELCID(LANG_ENGLISH, SORT_DEFAULT),
#endif
{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,
january, february, march, april, may, june, july,
august, september, october, november, december,
am, pm, cloc_short_date, cloc_date, cloc_time}},
#if _MSVCR_VER >= 110
en_us,
#endif
};
/* Friendly country strings & language names abbreviations. */
static const char * const _country_synonyms[] =
{
@ -843,7 +913,8 @@ void free_locinfo(MSVCRT_pthreadlocinfo locinfo)
MSVCRT_free(locinfo->pclmap);
MSVCRT_free(locinfo->pcumap);
MSVCRT_free(locinfo->lc_time_curr);
if(locinfo->lc_time_curr != &cloc_time_data)
MSVCRT_free(locinfo->lc_time_curr);
MSVCRT_free(locinfo);
}
@ -943,35 +1014,21 @@ static MSVCRT___lc_time_data* create_time_data(LCID lcid)
LOCALE_SSHORTDATE, LOCALE_SLONGDATE,
LOCALE_STIMEFORMAT
};
static const char cloc_short_date[] = "MM/dd/yy";
static const MSVCRT_wchar_t cloc_short_dateW[] = {'M','M','/','d','d','/','y','y',0};
static const char cloc_long_date[] = "dddd, MMMM dd, yyyy";
static const MSVCRT_wchar_t cloc_long_dateW[] = {'d','d','d','d',',',' ','M','M','M','M',' ','d','d',',',' ','y','y','y','y',0};
static const char cloc_time[] = "HH:mm:ss";
static const MSVCRT_wchar_t cloc_timeW[] = {'H','H',':','m','m',':','s','s',0};
MSVCRT___lc_time_data *cur;
const DWORD flags = lcid ? 0 : LOCALE_NOUSEROVERRIDE;
const LCID lcid_tmp = lcid ? lcid : MAKELCID(LANG_ENGLISH, SORT_DEFAULT);
int i, ret, size;
size = sizeof(MSVCRT___lc_time_data);
for(i=0; i<ARRAY_SIZE(time_data); i++) {
if(time_data[i]==LOCALE_SSHORTDATE && !lcid) {
size += sizeof(cloc_short_date) + sizeof(cloc_short_dateW);
}else if(time_data[i]==LOCALE_SLONGDATE && !lcid) {
size += sizeof(cloc_long_date) + sizeof(cloc_long_dateW);
}else {
ret = GetLocaleInfoA(lcid_tmp, time_data[i]|flags, NULL, 0);
if(!ret)
return NULL;
size += ret;
ret = GetLocaleInfoA(lcid, time_data[i], NULL, 0);
if(!ret)
return NULL;
size += ret;
ret = GetLocaleInfoW(lcid_tmp, time_data[i]|flags, NULL, 0);
if(!ret)
return NULL;
size += ret*sizeof(MSVCRT_wchar_t);
}
ret = GetLocaleInfoW(lcid, time_data[i], NULL, 0);
if(!ret)
return NULL;
size += ret*sizeof(MSVCRT_wchar_t);
}
#if _MSVCR_VER >= 110
size += LCIDToLocaleName(lcid, NULL, 0, 0)*sizeof(MSVCRT_wchar_t);
@ -984,35 +1041,12 @@ static MSVCRT___lc_time_data* create_time_data(LCID lcid)
ret = 0;
for(i=0; i<ARRAY_SIZE(time_data); i++) {
cur->str.str[i] = &cur->data[ret];
if(time_data[i]==LOCALE_SSHORTDATE && !lcid) {
memcpy(&cur->data[ret], cloc_short_date, sizeof(cloc_short_date));
ret += sizeof(cloc_short_date);
}else if(time_data[i]==LOCALE_SLONGDATE && !lcid) {
memcpy(&cur->data[ret], cloc_long_date, sizeof(cloc_long_date));
ret += sizeof(cloc_long_date);
}else if(time_data[i]==LOCALE_STIMEFORMAT && !lcid) {
memcpy(&cur->data[ret], cloc_time, sizeof(cloc_time));
ret += sizeof(cloc_time);
}else {
ret += GetLocaleInfoA(lcid_tmp, time_data[i]|flags,
&cur->data[ret], size-ret);
}
ret += GetLocaleInfoA(lcid, time_data[i], &cur->data[ret], size-ret);
}
for(i=0; i<ARRAY_SIZE(time_data); i++) {
cur->wstr.wstr[i] = (MSVCRT_wchar_t*)&cur->data[ret];
if(time_data[i]==LOCALE_SSHORTDATE && !lcid) {
memcpy(&cur->data[ret], cloc_short_dateW, sizeof(cloc_short_dateW));
ret += sizeof(cloc_short_dateW);
}else if(time_data[i]==LOCALE_SLONGDATE && !lcid) {
memcpy(&cur->data[ret], cloc_long_dateW, sizeof(cloc_long_dateW));
ret += sizeof(cloc_long_dateW);
}else if(time_data[i]==LOCALE_STIMEFORMAT && !lcid) {
memcpy(&cur->data[ret], cloc_timeW, sizeof(cloc_timeW));
ret += sizeof(cloc_timeW);
}else {
ret += GetLocaleInfoW(lcid_tmp, time_data[i]|flags,
(MSVCRT_wchar_t*)&cur->data[ret], size-ret)*sizeof(MSVCRT_wchar_t);
}
ret += GetLocaleInfoW(lcid, time_data[i],
(MSVCRT_wchar_t*)&cur->data[ret], size-ret)*sizeof(MSVCRT_wchar_t);
}
#if _MSVCR_VER >= 110
cur->locname = (MSVCRT_wchar_t*)&cur->data[ret];
@ -1678,26 +1712,26 @@ static MSVCRT_pthreadlocinfo create_locinfo(int category,
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;
} 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)) {
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)) {
free_locinfo(locinfo);
return NULL;
}
if(!set_lc_locale_name(locinfo, MSVCRT_LC_TIME)) {
free_locinfo(locinfo);
return NULL;
}
} else
locinfo->lc_category[MSVCRT_LC_TIME].locale = MSVCRT__strdup("C");
if(!set_lc_locale_name(locinfo, MSVCRT_LC_TIME)) {
free_locinfo(locinfo);
return NULL;
}
locinfo->lc_time_curr = create_time_data(lcid[MSVCRT_LC_TIME]);
if(!locinfo->lc_time_curr) {
free_locinfo(locinfo);
return NULL;
}
} else {
locinfo->lc_category[MSVCRT_LC_TIME].locale = MSVCRT__strdup("C");
locinfo->lc_time_curr = &cloc_time_data;
}
return locinfo;

View File

@ -305,6 +305,7 @@ extern thread_data_t *msvcrt_get_thread_data(void) DECLSPEC_HIDDEN;
LCID MSVCRT_locale_to_LCID(const char*, unsigned short*, BOOL*) DECLSPEC_HIDDEN;
extern MSVCRT__locale_t MSVCRT_locale DECLSPEC_HIDDEN;
extern MSVCRT___lc_time_data cloc_time_data DECLSPEC_HIDDEN;
extern unsigned int MSVCRT___lc_codepage;
extern int MSVCRT___lc_collate_cp;
extern WORD MSVCRT__ctype [257];