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.

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