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.

183 lines
4.2 KiB

  1. /***
  2. *_toupper.c - convert character to uppercase
  3. *
  4. * Copyright (c) 1996-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Defines _Toupper()
  8. *
  9. *Revision History:.
  10. * 01-XX-96 PJP Created from toupper.c January 1996 by P.J. Plauger
  11. * 04-17-96 GJF Updated for current locale locking. Also, reformatted
  12. * and made several cosmetic changes.
  13. * 03-17-97 RDK Added error flag to __crtLCMapStringA.
  14. * 05-17-99 PML Remove all Macintosh support.
  15. * 01-29-01 GB Added _func function version of data variable used in
  16. * msvcprt.lib to work with STATIC_CPPLIB
  17. * 03-12-01 PML Use supplied locale to check case VS7#190902
  18. * 04-03-01 PML Reverse lead/trail bytes in composed char (vs7#232853)
  19. *
  20. *******************************************************************************/
  21. #include <cruntime.h>
  22. #include <ctype.h>
  23. #include <stddef.h>
  24. #include <xlocinfo.h>
  25. #include <locale.h>
  26. #include <setlocal.h>
  27. #include <mtdll.h>
  28. #include <awint.h>
  29. /* remove macro definitions of _toupper() and toupper()
  30. */
  31. #undef _toupper
  32. #undef toupper
  33. /***
  34. *int _toupper(c) - convert character to uppercase
  35. *
  36. *Purpose:
  37. * _toupper() is a version of toupper with a locale argument.
  38. *
  39. *Entry:
  40. * c - int value of character to be converted
  41. * const _Ctypevec * = pointer to locale info
  42. *
  43. *Exit:
  44. * returns int value of uppercase representation of c
  45. *
  46. *Exceptions:
  47. *
  48. *******************************************************************************/
  49. #ifdef _MT
  50. int __cdecl _Toupper_lk (
  51. int c,
  52. const _Ctypevec *ploc
  53. );
  54. #endif
  55. _CRTIMP2 int __cdecl _Toupper (
  56. int c,
  57. const _Ctypevec *ploc
  58. )
  59. {
  60. #ifdef _MT
  61. LCID handle;
  62. int local_lock_flag;
  63. if (ploc == 0)
  64. handle = ___lc_handle_func()[LC_CTYPE];
  65. else
  66. handle = ploc->_Hand;
  67. if (handle == _CLOCALEHANDLE)
  68. {
  69. if ( (c >= 'a') && (c <= 'z') )
  70. c = c - ('a' - 'A');
  71. return c;
  72. }
  73. _lock_locale( local_lock_flag )
  74. c = _Toupper_lk(c, ploc);
  75. _unlock_locale( local_lock_flag )
  76. return c;
  77. }
  78. /***
  79. *int _toupper_lk(c) - convert character to uppercase
  80. *
  81. *Purpose:
  82. * Multi-thread function only! Non-locking version of toupper.
  83. *
  84. *Entry:
  85. *
  86. *Exit:
  87. *
  88. *Exceptions:
  89. *
  90. *******************************************************************************/
  91. int __cdecl _Toupper_lk (
  92. int c,
  93. const _Ctypevec *ploc
  94. )
  95. {
  96. #endif /* _MT */
  97. int size;
  98. unsigned char inbuffer[3];
  99. unsigned char outbuffer[3];
  100. LCID handle;
  101. UINT codepage;
  102. if (ploc == 0)
  103. {
  104. handle = ___lc_handle_func()[LC_CTYPE];
  105. codepage = ___lc_codepage_func();
  106. }
  107. else
  108. {
  109. handle = ploc->_Hand;
  110. codepage = ploc->_Page;
  111. }
  112. if (handle == _CLOCALEHANDLE)
  113. {
  114. if ( (c >= 'a') && (c <= 'z') )
  115. c = c - ('a' - 'A');
  116. return c;
  117. }
  118. /* if checking case of c does not require API call, do it */
  119. if ((unsigned)c < 256)
  120. {
  121. if (ploc == 0)
  122. {
  123. if (!islower(c))
  124. {
  125. return c;
  126. }
  127. }
  128. else
  129. {
  130. if (!ploc->_Table[c] & _LOWER)
  131. {
  132. return c;
  133. }
  134. }
  135. }
  136. /* convert int c to multibyte string */
  137. if (_cpp_isleadbyte(c >> 8 & 0xff))
  138. {
  139. inbuffer[0] = (c >> 8 & 0xff);
  140. inbuffer[1] = (unsigned char)c;
  141. inbuffer[2] = 0;
  142. size = 2;
  143. } else {
  144. inbuffer[0] = (unsigned char)c;
  145. inbuffer[1] = 0;
  146. size = 1;
  147. }
  148. /* convert wide char to uppercase */
  149. if (0 == (size = __crtLCMapStringA(handle, LCMAP_UPPERCASE,
  150. inbuffer, size, outbuffer, 3, codepage, TRUE)))
  151. {
  152. return c;
  153. }
  154. /* construct integer return value */
  155. if (size == 1)
  156. return ((int)outbuffer[0]);
  157. else
  158. return ((int)outbuffer[1] | ((int)outbuffer[0] << 8));
  159. }