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.

162 lines
4.3 KiB

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