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.

236 lines
5.9 KiB

  1. /***
  2. *_tolower.c - convert character to lower case
  3. *
  4. * Copyright (c) 1996-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Defines _Tolower().
  8. *
  9. *Revision History:
  10. * 01-xx-96 PJP Created from tolower.c, January 1996 by P.J. Plauger
  11. * 04-16-96 GJF Updated for current locale locking. Also, reformatted
  12. * and made several cosmetic changes.
  13. * 09-25-96 GJF Added locale locking to _Getctype.
  14. * 03-17-97 RDK Added error flag to __crtLCMapStringA.
  15. * 05-17-99 PML Remove all Macintosh support.
  16. * 01-29-01 GB Added _func function version of data variable used in
  17. * msvcprt.lib to work with STATIC_CPPLIB
  18. * 03-12-01 PML Use supplied locale to check case VS7#190902
  19. * 04-03-01 PML Reverse lead/trail bytes in composed char (vs7#232853)
  20. * 04-26-02 GB Fixed problem with operator precedence. problem was
  21. * !ploc->_Table[c]&_UPPER
  22. * 04-29-02 GB Added try-finally arounds lock-unlock.
  23. *
  24. *******************************************************************************/
  25. #include <cruntime.h>
  26. #include <ctype.h>
  27. #include <stddef.h>
  28. #include <xlocinfo.h>
  29. #include <locale.h>
  30. #include <setlocal.h>
  31. #include <mtdll.h>
  32. #include <awint.h>
  33. #include <stdlib.h>
  34. #include <dbgint.h>
  35. /* remove macro definitions of _tolower() and tolower()
  36. */
  37. #undef _tolower
  38. #undef tolower
  39. /***
  40. *int _tolower(c) - convert character to lower case
  41. *
  42. *Purpose:
  43. * _tolower() is a version of tolower with a locale argument.
  44. *
  45. *Entry:
  46. * c - int value of character to be converted
  47. * const _Ctypevec * = pointer to locale info
  48. *
  49. *Exit:
  50. * returns int value of lower case representation of c
  51. *
  52. *Exceptions:
  53. *
  54. *******************************************************************************/
  55. #ifdef _MT
  56. int __cdecl _Tolower_lk (
  57. int c,
  58. const _Ctypevec *ploc
  59. );
  60. #endif
  61. _CRTIMP2 int __cdecl _Tolower (
  62. int c,
  63. const _Ctypevec *ploc
  64. )
  65. {
  66. #ifdef _MT
  67. LCID handle;
  68. int local_lock_flag;
  69. if (ploc == 0)
  70. handle = ___lc_handle_func()[LC_CTYPE];
  71. else
  72. handle = ploc->_Hand;
  73. if (handle == _CLOCALEHANDLE)
  74. {
  75. if ( (c >= 'A') && (c <= 'Z') )
  76. c = c + ('a' - 'A');
  77. return c;
  78. }
  79. _lock_locale( local_lock_flag )
  80. __TRY
  81. c = _Tolower_lk(c, ploc);
  82. __FINALLY
  83. _unlock_locale( local_lock_flag )
  84. __END_TRY_FINALLY
  85. return c;
  86. }
  87. /***
  88. *int _tolower_lk(c) - convert character to lower case
  89. *
  90. *Purpose:
  91. * Multi-thread function only! Non-locking version of tolower.
  92. *
  93. *Entry:
  94. *
  95. *Exit:
  96. *
  97. *Exceptions:
  98. *
  99. *******************************************************************************/
  100. int __cdecl _Tolower_lk (
  101. int c,
  102. const _Ctypevec *ploc
  103. )
  104. {
  105. #endif /* _MT */
  106. int size;
  107. unsigned char inbuffer[3];
  108. unsigned char outbuffer[3];
  109. LCID handle;
  110. UINT codepage;
  111. if (ploc == 0)
  112. {
  113. handle = ___lc_handle_func()[LC_CTYPE];
  114. codepage = ___lc_codepage_func();
  115. }
  116. else
  117. {
  118. handle = ploc->_Hand;
  119. codepage = ploc->_Page;
  120. }
  121. if (handle == _CLOCALEHANDLE)
  122. {
  123. if ( (c >= 'A') && (c <= 'Z') )
  124. c = c + ('a' - 'A');
  125. return c;
  126. }
  127. /* if checking case of c does not require API call, do it */
  128. if ((unsigned)c < 256)
  129. {
  130. if (ploc == 0)
  131. {
  132. if (!isupper(c))
  133. {
  134. return c;
  135. }
  136. }
  137. else
  138. {
  139. if (!(ploc->_Table[c] & _UPPER))
  140. {
  141. return c;
  142. }
  143. }
  144. }
  145. /* convert int c to multibyte string */
  146. if (_cpp_isleadbyte(c >> 8 & 0xff))
  147. {
  148. inbuffer[0] = (c >> 8 & 0xff);
  149. inbuffer[1] = (unsigned char)c;
  150. inbuffer[2] = 0;
  151. size = 2;
  152. } else {
  153. inbuffer[0] = (unsigned char)c;
  154. inbuffer[1] = 0;
  155. size = 1;
  156. }
  157. /* convert wide char to lowercase */
  158. if (0 == (size = __crtLCMapStringA(handle, LCMAP_LOWERCASE,
  159. inbuffer, size, outbuffer, 3, codepage, TRUE)))
  160. {
  161. return c;
  162. }
  163. /* construct integer return value */
  164. if (size == 1)
  165. return ((int)outbuffer[0]);
  166. else
  167. return ((int)outbuffer[1] | ((int)outbuffer[0] << 8));
  168. }
  169. /***
  170. *_Ctypevec _Getctype() - get ctype info for current locale
  171. *
  172. *Purpose:
  173. *
  174. *Entry:
  175. *
  176. *Exit:
  177. *
  178. *Exceptions:
  179. *
  180. *******************************************************************************/
  181. _CRTIMP2 _Ctypevec __cdecl _Getctype()
  182. {
  183. /* get ctype info for current locale */
  184. _Ctypevec ctype;
  185. #ifdef _MT
  186. int local_lock_flag;
  187. #endif
  188. _lock_locale( local_lock_flag )
  189. __TRY
  190. ctype._Hand = ___lc_handle_func()[LC_COLLATE];
  191. ctype._Page = ___lc_codepage_func();
  192. ctype._Table = _malloc_crt(256 * sizeof (*__pctype_func()));
  193. if (ctype._Table != 0)
  194. {
  195. memcpy((void *)ctype._Table, __pctype_func(), 256 * sizeof (*__pctype_func()));
  196. ctype._Delfl = 1;
  197. }
  198. else
  199. {
  200. ctype._Table = (const short *)__pctype_func();
  201. ctype._Delfl = 0;
  202. }
  203. __FINALLY
  204. _unlock_locale( local_lock_flag )
  205. __END_TRY_FINALLY
  206. return (ctype);
  207. }