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

  1. /***
  2. *xstrcoll.c - Collate locale strings
  3. *
  4. *       Copyright (c) 1996-1998, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       Compare two strings using the locale LC_COLLATE information.
  8. *
  9. *Revision History:
  10. *       01-XX-96  PJP   Created from strcoll.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. *       05-14-96  JWM   Bug fix to _Strcoll(): error path failed to unlock.
  14. *       09-26-96  GJF   Made _GetColl() multithread safe.
  15. *       12-02-97  GJF   Removed bogus codepage determination.
  16. *       01-12-98  GJF   Use _lc_collate_cp codepage.
  17. *
  18. *******************************************************************************/
  19.  
  20. #include <cruntime.h>
  21. #include <string.h>
  22. #include <xlocinfo.h>   /* for _Collvec, _Strcoll */
  23.  
  24. #ifdef  _WIN32
  25. #include <windows.h>
  26. #include <stdlib.h>
  27. #include <malloc.h>
  28. #include <locale.h>
  29. #include <setlocal.h>
  30. #include <mtdll.h>
  31. #include <errno.h>
  32. #include <awint.h>
  33. #endif  /* _WIN32 */
  34.  
  35. /* Define _CRTIMP2 */
  36. #ifndef _CRTIMP2
  37. #ifdef  CRTDLL2
  38. #define _CRTIMP2 __declspec(dllexport)
  39. #else   /* ndef CRTDLL2 */
  40. #ifdef  _DLL
  41. #define _CRTIMP2 __declspec(dllimport)
  42. #else   /* ndef _DLL */
  43. #define _CRTIMP2
  44. #endif  /* _DLL */
  45. #endif  /* CRTDLL2 */
  46. #endif  /* _CRTIMP2 */
  47.  
  48. /***
  49. *int _Strcoll() - Collate locale strings
  50. *
  51. *Purpose:
  52. *       Compare two strings using the locale LC_COLLATE information.
  53. *       [ANSI].
  54. *
  55. *       Non-C locale support available under _INTL switch.
  56. *       In the C locale, strcoll() simply resolves to strcmp().
  57. *Entry:
  58. *       const char *s1b = pointer to beginning of the first string
  59. *       const char *s1e = pointer past end of the first string
  60. *       const char *s2b = pointer to beginning of the second string
  61. *       const char *s1e = pointer past end of the second string
  62. *       const _Collvec *ploc = pointer to locale info
  63. *
  64. *Exit:
  65. *       Less than 0    = first string less than second string
  66. *       0              = strings are equal
  67. *       Greater than 0 = first string greater than second string
  68. *
  69. *Exceptions:
  70. *       _NLSCMPERROR    = error
  71. *       errno = EINVAL
  72. *
  73. *******************************************************************************/
  74.  
  75. _CRTIMP2 int __cdecl _Strcoll (
  76.         const char *_string1,
  77.         const char *_end1,
  78.         const char *_string2,
  79.         const char *_end2,
  80.         const _Collvec *ploc
  81.         )
  82. {
  83. #ifdef  _WIN32
  84.         int ret;
  85.         LCID handle;
  86. #ifdef  _MT
  87.         int local_lock_flag;
  88. #endif
  89. #endif
  90.  
  91.         size_t n1 = _end1 - _string1;
  92.         size_t n2 = _end2 - _string2;
  93.  
  94.         _lock_locale( local_lock_flag )
  95.  
  96. #ifdef  _WIN32
  97.         if (ploc == 0)
  98.             handle = __lc_handle[LC_COLLATE];
  99.         else
  100.             handle = ploc->_Hand;
  101.  
  102.         if (handle == _CLOCALEHANDLE) {
  103.             int ans;
  104.             _unlock_locale( local_lock_flag )
  105.             ans = memcmp(_string1, _string2, n1 < n2 ? n1 : n2);
  106.             return ans != 0 || n1 == n2 ? ans : n1 < n2 ? -1 : +1;
  107.         }
  108.  
  109.         if ( 0 == (ret = __crtCompareStringA( handle,
  110.                                               0,
  111.                                               _string1,
  112.                                               n1,
  113.                                               _string2,
  114.                                               n2,
  115.                                               __lc_collate_cp )) )
  116.             goto error_cleanup;
  117.  
  118.         _unlock_locale( local_lock_flag )
  119.         return (ret - 2);
  120.  
  121. error_cleanup:
  122.  
  123.         _unlock_locale( local_lock_flag )
  124.         errno = EINVAL;
  125.         return _NLSCMPERROR;
  126.  
  127. #else   /* defined (_WIN32) */
  128.  
  129.         int ans = memcmp(_string1, _string2, n1 < n2 ? n1 : n2);
  130.         return ans != 0 || n1 == n2 ? ans : n1 < n2 ? -1 : +1;
  131.  
  132. #endif  /* defined (_WIN32) */
  133. }
  134.  
  135.  
  136. /***
  137. *_Collvec _Getcoll() - get collation info for current locale
  138. *
  139. *Purpose:
  140. *
  141. *Entry:
  142. *
  143. *Exit:
  144. *
  145. *Exceptions:
  146. *
  147. *******************************************************************************/
  148.  
  149. _CRTIMP2 _Collvec _Getcoll()
  150. {
  151.         _Collvec coll;
  152. #ifdef  _MT
  153.         int local_lock_flag;
  154. #endif
  155.         _lock_locale( local_lock_flag )
  156.         coll._Hand = __lc_handle[LC_COLLATE];
  157.         coll._Page = __lc_collate_cp;
  158.         _unlock_locale( local_lock_flag )
  159.  
  160.         return (coll);
  161. }
  162.