xref: /reactos/sdk/lib/ucrt/mbstring/mbsicmp.cpp (revision 53d808d2)
1 /***
2 *mbsicmp.c - Case-insensitive string comparision routine (MBCS)
3 *
4 *       Copyright (c) Microsoft Corporation.  All rights reserved.
5 *
6 *Purpose:
7 *       Case-insensitive string comparision routine (MBCS)
8 *
9 *******************************************************************************/
10 #ifndef _MBCS
11     #error This file should only be compiled with _MBCS defined
12 #endif
13 
14 #include <corecrt_internal.h>
15 #include <corecrt_internal_mbstring.h>
16 #include <locale.h>
17 #include <string.h>
18 
19 #pragma warning(disable:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED) // 26018
20 
21 /***
22 * _mbsicmp - Case-insensitive string comparision routine (MBCS)
23 *
24 *Purpose:
25 *       Compares two strings for ordinal order without regard to case.
26 *       Strings are compared on a character basis, not a byte basis.
27 *
28 *Entry:
29 *       char *s1, *s2 = strings to compare
30 *
31 *Exit:
32 *       Returns <0 if s1 < s2
33 *       Returns  0 if s1 == s2
34 *       Returns >0 if s1 > s2
35 *       Returns _NLSCMPERROR if something went wrong
36 *
37 *Exceptions:
38 *       Input parameters are validated. Refer to the validation section of the function.
39 *
40 *******************************************************************************/
41 
42 extern "C" int __cdecl _mbsicmp_l(
43         const unsigned char *s1,
44         const unsigned char *s2,
45         _locale_t plocinfo
46         )
47 {
48         unsigned short c1, c2;
49         _LocaleUpdate _loc_update(plocinfo);
50         int    retval;
51         unsigned char szResult[4];
52 
53         /* validation section */
54         _VALIDATE_RETURN(s1 != nullptr, EINVAL, _NLSCMPERROR);
55         _VALIDATE_RETURN(s2 != nullptr, EINVAL, _NLSCMPERROR);
56 
57         if (_loc_update.GetLocaleT()->mbcinfo->ismbcodepage == 0)
58             return _stricmp_l((const char *)s1, (const char *)s2, _loc_update.GetLocaleT());
59 
60         for (;;)
61         {
62             c1 = *s1++;
63             if ( _ismbblead_l(c1, _loc_update.GetLocaleT()) )
64             {
65                 if (*s1 == '\0')
66                     c1 = 0;
67                 else
68                 {
69                     retval = __acrt_LCMapStringA(
70                             _loc_update.GetLocaleT(),
71                             _loc_update.GetLocaleT()->mbcinfo->mblocalename,
72                             LCMAP_UPPERCASE,
73                             (LPCSTR)s1 - 1,
74                             2,
75                             (LPSTR)szResult,
76                             2,
77                             _loc_update.GetLocaleT()->mbcinfo->mbcodepage,
78                             TRUE );
79 
80                     if (retval == 1)
81                         c1 = szResult[0];
82                     else if (retval == 2)
83                         c1 = (szResult[0] << 8) + szResult[1];
84                     else
85                     {
86                         errno = EINVAL;
87                         return _NLSCMPERROR;
88                     }
89                     s1++;
90                 }
91             }
92             else
93                 c1 = _mbbtolower_l(c1, _loc_update.GetLocaleT());
94 
95             c2 = *s2++;
96             if ( _ismbblead_l(c2, _loc_update.GetLocaleT()) )
97             {
98                 if (*s2 == '\0')
99                     c2 = 0;
100                 else
101                 {
102                     retval = __acrt_LCMapStringA(
103                             _loc_update.GetLocaleT(),
104                             _loc_update.GetLocaleT()->mbcinfo->mblocalename,
105                             LCMAP_UPPERCASE,
106                             (LPCSTR)s2 - 1,
107                             2,
108                             (LPSTR)szResult,
109                             2,
110                             _loc_update.GetLocaleT()->mbcinfo->mbcodepage,
111                             TRUE );
112 
113                     if (retval == 1)
114                         c2 = szResult[0];
115                     else if (retval == 2)
116                         c2 = (szResult[0] << 8) + szResult[1];
117                     else
118                     {
119                         errno = EINVAL;
120                         return _NLSCMPERROR;
121                     }
122                     s2++;
123                 }
124             }
125             else
126                 c2 = _mbbtolower_l(c2, _loc_update.GetLocaleT());
127 
128             if (c1 != c2)
129                 return( (c1 > c2) ? 1 : -1 );
130 
131             if (c1 == 0)
132                 return(0);
133         }
134 }
135 
136 extern "C" int (__cdecl _mbsicmp)(
137         const unsigned char *s1,
138         const unsigned char *s2
139         )
140 {
141     return _mbsicmp_l(s1, s2, nullptr);
142 }
143