Reactos
1/***
2*mbsupr.c - Convert string upper case (MBCS)
3*
4* Copyright (c) Microsoft Corporation. All rights reserved.
5*
6*Purpose:
7* Convert string upper case (MBCS)
8*
9*******************************************************************************/
10#ifndef _MBCS
11 #error This file should only be compiled with _MBCS defined
12#endif
13
14#include <corecrt_internal_mbstring.h>
15#include <corecrt_internal_securecrt.h>
16#include <locale.h>
17#include <string.h>
18
19#pragma warning(disable:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED)
20
21/***
22* _mbsupr - Convert string upper case (MBCS)
23*
24*Purpose:
25* Converts all the lower case characters in a string
26* to upper case in place. Handles MBCS chars correctly.
27*
28*Entry:
29* unsigned char *string = pointer to string
30*
31*Exit:
32* Returns a pointer to the input string.
33* Returns nullptr on error.
34*
35*Exceptions:
36* Input parameters are validated. Refer to the validation section of the function.
37*
38*******************************************************************************/
39
40extern "C" errno_t __cdecl _mbsupr_s_l(
41 unsigned char *string,
42 size_t sizeInBytes,
43 _locale_t plocinfo
44 )
45{
46 size_t stringlen;
47
48 /* validation section */
49 _VALIDATE_RETURN_ERRCODE((string != nullptr && sizeInBytes > 0) || (string == nullptr && sizeInBytes == 0), EINVAL);
50
51 if (string == nullptr)
52 {
53 /* nothing to do */
54 return 0;
55 }
56
57 stringlen = strnlen((char *)string, sizeInBytes);
58 if (stringlen >= sizeInBytes)
59 {
60 _RESET_STRING(string, sizeInBytes);
61 _RETURN_DEST_NOT_NULL_TERMINATED(string, sizeInBytes);
62 }
63 _FILL_STRING(string, sizeInBytes, stringlen + 1);
64
65 unsigned char *cp, *dst;
66 _LocaleUpdate _loc_update(plocinfo);
67
68 for (cp = string, dst = string; *cp; ++cp)
69 {
70 if ( _ismbblead_l(*cp, _loc_update.GetLocaleT()) )
71 {
72
73
74 int retval;
75 unsigned char ret[4];
76
77 if ( (retval = __acrt_LCMapStringA(
78 _loc_update.GetLocaleT(),
79 _loc_update.GetLocaleT()->mbcinfo->mblocalename,
80 LCMAP_UPPERCASE,
81 (const char *)cp,
82 2,
83 (char *)ret,
84 2,
85 _loc_update.GetLocaleT()->mbcinfo->mbcodepage,
86 TRUE )) == 0 )
87 {
88 errno = EILSEQ;
89 _RESET_STRING(string, sizeInBytes);
90 return errno;
91 }
92
93 *(dst++) = ret[0];
94 ++cp;
95 if (retval > 1)
96 {
97 *(dst++) = ret[1];
98 }
99
100
101 }
102 else
103 /* single byte, macro version */
104 *(dst++) = (unsigned char) _mbbtoupper_l(*cp, _loc_update.GetLocaleT());
105 }
106 /* null terminate the string */
107 *dst = '\0';
108
109 return 0;
110}
111
112extern "C" errno_t (__cdecl _mbsupr_s)(
113 unsigned char *string,
114 size_t sizeInBytes
115 )
116{
117 return _mbsupr_s_l(string, sizeInBytes, nullptr);
118}
119
120extern "C" unsigned char * (__cdecl _mbsupr_l)(
121 unsigned char *string,
122 _locale_t plocinfo
123 )
124{
125 return (_mbsupr_s_l(string, (string == nullptr ? 0 : (size_t)-1), plocinfo) == 0 ? string : nullptr);
126}
127
128extern "C" unsigned char * (__cdecl _mbsupr)(
129 unsigned char *string
130 )
131{
132 return (_mbsupr_s_l(string, (string == nullptr ? 0 : (size_t)-1), nullptr) == 0 ? string : nullptr);
133}