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.

251 lines
7.3 KiB

  1. /***
  2. *toupper.c - convert character to uppercase
  3. *
  4. * Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Defines function versions of _toupper() and toupper().
  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 _toupper 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 toupper 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 _toupper 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. * 01-14-94 SRW if _NTSUBSET_ defined call Rtl functions
  31. * 09-06-94 CFW Remove _INTL switch.
  32. * 10-18-94 BWT Fix build warning in NTSUBSET section.
  33. * 10-17-94 GJF Sped up for C locale. Added _toupper_lk. Also,
  34. * cleaned up pre-processor conditionals.
  35. * 01-07-95 CFW Mac merge cleanup.
  36. * 09-26-95 GJF New locking macro, and scheme, for functions which
  37. * reference the locale.
  38. * 04-01-96 BWT POSIX work.
  39. * 06-25-96 GJF Removed DLL_FOR_WIN32S. Replaced defined(_WIN32) with
  40. * !defined(_MAC). Polished the format a bit.
  41. * 03-17-97 RDK Added error flag to __crtLCMapStringA.
  42. * 08-27-98 GJF Revised multithread support based on threadlocinfo
  43. * struct.
  44. * 05-17-99 PML Remove all Macintosh support.
  45. * 09-03-00 GB Modified for increased performance.
  46. * 04-03-01 PML Reverse lead/trail bytes in composed char (vs7#232853)
  47. *
  48. *******************************************************************************/
  49. #if defined(_NTSUBSET_) || defined(_POSIX_)
  50. #include <nt.h>
  51. #include <ntrtl.h>
  52. #include <nturtl.h>
  53. #endif
  54. #include <cruntime.h>
  55. #include <ctype.h>
  56. #include <stddef.h>
  57. #include <locale.h>
  58. #include <setlocal.h>
  59. #include <mtdll.h>
  60. #include <awint.h>
  61. /* remove macro definitions of _toupper() and toupper()
  62. */
  63. #undef _toupper
  64. #undef toupper
  65. /* define function-like macro equivalent to _toupper()
  66. */
  67. #define mkupper(c) ( (c)-'a'+'A' )
  68. /***
  69. *int _toupper(c) - convert character to uppercase
  70. *
  71. *Purpose:
  72. * _toupper() is simply a function version of the macro of the same name.
  73. *
  74. *Entry:
  75. * c - int value of character to be converted
  76. *
  77. *Exit:
  78. * returns int value of uppercase representation of c
  79. *
  80. *Exceptions:
  81. *
  82. *******************************************************************************/
  83. int __cdecl _toupper (
  84. int c
  85. )
  86. {
  87. return(mkupper(c));
  88. }
  89. /***
  90. *int toupper(c) - convert character to uppercase
  91. *
  92. *Purpose:
  93. * toupper() is simply a function version of the macro of the same name.
  94. *
  95. *Entry:
  96. * c - int value of character to be converted
  97. *
  98. *Exit:
  99. * if c is a lower case letter, returns int value of uppercase
  100. * representation of c. otherwise, it returns c.
  101. *
  102. *Exceptions:
  103. *
  104. *******************************************************************************/
  105. int __cdecl toupper (
  106. int c
  107. )
  108. {
  109. #if !defined(_NTSUBSET_) && !defined(_POSIX_)
  110. #ifdef _MT
  111. pthreadlocinfo ptloci = _getptd()->ptlocinfo;
  112. if ( ptloci != __ptlocinfo )
  113. ptloci = __updatetlocinfo();
  114. return __toupper_mt(ptloci, c);
  115. }
  116. /***
  117. *int __toupper_mt(ptloci, c) - convert character to uppercase
  118. *
  119. *Purpose:
  120. * Multi-thread function! Non-locking version of toupper.
  121. *
  122. *Entry:
  123. *
  124. *Exit:
  125. *
  126. *Exceptions:
  127. *
  128. *******************************************************************************/
  129. int __cdecl __toupper_mt (
  130. pthreadlocinfo ptloci,
  131. int c
  132. )
  133. {
  134. #endif /* _MT */
  135. int size;
  136. unsigned char inbuffer[3];
  137. unsigned char outbuffer[3];
  138. #ifndef _MT
  139. if ( __lc_handle[LC_CTYPE] == _CLOCALEHANDLE ||
  140. (__lc_clike && (unsigned)c <= 0x7f))
  141. return __ascii_toupper(c);
  142. #else
  143. if ( ptloci->lc_handle[LC_CTYPE] == _CLOCALEHANDLE ||
  144. (ptloci->lc_clike && (unsigned)c <= 0x7f))
  145. return __ascii_toupper(c);
  146. #endif
  147. /* if checking case of c does not require API call, do it */
  148. if ( (unsigned)c < 256 ) {
  149. #ifdef _MT
  150. if ( !__islower_mt(ptloci, c) )
  151. #else
  152. if ( !islower(c) )
  153. #endif
  154. {
  155. return c;
  156. }
  157. }
  158. /* convert int c to multibyte string */
  159. #ifdef _MT
  160. if ( __isleadbyte_mt(ptloci, c >> 8 & 0xff) ) {
  161. #else
  162. if ( isleadbyte(c >> 8 & 0xff) ) {
  163. #endif
  164. inbuffer[0] = (c >> 8 & 0xff); /* put lead-byte at start of str */
  165. inbuffer[1] = (unsigned char)c;
  166. inbuffer[2] = 0;
  167. size = 2;
  168. } else {
  169. inbuffer[0] = (unsigned char)c;
  170. inbuffer[1] = 0;
  171. size = 1;
  172. }
  173. /* convert wide char to lowercase */
  174. #ifdef _MT
  175. if ( 0 == (size = __crtLCMapStringA( ptloci->lc_handle[LC_CTYPE],
  176. #else
  177. if ( 0 == (size = __crtLCMapStringA( __lc_handle[LC_CTYPE],
  178. #endif
  179. LCMAP_UPPERCASE,
  180. inbuffer,
  181. size,
  182. outbuffer,
  183. 3,
  184. #ifdef _MT
  185. ptloci->lc_codepage,
  186. #else
  187. __lc_codepage,
  188. #endif
  189. TRUE)) )
  190. {
  191. return c;
  192. }
  193. /* construct integer return value */
  194. if (size == 1)
  195. return ((int)outbuffer[0]);
  196. else
  197. return ((int)outbuffer[1] | ((int)outbuffer[0] << 8));
  198. #else /* def(_NTSUBSET_) || def(_POSIX_) */
  199. {
  200. NTSTATUS Status;
  201. char *s = (char *) &c;
  202. WCHAR Unicode;
  203. ULONG UnicodeSize;
  204. ULONG MultiSize;
  205. UCHAR MultiByte[2];
  206. Unicode = RtlAnsiCharToUnicodeChar( &s );
  207. Status = RtlUpcaseUnicodeToMultiByteN( MultiByte,
  208. sizeof( MultiByte ),
  209. &MultiSize,
  210. &Unicode,
  211. sizeof( Unicode )
  212. );
  213. if (!NT_SUCCESS( Status ))
  214. return c;
  215. else
  216. if (MultiSize == 1)
  217. return ((int)MultiByte[0]);
  218. else
  219. return ((int)MultiByte[1] | ((int)MultiByte[0] << 8));
  220. }
  221. #endif /* def(_NTSUBSET_) || def(_POSIX_) */
  222. }