1*04e0dc4aSTimo Kreuzer /***
2*04e0dc4aSTimo Kreuzer *wcsicoll.c - Collate wide-character locale strings without regard to case
3*04e0dc4aSTimo Kreuzer *
4*04e0dc4aSTimo Kreuzer * Copyright (c) Microsoft Corporation. All rights reserved.
5*04e0dc4aSTimo Kreuzer *
6*04e0dc4aSTimo Kreuzer *Purpose:
7*04e0dc4aSTimo Kreuzer * Compare two wchar_t strings using the locale LC_COLLATE information
8*04e0dc4aSTimo Kreuzer * without regard to case.
9*04e0dc4aSTimo Kreuzer *
10*04e0dc4aSTimo Kreuzer *******************************************************************************/
11*04e0dc4aSTimo Kreuzer #include <corecrt_internal.h>
12*04e0dc4aSTimo Kreuzer #include <ctype.h>
13*04e0dc4aSTimo Kreuzer #include <locale.h>
14*04e0dc4aSTimo Kreuzer #include <string.h>
15*04e0dc4aSTimo Kreuzer
16*04e0dc4aSTimo Kreuzer #pragma warning(disable:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED) // 26018 Prefast can't see that we are checking for terminal nul.
17*04e0dc4aSTimo Kreuzer
18*04e0dc4aSTimo Kreuzer /***
19*04e0dc4aSTimo Kreuzer *int _wcsicoll() - Collate wide-character locale strings without regard to case
20*04e0dc4aSTimo Kreuzer *
21*04e0dc4aSTimo Kreuzer *Purpose:
22*04e0dc4aSTimo Kreuzer * Compare two wchar_t strings using the locale LC_COLLATE information
23*04e0dc4aSTimo Kreuzer * without regard to case.
24*04e0dc4aSTimo Kreuzer * In the C locale, _wcsicmp() is used to make the comparison.
25*04e0dc4aSTimo Kreuzer *
26*04e0dc4aSTimo Kreuzer *Entry:
27*04e0dc4aSTimo Kreuzer * const wchar_t *s1 = pointer to the first string
28*04e0dc4aSTimo Kreuzer * const wchar_t *s2 = pointer to the second string
29*04e0dc4aSTimo Kreuzer *
30*04e0dc4aSTimo Kreuzer *Exit:
31*04e0dc4aSTimo Kreuzer * -1 = first string less than second string
32*04e0dc4aSTimo Kreuzer * 0 = strings are equal
33*04e0dc4aSTimo Kreuzer * 1 = first string greater than second string
34*04e0dc4aSTimo Kreuzer * Returns _NLSCMPERROR is something went wrong
35*04e0dc4aSTimo Kreuzer * This range of return values may differ from other *cmp/*coll functions.
36*04e0dc4aSTimo Kreuzer *
37*04e0dc4aSTimo Kreuzer *Exceptions:
38*04e0dc4aSTimo Kreuzer * Input parameters are validated. Refer to the validation section of the function.
39*04e0dc4aSTimo Kreuzer *
40*04e0dc4aSTimo Kreuzer *******************************************************************************/
41*04e0dc4aSTimo Kreuzer
_wcsicoll_l(const wchar_t * _string1,const wchar_t * _string2,_locale_t plocinfo)42*04e0dc4aSTimo Kreuzer extern "C" int __cdecl _wcsicoll_l (
43*04e0dc4aSTimo Kreuzer const wchar_t *_string1,
44*04e0dc4aSTimo Kreuzer const wchar_t *_string2,
45*04e0dc4aSTimo Kreuzer _locale_t plocinfo
46*04e0dc4aSTimo Kreuzer )
47*04e0dc4aSTimo Kreuzer {
48*04e0dc4aSTimo Kreuzer int ret;
49*04e0dc4aSTimo Kreuzer _LocaleUpdate _loc_update(plocinfo);
50*04e0dc4aSTimo Kreuzer
51*04e0dc4aSTimo Kreuzer /* validation section */
52*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN(_string1 != nullptr, EINVAL, _NLSCMPERROR );
53*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN(_string2 != nullptr, EINVAL, _NLSCMPERROR );
54*04e0dc4aSTimo Kreuzer
55*04e0dc4aSTimo Kreuzer if ( _loc_update.GetLocaleT()->locinfo->locale_name[LC_COLLATE] == nullptr )
56*04e0dc4aSTimo Kreuzer {
57*04e0dc4aSTimo Kreuzer return __ascii_wcsicmp(_string1, _string2);
58*04e0dc4aSTimo Kreuzer }
59*04e0dc4aSTimo Kreuzer
60*04e0dc4aSTimo Kreuzer if ( 0 == (ret = __acrt_CompareStringW(
61*04e0dc4aSTimo Kreuzer _loc_update.GetLocaleT()->locinfo->locale_name[LC_COLLATE],
62*04e0dc4aSTimo Kreuzer SORT_STRINGSORT | NORM_IGNORECASE,
63*04e0dc4aSTimo Kreuzer _string1,
64*04e0dc4aSTimo Kreuzer -1,
65*04e0dc4aSTimo Kreuzer _string2,
66*04e0dc4aSTimo Kreuzer -1)) )
67*04e0dc4aSTimo Kreuzer {
68*04e0dc4aSTimo Kreuzer errno = EINVAL;
69*04e0dc4aSTimo Kreuzer return _NLSCMPERROR;
70*04e0dc4aSTimo Kreuzer }
71*04e0dc4aSTimo Kreuzer
72*04e0dc4aSTimo Kreuzer return (ret - 2);
73*04e0dc4aSTimo Kreuzer }
74*04e0dc4aSTimo Kreuzer
_wcsicoll(const wchar_t * _string1,const wchar_t * _string2)75*04e0dc4aSTimo Kreuzer extern "C" int __cdecl _wcsicoll (
76*04e0dc4aSTimo Kreuzer const wchar_t *_string1,
77*04e0dc4aSTimo Kreuzer const wchar_t *_string2
78*04e0dc4aSTimo Kreuzer )
79*04e0dc4aSTimo Kreuzer {
80*04e0dc4aSTimo Kreuzer if (!__acrt_locale_changed())
81*04e0dc4aSTimo Kreuzer {
82*04e0dc4aSTimo Kreuzer /* validation section */
83*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN(_string1 != nullptr, EINVAL, _NLSCMPERROR );
84*04e0dc4aSTimo Kreuzer _VALIDATE_RETURN(_string2 != nullptr, EINVAL, _NLSCMPERROR );
85*04e0dc4aSTimo Kreuzer
86*04e0dc4aSTimo Kreuzer return __ascii_wcsicmp(_string1, _string2);
87*04e0dc4aSTimo Kreuzer }
88*04e0dc4aSTimo Kreuzer else
89*04e0dc4aSTimo Kreuzer {
90*04e0dc4aSTimo Kreuzer return _wcsicoll_l(_string1, _string2, nullptr);
91*04e0dc4aSTimo Kreuzer }
92*04e0dc4aSTimo Kreuzer
93*04e0dc4aSTimo Kreuzer }
94