Source code of Windows XP (NT5)
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.

229 lines
5.3 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. *
  21. *******************************************************************************/
  22. #include <cruntime.h>
  23. #include <ctype.h>
  24. #include <stddef.h>
  25. #include <xlocinfo.h>
  26. #include <locale.h>
  27. #include <setlocal.h>
  28. #include <mtdll.h>
  29. #include <awint.h>
  30. #include <stdlib.h>
  31. #include <dbgint.h>
  32. /* remove macro definitions of _tolower() and tolower()
  33. */
  34. #undef _tolower
  35. #undef tolower
  36. /***
  37. *int _tolower(c) - convert character to lower case
  38. *
  39. *Purpose:
  40. * _tolower() is a version of tolower with a locale argument.
  41. *
  42. *Entry:
  43. * c - int value of character to be converted
  44. * const _Ctypevec * = pointer to locale info
  45. *
  46. *Exit:
  47. * returns int value of lower case representation of c
  48. *
  49. *Exceptions:
  50. *
  51. *******************************************************************************/
  52. #ifdef _MT
  53. int __cdecl _Tolower_lk (
  54. int c,
  55. const _Ctypevec *ploc
  56. );
  57. #endif
  58. _CRTIMP2 int __cdecl _Tolower (
  59. int c,
  60. const _Ctypevec *ploc
  61. )
  62. {
  63. #ifdef _MT
  64. LCID handle;
  65. int local_lock_flag;
  66. if (ploc == 0)
  67. handle = ___lc_handle_func()[LC_CTYPE];
  68. else
  69. handle = ploc->_Hand;
  70. if (handle == _CLOCALEHANDLE)
  71. {
  72. if ( (c >= 'A') && (c <= 'Z') )
  73. c = c + ('a' - 'A');
  74. return c;
  75. }
  76. _lock_locale( local_lock_flag )
  77. c = _Tolower_lk(c, ploc);
  78. _unlock_locale( local_lock_flag )
  79. return c;
  80. }
  81. /***
  82. *int _tolower_lk(c) - convert character to lower case
  83. *
  84. *Purpose:
  85. * Multi-thread function only! Non-locking version of tolower.
  86. *
  87. *Entry:
  88. *
  89. *Exit:
  90. *
  91. *Exceptions:
  92. *
  93. *******************************************************************************/
  94. int __cdecl _Tolower_lk (
  95. int c,
  96. const _Ctypevec *ploc
  97. )
  98. {
  99. #endif /* _MT */
  100. int size;
  101. unsigned char inbuffer[3];
  102. unsigned char outbuffer[3];
  103. LCID handle;
  104. UINT codepage;
  105. if (ploc == 0)
  106. {
  107. handle = ___lc_handle_func()[LC_CTYPE];
  108. codepage = ___lc_codepage_func();
  109. }
  110. else
  111. {
  112. handle = ploc->_Hand;
  113. codepage = ploc->_Page;
  114. }
  115. if (handle == _CLOCALEHANDLE)
  116. {
  117. if ( (c >= 'A') && (c <= 'Z') )
  118. c = c + ('a' - 'A');
  119. return c;
  120. }
  121. /* if checking case of c does not require API call, do it */
  122. if ((unsigned)c < 256)
  123. {
  124. if (ploc == 0)
  125. {
  126. if (!isupper(c))
  127. {
  128. return c;
  129. }
  130. }
  131. else
  132. {
  133. if (!ploc->_Table[c] & _UPPER)
  134. {
  135. return c;
  136. }
  137. }
  138. }
  139. /* convert int c to multibyte string */
  140. if (_cpp_isleadbyte(c >> 8 & 0xff))
  141. {
  142. inbuffer[0] = (c >> 8 & 0xff);
  143. inbuffer[1] = (unsigned char)c;
  144. inbuffer[2] = 0;
  145. size = 2;
  146. } else {
  147. inbuffer[0] = (unsigned char)c;
  148. inbuffer[1] = 0;
  149. size = 1;
  150. }
  151. /* convert wide char to lowercase */
  152. if (0 == (size = __crtLCMapStringA(handle, LCMAP_LOWERCASE,
  153. inbuffer, size, outbuffer, 3, codepage, TRUE)))
  154. {
  155. return c;
  156. }
  157. /* construct integer return value */
  158. if (size == 1)
  159. return ((int)outbuffer[0]);
  160. else
  161. return ((int)outbuffer[1] | ((int)outbuffer[0] << 8));
  162. }
  163. /***
  164. *_Ctypevec _Getctype() - get ctype info for current locale
  165. *
  166. *Purpose:
  167. *
  168. *Entry:
  169. *
  170. *Exit:
  171. *
  172. *Exceptions:
  173. *
  174. *******************************************************************************/
  175. _CRTIMP2 _Ctypevec __cdecl _Getctype()
  176. {
  177. /* get ctype info for current locale */
  178. _Ctypevec ctype;
  179. #ifdef _MT
  180. int local_lock_flag;
  181. #endif
  182. _lock_locale( local_lock_flag )
  183. ctype._Hand = ___lc_handle_func()[LC_COLLATE];
  184. ctype._Page = ___lc_codepage_func();
  185. ctype._Table = _malloc_crt(256 * sizeof (*__pctype_func()));
  186. if (ctype._Table != 0)
  187. {
  188. memcpy((void *)ctype._Table, __pctype_func(), 256 * sizeof (*__pctype_func()));
  189. ctype._Delfl = 1;
  190. }
  191. else
  192. {
  193. ctype._Table = (const short *)__pctype_func();
  194. ctype._Delfl = 0;
  195. }
  196. _unlock_locale( local_lock_flag )
  197. return (ctype);
  198. }