ReactOS 0.4.16-dev-732-g2d1144a
initctype.cpp
Go to the documentation of this file.
1/***
2*initctype.cpp - contains __acrt_locale_initialize_ctype
3*
4* Copyright (c) Microsoft Corporation. All rights reserved.
5*
6*Purpose:
7* Contains the locale-category initialization function: __acrt_locale_initialize_ctype().
8*
9* Each initialization function sets up locale-specific information
10* for their category, for use by functions which are affected by
11* their locale category.
12*
13* *** For internal use by setlocale() only ***
14*
15*******************************************************************************/
16#include <corecrt_internal.h>
17#include <locale.h>
18#include <stdlib.h>
19
20#define _CTABSIZE 257 /* size of ctype tables */
21
22// Enclaves have no ability to create new locales.
23#ifndef _UCRT_ENCLAVE_BUILD
24
25/***
26*int __acrt_locale_initialize_ctype() - initialization for LC_CTYPE locale category.
27*
28*Purpose:
29* In non-C locales, preread ctype tables for chars and wide-chars.
30* Old tables are freed when new tables are fully established, else
31* the old tables remain intact (as if original state unaltered).
32* The leadbyte table is implemented as the high bit in ctype1.
33*
34* In the C locale, ctype tables are freed, and pointers point to
35* the static ctype table.
36*
37* Tables contain 257 entries: -1 to 256.
38* Table pointers point to entry 0 (to allow index -1).
39*
40*Entry:
41* None.
42*
43*Exit:
44* 0 success
45* 1 fail
46*
47*Exceptions:
48*
49*******************************************************************************/
50
53 )
54{
55 /* non-C locale table for char's */
56 unsigned short *newctype1 = nullptr; /* temp new table */
57 unsigned char *newclmap = nullptr; /* temp new map table */
58 unsigned char *newcumap = nullptr; /* temp new map table */
59
60 /* non-C locale table for wchar_t's */
61
62 unsigned char *cbuffer = nullptr; /* char working buffer */
63
64 int i; /* general purpose counter */
65 unsigned char *cp; /* char pointer */
66 CPINFO cpInfo; /* struct for use with GetCPInfo */
67 int mb_cur_max;
69
70 locinfo.locinfo = ploci;
71 locinfo.mbcinfo = 0;
72
73 /* allocate and set up buffers before destroying old ones */
74 /* codepage will be restored by setlocale if error */
75
76 if (ploci->locale_name[LC_CTYPE] != nullptr)
77 {
78 long* refcount = nullptr;
79
80 if (ploci->_public._locale_lc_codepage == 0)
81 { /* code page was not specified */
83 ploci->locale_name[LC_CTYPE],
85 (char **)&ploci->_public._locale_lc_codepage ) )
86 goto error_cleanup;
87 }
88
89 /* allocate a new (thread) reference counter */
90 refcount = _calloc_crt_t(long, 1).detach();
91
92 /* allocate new buffers for tables */
93 newctype1 = _calloc_crt_t(unsigned short, _COFFSET + _CTABSIZE).detach();
94 newclmap = _calloc_crt_t(unsigned char, _COFFSET + _CTABSIZE).detach();
95 newcumap = _calloc_crt_t(unsigned char, _COFFSET + _CTABSIZE).detach();
96 cbuffer = _calloc_crt_t(unsigned char, _CTABSIZE).detach();
97
98 if (!refcount || !newctype1 || !cbuffer || !newclmap || !newcumap)
99 goto error_cleanup;
100
101 /* construct string composed of first 256 chars in sequence */
102 for (cp=cbuffer, i=0; i<_CTABSIZE-1; i++)
103 *cp++ = (unsigned char)i;
104
105 if (GetCPInfo( ploci->_public._locale_lc_codepage, &cpInfo) == FALSE)
106 goto error_cleanup;
107
108 if (cpInfo.MaxCharSize > MB_LEN_MAX)
109 goto error_cleanup;
110
111 mb_cur_max = (unsigned short) cpInfo.MaxCharSize;
112
113 /* zero (space actually) out leadbytes so GetStringType and
114 LCMapStringA don't interpret them as multi-byte chars */
115 if (mb_cur_max > 1)
116 {
117 if (ploci->_public._locale_lc_codepage == CP_UTF8)
118 {
119 // For UTF-8 anything above 0x7f is part of a multibyte sequence and
120 // would confuse the codepage/character code below.
121 for (i = 0x80; i <= 0xff; i++)
122 {
123 // spaces are safe.
124 cbuffer[i] = ' ';
125 }
126 }
127 else
128 {
129 // use the lead byte table to mark off the appropriate bytes
130 for (cp = (unsigned char *)cpInfo.LeadByte; cp[0] && cp[1]; cp += 2)
131 {
132 for (i = cp[0]; i <= cp[1]; i++)
133 cbuffer[i] = ' ';
134 }
135 }
136 }
137
138 /*
139 * LCMapString will map past nullptr. Must find nullptr if in string
140 * before cchSrc characters.
141 */
142 if ( __acrt_LCMapStringA(nullptr,
143 ploci->locale_name[LC_CTYPE],
145 reinterpret_cast<char*>(cbuffer + 1),
146 _CTABSIZE-2,
147 reinterpret_cast<char*>(newclmap + 2 + _COFFSET),
148 _CTABSIZE-2,
150 FALSE ) == FALSE)
151 goto error_cleanup;
152
153 if ( __acrt_LCMapStringA(nullptr,
154 ploci->locale_name[LC_CTYPE],
156 reinterpret_cast<char*>(cbuffer + 1),
157 _CTABSIZE-2,
158 reinterpret_cast<char*>(newcumap + 2 + _COFFSET),
159 _CTABSIZE-2,
161 FALSE ) == FALSE)
162 goto error_cleanup;
163
164 /* convert to newctype1 table - ignore invalid char errors */
165 if ( __acrt_GetStringTypeA(nullptr, CT_CTYPE1,
166 reinterpret_cast<char*>(cbuffer),
167 _CTABSIZE-1,
168 newctype1+1+_COFFSET,
170 FALSE ) == FALSE )
171 goto error_cleanup;
172
173 newctype1[_COFFSET] = 0; /* entry for EOF */
174 newclmap[_COFFSET] = 0;
175 newcumap[_COFFSET] = 0;
176 newclmap[_COFFSET+1] = 0; /* entry for null */
177 newcumap[_COFFSET+1] = 0; /* entry for null */
178
179 /* ignore DefaultChar */
180
181 /* mark lead-byte entries in newctype1 table and
182 restore original values for lead-byte entries for clmap/cumap */
183 if (mb_cur_max > 1)
184 {
185 if (ploci->_public._locale_lc_codepage == CP_UTF8)
186 {
187 // For UTF-8 anything above 0x7f is part of a multibyte sequence
188 // "real" leadbytes start with C0 and end at F7
189 // However, C0 & C1 are overlong encoded ASCII, F5 & F6 would be > U+10FFFF.
190 // Note that some starting with E0 and F0 are overlong and not legal though.
191 for (i = 0x80; i <= 0xff; i++)
192 {
193 newctype1[_COFFSET + i + 1] = (i >= 0xc2 && i < 0xf5) ? _LEADBYTE : 0;
194 newclmap[_COFFSET + i + 1] = static_cast<unsigned char>(i);
195 newcumap[_COFFSET + i + 1] = static_cast<unsigned char>(i);
196 }
197 }
198 else
199 {
200 for (cp = (unsigned char *)cpInfo.LeadByte; cp[0] && cp[1]; cp += 2)
201 {
202 for (i = cp[0]; i <= cp[1]; i++)
203 {
204 newctype1[_COFFSET + i + 1] = _LEADBYTE;
205 newclmap[_COFFSET + i + 1] = static_cast<unsigned char>(i);
206 newcumap[_COFFSET + i + 1] = static_cast<unsigned char>(i);
207 }
208 }
209 }
210 }
211 /* copy last-1 _COFFSET unsigned short to front
212 * note -1, we don't really want to copy 0xff
213 */
214 memcpy(newctype1,newctype1+_CTABSIZE-1,_COFFSET*sizeof(unsigned short));
215 memcpy(newclmap,newclmap+_CTABSIZE-1,_COFFSET*sizeof(char));
216 memcpy(newcumap,newcumap+_CTABSIZE-1,_COFFSET*sizeof(char));
217
218 /* free old tables */
219 if ((ploci->ctype1_refcount) &&
221 {
222 _ASSERT(0);
223 _free_crt(ploci->ctype1 - _COFFSET);
224 _free_crt((char *)(ploci->pclmap - _COFFSET - 1));
225 _free_crt((char *)(ploci->pcumap - _COFFSET - 1));
227 }
228 (*refcount) = 1;
229 ploci->ctype1_refcount = refcount;
230 /* set pointers to point to entry 0 of tables */
231 ploci->_public._locale_pctype = newctype1 + 1 + _COFFSET;
232 ploci->ctype1 = newctype1 + _COFFSET;
233 ploci->pclmap = newclmap + 1 + _COFFSET;
234 ploci->pcumap = newcumap + 1 + _COFFSET;
235 ploci->_public._locale_mb_cur_max = mb_cur_max;
236
237 /* cleanup and return success */
238 _free_crt (cbuffer);
239 return 0;
240
241error_cleanup:
242 _free_crt (refcount);
243 _free_crt (newctype1);
244 _free_crt (newclmap);
245 _free_crt (newcumap);
246 _free_crt (cbuffer);
247 return 1;
248
249 } else {
250
251 if ( (ploci->ctype1_refcount != nullptr)&&
253 {
254 _ASSERTE(*ploci->ctype1_refcount > 0);
255 }
256 ploci->ctype1_refcount = nullptr;
257 ploci->ctype1 = nullptr;
259 ploci->pclmap = __newclmap + 1 + _COFFSET;
260 ploci->pcumap = __newcumap + 1 + _COFFSET;
261 ploci->_public._locale_mb_cur_max = 1;
262
263 return 0;
264 }
265}
266
267#endif /* _UCRT_ENCLAVE_BUILD */
268
269/* Define a number of functions which exist so, under _STATIC_CPPLIB, the
270 * static multithread C++ Library libcpmt.lib can access data found in the
271 * main CRT DLL without using __declspec(dllimport).
272 */
273
275{
276 /*
277 * Note that we don't need _LocaleUpdate in this function.
278 * The main reason being, that this is a leaf function in
279 * locale usage terms.
280 */
281 __acrt_ptd* const ptd = __acrt_getptd();
282 __crt_locale_data* ptloci = ptd->_locale_info;
283
285
286 return ptloci->_public._locale_mb_cur_max;
287}
288
290{
291 return locale == nullptr
293 : locale->locinfo->_public._locale_mb_cur_max;
294}
295
297{
298 /*
299 * Note that we don't need _LocaleUpdate in this function.
300 * The main reason being, that this is a leaf function in
301 * locale usage terms.
302 */
303 __acrt_ptd* const ptd = __acrt_getptd();
304 __crt_locale_data* ptloci = ptd->_locale_info;
305
307
308 return ptloci->_public._locale_lc_codepage;
309}
310
312{
313 /*
314 * Note that we don't need _LocaleUpdate in this function.
315 * The main reason being, that this is a leaf function in
316 * locale usage terms.
317 */
318 __acrt_ptd* const ptd = __acrt_getptd();
319 __crt_locale_data* ptloci = ptd->_locale_info;
320
322
323 return ptloci->lc_collate_cp;
324}
325
327{
328 /*
329 * Note that we don't need _LocaleUpdate in this function.
330 * The main reason being, that this is a leaf function in
331 * locale usage terms.
332 */
333 __acrt_ptd* const ptd = __acrt_getptd();
334 __crt_locale_data* ptloci = ptd->_locale_info;
335
337
338 return ptloci->locale_name;
339}
#define _ASSERT(x)
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 __cdecl __acrt_LCMapStringA(_locale_t const plocinfo, PCWSTR const LocaleName, DWORD const dwMapFlags, PCCH const lpSrcStr, int const cchSrc, PCH const lpDestStr, int const cchDest, int const code_page, BOOL const bError)
#define __cdecl
Definition: accygwin.h:79
#define InterlockedDecrement
Definition: armddk.h:52
Definition: _locale.h:75
__acrt_ptd *__cdecl __acrt_getptd(void)
#define LC_INT_TYPE
#define _COFFSET
int __cdecl __acrt_GetLocaleInfoA(_In_opt_ _locale_t _Locale, _In_ int _LCType, _In_ LPCWSTR _LocaleName, _In_ LCTYPE _FieldType, _Out_ void *_Address)
unsigned short const __newctype[]
Definition: ctype.cpp:304
#define _ASSERTE(expr)
Definition: crtdbg.h:114
_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
#define FALSE
Definition: types.h:117
BOOL WINAPI GetCPInfo(UINT codepage, LPCPINFO cpinfo)
Definition: locale.c:2144
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
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
const unsigned char __newcumap[]
Definition: ctype.cpp:595
#define _LEADBYTE
Definition: ctype.h:75
const unsigned char __newclmap[]
Definition: ctype.cpp:447
#define LC_CTYPE
Definition: locale.h:19
#define MB_LEN_MAX
Definition: stdlib.h:19
int __cdecl __acrt_locale_initialize_ctype(__crt_locale_data *ploci)
Definition: initctype.cpp:51
unsigned int __cdecl ___lc_codepage_func()
Definition: initctype.cpp:296
int __cdecl ___mb_cur_max_l_func(_locale_t locale)
Definition: initctype.cpp:289
unsigned int __cdecl ___lc_collate_cp_func()
Definition: initctype.cpp:311
#define _CTABSIZE
Definition: initctype.cpp:20
int __cdecl ___mb_cur_max_func()
Definition: initctype.cpp:274
wchar_t **__cdecl ___lc_locale_name_func()
Definition: initctype.cpp:326
#define _free_crt
if(dx< 0)
Definition: linetemp.h:194
void __acrt_update_locale_info(__acrt_ptd *const ptd, __crt_locale_data **const locale_info)
POINT cp
Definition: magnifier.c:59
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
else locinfo
Definition: scanf.h:159
#define CP_UTF8
Definition: nls.h:20
unsigned int _locale_lc_codepage
Definition: corecrt.h:625
unsigned short const * _locale_pctype
Definition: stubs.c:95
unsigned char const * pcumap
__crt_locale_data_public _public
unsigned int lc_collate_cp
wchar_t * locale_name[6]
unsigned char const * pclmap
unsigned short * ctype1
BYTE LeadByte[MAX_LEADBYTES]
Definition: winnls.h:585
UINT MaxCharSize
Definition: winnls.h:583
#define CT_CTYPE1
Definition: winnls.h:239
#define LCMAP_UPPERCASE
Definition: winnls.h:187
#define LCMAP_LOWERCASE
Definition: winnls.h:186
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:40