home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / _toupper.c < prev    next >
C/C++ Source or Header  |  1998-06-16  |  4KB  |  182 lines

  1. /***
  2. *_toupper.c - convert character to uppercase
  3. *
  4. *       Copyright (c) 1996, 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. *
  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.  
  28. /* remove macro definitions of _toupper() and toupper()
  29.  */
  30. #undef  _toupper
  31. #undef  toupper
  32.  
  33. /* define function-like macro equivalent to _toupper()
  34.  */
  35. #define mkupper(c)  ( (c)-'a'+'A' )
  36.  
  37. /***
  38. *int _toupper(c) - convert character to uppercase
  39. *
  40. *Purpose:
  41. *       _toupper() is a version of toupper 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 uppercase representation of c
  49. *
  50. *Exceptions:
  51. *
  52. *******************************************************************************/
  53.  
  54. #ifdef _MT
  55. int __cdecl _Toupper_lk (
  56.         int c,
  57.         const _Ctypevec *ploc
  58.         );
  59. #endif
  60.  
  61. _CRTIMP2 int __cdecl _Toupper (
  62.         int c,
  63.         const _Ctypevec *ploc
  64.         )
  65. {
  66. #if defined (_WIN32)
  67.  
  68. #ifdef _MT
  69.  
  70.         LCID handle;
  71.         int local_lock_flag;
  72.  
  73.  
  74.         if (ploc == 0)
  75.                 handle = __lc_handle[LC_CTYPE];
  76.         else
  77.                 handle = ploc->_Hand;
  78.  
  79.         if (handle == _CLOCALEHANDLE)
  80.         {
  81.                 if ( (c >= 'a') && (c <= 'z') )
  82.                         c = c - ('a' - 'A');
  83.                 return c;
  84.         }
  85.  
  86.         _lock_locale( local_lock_flag )
  87.  
  88.         c = _Toupper_lk(c, ploc);
  89.  
  90.         _unlock_locale( local_lock_flag )
  91.  
  92.         return c;
  93. }
  94.  
  95.  
  96. /***
  97. *int _toupper_lk(c) - convert character to uppercase
  98. *
  99. *Purpose:
  100. *       Multi-thread function! Non-locking version of toupper.
  101. *
  102. *Entry:
  103. *
  104. *Exit:
  105. *
  106. *Exceptions:
  107. *
  108. *******************************************************************************/
  109.  
  110.  
  111. int __cdecl _Toupper_lk (
  112.         int c,
  113.         const _Ctypevec *ploc
  114.         )
  115. {
  116.  
  117. #endif  /* _MT */
  118.  
  119.         int size;
  120.         unsigned char inbuffer[3];
  121.         unsigned char outbuffer[3];
  122.  
  123.         LCID handle;
  124.         UINT codepage;
  125.  
  126.         if (ploc == 0)
  127.         {
  128.                 handle = __lc_handle[LC_CTYPE];
  129.                 codepage = __lc_codepage;
  130.         }
  131.         else
  132.         {
  133.                 handle = ploc->_Hand;
  134.                 codepage = ploc->_Page;
  135.         }
  136.  
  137.         if (handle == _CLOCALEHANDLE)
  138.         {
  139.                 if ( (c >= 'a') && (c <= 'z') )
  140.                         c = c - ('a' - 'A');
  141.                 return c;
  142.         }
  143.  
  144.         /* if checking case of c does not require API call, do it */
  145.         if (c < 256) {
  146.                 if (!islower(c))
  147.                 {
  148.                         return c;
  149.                 }
  150.         }
  151.  
  152.         /* convert int c to multibyte string */
  153.         if (isleadbyte(c >> 8 & 0xff)) {
  154.                 inbuffer[0] = (c >> 8 & 0xff); /* put lead-byte at start of str */
  155.                 inbuffer[1] = (unsigned char)c;
  156.                 inbuffer[2] = 0;
  157.                 size = 2;
  158.         } else {
  159.                 inbuffer[0] = (unsigned char)c;
  160.                 inbuffer[1] = 0;
  161.                 size = 1;
  162.         }
  163.  
  164.         /* convert wide char to lowercase */
  165.         if (0 == (size = __crtLCMapStringA(handle, LCMAP_UPPERCASE,
  166.                 inbuffer, size, outbuffer, 3, codepage, TRUE))) {
  167.                 return c;
  168.         }
  169.  
  170.         /* construct integer return value */
  171.         if (size == 1)
  172.                 return ((int)outbuffer[0]);
  173.         else
  174.                 return ((int)outbuffer[0] | ((int)outbuffer[1] << 8));
  175.  
  176. #else  /* defined (_WIN32) */
  177.  
  178.         return(islower(c) ? mkupper(c) : c);
  179.  
  180. #endif  /* defined (_WIN32) */
  181. }
  182.