Reactos
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
42extern "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
136extern "C" int (__cdecl _mbsicmp)(
137 const unsigned char *s1,
138 const unsigned char *s2
139 )
140{
141 return _mbsicmp_l(s1, s2, nullptr);
142}