ReactOS 0.4.16-dev-822-gbcedb53
wsetlocale.cpp File Reference
#include <corecrt_internal.h>
#include <locale.h>
Include dependency graph for wsetlocale.cpp:

Go to the source code of this file.

Classes

struct  _bcp47_section
 
class  _expandlocale_locale_name_cache
 

Enumerations

enum class  _bcp47_section_delimiter { normal , end_of_string , code_page }
 

Functions

 _Success_ (return !=0) static wchar_t *_expandlocale(_In_z_ wchar_t const *expr
 
 _Out_writes_z_ (sizeInChars) wchar_t *output
 
_In_ size_t _Out_writes_z_ (localeNameSizeInChars) wchar_t *localeNameOutput
 
void _wcscats (_Inout_updates_z_(_Param_(2)) wchar_t *, size_t, int,...)
 
void __lc_lctowcs (_Inout_updates_z_(_Param_(2)) wchar_t *, size_t, const __crt_locale_strings *)
 
int __lc_wcstolc (__crt_locale_strings *, const wchar_t *)
 
static wchar_t *__cdecl _wsetlocale_set_cat (__crt_locale_data *, int, const wchar_t *)
 
static wchar_t *__cdecl _wsetlocale_get_all (__crt_locale_data *)
 
static __crt_locale_data *__cdecl _updatetlocinfo_nolock (void)
 
static wchar_t *__cdecl _wsetlocale_nolock (__crt_locale_data *, int, const wchar_t *)
 
int __cdecl _setmbcp_nolock (int, __crt_multibyte_data *)
 
__crt_locale_data *__cdecl _updatetlocinfoEx_nolock (__crt_locale_data **, __crt_locale_data *)
 
void __cdecl __acrt_set_locale_changed ()
 
int __cdecl _configthreadlocale (int i)
 
void __cdecl __acrt_uninitialize_locale ()
 
void __cdecl _free_locale (_locale_t plocinfo)
 
_locale_t __cdecl _get_current_locale (void)
 
static int __cdecl no_op_initialize (__crt_locale_data *)
 
void __cdecl __acrt_free_locale (__crt_locale_data *)
 
 _CRT_LINKER_FORCE_INCLUDE (__acrt_locale_terminator)
 
 __declspec (selectany) struct
 
static void __cdecl _copytlocinfo_nolock (__crt_locale_data *ptlocid, __crt_locale_data *ptlocis)
 
static __inline void sync_legacy_variables_lk ()
 
_locale_t __cdecl _wcreate_locale (int _category, const wchar_t *locale)
 
_locale_t __cdecl _create_locale (int _category, const char *_locale)
 
wchar_t *__cdecl _wsetlocale (int _category, const wchar_t *_wlocale)
 
static _bcp47_section_delimiter categorize_delimiter (wchar_t const wc)
 
static bool string_is_alpha (wchar_t const *const str, size_t const len)
 
static bool string_is_digit (wchar_t const *const str, size_t const len)
 
static bool parse_bcp47_language (__crt_locale_strings *const names, _bcp47_section const &section)
 
static bool parse_bcp47_script (__crt_locale_strings *const names, _bcp47_section const &section)
 
static bool parse_bcp47_region (__crt_locale_strings *const names, _bcp47_section const &section)
 
static bool parse_bcp47_code_page (__crt_locale_strings *const names, _bcp47_section const &section)
 
static bool parse_bcp47 (__crt_locale_strings *const names, const wchar_t *const expr)
 
static int get_default_code_page (wchar_t const *const valid_windows_locale_name)
 
wchar_t_expandlocale (wchar_t const *const expr, wchar_t *const output, size_t const sizeInChars, wchar_t *const localeNameOutput, size_t const localeNameSizeInChars, UINT &output_code_page)
 
void _wcscats (wchar_t *outstr, size_t numberOfElements, int n,...)
 
void __lc_lctowcs (wchar_t *locale, size_t numberOfElements, const __crt_locale_strings *names)
 
LPWSTR __cdecl __acrt_copy_locale_name (LPCWSTR localeName)
 

Variables

static const char _first_127char []
 
__crt_locale_data __acrt_initial_locale_data
 
const unsigned short _wctype []
 
static const unsigned short_ctype_loc_style = _wctype + 2
 
long __acrt_locale_changed_data = FALSE
 
_In_ size_t sizeInChars
 
_In_ size_t _In_ size_t localeNameSizeInChars
 
_In_ size_t _In_ size_t _Out_ UINTcp
 
const __lc_category [LC_MAX-LC_MIN+1]
 

Enumeration Type Documentation

◆ _bcp47_section_delimiter

Enumerator
normal 
end_of_string 
code_page 

Definition at line 877 of file wsetlocale.cpp.

Function Documentation

◆ __acrt_copy_locale_name()

LPWSTR __cdecl __acrt_copy_locale_name ( LPCWSTR  localeName)

Definition at line 1411 of file wsetlocale.cpp.

1412{
1413 size_t cch;
1414 wchar_t* localeNameCopy;
1415
1416 if (!localeName) // Input cannot be nullptr
1417 return nullptr;
1418
1419 cch = wcsnlen(localeName, LOCALE_NAME_MAX_LENGTH);
1420 if (cch >= LOCALE_NAME_MAX_LENGTH) // locale name length must be <= LOCALE_NAME_MAX_LENGTH
1421 return nullptr;
1422
1423 if ((localeNameCopy = (wchar_t *) _malloc_crt((cch + 1) * sizeof(wchar_t))) == nullptr)
1424 return nullptr;
1425
1426 _ERRCHECK(wcsncpy_s(localeNameCopy, cch+1, localeName, cch+1));
1427 return localeNameCopy;
1428}
#define _ERRCHECK(e)
#define _malloc_crt
#define wcsncpy_s(d, l, s, n)
Definition: utility.h:202
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
#define LOCALE_NAME_MAX_LENGTH
size_t __cdecl wcsnlen(wchar_t const *const string, size_t const maximum_count)
Definition: strnlen.cpp:210

Referenced by _wsetlocale_set_cat(), and throw().

◆ __acrt_free_locale()

void __cdecl __acrt_free_locale ( __crt_locale_data ptloci)

Definition at line 125 of file locale_refcounting.cpp.

126{
127 /*
128 * Free up lconv struct
129 */
130 if (ptloci->lconv != nullptr &&
131 ptloci->lconv != &__acrt_lconv_c &&
132 ptloci->lconv_intl_refcount != nullptr &&
133 *ptloci->lconv_intl_refcount == 0)
134 {
135 if (ptloci->lconv_mon_refcount != nullptr && *ptloci->lconv_mon_refcount == 0)
136 {
139 }
140
141 if (ptloci->lconv_num_refcount != nullptr && *ptloci->lconv_num_refcount == 0)
142 {
145 }
146
148 _free_crt(ptloci->lconv);
149 }
150
151 /*
152 * Free up ctype tables
153 */
154 if (ptloci->ctype1_refcount != nullptr && *ptloci->ctype1_refcount == 0)
155 {
156 _free_crt(ptloci->ctype1 - _COFFSET);
157 _free_crt(const_cast<unsigned char*>(ptloci->pclmap - _COFFSET - 1));
158 _free_crt(const_cast<unsigned char*>(ptloci->pcumap - _COFFSET - 1));
159 _free_crt(ptloci->ctype1_refcount);
160 }
161
163
164 for (int category = LC_MIN; category <= LC_MAX; ++category)
165 {
167 ptloci->lc_category[category].wrefcount != nullptr &&
168 *ptloci->lc_category[category].wrefcount == 0)
169 {
172 }
173
174 _ASSERTE((ptloci->lc_category[category].locale != nullptr && ptloci->lc_category[category].refcount != nullptr) ||
175 (ptloci->lc_category[category].locale == nullptr && ptloci->lc_category[category].refcount == nullptr));
176
177 if (ptloci->lc_category[category].locale != nullptr &&
178 ptloci->lc_category[category].refcount != nullptr &&
179 *ptloci->lc_category[category].refcount == 0)
180 {
182 }
183 }
184
185 /*
186 * Free up the __crt_locale_data struct
187 */
188 _free_crt(ptloci);
189}
void __cdecl __acrt_locale_free_numeric(_Inout_ struct lconv *lconv)
wchar_t __acrt_wide_c_locale_string[]
Definition: nlsdata.cpp:28
#define _COFFSET
void __cdecl __acrt_locale_free_monetary(_Inout_ struct lconv *lconv)
#define _ASSERTE(expr)
Definition: crtdbg.h:114
#define LC_MAX
Definition: locale.h:25
#define LC_MIN
Definition: locale.h:24
#define _free_crt
void __cdecl __acrt_locale_free_lc_time_if_unreferenced(__crt_lc_time_data const *const lc_time)
unsigned char const * pcumap
__crt_locale_refcount lc_category[6]
wchar_t * locale_name[6]
__crt_lc_time_data const * lc_time_curr
unsigned char const * pclmap
unsigned short * ctype1
struct lconv * lconv

Referenced by _free_locale(), _updatetlocinfoEx_nolock(), _wcreate_locale(), and _wsetlocale().

◆ __acrt_set_locale_changed()

void __cdecl __acrt_set_locale_changed ( void  )

Definition at line 54 of file wsetlocale.cpp.

55{
57}
#define TRUE
Definition: types.h:120
long __cdecl _InterlockedExchange(_Interlocked_operand_ long volatile *_Target, long _Value)
long __acrt_locale_changed_data
Definition: wsetlocale.cpp:31

Referenced by _wsetlocale(), and setmbcp_internal().

◆ __acrt_uninitialize_locale()

void __cdecl __acrt_uninitialize_locale ( )

Definition at line 119 of file wsetlocale.cpp.

120{
121 __acrt_lock_and_call(__acrt_locale_lock, [&]
122 {
124 {
126 {
127 return;
128 }
129
131 });
132 });
133}
Definition: _locale.h:75
@ __acrt_locale_lock
__crt_state_management::dual_state_global< __crt_locale_data * > __acrt_current_locale_data
Definition: nlsdata.cpp:132
__crt_locale_data *__cdecl _updatetlocinfoEx_nolock(__crt_locale_data **, __crt_locale_data *)
__crt_locale_data __acrt_initial_locale_data
Definition: nlsdata.cpp:92

◆ __declspec()

__declspec ( selectany  )

Definition at line 257 of file wsetlocale.cpp.

257 {
258 const wchar_t * catname;
259 wchar_t * locale;
261} const __lc_category[LC_MAX-LC_MIN+1] = {
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
static int init
Definition: wintirpc.c:33
const __lc_category[LC_MAX-LC_MIN+1]
Definition: wsetlocale.cpp:261

◆ __lc_lctowcs() [1/2]

void __lc_lctowcs ( _Inout_updates_z_(_Param_(2)) wchar_t ,
size_t  ,
const __crt_locale_strings  
)

Referenced by _expandlocale().

◆ __lc_lctowcs() [2/2]

void __lc_lctowcs ( wchar_t locale,
size_t  numberOfElements,
const __crt_locale_strings names 
)

Definition at line 1401 of file wsetlocale.cpp.

1402{
1404 if (*(names->szCountry))
1405 _wcscats(locale, numberOfElements, 2, L"_", names->szCountry);
1406 if (*(names->szCodePage))
1407 _wcscats(locale, numberOfElements, 2, L".", names->szCodePage);
1408}
GLuint GLuint * names
Definition: glext.h:11545
#define wcscpy_s(d, l, s)
Definition: utility.h:201
static size_t numberOfElements
Definition: string.c:96
#define L(x)
Definition: ntvdm.h:50
void _wcscats(_Inout_updates_z_(_Param_(2)) wchar_t *, size_t, int,...)

◆ __lc_wcstolc()

int __lc_wcstolc ( __crt_locale_strings names,
const wchar_t wlocale 
)

Definition at line 1336 of file wsetlocale.cpp.

1337{
1338 int i;
1339 size_t len;
1340 wchar_t wch;
1341
1342 memset((void *)names, '\0', sizeof(__crt_locale_strings)); /* clear out result */
1343
1344 if (*wlocale==L'\0')
1345 return 0; /* trivial case */
1346
1347 /* only code page is given */
1348 if (wlocale[0] == L'.' && wlocale[1] != L'\0')
1349 {
1350 _ERRCHECK(wcsncpy_s(names->szCodePage, _countof(names->szCodePage), &wlocale[1], MAX_CP_LEN-1));
1351 /* Make sure to null terminate the string in case wlocale is > MAX_CP_LEN */
1352 names->szCodePage[ MAX_CP_LEN -1] = 0;
1353 return 0;
1354 }
1355
1356 // Looks like Language_Country/Region.Codepage
1357 for (i=0; ; i++)
1358 {
1359 // _ language country/region separator, . is before codepage, either , or \0 are end of string.
1360 len = wcscspn(wlocale, L"_.,");
1361 if (len == 0)
1362 return -1; /* syntax error, can't start with a separator */
1363
1364 wch = wlocale[len];
1365
1366 if ((i == 0) && (len < MAX_LANG_LEN))
1367 {
1368 _ERRCHECK(wcsncpy_s(names->szLanguage, _countof(names->szLanguage), wlocale, len));
1369 if (wch == L'.')
1370 {
1371 // '.' is a delimiter before codepage, so codepage is expected next (skip country/region)
1372 i++;
1373 }
1374 }
1375
1376 else if ((i==1) && (len<MAX_CTRY_LEN) && (wch!=L'_'))
1377 _ERRCHECK(wcsncpy_s(names->szCountry, _countof(names->szCountry), wlocale, len));
1378
1379 else if ((i==2) && (len<MAX_CP_LEN) && (wch==L'\0' || wch==L','))
1380 _ERRCHECK(wcsncpy_s(names->szCodePage, _countof(names->szCodePage), wlocale, len));
1381
1382 else
1383 return -1; /* error parsing wlocale string */
1384
1385 if (wch==L',')
1386 {
1387 /* modifier not used in current implementation, but it
1388 must be parsed to for POSIX/XOpen conformance */
1389 /* wcsncpy(names->szModifier, wlocale, MAX_MODIFIER_LEN-1); */
1390 break;
1391 }
1392
1393 if (!wch)
1394 break;
1395 wlocale+=(len+1);
1396 }
1397 return 0;
1398}
#define MAX_LANG_LEN
#define MAX_CP_LEN
#define MAX_CTRY_LEN
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_ _CRTIMP size_t __cdecl wcscspn(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_Control)
#define memset(x, y, z)
Definition: compat.h:39
#define _countof(array)
Definition: sndvol32.h:70

Referenced by _expandlocale().

◆ _configthreadlocale()

int __cdecl _configthreadlocale ( int  i)

Definition at line 71 of file wsetlocale.cpp.

72{
73 /*
74 * ownlocale flag struct:
75 * bits: 000000000000000000000000 000W 00P1
76 * P is set when _ENABLE_PER_THREAD_LOCALE is called for this thread
77 * or _ENABLE_PER_THREAD_LOCALE_NEW was set when this thread was created.
78 * W is set when _WSETLOCALE_AVOID_SYNC_LOCALE_BIT is set by _wsetlocale.
79 * It is used to disable global-ptd resynchronization during a call to _wsetlocale.
80 *
81 * __globallocalestatus structure:
82 * bits: 111111111111111111111111 1111 1N1G
83 * G is set if _ENABLE_PER_THREAD_LOCALE_GLOBAL is set.
84 * G is 0 if _ENABLE_PER_THREAD_LOCALE_GLOBAL is not set.
85 * N is set if _ENABLE_PER_THREAD_LOCALE_NEW is set.
86 * N is 0 if _ENABLE_PER_THREAD_LOCALE_NEW is not set.
87 */
88 __acrt_ptd* const ptd = __acrt_getptd();
90
91 switch(i)
92 {
94 // same behavior as __acrt_disable_global_locale_sync()
95 ptd->_own_locale = ptd->_own_locale | _PER_THREAD_LOCALE_BIT;
96 break;
97
99 // same behavior as __acrt_enable_global_locale_sync()
100 ptd->_own_locale = ptd->_own_locale & ~_PER_THREAD_LOCALE_BIT;
101 break;
102
103 case 0:
104 break;
105
106 /* used only during dll startup for linkopt */
107 case -1:
109 break;
110
111 default:
112 _VALIDATE_RETURN(("Invalid parameter for _configthreadlocale",0),EINVAL,-1);
113 break;
114 }
115
116 return retval;
117}
#define EINVAL
Definition: acclib.h:90
__acrt_ptd *__cdecl __acrt_getptd(void)
#define _PER_THREAD_LOCALE_BIT
#define _VALIDATE_RETURN(expr, errorcode, retexpr)
_In_ size_t const _In_ int _In_ bool const _In_ unsigned const _In_ __acrt_rounding_mode const _Inout_ __crt_cached_ptd_host & ptd
Definition: cvt.cpp:355
int __globallocalestatus
Definition: glstatus.cpp:13
#define _DISABLE_PER_THREAD_LOCALE
Definition: locale.h:55
#define _ENABLE_PER_THREAD_LOCALE
Definition: locale.h:54
int retval
Definition: wcstombs.cpp:91

◆ _copytlocinfo_nolock()

static void __cdecl _copytlocinfo_nolock ( __crt_locale_data ptlocid,
__crt_locale_data ptlocis 
)
static

Definition at line 280 of file wsetlocale.cpp.

283{
284 if (ptlocis != nullptr && ptlocid != nullptr && ptlocid != ptlocis) {
285 *ptlocid = *ptlocis;
286 ptlocid->refcount = 0;
287 __acrt_add_locale_ref(ptlocid);
288 }
289}
void __cdecl __acrt_add_locale_ref(__crt_locale_data *)

Referenced by _wcreate_locale(), and _wsetlocale().

◆ _create_locale()

_locale_t __cdecl _create_locale ( int  _category,
const char _locale 
)

Definition at line 378 of file wsetlocale.cpp.

382{
383 wchar_t _wlocale[MAX_LC_LEN];
384
385 /* Early input validation */
386 if ( (_category < LC_MIN) || (_category > LC_MAX) || _locale == nullptr)
387 return nullptr;
388
389 if ( __acrt_MultiByteToWideChar(CP_ACP, 0, _locale, -1, _wlocale, _countof(_wlocale)) == 0 )
390 { // conversion to wide char failed
391 return nullptr;
392 }
393
394 return _wcreate_locale(_category, _wlocale);
395}
#define MAX_LC_LEN
#define CP_ACP
Definition: compat.h:109
_locale_t __cdecl _wcreate_locale(int _category, const wchar_t *locale)
Definition: wsetlocale.cpp:340

◆ _CRT_LINKER_FORCE_INCLUDE()

_CRT_LINKER_FORCE_INCLUDE ( __acrt_locale_terminator  )

◆ _expandlocale()

wchar_t * _expandlocale ( wchar_t const *const  expr,
wchar_t *const  output,
size_t const  sizeInChars,
wchar_t *const  localeNameOutput,
size_t const  localeNameSizeInChars,
UINT output_code_page 
)

Definition at line 1139 of file wsetlocale.cpp.

1147{
1148 // Returns: locale name to return to user (lifetime bound to PTD variable _cacheout)
1149 // Out Parameters:
1150 // * output: locale name to return to user (lifetime bound to supplied buffer)
1151 // * localeNameOutput: normalized locale name to be used internally (lifetime bound to supplied buffer)
1152 // * output_code_page: code page used
1153 //
1154 // Effects:
1155 // Parses an input locale string and returns the string that will replicate the effects just taken (output), the string to be used
1156 // for Win32 calls (localeNameOutput), and the code page.
1157 // Note that there are three modes here:
1158 // * Legacy and Windows Locale Names:
1159 // The output locale string and internally used locale string become normalized for Win32 APIs.
1160 // Neither necessarily match the user input locale.
1161 // Uses ACP as default if Windows does not know the code page.
1162 // * Permissive Windows locale names:
1163 // Ask Windows whether full given user string is a known locale name.
1164 // In that case, the output locale string, internally used locale string, and user input locale all match.
1165 // Uses UTF-8 as default if Windows does not know the code page.
1166 // * BCP-47 Locale Names:
1167 // Windows doesn't recognize BCP-47 + code page specifiers, but we must support them for proper UTF-8 support.
1168 // The output locale name must include the code page, but internally we modify the format so Windows understands it.
1169 // Uses UTF-8 as default if Windows does not know the code page.
1170 //
1171 // Also populates _psetloc_data structure from the PTD:
1172 // Caching Internals:
1173 // * _cachein: Caches last successful 'expr'.
1174 // * _cacheout: Caches last successful 'output' (which is also the return value).
1175 // * _cachecp: Caches last successful 'output_code_page'.
1176 // * _cacheLocaleName: Caches last successful 'localeNameOutput'.
1177 // Legacy Internals (used by __acrt_get_qualified_locale and __acrt_get_qualified_locale_downlevel only):
1178 // * pchLanguage: Pointer to start of language name, ex: "English"
1179 // * pchCountry: Pointer to start of country/region name, ex: "United States"
1180 // * iLocState: Used to record the match degree for locales checked (i.e. language and region match vs just language match)
1181 // * bAbbrevLanguage: Whether language name is a three-letter short-form, ex: "ENU"
1182 // * bAbbrevCountry: Whether country/region name is a three letter short-form, ex: "USA"
1183 // * iPrimaryLen: Length of pchLanguage portion of locale string
1184 // Also in _psetloc_data, but not used in _expandlocale: _Loc_c
1185
1186 if (!expr)
1187 {
1188 return nullptr; // error if no input
1189 }
1190
1191 // C locale
1192 // Callers know that LocaleNameOutput has not been updated and check for "C" locale before using it.
1193 if (expr[0] == L'C' && expr[1] == L'\0')
1194 {
1195 _ERRCHECK(wcscpy_s(output, sizeInChars, L"C"));
1196 output_code_page = CP_ACP;
1197 return output;
1198 }
1199
1200 __crt_qualified_locale_data * const _psetloc_data = &__acrt_getptd()->_setloc_data;
1201 UINT * const pcachecp = &_psetloc_data->_cachecp;
1202 wchar_t * const cachein = _psetloc_data->_cachein;
1203 size_t const cacheinLen = _countof(_psetloc_data->_cachein);
1204 wchar_t * const cacheout = _psetloc_data->_cacheout;
1205 size_t const cacheoutLen = _countof(_psetloc_data->_cacheout);
1206 size_t charactersInExpression = 0;
1207 int iCodePage = 0;
1208
1209 // This guard owns access to localeNameOutput. It expresses the invariants that localeNameOutput and _cacheLocaleName have.
1210 _expandlocale_locale_name_cache locale_name_guard(localeNameOutput, localeNameSizeInChars, _psetloc_data);
1211
1212 // First, make sure we didn't just do this one
1213 charactersInExpression = wcslen(expr);
1214 if (charactersInExpression >= MAX_LC_LEN || // we would never have cached this
1215 (wcscmp(cacheout, expr) && wcscmp(cachein, expr)))
1216 {
1218 BOOL getqloc_results = FALSE;
1219 BOOL const isDownlevel = !__acrt_can_use_vista_locale_apis();
1220
1221 // Check if can parse as Legacy/Windows locale name
1222 if (__lc_wcstolc(&names, expr) == 0)
1223 {
1224 if (isDownlevel)
1225 {
1226 getqloc_results = __acrt_get_qualified_locale_downlevel(&names, pcachecp, &names);
1227 }
1228 else
1229 {
1230 getqloc_results = __acrt_get_qualified_locale(&names, pcachecp, &names);
1231 }
1232 }
1233
1234 // If successfully parsed as Legacy/Windows name
1235 if (getqloc_results)
1236 {
1237 // Legacy/Windows name resolution returns applies normalization to both returned and internally used locale names.
1238 __lc_lctowcs(cacheout, cacheoutLen, &names);
1239
1240 // __acrt_get_qualified_locale and __acrt_get_qualified_locale_downlevel update _cacheLocaleName - if successful commit locale changes
1241 locale_name_guard.commit_locale_name_cache_already_updated(names.szLocaleName, wcslen(names.szLocaleName) + 1);
1242 }
1244 {
1245 // Windows recognizes the locale expression - only work is to grab the code page to be used.
1246 iCodePage = get_default_code_page(expr);
1247
1248 // Commit code page
1249 *pcachecp = static_cast<WORD>(iCodePage);
1250
1251 // Commit locale name that we will return to the user (same as input locale string).
1252 _ERRCHECK(wcsncpy_s(cacheout, cacheoutLen, expr, charactersInExpression + 1));
1253
1254 // Commit locale name for internal use (same as input locale string).
1255 locale_name_guard.commit_locale_name(expr, charactersInExpression + 1);
1256 }
1257 else if (parse_bcp47(&names, expr) && __acrt_IsValidLocaleName(names.szLocaleName))
1258 {
1259 // Parsed as Windows-recognized BCP-47 tag
1260 wchar_t const * const normalized_locale_name = names.szLocaleName;
1261
1262 if (names.szCodePage[0])
1263 {
1264 wchar_t const * const cp = names.szCodePage;
1265
1266 // Allow .utf8/.utf-8 for BCP-47 tags.
1267 if ( __ascii_towlower(cp[0]) == L'u'
1268 && __ascii_towlower(cp[1]) == L't'
1269 && __ascii_towlower(cp[2]) == L'f'
1270 && (cp[3] == L'8' && cp[4] == L'\0')
1271 || (cp[3] == L'-' && cp[4] == L'8' && cp[5] == L'\0'))
1272 {
1273 iCodePage = CP_UTF8;
1274 }
1275 else
1276 {
1277 // Other codepage tokens (fr-FR.1252, etc.) aren't supported for BCP-47 tags (eg: Use Unicode!)
1278 return nullptr;
1279 }
1280 }
1281 else
1282 {
1283 iCodePage = get_default_code_page(normalized_locale_name);
1284 }
1285
1286 // Commit code page
1287 *pcachecp = static_cast<WORD>(iCodePage);
1288
1289 // Commit locale name that we will return to the user (same as input locale string).
1290 _ERRCHECK(wcsncpy_s(cacheout, cacheoutLen, expr, charactersInExpression + 1));
1291
1292 // Commit normalized name for internal use.
1293 locale_name_guard.commit_locale_name(normalized_locale_name, wcslen(normalized_locale_name) + 1);
1294 }
1295 else
1296 {
1297 return nullptr; // input unrecognized as locale name
1298 }
1299
1300 // Operation succeeded - commit input cache.
1301 if (*expr && charactersInExpression < MAX_LC_LEN)
1302 {
1303 _ERRCHECK(wcsncpy_s(cachein, cacheinLen, expr, charactersInExpression + 1));
1304 }
1305 else
1306 {
1307 *cachein = L'\x0';
1308 }
1309 }
1310
1311 output_code_page = *pcachecp; // Update code page
1312
1313 _ERRCHECK(wcscpy_s(output, sizeInChars, cacheout));
1314 return cacheout; // Return locale name to be given back to user, with lifetime bound in PTD
1315}
bool __cdecl __acrt_can_use_vista_locale_apis(void)
BOOL WINAPI __acrt_IsValidLocaleName(_In_ LPCWSTR locale_name)
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned short WORD
Definition: ntddk_ex.h:93
BOOL __cdecl __acrt_get_qualified_locale(const __crt_locale_strings *, UINT *, __crt_locale_strings *)
BOOL __cdecl __acrt_get_qualified_locale_downlevel(const __crt_locale_strings *lpInStr, UINT *lpOutCodePage, __crt_locale_strings *lpOutStr)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
__forceinline int __CRTDECL __ascii_towlower(int const _C)
Definition: ctype.h:180
unsigned int UINT
Definition: ndis.h:50
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define CP_UTF8
Definition: nls.h:20
__crt_qualified_locale_data _setloc_data
wchar_t _cachein[MAX_LC_LEN]
wchar_t _cacheout[MAX_LC_LEN]
Definition: query.h:86
_In_ size_t sizeInChars
Definition: wsetlocale.cpp:38
_In_ size_t _In_ size_t localeNameSizeInChars
Definition: wsetlocale.cpp:40
int __lc_wcstolc(__crt_locale_strings *, const wchar_t *)
static int get_default_code_page(wchar_t const *const valid_windows_locale_name)
_In_ size_t _In_ size_t _Out_ UINT & cp
Definition: wsetlocale.cpp:42
static bool parse_bcp47(__crt_locale_strings *const names, const wchar_t *const expr)
void __lc_lctowcs(_Inout_updates_z_(_Param_(2)) wchar_t *, size_t, const __crt_locale_strings *)

Referenced by _wsetlocale_nolock(), and _wsetlocale_set_cat().

◆ _free_locale()

void __cdecl _free_locale ( _locale_t  plocinfo)

Definition at line 151 of file wsetlocale.cpp.

154{
155 if (plocinfo != nullptr)
156 {
158 __try
159 {
160 if (plocinfo->mbcinfo != nullptr &&
163 {
165 }
166 }
168 {
170 }
172
173 if (plocinfo->locinfo != nullptr)
174 {
175 /*
176 * this portion has to be in locale lock as there may be case when
177 * not this thread but some other thread is still holding to this
178 * locale and is also trying to free this locale. In this case
179 * we may end up leaking memory.
180 */
181
183 __try
184 {
186 if ( (plocinfo->locinfo != nullptr) &&
187 (plocinfo->locinfo->refcount == 0) &&
190 }
192 {
194 }
196 }
197
199 }
200}
#define InterlockedDecrement
Definition: armddk.h:52
void __cdecl __acrt_unlock(_In_ __acrt_lock_id lock)
Definition: locks.cpp:57
void __cdecl __acrt_release_locale_ref(__crt_locale_data *)
@ __acrt_multibyte_cp_lock
__crt_multibyte_data __acrt_initial_multibyte_data
Definition: mbctype.cpp:42
__acrt_lock(__acrt_heap_lock)
_locale_t plocinfo
Definition: ismbbyte.cpp:75
#define __try
Definition: pseh2_64.h:172
#define __endtry
Definition: pseh2_64.h:175
#define __finally
Definition: pseh2_64.h:174
pthreadlocinfo locinfo
Definition: corecrt.h:23
pthreadmbcinfo mbcinfo
Definition: corecrt.h:24
void __cdecl __acrt_free_locale(__crt_locale_data *)

◆ _get_current_locale()

_locale_t __cdecl _get_current_locale ( void  )

Definition at line 213 of file wsetlocale.cpp.

214{
215 __acrt_ptd* const ptd = __acrt_getptd();
216
217 auto locale_copy(_calloc_crt_t(__crt_locale_pointers, 1));
218 if (!locale_copy)
219 return nullptr; // calloc will set errno
220
223
224 // No one can free the data pointed to by ptlocinfo while we're copying
225 // it, since we're copying this thread's ptlocinfo, which won't be updated
226 // during the copy. So there are no worries about it being freed from
227 // under us. We still need a lock while adding a reference for the new
228 // copy, though, because of the race condition found in _wsetlocale.
229 locale_copy.get()->locinfo = ptd->_locale_info;
230 locale_copy.get()->mbcinfo = ptd->_multibyte_info;
231 __acrt_lock_and_call(__acrt_locale_lock, [&]
232 {
233 __acrt_add_locale_ref(locale_copy.get()->locinfo);
234 });
235
236 __acrt_lock_and_call(__acrt_multibyte_cp_lock, [&]
237 {
238 InterlockedIncrement(&locale_copy.get()->mbcinfo->refcount);
239 });
240
241 return locale_copy.detach();
242}
#define InterlockedIncrement
Definition: armddk.h:53
__crt_multibyte_data *__cdecl __acrt_update_thread_multibyte_data(void)
Definition: mbctype.cpp:361
__crt_locale_data *__cdecl __acrt_update_thread_locale_data(void)

◆ _Out_writes_z_() [1/2]

_In_ size_t _Out_writes_z_ ( localeNameSizeInChars  )

◆ _Out_writes_z_() [2/2]

_Out_writes_z_ ( sizeInChars  )

◆ _setmbcp_nolock()

int __cdecl _setmbcp_nolock ( int  codepage,
__crt_multibyte_data ptmbci 
)

Definition at line 692 of file mbctype.cpp.

693{
694 unsigned int icp;
695 unsigned int irg;
696 unsigned int ich;
697 unsigned char *rgptr;
698 CPINFO cpInfo;
699
701
702 /* user wants 'single-byte' MB code page */
703 if (codepage == _MB_CP_SBCS)
704 {
705 setSBCS(ptmbci);
706 return 0;
707 }
708
709 /* check for CRT code page info */
710 for (icp = 0;
711 icp < (sizeof(__rgcode_page_info) / sizeof(code_page_info));
712 icp++)
713 {
714 /* see if we have info for this code page */
716 {
717 /* clear the table */
718 for (ich = 0; ich < NUM_CHARS; ich++)
719 ptmbci->mbctype[ich] = 0;
720
721 /* for each type of info, load table */
722 for (irg = 0; irg < NUM_CTYPES; irg++)
723 {
724 /* go through all the ranges for each type of info */
725 for (rgptr = (unsigned char *)__rgcode_page_info[icp].rgrange[irg];
726 rgptr[0] && rgptr[1];
727 rgptr += 2)
728 {
729 /* set the type for every character in range */
730 for (ich = rgptr[0]; ich <= rgptr[1] && ich < 256; ich++)
731 ptmbci->mbctype[ich + 1] |= __rgctypeflag[irg];
732 }
733 }
734 /* code page has changed */
735 ptmbci->mbcodepage = codepage;
736 /* all the code pages we keep info for are truly multibyte */
737 ptmbci->ismbcodepage = 1;
738 ptmbci->mblocalename = CPtoLocaleName(ptmbci->mbcodepage);
739 for (irg = 0; irg < NUM_ULINFO; irg++)
740 {
741 ptmbci->mbulinfo[irg] = __rgcode_page_info[icp].mbulinfo[irg];
742 }
743
744 /* return success */
745 setSBUpLow(ptmbci);
746 return 0;
747 }
748 }
749
750 /* verify codepage validity */
751 // Unclear why UTF7 is excluded yet stateful and other complex encodings are not
753 {
754 /* return failure, code page not changed */
755 return -1;
756 }
757
758 // Special case for UTF-8
759 if (codepage == CP_UTF8)
760 {
761 ptmbci->mbcodepage = CP_UTF8;
762 ptmbci->mblocalename = nullptr;
763
764 // UTF-8 does not have lead or trail bytes in the terms
765 // the CRT thinks of it for DBCS codepages, so we'll
766 // clear the flags for all bytes.
767 // Note that this array is 257 bytes because there's a
768 // "-1" that is used someplaces for EOF. So this array
769 // is actually -1 based.
770 for (ich = 0; ich < NUM_ULINFO; ich++)
771 {
772 ptmbci->mbctype[ich] = 0;
773 }
774
775 // not really a multibyte code page, we'll have to test
776 // ptmbci->mbcodepage == CP_UTF8 when we use this structure.
777 ptmbci->ismbcodepage = 0;
778
779 // CJK encodings have some full-width mappings, but not here.
780 for (irg = 0; irg < NUM_ULINFO; irg++)
781 {
782 ptmbci->mbulinfo[irg] = 0;
783 }
784
785 setSBUpLow(ptmbci);
786
787 // return success
788 return 0;
789 }
790 /* code page not supported by CRT, try the OS */\
791 else if (GetCPInfo(codepage, &cpInfo) != 0)
792 {
793 BYTE *lbptr;
794
795 /* clear the table */
796 for (ich = 0; ich < NUM_CHARS; ich++)
797 {
798 ptmbci->mbctype[ich] = 0;
799 }
800
801 ptmbci->mbcodepage = codepage;
802 ptmbci->mblocalename = nullptr;
803
804 // Special case for DBCS where we know there may be a leadbyte/trailbyte pattern
805 if (cpInfo.MaxCharSize == 2)
806 {
807 /* LeadByte range always terminated by two 0's */
808 for (lbptr = cpInfo.LeadByte; *lbptr && *(lbptr + 1); lbptr += 2)
809 {
810 for (ich = *lbptr; ich <= *(lbptr + 1); ich++)
811 ptmbci->mbctype[ich + 1] |= _M1;
812 }
813
814 /* All chars > 1 must be considered valid trail bytes */
815 for (ich = 0x01; ich < 0xFF; ich++)
816 {
817 ptmbci->mbctype[ich + 1] |= _M2;
818 }
819
820 /* code page has changed */
821 ptmbci->mblocalename = CPtoLocaleName(ptmbci->mbcodepage);
822
823 /* really a multibyte code page */
824 ptmbci->ismbcodepage = 1;
825 }
826 else
827 {
828 /* single-byte code page */
829 ptmbci->ismbcodepage = 0;
830 }
831
832 for (irg = 0; irg < NUM_ULINFO; irg++)
833 {
834 ptmbci->mbulinfo[irg] = 0;
835 }
836
837 setSBUpLow(ptmbci);
838 /* return success */
839 return 0;
840 }
841
842
843 /* If system default call, don't fail - set to SBCS */
844 if (fSystemSet)
845 {
846 setSBCS(ptmbci);
847 return 0;
848 }
849
850 /* return failure, code page not changed */
851 return -1;
852}
_Out_opt_ UINT * code_page
#define NUM_ULINFO
BOOL WINAPI IsValidCodePage(UINT codepage)
Definition: locale.c:2079
BOOL WINAPI GetCPInfo(UINT codepage, LPCPINFO cpinfo)
Definition: locale.c:2144
#define NUM_CHARS
Definition: mbctype.cpp:27
static const wchar_t * CPtoLocaleName(int codepage)
Definition: mbctype.cpp:514
static void setSBCS(__crt_multibyte_data *ptmbci)
Definition: mbctype.cpp:261
static int getSystemCP(int)
Definition: mbctype.cpp:554
static void setSBUpLow(__crt_multibyte_data *ptmbci)
Definition: mbctype.cpp:598
#define NUM_CTYPES
Definition: mbctype.cpp:29
static code_page_info __rgcode_page_info[]
Definition: mbctype.cpp:138
static int fSystemSet
Definition: mbctype.cpp:134
static char __rgctypeflag[NUM_CTYPES]
Definition: mbctype.cpp:136
#define for
Definition: utility.h:88
#define _M2
Definition: msvcrt.h:818
#define _M1
Definition: msvcrt.h:817
#define _MB_CP_SBCS
Definition: msvcrt.h:828
unsigned short mbulinfo[6]
unsigned char mbctype[257]
wchar_t const * mblocalename
BYTE LeadByte[MAX_LEADBYTES]
Definition: winnls.h:585
UINT MaxCharSize
Definition: winnls.h:583
unsigned short mbulinfo[NUM_ULINFO]
Definition: mbctype.cpp:36
unsigned char rgrange[NUM_CTYPES][MAX_RANGES]
Definition: mbctype.cpp:37
int codepage
Definition: win_iconv.c:156
#define CP_UTF7
Definition: winnls.h:237
unsigned char BYTE
Definition: xxhash.c:193

Referenced by _wcreate_locale(), and setmbcp_internal().

◆ _Success_()

_Success_ ( return = 0) const

Definition at line 86 of file inittime.cpp.

77{
78 // C Locale
79 if (!locale_data->locale_name[LC_TIME])
80 {
81 return &__lc_time_c;
82 }
83
84 // Non-C Locale
85 __crt_unique_heap_ptr<__crt_lc_time_data> lc_time = _calloc_crt_t(__crt_lc_time_data, 1);
86 if (!lc_time)
87 {
88 return nullptr;
89 }
90
91 if (!initialize_lc_time(lc_time.get(), locale_data))
92 {
94 return nullptr;
95 }
96
97 lc_time.get()->refcount = 1;
98
99 return lc_time.detach();
100}
__crt_lc_time_data const __lc_time_c
Definition: nlsdata.cpp:33
#define LC_TIME
Definition: locale.h:22
void __cdecl __acrt_locale_free_time(__crt_lc_time_data *const lc_time)
Definition: inittime.cpp:147
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t _Inout_ size_t __crt_lc_time_data const * lc_time
Definition: wcsftime.cpp:385

◆ _updatetlocinfo_nolock()

static __crt_locale_data *__cdecl _updatetlocinfo_nolock ( void  )
static

◆ _updatetlocinfoEx_nolock()

__crt_locale_data *__cdecl _updatetlocinfoEx_nolock ( __crt_locale_data **  pptlocid,
__crt_locale_data ptlocis 
)

Definition at line 200 of file locale_refcounting.cpp.

204{
205 if (ptlocis == nullptr || pptlocid == nullptr)
206 return nullptr;
207
208 __crt_locale_data* const ptloci = *pptlocid;
209 if (ptloci == ptlocis)
210 return ptlocis;
211
212 /*
213 * Update to the current locale info structure and increment the
214 * reference counts.
215 */
216 *pptlocid = ptlocis;
217 __acrt_add_locale_ref(ptlocis);
218
219 /*
220 * Decrement the reference counts in the old locale info
221 * structure.
222 */
223 if (ptloci != nullptr)
224 {
226 }
227
228 /*
229 * Free the old locale info structure, if necessary. Must be done
230 * after incrementing reference counts in current locale in case
231 * any refcounts are shared with the old locale.
232 */
233 if (ptloci != nullptr &&
234 ptloci->refcount == 0 &&
236 {
237 __acrt_free_locale(ptloci);
238 }
239
240 return ptlocis;
241}
__crt_locale_data __acrt_initial_locale_data
Definition: nlsdata.cpp:92
void __cdecl __acrt_free_locale(__crt_locale_data *ptloci)
void __cdecl __acrt_release_locale_ref(__crt_locale_data *ptloci)
void __cdecl __acrt_add_locale_ref(__crt_locale_data *ptloci)

Referenced by __acrt_uninitialize_locale(), __acrt_update_thread_locale_data(), and _wsetlocale().

◆ _wcreate_locale()

_locale_t __cdecl _wcreate_locale ( int  _category,
const wchar_t locale 
)

Definition at line 340 of file wsetlocale.cpp.

344{
345 if (_category < LC_MIN || _category > LC_MAX || locale == nullptr)
346 return nullptr;
347
348 auto result = _calloc_crt_t(__crt_locale_pointers, 1);
350
351 auto locale_data = _calloc_crt_t(__crt_locale_data, 1);
352 _VALIDATE_RETURN_NOEXC(locale_data, ENOMEM, nullptr);
353
354 auto multibyte_data = _calloc_crt_t(__crt_multibyte_data, 1);
355 _VALIDATE_RETURN_NOEXC(multibyte_data, ENOMEM, nullptr);
356
358
359 if (_wsetlocale_nolock(locale_data.get(), _category, locale) == nullptr ||
360 _setmbcp_nolock(locale_data.get()->_public._locale_lc_codepage, multibyte_data.get()) != 0)
361 {
362 __acrt_release_locale_ref(locale_data.get());
363 __acrt_free_locale(locale_data.detach());
364 return nullptr;
365 }
366
367 multibyte_data.get()->refcount = 1;
368
369 result.get()->locinfo = locale_data.detach();
370 result.get()->mbcinfo = multibyte_data.detach();
371 return result.detach();
372}
#define ENOMEM
Definition: acclib.h:84
GLuint64EXT * result
Definition: glext.h:11304
#define _VALIDATE_RETURN_NOEXC(expr, errorcode, retexpr)
int __cdecl _setmbcp_nolock(int, __crt_multibyte_data *)
Definition: mbctype.cpp:692
static void __cdecl _copytlocinfo_nolock(__crt_locale_data *ptlocid, __crt_locale_data *ptlocis)
Definition: wsetlocale.cpp:280
static wchar_t *__cdecl _wsetlocale_nolock(__crt_locale_data *, int, const wchar_t *)
Definition: wsetlocale.cpp:536

Referenced by _create_locale().

◆ _wcscats() [1/2]

void _wcscats ( _Inout_updates_z_(_Param_(2)) wchar_t ,
size_t  ,
int  ,
  ... 
)

◆ _wcscats() [2/2]

void _wcscats ( wchar_t outstr,
size_t  numberOfElements,
int  n,
  ... 
)

Definition at line 1319 of file wsetlocale.cpp.

1320{
1321 int i;
1323
1324 va_start (substr, n);
1325
1326 for (i =0; i<n; i++)
1327 {
1328 _ERRCHECK(wcscat_s(outstr, numberOfElements, va_arg(substr, wchar_t *)));
1329 }
1330 va_end(substr);
1331}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define va_arg(ap, T)
Definition: acmsvcex.h:89
GLdouble n
Definition: glext.h:7729
static substr_t substr(const WCHAR *str, size_t len)
Definition: internet.h:203
INT CDECL wcscat_s(wchar_t *dst, size_t elem, const wchar_t *src)
Definition: wcs.c:406

◆ _wsetlocale()

wchar_t *__cdecl _wsetlocale ( int  _category,
const wchar_t _wlocale 
)

Definition at line 441 of file wsetlocale.cpp.

445{
446 wchar_t * retval=nullptr;
447 __crt_locale_data* ptloci = nullptr;
448
449 /* Validate category */
450 _VALIDATE_RETURN(LC_MIN <= _category && _category <= LC_MAX, EINVAL, nullptr);
451
452 __acrt_ptd* const ptd = __acrt_getptd();
453
454 // Deadlock Avoidance: When a new thread is created in the process, we
455 // create a new PTD for the thread. The PTD initialization function is
456 // called under the loader lock. This initialization function will also
457 // acquire the locale lock in order to acquire a reference to the current
458 // global locale for the new thread.
459 //
460 // Some of the locale APIs are not available on all supported target OSes.
461 // We dynamically obtain these libraries via LoadLibrary/GetProcAddress.
462 // We must ensure that no call to LoadLibrary is made while we hold the
463 // locale lock, lest we deadlock due to lock order inversion between the
464 // loader lock and the locale lock.
465 //
466 // This function call here will ensure that any required modules are loaded
467 // before we acquire the locale lock.
469
471
472 // Prevent global locale resynchronization - we call things like stricmp() further down
473 // without passing our _locale_t which would trigger a resynchronization.
474 // Use _WSETLOCALE_AVOID_SYNC_LOCALE_BIT to avoid interfering with other locale settings
475 // (see _configthreadlocale() for details).
476
477 // This may not be necessary anymore and may be a hold-over from when _wsetlocale called
478 // setlocale instead of the other way around.
479 // (MSFT:20394962 - Investigate whether _WSETLOCALE_AVOID_SYNC_LOCALE_BIT is needed)
480 __acrt_disable_global_locale_sync(ptd, _WSETLOCALE_AVOID_SYNC_LOCALE_BIT);
481
482 __crt_call_and_cleanup([&]
483 {
484 if ((ptloci = _calloc_crt_t(__crt_locale_data, 1).detach()) != nullptr)
485 {
486 __acrt_lock_and_call(__acrt_locale_lock, [&]
487 {
488 _copytlocinfo_nolock(ptloci, ptd->_locale_info);
489
490 if ((retval = _wsetlocale_nolock(ptloci, _category, _wlocale)) != 0)
491 {
492 // If no call has been made to setlocale to change locale from "C" locale
493 // to some other locale, we keep locale_changed = 0. Other functions that
494 // depend on locale use this variable to optimize performance for C locale
495 // which is normally the case in applications.
496 if (_wlocale != nullptr)
497 {
498 if (wcscmp(_wlocale, __acrt_wide_c_locale_string) != 0)
499 {
501 }
502 // If it is again set to the C locale, could we not retain that state?
503 // else
504 // {
505 // __acrt_set_locale_unchanged();
506 // }
507 }
508
509 (void)_updatetlocinfoEx_nolock(&ptd->_locale_info, ptloci);
511 // Note that after incrementing _own_locale, if this thread doesn't
512 // have its own locale, _own_locale variable should be 1.
513
514 // Do not use __acrt_should_sync_with_global_locale() because
515 // _WSETLOCALE_AVOID_SYNC_LOCALE_BIT will interfere.
516 if (!(ptd->_own_locale & _PER_THREAD_LOCALE_BIT) &&
518 {
521 }
522 }
523 else
524 {
526 __acrt_free_locale(ptloci);
527 }
528 });
529 }
530 },
531 [&]{ __acrt_enable_global_locale_sync(ptd, _WSETLOCALE_AVOID_SYNC_LOCALE_BIT); });
532
533 return retval;
534}
#define _WSETLOCALE_AVOID_SYNC_LOCALE_BIT
void __cdecl __acrt_eagerly_load_locale_apis(void)
#define _GLOBAL_LOCALE_BIT
static __inline void sync_legacy_variables_lk()
Definition: wsetlocale.cpp:298
void __cdecl __acrt_set_locale_changed()
Definition: wsetlocale.cpp:54

◆ _wsetlocale_get_all()

static wchar_t *__cdecl _wsetlocale_get_all ( __crt_locale_data ploci)
static

Definition at line 802 of file wsetlocale.cpp.

803{
804 int i;
805 int same = 1;
806 wchar_t *pch = nullptr;
807 size_t cch = 0;
808 long *refcount = nullptr;
809 size_t refcountSize = 0;
810
811 /* allocate memory if necessary */
812 refcountSize = sizeof(int) + (sizeof(wchar_t) * (MAX_LC_LEN+1) * (LC_MAX-LC_MIN+1)) + (sizeof(wchar_t) * CATNAMES_LEN);
813 if ( (refcount = static_cast<long*>(_malloc_crt(refcountSize))) == nullptr)
814 return nullptr;
815
816 pch = ((wchar_t*)refcount) + (sizeof(int) / sizeof(wchar_t));
817 cch = (refcountSize - sizeof(int)) / sizeof(wchar_t);
818 *pch = L'\0';
819 *refcount = 1;
820 for (i=LC_MIN+1; ; i++)
821 {
822 _wcscats(pch, cch, 3, __lc_category[i].catname, L"=", ploci->lc_category[i].wlocale);
823 if (i<LC_MAX)
824 {
825 _ERRCHECK(wcscat_s(pch, cch, L";"));
826 if (wcscmp(ploci->lc_category[i].wlocale, ploci->lc_category[i+1].wlocale))
827 same=0;
828 }
829 else
830 {
831 if (!same) {
832 if (ploci->lc_category[LC_ALL].wrefcount != nullptr &&
834 _ASSERT(0);
836 }
837 if (ploci->lc_category[LC_ALL].refcount != nullptr &&
839 _ASSERT(0);
841 }
842 ploci->lc_category[LC_ALL].refcount = nullptr;
843 ploci->lc_category[LC_ALL].locale = nullptr;
844 ploci->lc_category[LC_ALL].wrefcount = refcount;
845 return ploci->lc_category[LC_ALL].wlocale = pch;
846 } else {
847 _free_crt(refcount);
848 if (ploci->lc_category[LC_ALL].wrefcount != nullptr &&
850 _ASSERT(0);
852 }
853 if (ploci->lc_category[LC_ALL].refcount != nullptr &&
855 _ASSERT(0);
857 }
858 ploci->lc_category[LC_ALL].refcount = nullptr;
859 ploci->lc_category[LC_ALL].locale = nullptr;
860 ploci->lc_category[LC_ALL].wrefcount = nullptr;
861 ploci->lc_category[LC_ALL].wlocale = nullptr;
862 return ploci->lc_category[LC_CTYPE].wlocale;
863 }
864 }
865 }
866} /* _wsetlocale_get_all */
#define _ASSERT(x)
#define CATNAMES_LEN
#define LC_CTYPE
Definition: locale.h:19
#define LC_ALL
Definition: locale.h:17
#define pch(ap)
Definition: match.c:418
#define wchar_t
Definition: wchar.h:102

Referenced by _wsetlocale_nolock().

◆ _wsetlocale_nolock()

static wchar_t *__cdecl _wsetlocale_nolock ( __crt_locale_data ploci,
int  _category,
const wchar_t _wlocale 
)
static

Definition at line 536 of file wsetlocale.cpp.

541{
542 wchar_t * retval;
543 /* Interpret locale */
544
545 if (_category != LC_ALL)
546 {
547 retval = (_wlocale) ? _wsetlocale_set_cat(ploci, _category,_wlocale) :
548 ploci->lc_category[_category].wlocale;
549
550 } else { /* LC_ALL */
551 wchar_t lctemp[MAX_LC_LEN];
552 int i;
553 int same = 1;
554 int fLocaleSet = 0; /* flag to indicate if anything successfully set */
555
556 if (_wlocale != nullptr)
557 {
558 if ( (_wlocale[0]==L'L') && (_wlocale[1]==L'C') && (_wlocale[2]==L'_') )
559 {
560 /* parse compound locale string */
561 size_t len;
562 const wchar_t * p = _wlocale; /* start of string to parse */
563 const wchar_t * s;
564
565 do {
566 s = wcspbrk(p, L"=;");
567
568 if (s == nullptr || (len=(size_t)(s - p)) == 0 || (*s == L';'))
569 return nullptr; /* syntax error */
570
571 /* match with known LC_ strings, if possible, else ignore */
572 for (i=LC_ALL+1; i<=LC_MAX; i++)
573 {
574 if ((!wcsncmp(__lc_category[i].catname,p,len))
575 && (len==wcslen(__lc_category[i].catname)))
576 {
577 break; /* matched i */
578 }
579 } /* no match if (i>LC_MAX) -- just ignore */
580
581 if ((len = wcscspn(++s, L";")) == 0 && *s != L';')
582 return nullptr; /* syntax error */
583
584 if (i<=LC_MAX)
585 {
586 _ERRCHECK(wcsncpy_s(lctemp, _countof(lctemp), s, len));
587 lctemp[len]=L'\0'; /* null terminate string */
588
589 /* don't fail unless all categories fail */
590 if (_wsetlocale_set_cat(ploci, i,lctemp))
591 fLocaleSet++; /* record a success */
592 }
593 if (*(p = s+len)!=L'\0')
594 p++; /* skip ';', if present */
595
596 } while (*p);
597
598 retval = (fLocaleSet) ? _wsetlocale_get_all(ploci) : nullptr;
599
600 } else { /* simple LC_ALL locale string */
601
603 wchar_t localeNameTemp[LOCALE_NAME_MAX_LENGTH];
604 /* confirm locale is supported, get expanded locale */
605 retval = _expandlocale(_wlocale, lctemp, _countof(lctemp), localeNameTemp, _countof(localeNameTemp), code_page);
606 if (retval != 0)
607 {
608 for (i=LC_MIN; i<=LC_MAX; i++)
609 {
610 if (i!=LC_ALL)
611 {
612 if (wcscmp(lctemp, ploci->lc_category[i].wlocale) != 0)
613 { // does not match the LC_ALL locale
614 if (_wsetlocale_set_cat(ploci, i, lctemp))
615 {
616 fLocaleSet++; /* record a success */
617 }
618 else
619 {
620 same = 0; /* record a failure */
621 }
622 }
623 else
624 fLocaleSet++; /* trivial succcess */
625 }
626 }
627 if (same) /* needn't call setlocale_get_all() if all the same */
628 {
630 /* retval set above */
631 }
632 else
633 retval = (fLocaleSet) ? _wsetlocale_get_all(ploci) : nullptr;
634 }
635 }
636 } else { /* LC_ALL & nullptr */
637 retval = _wsetlocale_get_all (ploci);
638 }
639 }
640
641 /* common exit point */
642 return retval;
643} /* setlocale */
GLdouble s
Definition: gl.h:2039
GLfloat GLfloat p
Definition: glext.h:8902
_Check_return_ _CRTIMP _CONST_RETURN wchar_t *__cdecl wcspbrk(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_Control)
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
static wchar_t *__cdecl _wsetlocale_get_all(__crt_locale_data *)
Definition: wsetlocale.cpp:802
static wchar_t *__cdecl _wsetlocale_set_cat(__crt_locale_data *, int, const wchar_t *)
Definition: wsetlocale.cpp:646
wchar_t * _expandlocale(wchar_t const *const expr, wchar_t *const output, size_t const sizeInChars, wchar_t *const localeNameOutput, size_t const localeNameSizeInChars, UINT &output_code_page)

Referenced by _wcreate_locale(), and _wsetlocale().

◆ _wsetlocale_set_cat()

static wchar_t *__cdecl _wsetlocale_set_cat ( __crt_locale_data ploci,
int  category,
const wchar_t wlocale 
)
static

Definition at line 646 of file wsetlocale.cpp.

651{
652 wchar_t * oldlocale;
653 wchar_t * oldlocalename;
654 UINT oldcodepage;
655
656 UINT cptemp;
657 wchar_t lctemp[MAX_LC_LEN];
658 wchar_t localeNameString[LOCALE_NAME_MAX_LENGTH];
659 wchar_t * pch = nullptr;
660 wchar_t * pch_cat_locale = nullptr;
661 size_t cch = 0;
662 unsigned short out[sizeof(_first_127char)];
663 int i;
664 __acrt_ptd* const ptd = __acrt_getptd();
665 __crt_ctype_compatibility_data* _Loc_c = ptd->_setloc_data._Loc_c; // __setloc_data._Loc_c is array
666 int _LOC_CCACHE = _countof(ptd->_setloc_data._Loc_c);
668
669 if (!_expandlocale(wlocale, lctemp, _countof(lctemp), localeNameString, _countof(localeNameString), cptemp))
670 return nullptr;
671
672 // if this category's locale hadn't changed
673 if (wcscmp(lctemp, ploci->lc_category[category].wlocale) == 0)
674 {
675 return ploci->lc_category[category].wlocale;
676 }
677
678 cch = wcslen(lctemp) + 1;
679 if ((pch = static_cast<wchar_t*>(_malloc_crt(sizeof(int) + (cch * sizeof(wchar_t))))) == nullptr)
680 return nullptr; /* error if malloc fails */
681
682 pch_cat_locale = pch + (sizeof(int) / sizeof(wchar_t));
683
684 /* save for possible restore */
685 oldlocale = ploci->lc_category[category].wlocale;
686 oldlocalename = ploci->locale_name[category];
687 oldcodepage = ploci->_public._locale_lc_codepage;
688
689 /* update locale string */
690 _ERRCHECK(wcscpy_s(pch_cat_locale, cch, lctemp));
691 ploci->lc_category[category].wlocale = pch_cat_locale;
692
693 /* Copy locale name */
694 if (lctemp[0] == L'C' && lctemp[1] == L'\x0') // if "C" locale
695 ploci->locale_name[category] = nullptr;
696 else
697 ploci->locale_name[category] = __acrt_copy_locale_name(localeNameString);
698
699 /* To speedup locale based comparisions, we identify if the current
700 * local has first 127 character set same as CLOCALE. If yes then
701 * ploci->lc_clike = TRUE.
702 */
703
704 if (category==LC_CTYPE)
705 {
706 ploci->_public._locale_lc_codepage = cptemp;
707 buf1 = _Loc_c[_LOC_CCACHE -1];
708 /* brings the recently used codepage to the top. or else shifts
709 * every thing down by one so that new _Loc_c can be placed at
710 * the top.
711 */
712 for ( i = 0; i < _LOC_CCACHE; i++)
713 {
714 if (ploci->_public._locale_lc_codepage == _Loc_c[i].id)
715 {
716 /* We don't really want to swap cache around in case what we are looking
717 * for is the first element of the cache
718 */
719 if (i!=0)
720 {
721 _Loc_c[0] = _Loc_c[i];
722 _Loc_c[i] = buf1;
723 }
724 break;
725 }
726 else
727 {
728 buf2 = _Loc_c[i];
729 _Loc_c[i] = buf1;
730 buf1 = buf2;
731 }
732 }
733 if ( i == _LOC_CCACHE)
734 {
735 if ( __acrt_GetStringTypeA(nullptr, CT_CTYPE1,
737 sizeof(_first_127char),
738 out,
740 TRUE ))
741 {
742 int j;
743 for ( j = 0; j < sizeof(_first_127char); j++)
744 out[j] = out[j]&
746 if ( !memcmp(out, _ctype_loc_style, (sizeof(_first_127char)/sizeof(char))*sizeof(short)))
747 {
748 _Loc_c[0].is_clike = TRUE;
749 }
750 else
751 {
752 _Loc_c[0].is_clike = FALSE;
753 }
754 }
755 else
756 _Loc_c[0].is_clike = FALSE;
757 _Loc_c[0].id = ploci->_public._locale_lc_codepage;
758 }
759 ploci->lc_clike = _Loc_c[0].is_clike;
760 } /* category==LC_CTYPE */
761 else if ( category == LC_COLLATE )
762 ploci->lc_collate_cp = cptemp;
763 else if ( category == LC_TIME )
764 ploci->lc_time_cp = cptemp;
765
766 if (__lc_category[category].init(ploci) != 0)
767 {
768 /* restore previous state */
769 ploci->lc_category[category].wlocale = oldlocale;
771 ploci->locale_name[category] = oldlocalename;
772 _free_crt(pch);
773 ploci->_public._locale_lc_codepage = oldcodepage;
774
775 return nullptr; /* error if non-zero return */
776 }
777
778 /* locale set up successfully */
779 /* Cleanup */
780 if ((oldlocale != __acrt_wide_c_locale_string) &&
782 )
783 {
784 _ASSERT(0);
788 ploci->lc_category[category].wlocale = nullptr;
789 ploci->locale_name[category] = nullptr;
790 }
791 if (pch)
792 {
793 reinterpret_cast<long&>(*pch) = 1;
794 }
795 ploci->lc_category[category].wrefcount = reinterpret_cast<long*>(pch);
796
797 return ploci->lc_category[category].wlocale;
798} /* _wsetlocale_set_cat */
BOOL __cdecl __acrt_GetStringTypeA(_locale_t const locale, DWORD const info_type, LPCSTR const string, int const string_size_in_bytes, unsigned short *const char_type, int const code_page, BOOL const error)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define _BLANK
Definition: ctype.h:72
#define _PUNCT
Definition: ctype.h:70
#define _CONTROL
Definition: ctype.h:71
#define _LOWER
Definition: ctype.h:66
#define _SPACE
Definition: ctype.h:68
#define _ALPHA
Definition: ctype.h:76
#define _UPPER
Definition: ctype.h:65
#define _HEX
Definition: ctype.h:73
#define _DIGIT
Definition: ctype.h:67
#define LC_COLLATE
Definition: locale.h:18
unsigned int _locale_lc_codepage
Definition: corecrt.h:625
__crt_locale_data_public _public
unsigned int lc_collate_cp
unsigned int lc_time_cp
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
#define CT_CTYPE1
Definition: winnls.h:239
LPWSTR __cdecl __acrt_copy_locale_name(LPCWSTR localeName)
static const char _first_127char[]
Definition: wsetlocale.cpp:16
static const unsigned short * _ctype_loc_style
Definition: wsetlocale.cpp:29

Referenced by _wsetlocale_nolock().

◆ categorize_delimiter()

static _bcp47_section_delimiter categorize_delimiter ( wchar_t const  wc)
static

Definition at line 891 of file wsetlocale.cpp.

892{
893 switch (wc)
894 {
895 case '-':
896 case '_':
898 case '.':
900 case '\0':
901 default:
903 }
904}

Referenced by parse_bcp47().

◆ get_default_code_page()

static int get_default_code_page ( wchar_t const *const  valid_windows_locale_name)
static

Definition at line 1071 of file wsetlocale.cpp.

1072{
1073 int code_page{};
1074
1075 int const size_written = __acrt_GetLocaleInfoEx(
1076 valid_windows_locale_name,
1077 LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
1078 reinterpret_cast<LPWSTR>(&code_page),
1079 sizeof(int) / sizeof(wchar_t)
1080 );
1081
1082 if (size_written == 0 || code_page == 0)
1083 { // Default to UTF-8 if could not find or no default code page.
1084 return CP_UTF8;
1085 }
1086
1087 return code_page;
1088}
int WINAPI __acrt_GetLocaleInfoEx(_In_opt_ LPCWSTR locale_name, _In_ LCTYPE lc_type, _Out_writes_opt_(data_count) LPWSTR data, _In_ int data_count)
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:40
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by _expandlocale().

◆ no_op_initialize()

static int __cdecl no_op_initialize ( __crt_locale_data )
static

Definition at line 248 of file wsetlocale.cpp.

249{
250 return 0;
251}

◆ parse_bcp47()

static bool parse_bcp47 ( __crt_locale_strings *const  names,
const wchar_t *const  expr 
)
static

Definition at line 1003 of file wsetlocale.cpp.

1004{
1005 wchar_t const * p = expr;
1006 wchar_t const * const delimiters = L"-_.";
1007
1008 memset(names, 0, sizeof(__crt_locale_strings));
1009
1010 size_t const max_sections = 4;
1012 size_t num_sections = 0;
1013
1014 for (auto last_delimiter = _bcp47_section_delimiter::normal;
1016 last_delimiter = categorize_delimiter(*p++)
1017 )
1018 {
1019 if (num_sections >= max_sections)
1020 {
1021 // Didn't reach end of string before running out of sections to parse.
1022 return false;
1023 }
1024
1025 size_t const section_length = (last_delimiter != _bcp47_section_delimiter::code_page)
1026 ? wcscspn(p, delimiters) : wcslen(p);
1027
1028 sections[num_sections].ptr = p;
1029 sections[num_sections].length = section_length;
1030 sections[num_sections].delimiter = last_delimiter;
1031
1032 p += section_length;
1033 ++num_sections;
1034 }
1035
1036 switch (num_sections)
1037 {
1038 case 1:
1039 // en
1041 case 2:
1042 // en-US
1043 // zh-Hans
1044 // en.utf-8
1045 // .utf-8
1050 );
1051 case 3:
1052 // en-US.utf-8
1053 // zh-Hans-HK
1057 );
1058 case 4:
1059 // zh-Hans-HK.utf-8
1064 default:
1065 return false;
1066 }
1067}
@ max_sections
Definition: resource.c:32
struct section sections[2]
Definition: diskspace.c:792
static bool parse_bcp47_language(__crt_locale_strings *const names, _bcp47_section const &section)
Definition: wsetlocale.cpp:930
static bool parse_bcp47_script(__crt_locale_strings *const names, _bcp47_section const &section)
Definition: wsetlocale.cpp:952
static bool parse_bcp47_code_page(__crt_locale_strings *const names, _bcp47_section const &section)
Definition: wsetlocale.cpp:992
static bool parse_bcp47_region(__crt_locale_strings *const names, _bcp47_section const &section)
Definition: wsetlocale.cpp:973
static _bcp47_section_delimiter categorize_delimiter(wchar_t const wc)
Definition: wsetlocale.cpp:891

Referenced by _expandlocale().

◆ parse_bcp47_code_page()

static bool parse_bcp47_code_page ( __crt_locale_strings *const  names,
_bcp47_section const section 
)
static

Definition at line 992 of file wsetlocale.cpp.

993{
995 {
996 return false;
997 }
998
999 _ERRCHECK(wcsncpy_s(names->szCodePage, _countof(names->szCodePage), section.ptr, section.length));
1000 return true; // Success
1001}
Definition: parser.c:56

Referenced by parse_bcp47().

◆ parse_bcp47_language()

static bool parse_bcp47_language ( __crt_locale_strings *const  names,
_bcp47_section const section 
)
static

Definition at line 930 of file wsetlocale.cpp.

931{
933 {
934 return false;
935 }
936
937 if (section.length < 2 || section.length > 3)
938 {
939 return false; // Failure, only 2-3 letter language codes permitted.
940 }
941
942 if (!string_is_alpha(section.ptr, section.length))
943 {
944 return false;
945 }
946
947 _ERRCHECK(wcsncpy_s(names->szLanguage, _countof(names->szLanguage), section.ptr, section.length));
948 _ERRCHECK(wcsncpy_s(names->szLocaleName, _countof(names->szLocaleName), section.ptr, section.length));
949 return true;
950}
static bool string_is_alpha(wchar_t const *const str, size_t const len)
Definition: wsetlocale.cpp:906

Referenced by parse_bcp47().

◆ parse_bcp47_region()

static bool parse_bcp47_region ( __crt_locale_strings *const  names,
_bcp47_section const section 
)
static

Definition at line 973 of file wsetlocale.cpp.

974{
976 {
977 return false;
978 }
979
980 if ( !(section.length == 2 && string_is_alpha(section.ptr, section.length)) // if not 2 letters
981 && !(section.length == 3 && string_is_digit(section.ptr, section.length))) // and not 3 digits
982 {
983 return false;
984 }
985
986 _ERRCHECK(wcsncpy_s(names->szCountry, _countof(names->szCountry), section.ptr, section.length));
987 _ERRCHECK(wcsncat_s(names->szLocaleName, _countof(names->szLocaleName), L"-", 1));
988 _ERRCHECK(wcsncat_s(names->szLocaleName, _countof(names->szLocaleName), section.ptr, section.length));
989 return true;
990}
wcsncat_s
static bool string_is_digit(wchar_t const *const str, size_t const len)
Definition: wsetlocale.cpp:918

Referenced by parse_bcp47().

◆ parse_bcp47_script()

static bool parse_bcp47_script ( __crt_locale_strings *const  names,
_bcp47_section const section 
)
static

Definition at line 952 of file wsetlocale.cpp.

953{
955 {
956 return false;
957 }
958
959 if (section.length != 4) {
960 return false; // Failure, only 4 letter script codes permitted.
961 }
962
963 if (!string_is_alpha(section.ptr, section.length))
964 {
965 return false;
966 }
967
968 _ERRCHECK(wcsncat_s(names->szLocaleName, _countof(names->szLocaleName), L"-", 1));
969 _ERRCHECK(wcsncat_s(names->szLocaleName, _countof(names->szLocaleName), section.ptr, section.length));
970 return true;
971}

Referenced by parse_bcp47().

◆ string_is_alpha()

static bool string_is_alpha ( wchar_t const *const  str,
size_t const  len 
)
static

Definition at line 906 of file wsetlocale.cpp.

907{
908 for (size_t i = 0; i < len; ++i)
909 {
910 if (!__ascii_isalpha(str[i]))
911 {
912 return false;
913 }
914 }
915 return true;
916}
#define __ascii_isalpha(c)
Definition: ctype.h:141
const WCHAR * str

Referenced by parse_bcp47_language(), parse_bcp47_region(), and parse_bcp47_script().

◆ string_is_digit()

static bool string_is_digit ( wchar_t const *const  str,
size_t const  len 
)
static

Definition at line 918 of file wsetlocale.cpp.

919{
920 for (size_t i = 0; i < len; ++i)
921 {
922 if (!__ascii_isdigit(str[i]))
923 {
924 return false;
925 }
926 }
927 return true;
928}
#define __ascii_isdigit(c)
Definition: ctype.h:142

Referenced by parse_bcp47_region().

◆ sync_legacy_variables_lk()

static __inline void sync_legacy_variables_lk ( )
static

Definition at line 298 of file wsetlocale.cpp.

299{
301 _pctype = __acrt_current_locale_data.value()->_public._locale_pctype;
302 __mb_cur_max = __acrt_current_locale_data.value()->_public._locale_mb_cur_max;
303}
struct lconv * __acrt_lconv
Definition: localeconv.cpp:56
#define __mb_cur_max
Definition: ctype.h:629
#define _pctype
Definition: wctype.h:43

Referenced by _wsetlocale().

Variable Documentation

◆ __acrt_initial_locale_data

__crt_locale_data __acrt_initial_locale_data
extern

Definition at line 91 of file nlsdata.cpp.

Referenced by __acrt_uninitialize_locale(), _free_locale(), and _wcreate_locale().

◆ __acrt_locale_changed_data

long __acrt_locale_changed_data = FALSE

Definition at line 31 of file wsetlocale.cpp.

Referenced by __acrt_set_locale_changed().

◆ __lc_category

const __lc_category[LC_MAX-LC_MIN+1]
Initial value:
= {
{ L"LC_ALL", nullptr, no_op_initialize },
}
int __cdecl __acrt_locale_initialize_ctype(__crt_locale_data *ploci)
Definition: initctype.cpp:51
int __cdecl __acrt_locale_initialize_monetary(__crt_locale_data *ploci)
Definition: initmon.cpp:61
int __cdecl __acrt_locale_initialize_numeric(__crt_locale_data *ploci)
Definition: initnum.cpp:76
int __cdecl __acrt_locale_initialize_time(__crt_locale_data *const locale_data)
Definition: inittime.cpp:104
static int __cdecl no_op_initialize(__crt_locale_data *)
Definition: wsetlocale.cpp:248

Definition at line 261 of file wsetlocale.cpp.

Referenced by _wsetlocale_get_all(), _wsetlocale_nolock(), and _wsetlocale_set_cat().

◆ _ctype_loc_style

const unsigned short* _ctype_loc_style = _wctype + 2
static

Definition at line 29 of file wsetlocale.cpp.

Referenced by _wsetlocale_set_cat().

◆ _first_127char

const char _first_127char[]
static
Initial value:
= {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68,
69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100,101,102,
103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,
120,121,122,123,124,125,126,127
}

Definition at line 16 of file wsetlocale.cpp.

Referenced by _wsetlocale_set_cat().

◆ _wctype

const unsigned short _wctype[]
extern

Definition at line 296 of file ctype.c.

◆ cp

Definition at line 41 of file wsetlocale.cpp.

Referenced by _expandlocale().

◆ localeNameSizeInChars

_In_ size_t _In_ size_t localeNameSizeInChars

◆ sizeInChars

_In_ size_t sizeInChars

Definition at line 38 of file wsetlocale.cpp.

Referenced by _expandlocale().