Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

318 lines
10 KiB

  1. /***
  2. *initctyp.c - contains __init_ctype
  3. *
  4. * Copyright (c) 1991-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Contains the locale-category initialization function: __init_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. *Revision History:
  16. * 12-08-91 ETC Created.
  17. * 12-20-91 ETC Updated to use new NLSAPI GetLocaleInfo.
  18. * 12-18-92 CFW Ported to Cuda tree, changed _CALLTYPE4 to _CRTAPI3.
  19. * 01-19-03 CFW Move to _NEWCTYPETABLE, remove switch.
  20. * 02-08-93 CFW Bug fixes under _INTL switch.
  21. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  22. * 04-20-93 CFW Check return val.
  23. * 05-20-93 GJF Include windows.h, not individual win*.h files
  24. * 05-24-93 CFW Clean up file (brief is evil).
  25. * 09-15-93 CFW Use ANSI conformant "__" names.
  26. * 09-15-93 CFW Fix size parameters.
  27. * 09-17-93 CFW Use unsigned chars.
  28. * 09-22-93 CFW Use __crtxxx internal NLS API wrapper.
  29. * 09-22-93 CFW NT merge.
  30. * 11-09-93 CFW Add code page for __crtxxx().
  31. * 03-31-94 CFW Include awint.h.
  32. * 04-15-94 GJF Made definitions of ctype1 and wctype1 conditional
  33. * on DLL_FOR_WIN32S.
  34. * 04-18-94 CFW Pass lcid to _crtGetStringType.
  35. * 09-06-94 CFW Remove _INTL switch.
  36. * 01-10-95 CFW Debug CRT allocs.
  37. * 02-02-95 BWT Update POSIX support
  38. * 03-16-97 RDK Added error flag to __crtGetStringTypeA.
  39. * 11-25-97 GJF When necessary, use LOCALE_IDEFAULTANSICODEPAGE,
  40. * not LOCALE_IDEFAULTCODEPAGE.
  41. * 06-29-98 GJF Changed to support multithread scheme - old ctype
  42. * tables must be kept around until all affected threads
  43. * have updated or terminated.
  44. * 03-05-99 GJF Added __ctype1_refcount for use in cleaning up
  45. * per-thread ctype info.
  46. * 09-06-00 GB Made pwctype independent of locale.
  47. * 01-29-01 GB Added _func function version of data variable used in msvcprt.lib
  48. * to work with STATIC_CPPLIB
  49. * 07-07-01 BWT Cleanup malloc/free abuse - Only free __ctype1/refcount/
  50. * newctype1/cbuffer if they're no zero. Init refcount to zero
  51. * 04-25-02 GB Increased the size of _ctype perthread variable and pointed
  52. * it at begin+_COFFSET position so that isxxx macro would work
  53. * same for signed char, usigned char and EOF.
  54. *
  55. *******************************************************************************/
  56. #include <stdlib.h>
  57. #include <windows.h>
  58. #include <locale.h>
  59. #include <setlocal.h>
  60. #include <ctype.h>
  61. #include <malloc.h>
  62. #include <limits.h>
  63. #include <awint.h>
  64. #include <dbgint.h>
  65. #ifdef _MT
  66. #include <mtdll.h>
  67. #endif
  68. #define _CTABSIZE 257 /* size of ctype tables */
  69. #ifdef _MT
  70. /*
  71. * Keep track of how many threads are using a instance of the ctype info. Only
  72. * used for non-'C' locales.
  73. */
  74. int *__ctype1_refcount;
  75. #endif
  76. unsigned short *__ctype1; /* keep around until next time */
  77. /***
  78. *int __init_ctype() - initialization for LC_CTYPE locale category.
  79. *
  80. *Purpose:
  81. * In non-C locales, preread ctype tables for chars and wide-chars.
  82. * Old tables are freed when new tables are fully established, else
  83. * the old tables remain intact (as if original state unaltered).
  84. * The leadbyte table is implemented as the high bit in ctype1.
  85. *
  86. * In the C locale, ctype tables are freed, and pointers point to
  87. * the static ctype table.
  88. *
  89. * Tables contain 257 entries: -1 to 256.
  90. * Table pointers point to entry 0 (to allow index -1).
  91. *
  92. *Entry:
  93. * None.
  94. *
  95. *Exit:
  96. * 0 success
  97. * 1 fail
  98. *
  99. *Exceptions:
  100. *
  101. *******************************************************************************/
  102. int __cdecl __init_ctype (
  103. void
  104. )
  105. {
  106. #if defined(_POSIX_)
  107. return(0);
  108. #else /* _POSIX_ */
  109. #ifdef _MT
  110. int *refcount = NULL;
  111. #endif
  112. /* non-C locale table for char's */
  113. unsigned short *newctype1 = NULL; /* temp new table */
  114. /* non-C locale table for wchar_t's */
  115. unsigned char *cbuffer = NULL; /* char working buffer */
  116. int i; /* general purpose counter */
  117. unsigned char *cp; /* char pointer */
  118. CPINFO lpCPInfo; /* struct for use with GetCPInfo */
  119. /* allocate and set up buffers before destroying old ones */
  120. /* codepage will be restored by setlocale if error */
  121. if (__lc_handle[LC_CTYPE] != _CLOCALEHANDLE)
  122. {
  123. if (__lc_codepage == 0)
  124. { /* code page was not specified */
  125. if ( __getlocaleinfo( LC_INT_TYPE,
  126. MAKELCID(__lc_id[LC_CTYPE].wLanguage, SORT_DEFAULT),
  127. LOCALE_IDEFAULTANSICODEPAGE,
  128. (char **)&__lc_codepage ) )
  129. goto error_cleanup;
  130. }
  131. #ifdef _MT
  132. /* allocate a new (thread) reference counter */
  133. refcount = (int *)_malloc_crt(sizeof(int));
  134. #endif
  135. /* allocate new buffers for tables */
  136. newctype1 = (unsigned short *)
  137. _malloc_crt((_COFFSET+_CTABSIZE) * sizeof(unsigned short));
  138. cbuffer = (unsigned char *)
  139. _malloc_crt (_CTABSIZE * sizeof(char));
  140. #ifdef _MT
  141. if (!refcount || !newctype1 || !cbuffer )
  142. #else
  143. if (!newctype1 || !cbuffer )
  144. #endif
  145. goto error_cleanup;
  146. #ifdef _MT
  147. *refcount = 0;
  148. #endif
  149. /* construct string composed of first 256 chars in sequence */
  150. for (cp=cbuffer, i=0; i<_CTABSIZE-1; i++)
  151. *cp++ = (unsigned char)i;
  152. if (GetCPInfo( __lc_codepage, &lpCPInfo) == FALSE)
  153. goto error_cleanup;
  154. if (lpCPInfo.MaxCharSize > MB_LEN_MAX)
  155. goto error_cleanup;
  156. __mb_cur_max = (unsigned short) lpCPInfo.MaxCharSize;
  157. /* zero out leadbytes so GetStringType doesn't interpret as multi-byte chars */
  158. if (__mb_cur_max > 1)
  159. {
  160. for (cp = (unsigned char *)lpCPInfo.LeadByte; cp[0] && cp[1]; cp += 2)
  161. {
  162. for (i = cp[0]; i <= cp[1]; i++)
  163. cbuffer[i] = 0;
  164. }
  165. }
  166. /* convert to newctype1 table - ignore invalid char errors */
  167. if ( __crtGetStringTypeA( CT_CTYPE1,
  168. cbuffer,
  169. _CTABSIZE-1,
  170. newctype1+1+_COFFSET,
  171. 0,
  172. 0,
  173. FALSE ) == FALSE )
  174. goto error_cleanup;
  175. newctype1[_COFFSET] = 0; /* entry for EOF */
  176. /* ignore DefaultChar */
  177. /* mark lead-byte entries in newctype1 table */
  178. if (__mb_cur_max > 1)
  179. {
  180. for (cp = (unsigned char *)lpCPInfo.LeadByte; cp[0] && cp[1]; cp += 2)
  181. {
  182. for (i = cp[0]; i <= cp[1]; i++)
  183. newctype1[_COFFSET+i+1] = _LEADBYTE;
  184. }
  185. }
  186. memcpy(newctype1,newctype1+_CTABSIZE-1,_COFFSET*sizeof(unsigned short));
  187. /* set pointers to point to entry 0 of tables */
  188. _pctype = newctype1 + 1 + _COFFSET;
  189. #ifdef _MT
  190. __ctype1_refcount = refcount;
  191. #endif
  192. /* free old tables */
  193. #ifndef _MT
  194. if (__ctype1)
  195. _free_crt (__ctype1 - _COFFSET);
  196. #endif
  197. __ctype1 = newctype1 + _COFFSET;
  198. /* cleanup and return success */
  199. _free_crt (cbuffer);
  200. return 0;
  201. error_cleanup:
  202. #ifdef _MT
  203. if (refcount)
  204. _free_crt (refcount);
  205. #endif
  206. if (newctype1)
  207. _free_crt (newctype1);
  208. if (cbuffer)
  209. _free_crt (cbuffer);
  210. return 1;
  211. } else {
  212. /* set pointers to static C-locale table */
  213. _pctype = _ctype + 1;
  214. #ifndef _MT
  215. /* free dynamic locale-specific tables */
  216. if (__ctype1)
  217. _free_crt (__ctype1- _COFFSET);
  218. #endif
  219. #ifdef _MT
  220. __ctype1_refcount = NULL;
  221. #endif
  222. __ctype1 = NULL;
  223. return 0;
  224. }
  225. #endif /* _POSIX_ */
  226. }
  227. /* Define a number of functions which exist so, under _STATIC_CPPLIB, the
  228. * static multithread C++ Library libcpmt.lib can access data found in the
  229. * main CRT DLL without using __declspec(dllimport).
  230. */
  231. _CRTIMP int __cdecl ___mb_cur_max_func(void)
  232. {
  233. return __mb_cur_max;
  234. }
  235. _CRTIMP UINT __cdecl ___lc_codepage_func(void)
  236. {
  237. #ifdef _MT
  238. pthreadlocinfo ptloci = _getptd()->ptlocinfo;
  239. if ( ptloci != __ptlocinfo )
  240. ptloci = __updatetlocinfo();
  241. return ptloci->lc_codepage;
  242. #else
  243. return __lc_codepage;
  244. #endif
  245. }
  246. _CRTIMP UINT __cdecl ___lc_collate_cp_func(void)
  247. {
  248. #ifdef _MT
  249. pthreadlocinfo ptloci = _getptd()->ptlocinfo;
  250. if ( ptloci != __ptlocinfo )
  251. ptloci = __updatetlocinfo();
  252. return ptloci->lc_collate_cp;
  253. #else
  254. return __lc_collate_cp;
  255. #endif
  256. }
  257. _CRTIMP LCID* __cdecl ___lc_handle_func(void)
  258. {
  259. #ifdef _MT
  260. pthreadlocinfo ptloci = _getptd()->ptlocinfo;
  261. if ( ptloci != __ptlocinfo )
  262. ptloci = __updatetlocinfo();
  263. return ptloci->lc_handle;
  264. #else
  265. return __lc_handle;
  266. #endif
  267. }