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.

146 lines
4.2 KiB

  1. /***
  2. *wcsnicoll.c - Collate wide-character locale strings without regard to case
  3. *
  4. * Copyright (c) 1988-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * Compare two wchar_t strings using the locale LC_COLLATE information
  8. * without regard to case.
  9. * Compares at most n characters of two strings.
  10. *
  11. *Revision History:
  12. * 01-13-94 CFW Created from wcsicoll.c.
  13. * 02-07-94 CFW POSIXify.
  14. * 04-11-93 CFW Change NLSCMPERROR to _NLCMPERROR.
  15. * 05-09-94 CFW Fix !_INTL case.
  16. * 05-26-94 CFW If count is zero, return EQUAL.
  17. * 09-06-94 CFW Remove _INTL switch.
  18. * 10-25-94 GJF Sped up C locale, multi-thread case.
  19. * 09-26-95 GJF New locking macro, and scheme, for functions which
  20. * reference the locale.
  21. * 10-30-95 GJF Specify SORT_STRINGSORT to CompareString.
  22. * 07-16-96 SKS Added missing call to _unlock_locale()
  23. * 11-24-97 GJF Removed bogus codepage determination.
  24. * 01-12-98 GJF Use _lc_collate_cp codepage.
  25. * 08-27-98 GJF Revised multithread support based on threadlocinfo
  26. * struct.
  27. * 01-04-99 GJF Changes for 64-bit size_t.
  28. * 04-30-99 PML Minor cleanup as part of 64-bit merge.
  29. *
  30. *******************************************************************************/
  31. #ifndef _POSIX_
  32. #include <cruntime.h>
  33. #include <windows.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #include <limits.h>
  37. #include <locale.h>
  38. #include <setlocal.h>
  39. #include <mtdll.h>
  40. #include <errno.h>
  41. #include <awint.h>
  42. /***
  43. *int _wcsnicoll() - Collate wide-character locale strings without regard to case
  44. *
  45. *Purpose:
  46. * Compare two wchar_t strings using the locale LC_COLLATE information
  47. * without regard to case.
  48. * Compares at most n characters of two strings.
  49. * In the C locale, _wcsicmp() is used to make the comparison.
  50. *
  51. *Entry:
  52. * const wchar_t *s1 = pointer to the first string
  53. * const wchar_t *s2 = pointer to the second string
  54. * size_t count - maximum number of characters to compare
  55. *
  56. *Exit:
  57. * -1 = first string less than second string
  58. * 0 = strings are equal
  59. * 1 = first string greater than second string
  60. * This range of return values may differ from other *cmp/*coll functions.
  61. *
  62. *Exceptions:
  63. * _NLSCMPERROR = error
  64. * errno = EINVAL
  65. *
  66. *******************************************************************************/
  67. int __cdecl _wcsnicoll (
  68. const wchar_t *_string1,
  69. const wchar_t *_string2,
  70. size_t count
  71. )
  72. {
  73. #if !defined(_NTSUBSET_)
  74. int ret;
  75. #ifdef _MT
  76. pthreadlocinfo ptloci;
  77. #endif
  78. if (!count)
  79. return 0;
  80. if ( count > INT_MAX ) {
  81. errno = EINVAL;
  82. return _NLSCMPERROR;
  83. }
  84. #ifdef _MT
  85. ptloci = _getptd()->ptlocinfo;
  86. if ( ptloci != __ptlocinfo )
  87. ptloci = __updatetlocinfo();
  88. #endif
  89. #ifdef _MT
  90. if ( ptloci->lc_handle[LC_COLLATE] == _CLOCALEHANDLE )
  91. #else
  92. if ( __lc_handle[LC_COLLATE] == _CLOCALEHANDLE )
  93. #endif
  94. {
  95. wchar_t f, l;
  96. do {
  97. f = __ascii_towlower(*_string1);
  98. l = __ascii_towlower(*_string2);
  99. _string1++;
  100. _string2++;
  101. } while ( (--count) && f && (f == l) );
  102. return (int)(f - l);
  103. }
  104. #ifdef _MT
  105. if ( 0 == (ret = __crtCompareStringW( ptloci->lc_handle[LC_COLLATE],
  106. #else
  107. if ( 0 == (ret = __crtCompareStringW( __lc_handle[LC_COLLATE],
  108. #endif
  109. SORT_STRINGSORT | NORM_IGNORECASE,
  110. _string1,
  111. (int)count,
  112. _string2,
  113. (int)count,
  114. #ifdef _MT
  115. ptloci->lc_collate_cp )) )
  116. #else
  117. __lc_collate_cp )) )
  118. #endif
  119. {
  120. errno = EINVAL;
  121. return _NLSCMPERROR;
  122. }
  123. return (ret - 2);
  124. #else
  125. return _wcsnicmp(_string1, _string2, count);
  126. #endif
  127. }
  128. #endif /* _POSIX_ */