xref: /reactos/sdk/lib/ucrt/string/strncoll.cpp (revision fe93a3f9)
1 /***
2 *strncoll.c - Collate locale strings
3 *
4 *       Copyright (c) Microsoft Corporation. All rights reserved.
5 *
6 *Purpose:
7 *       Compare two strings using the locale LC_COLLATE information.
8 *       Compares at most n characters of two strings.
9 *
10 *******************************************************************************/
11 #include <corecrt_internal.h>
12 #include <ctype.h>
13 #include <locale.h>
14 #include <string.h>
15 
16 /***
17 *int _strncoll() - Collate locale strings
18 *
19 *Purpose:
20 *       Compare two strings using the locale LC_COLLATE information.
21 *       Compares at most n characters of two strings.
22 *
23 *Entry:
24 *       const char *s1 = pointer to the first string
25 *       const char *s2 = pointer to the second string
26 *       size_t count - maximum number of characters to compare
27 *
28 *Exit:
29 *       Less than 0    = first string less than second string
30 *       0              = strings are equal
31 *       Greater than 0 = first string greater than second string
32 *       Returns _NLSCMPERROR is something went wrong
33 *
34 *Exceptions:
35 *       Input parameters are validated. Refer to the validation section of the function.
36 *
37 *******************************************************************************/
38 extern "C" int __cdecl _strncoll_l (
39         const char *_string1,
40         const char *_string2,
41         size_t count,
42         _locale_t plocinfo
43         )
44 {
45     int ret;
46 
47     if ( !count )
48         return 0;
49 
50     /* validation section */
51     _VALIDATE_RETURN(_string1 != nullptr, EINVAL, _NLSCMPERROR);
52     _VALIDATE_RETURN(_string2 != nullptr, EINVAL, _NLSCMPERROR);
53     _VALIDATE_RETURN(count <= INT_MAX, EINVAL, _NLSCMPERROR);
54 
55     _LocaleUpdate _loc_update(plocinfo);
56 
57     if ( _loc_update.GetLocaleT()->locinfo->locale_name[LC_COLLATE] == nullptr )
58     {
59         return strncmp(_string1, _string2, count);
60     }
61 
62     if ( 0 == (ret = __acrt_CompareStringA(
63                     _loc_update.GetLocaleT(),
64                     _loc_update.GetLocaleT()->locinfo->locale_name[LC_COLLATE],
65                     SORT_STRINGSORT,
66                     _string1,
67                     (int)count,
68                     _string2,
69                     (int)count,
70                     _loc_update.GetLocaleT()->locinfo->lc_collate_cp)) )
71     {
72         errno = EINVAL;
73         return _NLSCMPERROR;
74     }
75 
76     return (ret - 2);
77 }
78 
79 extern "C" int __cdecl _strncoll (
80         const char *_string1,
81         const char *_string2,
82         size_t count
83         )
84 {
85     if (!__acrt_locale_changed())
86     {
87         /* validation section */
88         _VALIDATE_RETURN(_string1 != nullptr, EINVAL, _NLSCMPERROR);
89         _VALIDATE_RETURN(_string2 != nullptr, EINVAL, _NLSCMPERROR);
90         _VALIDATE_RETURN(count <= INT_MAX, EINVAL, _NLSCMPERROR);
91 
92         return strncmp(_string1, _string2, count);
93     }
94     else
95     {
96         return _strncoll_l(_string1, _string2, count, nullptr);
97     }
98 }
99