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

  1. /***
  2. *xwcscoll.c - Collate wide-character locale strings
  3. *
  4. *       Copyright (c) 1996-1998, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       Compare two wchar_t strings using the locale LC_COLLATE information.
  8. *
  9. *Revision History:
  10. *       01-XX-96  GJF   Created from wcscoll.c January 1996 by P.J. Plauger
  11. *       04-18-96  GJF   Updated for current locale locking. Also, reformatted
  12. *                       and made several cosmetic changes.
  13. *       12-02-97  GJF   Removed bogus codepage determination.
  14. *       01-12-98  GJF   Use _lc_collate_cp codepage.
  15. *
  16. *******************************************************************************/
  17.  
  18.  
  19. #include <cruntime.h>
  20. #include <windows.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <locale.h>
  24. #include <setlocal.h>
  25. #include <mtdll.h>
  26. #include <errno.h>
  27. #include <awint.h>
  28. #include <xlocinfo.h>   /* for _Collvec, _Wcscoll */
  29.  
  30. /***
  31. *static int _Wmemcmp(s1, s2, n) - compare wchar_t s1[n], s2[n]
  32. *
  33. *Purpose:
  34. *
  35. *Entry:
  36. *
  37. *Exit:
  38. *
  39. *Exceptions:
  40. *
  41. *******************************************************************************/
  42.  
  43. static int _Wmemcmp(
  44.         const wchar_t *s1, 
  45.         const wchar_t *s2, 
  46.         size_t n
  47.         )
  48. {
  49.         for (; 0 < n; ++s1, ++s2, --n)
  50.              if (*s1 != *s2)
  51.                return (*s1 < *s2 ? -1 : +1);
  52.         return (0);
  53. }
  54.  
  55. /***
  56. *int _Wcscoll() - Collate wide-character locale strings
  57. *
  58. *Purpose:
  59. *       Compare two wchar_t strings using the locale LC_COLLATE information.
  60. *       In the C locale, wcscmp() is used to make the comparison.
  61. *
  62. *Entry:
  63. *       const wchar_t *_string1 = pointer to beginning of the first string
  64. *       const wchar_t *_end1    = pointer past end of the first string
  65. *       const wchar_t *_string2 = pointer to beginning of the second string
  66. *       const wchar_t *_end2    = pointer past end of the second string
  67. *       const _Collvec *ploc = pointer to locale info
  68. *
  69. *Exit:
  70. *       -1 = first string less than second string
  71. *        0 = strings are equal
  72. *        1 = first string greater than second string
  73. *       This range of return values may differ from other *cmp/*coll functions.
  74. *
  75. *Exceptions:
  76. *       _NLSCMPERROR    = error
  77. *       errno = EINVAL
  78. *
  79. *******************************************************************************/
  80.  
  81. int __cdecl _Wcscoll (
  82.         const wchar_t *_string1,
  83.         const wchar_t *_end1,
  84.         const wchar_t *_string2,
  85.         const wchar_t *_end2,
  86.         const _Collvec *ploc
  87.         )
  88. {
  89.  
  90.         size_t n1 = _end1 - _string1;
  91.         size_t n2 = _end2 - _string2;
  92.         int ret;
  93.         LCID handle;
  94. #ifdef  _MT
  95.         int local_lock_flag;
  96.  
  97.         _lock_locale( local_lock_flag )
  98. #endif
  99.         if (ploc == 0)
  100.             handle = __lc_handle[LC_COLLATE];
  101.         else
  102.             handle = ploc->_Hand;
  103.  
  104.         if (handle == _CLOCALEHANDLE) {
  105.             int ans;
  106.             _unlock_locale( local_lock_flag )
  107.             ans = _Wmemcmp(_string1, _string2, n1 < n2 ? n1 : n2);
  108.             return ans != 0 || n1 == n2 ? ans : n1 < n2 ? -1 : +1;
  109.         }
  110.  
  111.         if (0 == (ret = __crtCompareStringW(handle, 
  112.                                             0, 
  113.                                             _string1, 
  114.                                             n1,
  115.                                             _string2, 
  116.                                             n2, 
  117.                                             __lc_collate_cp)))
  118.         {
  119.             _unlock_locale( local_lock_flag )
  120.             errno = EINVAL;
  121.             return _NLSCMPERROR;
  122.         }
  123.  
  124.         _unlock_locale( local_lock_flag )
  125.         return (ret - 2);
  126.  
  127. }
  128.