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.

182 lines
4.1 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. * 04-03-01 PML Reverse lead/trail bytes in composed char (vs7#232853)
  15. *
  16. *******************************************************************************/
  17. #include <cruntime.h>
  18. #include <ctype.h>
  19. #include <stddef.h>
  20. #include <xlocinfo.h>
  21. #ifdef _WIN32
  22. #include <locale.h>
  23. #include <setlocal.h>
  24. #include <mtdll.h>
  25. #include <awint.h>
  26. #endif /* _WIN32 */
  27. /* remove macro definitions of _toupper() and toupper()
  28. */
  29. #undef _toupper
  30. #undef toupper
  31. /* define function-like macro equivalent to _toupper()
  32. */
  33. #define mkupper(c) ( (c)-'a'+'A' )
  34. /***
  35. *int _toupper(c) - convert character to uppercase
  36. *
  37. *Purpose:
  38. * _toupper() is a version of toupper with a locale argument.
  39. *
  40. *Entry:
  41. * c - int value of character to be converted
  42. * const _Ctypevec * = pointer to locale info
  43. *
  44. *Exit:
  45. * returns int value of uppercase representation of c
  46. *
  47. *Exceptions:
  48. *
  49. *******************************************************************************/
  50. #ifdef _MT
  51. int __cdecl _Toupper_lk (
  52. int c,
  53. const _Ctypevec *ploc
  54. );
  55. #endif
  56. _CRTIMP2 int __cdecl _Toupper (
  57. int c,
  58. const _Ctypevec *ploc
  59. )
  60. {
  61. #if defined (_WIN32)
  62. #ifdef _MT
  63. LCID handle;
  64. int local_lock_flag;
  65. if (ploc == 0)
  66. handle = __lc_handle[LC_CTYPE];
  67. else
  68. handle = ploc->_Hand;
  69. if (handle == _CLOCALEHANDLE)
  70. {
  71. if ( (c >= 'a') && (c <= 'z') )
  72. c = c - ('a' - 'A');
  73. return c;
  74. }
  75. _lock_locale( local_lock_flag )
  76. c = _Toupper_lk(c, ploc);
  77. _unlock_locale( local_lock_flag )
  78. return c;
  79. }
  80. /***
  81. *int _toupper_lk(c) - convert character to uppercase
  82. *
  83. *Purpose:
  84. * Multi-thread function! Non-locking version of toupper.
  85. *
  86. *Entry:
  87. *
  88. *Exit:
  89. *
  90. *Exceptions:
  91. *
  92. *******************************************************************************/
  93. int __cdecl _Toupper_lk (
  94. int c,
  95. const _Ctypevec *ploc
  96. )
  97. {
  98. #endif /* _MT */
  99. int size;
  100. unsigned char inbuffer[3];
  101. unsigned char outbuffer[3];
  102. LCID handle;
  103. UINT codepage;
  104. if (ploc == 0)
  105. {
  106. handle = __lc_handle[LC_CTYPE];
  107. codepage = __lc_codepage;
  108. }
  109. else
  110. {
  111. handle = ploc->_Hand;
  112. codepage = ploc->_Page;
  113. }
  114. if (handle == _CLOCALEHANDLE)
  115. {
  116. if ( (c >= 'a') && (c <= 'z') )
  117. c = c - ('a' - 'A');
  118. return c;
  119. }
  120. /* if checking case of c does not require API call, do it */
  121. if (c < 256) {
  122. if (!islower(c))
  123. {
  124. return c;
  125. }
  126. }
  127. /* convert int c to multibyte string */
  128. if (isleadbyte(c >> 8 & 0xff)) {
  129. inbuffer[0] = (c >> 8 & 0xff); /* put lead-byte at start of str */
  130. inbuffer[1] = (unsigned char)c;
  131. inbuffer[2] = 0;
  132. size = 2;
  133. } else {
  134. inbuffer[0] = (unsigned char)c;
  135. inbuffer[1] = 0;
  136. size = 1;
  137. }
  138. /* convert wide char to lowercase */
  139. if (0 == (size = __crtLCMapStringA(handle, LCMAP_UPPERCASE,
  140. inbuffer, size, outbuffer, 3, codepage, TRUE))) {
  141. return c;
  142. }
  143. /* construct integer return value */
  144. if (size == 1)
  145. return ((int)outbuffer[0]);
  146. else
  147. return ((int)outbuffer[1] | ((int)outbuffer[0] << 8));
  148. #else /* defined (_WIN32) */
  149. return(islower(c) ? mkupper(c) : c);
  150. #endif /* defined (_WIN32) */
  151. }