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.

218 lines
6.1 KiB

  1. /***
  2. *tolower.c - convert character to lower case
  3. *
  4. * Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Defines function versions of _tolower() and tolower().
  8. *
  9. *Revision History:
  10. * 11-09-84 DFW created
  11. * 12-11-87 JCR Added "_LOAD_DS" to declaration
  12. * 02-23-89 GJF Added function version of _tolower and cleaned up.
  13. * 03-26-89 GJF Migrated to 386 tree
  14. * 03-06-90 GJF Fixed calling type, added #include <cruntime.h> and
  15. * fixed copyright.
  16. * 09-27-90 GJF New-style function declarators.
  17. * 10-11-91 ETC Locale support for tolower under _INTL switch.
  18. * 12-10-91 ETC Updated nlsapi; added multithread.
  19. * 12-17-92 KRS Updated and optimized for latest NLSAPI. Bug-fixes.
  20. * 01-19-93 CFW Fixed typo.
  21. * 03-25-93 CFW _tolower now defined when _INTL.
  22. * 04-06-93 SKS Replace _CRTAPI* with _cdecl
  23. * 06-01-93 CFW Simplify "C" locale test.
  24. * 06-02-93 SRW ignore _INTL if _NTSUBSET_ defined.
  25. * 09-15-93 CFW Change buffer to unsigned char to fix nasty cast bug.
  26. * 09-15-93 CFW Use ANSI conformant "__" names.
  27. * 09-22-93 CFW Use __crtxxx internal NLS API wrapper.
  28. * 09-28-93 GJF Merged NT SDK and Cuda versions.
  29. * 11-09-93 CFW Add code page for __crtxxx().
  30. * 09-06-94 CFW Remove _INTL switch.
  31. * 10-17-94 GJF Sped up for C locale. Also, added _tolower_lk.
  32. * 01-07-95 CFW Mac merge cleanup.
  33. * 09-26-95 GJF New locking macro, and scheme, for functions which
  34. * reference the locale.
  35. * 04-01-96 BWT POSIX work.
  36. * 06-25-96 GJF Removed DLL_FOR_WIN32S. Replaced defined(_WIN32) with
  37. * !defined(_MAC). Polished the format a bit.
  38. * 03-17-97 RDK Added error flag to __crtLCMapStringA.
  39. * 08-27-98 GJF Revised multithread support based on threadlocinfo
  40. * struct.
  41. * 05-17-99 PML Remove all Macintosh support.
  42. * 09-03-00 GB Modified for increased performance.
  43. * 04-03-01 PML Reverse lead/trail bytes in composed char (vs7#232853)
  44. *
  45. *******************************************************************************/
  46. #include <cruntime.h>
  47. #include <ctype.h>
  48. #include <stddef.h>
  49. #include <locale.h>
  50. #include <setlocal.h>
  51. #include <mtdll.h>
  52. #include <awint.h>
  53. /* remove macro defintions of _tolower() and tolower()
  54. */
  55. #undef _tolower
  56. #undef tolower
  57. /* define function-like macro equivalent to _tolower()
  58. */
  59. #define mklower(c) ( (c)-'A'+'a' )
  60. /***
  61. *int _tolower(c) - convert character to lower case
  62. *
  63. *Purpose:
  64. * _tolower() is simply a function version of the macro of the same name.
  65. *
  66. *Entry:
  67. * c - int value of character to be converted
  68. *
  69. *Exit:
  70. * returns int value of lower case representation of c
  71. *
  72. *Exceptions:
  73. *
  74. *******************************************************************************/
  75. int __cdecl _tolower (
  76. int c
  77. )
  78. {
  79. return(mklower(c));
  80. }
  81. /***
  82. *int tolower(c) - convert character to lower case
  83. *
  84. *Purpose:
  85. * tolower() is simply a function version of the macro of the same name.
  86. *
  87. *Entry:
  88. * c - int value of character to be converted
  89. *
  90. *Exit:
  91. * if c is an upper case letter, returns int value of lower case
  92. * representation of c. otherwise, it returns c.
  93. *
  94. *Exceptions:
  95. *
  96. *******************************************************************************/
  97. int __cdecl tolower (
  98. int c
  99. )
  100. {
  101. #if !defined (_NTSUBSET_) && !defined(_POSIX_)
  102. #ifdef _MT
  103. pthreadlocinfo ptloci = _getptd()->ptlocinfo;
  104. if ( ptloci != __ptlocinfo )
  105. ptloci = __updatetlocinfo();
  106. return __tolower_mt(ptloci, c);
  107. }
  108. /***
  109. *int __tolower_mt(c) - convert character to lower case
  110. *
  111. *Purpose:
  112. * Multi-thread function only!
  113. *
  114. *Entry:
  115. *
  116. *Exit:
  117. *
  118. *Exceptions:
  119. *
  120. *******************************************************************************/
  121. int __cdecl __tolower_mt (
  122. pthreadlocinfo ptloci,
  123. int c
  124. )
  125. {
  126. #endif /* _MT */
  127. int size;
  128. unsigned char inbuffer[3];
  129. unsigned char outbuffer[3];
  130. #ifndef _MT
  131. if ( __lc_handle[LC_CTYPE] == _CLOCALEHANDLE ||
  132. (__lc_clike && (unsigned) c <= 0x7f))
  133. return __ascii_tolower(c);
  134. #else
  135. if ( ptloci->lc_handle[LC_CTYPE] == _CLOCALEHANDLE ||
  136. (ptloci->lc_clike && (unsigned)c <= 0x7f) )
  137. return __ascii_tolower(c);
  138. #endif
  139. /* if checking case of c does not require API call, do it */
  140. if ( (unsigned)c < 256 )
  141. {
  142. #ifdef _MT
  143. if ( !__isupper_mt(ptloci, c) )
  144. #else
  145. if ( !isupper(c) )
  146. #endif
  147. {
  148. return c;
  149. }
  150. }
  151. /* convert int c to multibyte string */
  152. #ifdef _MT
  153. if ( __isleadbyte_mt(ptloci, c >> 8 & 0xff) )
  154. #else
  155. if ( isleadbyte(c >> 8 & 0xff) )
  156. #endif
  157. {
  158. inbuffer[0] = (c >> 8 & 0xff); /* put lead-byte at start of str */
  159. inbuffer[1] = (unsigned char)c;
  160. inbuffer[2] = 0;
  161. size = 2;
  162. } else {
  163. inbuffer[0] = (unsigned char)c;
  164. inbuffer[1] = 0;
  165. size = 1;
  166. }
  167. /* convert to lowercase */
  168. #ifdef _MT
  169. if ( 0 == (size = __crtLCMapStringA( ptloci->lc_handle[LC_CTYPE],
  170. #else
  171. if ( 0 == (size = __crtLCMapStringA( __lc_handle[LC_CTYPE],
  172. #endif
  173. LCMAP_LOWERCASE,
  174. inbuffer,
  175. size,
  176. outbuffer,
  177. 3,
  178. #ifdef _MT
  179. ptloci->lc_codepage,
  180. #else
  181. __lc_codepage,
  182. #endif
  183. TRUE)) )
  184. {
  185. return c;
  186. }
  187. /* construct integer return value */
  188. if (size == 1)
  189. return ((int)outbuffer[0]);
  190. else
  191. return ((int)outbuffer[1] | ((int)outbuffer[0] << 8));
  192. #else
  193. return(isupper(c) ? mklower(c) : c);
  194. #endif
  195. }