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

  1. /***
  2. *_tolower.c - convert character to lower case
  3. *
  4. *       Copyright (c) 1996, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       Defines _Tolower().
  8. *
  9. *Revision History:
  10. *       01-xx-96  PJP   Created from tolower.c, January 1996 by P.J. Plauger
  11. *       04-16-96  GJF   Updated for current locale locking. Also, reformatted
  12. *                       and made several cosmetic changes.
  13. *       09-25-96  GJF   Added locale locking to _Getctype.
  14. *       03-17-97  RDK   Added error flag to __crtLCMapStringA.
  15. *
  16. *******************************************************************************/
  17.  
  18. #include <cruntime.h>
  19. #include <ctype.h>
  20. #include <stddef.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <xlocinfo.h>
  24. #ifdef _WIN32
  25. #include <locale.h>
  26. #include <setlocal.h>
  27. #include <mtdll.h>
  28. #include <awint.h>
  29. #endif  /* _WIN32 */
  30.  
  31. /* remove macro defintions of _tolower() and tolower()
  32.  */
  33. #undef  _tolower
  34. #undef  tolower
  35.  
  36. /* define function-like macro equivalent to _tolower()
  37.  */
  38. #define mklower(c)      ( (c)-'A'+'a' )
  39.  
  40. /***
  41. *int _tolower(c) - convert character to lower case
  42. *
  43. *Purpose:
  44. *       _tolower() is a version of tolower with a locale argument.
  45. *
  46. *Entry:
  47. *       c - int value of character to be converted
  48. *       const _Ctypevec * = pointer to locale info
  49. *
  50. *Exit:
  51. *       returns int value of lower case representation of c
  52. *
  53. *Exceptions:
  54. *
  55. *******************************************************************************/
  56.  
  57. #ifdef _MT
  58. int __cdecl _Tolower_lk (
  59.         int c,
  60.         const _Ctypevec *ploc
  61.         );
  62. #endif
  63.  
  64. _CRTIMP2 int __cdecl _Tolower (
  65.         int c,
  66.         const _Ctypevec *ploc
  67.         )
  68. {
  69.  
  70. #if defined (_WIN32)
  71.  
  72. #ifdef _MT
  73.  
  74.         LCID handle;
  75.         int local_lock_flag;
  76.  
  77.         if (ploc == 0)
  78.                 handle = __lc_handle[LC_CTYPE];
  79.         else
  80.                 handle = ploc->_Hand;
  81.  
  82.         if (handle == _CLOCALEHANDLE)
  83.         {
  84.                 if ( (c >= 'A') && (c <= 'Z') )
  85.                         c = c + ('a' - 'A');
  86.                 return c;
  87.         }
  88.  
  89.         _lock_locale( local_lock_flag )
  90.  
  91.         c = _Tolower_lk(c, ploc);
  92.  
  93.         _unlock_locale( local_lock_flag )
  94.  
  95.         return c;
  96.  
  97. }
  98.  
  99. /***
  100. *int _tolower_lk(c) - convert character to lower case
  101. *
  102. *Purpose:
  103. *       Multi-thread function only! Non-locking version of tolower.
  104. *
  105. *Entry:
  106. *
  107. *Exit:
  108. *
  109. *Exceptions:
  110. *
  111. *******************************************************************************/
  112.  
  113. int __cdecl _Tolower_lk (
  114.         int c,
  115.         const _Ctypevec *ploc
  116.         )
  117. {
  118.  
  119. #endif  /* _MT */
  120.  
  121.         int size;
  122.         unsigned char inbuffer[3];
  123.         unsigned char outbuffer[3];
  124.  
  125.         LCID handle;
  126.         UINT codepage;
  127.  
  128.         if (ploc == 0)
  129.         {
  130.                 handle = __lc_handle[LC_CTYPE];
  131.                 codepage = __lc_codepage; 
  132.         }
  133.         else
  134.         {
  135.                 handle = ploc->_Hand;
  136.                 codepage = ploc->_Page; 
  137.         }
  138.  
  139.         if (handle == _CLOCALEHANDLE)
  140.         {
  141.                 if ( (c >= 'A') && (c <= 'Z') )
  142.                         c = c + ('a' - 'A');
  143.                 return c;
  144.         }
  145.  
  146.         /* if checking case of c does not require API call, do it */
  147.         if (c < 256)
  148.         {
  149.                 if (!isupper(c))
  150.                 {
  151.                         return c;
  152.                 }
  153.         }
  154.  
  155.         /* convert int c to multibyte string */
  156.         if (isleadbyte(c >> 8 & 0xff))
  157.         {
  158.                 inbuffer[0] = (c >> 8 & 0xff); 
  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.  
  168.         /* convert to lowercase */
  169.         if (0 == (size = __crtLCMapStringA(handle, LCMAP_LOWERCASE,
  170.                 inbuffer, size, outbuffer, 3, codepage, TRUE)))
  171.         {
  172.                 return c;
  173.         }
  174.  
  175.         /* construct integer return value */
  176.         if (size == 1)
  177.                 return ((int)outbuffer[0]);
  178.         else
  179.                 return ((int)outbuffer[0] | ((int)outbuffer[1] << 8));
  180.  
  181. #else  /* defined (_WIN32) */
  182.  
  183.         return(isupper(c) ? mklower(c) : c);
  184.  
  185. #endif  /* defined (_WIN32) */
  186. }
  187.  
  188.  
  189. /***
  190. *_Ctypevec _Getctype() - get ctype info for current locale
  191. *
  192. *Purpose:
  193. *
  194. *Entry:
  195. *
  196. *Exit:
  197. *
  198. *Exceptions:
  199. *
  200. *******************************************************************************/
  201.  
  202. _CRTIMP2 _Ctypevec __cdecl _Getctype()
  203. {       
  204.         /* get ctype info for current locale */
  205.         _Ctypevec ctype;
  206. #ifdef  _MT
  207.         int local_lock_flag;
  208. #endif
  209.  
  210.         _lock_locale( local_lock_flag )
  211.  
  212.         ctype._Hand = __lc_handle[LC_COLLATE];
  213.         ctype._Page = __lc_codepage;
  214.         ctype._Table = malloc(256 * sizeof (*_pctype));
  215.         if (ctype._Table != 0)
  216.         {
  217.                 memcpy((void *)ctype._Table, _pctype, 256 * sizeof (*_pctype));
  218.                 ctype._Delfl = 1; 
  219.         }
  220.         else
  221.         {
  222.                 ctype._Table = (const short *)_pctype;
  223.                 ctype._Delfl = 0; 
  224.         }
  225.  
  226.         _unlock_locale( local_lock_flag )
  227.  
  228.         return (ctype);
  229. }
  230.