Reactos
at master 206 lines 5.8 kB view raw
1/*** 2*strlwr.c - routine to map upper-case characters in a string to lower-case 3* 4* Copyright (c) Microsoft Corporation. All rights reserved. 5* 6*Purpose: 7* Converts all the upper case characters in a string to lower case, 8* in place. 9* 10*******************************************************************************/ 11#include <corecrt_internal.h> 12#include <ctype.h> 13#include <corecrt_internal_securecrt.h> 14#include <limits.h> 15#include <locale.h> 16#include <string.h> 17 18#pragma warning(disable:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED) // 26018 19 20/*** 21*char *_strlwr(string) - map upper-case characters in a string to lower-case 22* 23*Purpose: 24* _strlwr() converts upper-case characters in a null-terminated string 25* to their lower-case equivalents. Conversion is done in place and 26* characters other than upper-case letters are not modified. 27* 28* In the C locale, this function modifies only 7-bit ASCII characters 29* in the range 0x41 through 0x5A ('A' through 'Z'). 30* 31* If the locale is not the 'C' locale, LCMapString() is used to do 32* the work. Assumes enough space in the string to hold result. 33* 34*Entry: 35* char *string - string to change to lower case 36* 37*Exit: 38* input string address 39* 40*Exceptions: 41* The original string is returned unchanged on any error, and errno is set. 42* 43*******************************************************************************/ 44 45extern "C" char * __cdecl _strlwr_l ( 46 char * string, 47 _locale_t plocinfo 48 ) 49{ 50 _strlwr_s_l(string, (size_t)(-1), plocinfo); 51 return string; 52} 53 54extern "C" char * __cdecl _strlwr ( 55 char * string 56 ) 57{ 58 if (!__acrt_locale_changed()) 59 { 60 char * cp; 61 62 /* validation section */ 63 _VALIDATE_RETURN(string != nullptr, EINVAL, nullptr); 64 65 for (cp=string; *cp; ++cp) 66 { 67 if ('A' <= *cp && *cp <= 'Z') 68 *cp += 'a' - 'A'; 69 } 70 71 return(string); 72 } 73 else 74 { 75 _strlwr_s_l(string, (size_t)(-1), nullptr); 76 return string; 77 } 78} 79 80/*** 81*errno_t _strlwr_s(string, size_t) - map upper-case characters in a string to lower-case 82* 83*Purpose: 84* _strlwr_s() converts upper-case characters in a null-terminated string 85* to their lower-case equivalents. Conversion is done in place and 86* characters other than upper-case letters are not modified. 87* 88* In the C locale, this function modifies only 7-bit ASCII characters 89* in the range 0x41 through 0x5A ('A' through 'Z'). 90* 91* If the locale is not the 'C' locale, LCMapString() is used to do 92* the work. Assumes enough space in the string to hold result. 93* 94*Entry: 95* char *string - string to change to lower case 96* size_t sizeInBytes - size of the destination buffer 97* 98*Exit: 99* the error code 100* 101*Exceptions: 102* The original string is returned unchanged on any error, and errno is set. 103* 104*******************************************************************************/ 105 106static 107errno_t __cdecl _strlwr_s_l_stat ( 108 _Inout_updates_z_(sizeInBytes) char * const string, 109 size_t const sizeInBytes, 110 _locale_t const plocinfo 111 ) throw() 112{ 113 114 int dstsize; /* size of dst string buffer (include null) */ 115 size_t stringlen; 116 117 /* validation section */ 118 _VALIDATE_RETURN_ERRCODE(string != nullptr, EINVAL); 119 stringlen = strnlen(string, sizeInBytes); 120 if (stringlen >= sizeInBytes) 121 { 122 _RESET_STRING(string, sizeInBytes); 123 _RETURN_DEST_NOT_NULL_TERMINATED(string, sizeInBytes); 124 } 125 _FILL_STRING(string, sizeInBytes, stringlen + 1); 126 127 if ( plocinfo->locinfo->locale_name[LC_CTYPE] == nullptr ) { 128 char *cp; /* traverses string for C locale conversion */ 129 130 for ( cp = string ; *cp ; ++cp ) 131 if ( ('A' <= *cp) && (*cp <= 'Z') ) 132 *cp -= 'A' - 'a'; 133 134 return 0; 135 } /* C locale */ 136 137 /* Inquire size of dst string */ 138 if ( 0 == (dstsize = __acrt_LCMapStringA( 139 plocinfo, 140 plocinfo->locinfo->locale_name[LC_CTYPE], 141 LCMAP_LOWERCASE, 142 string, 143 -1, 144 nullptr, 145 0, 146 plocinfo->locinfo->_public._locale_lc_codepage, 147 TRUE )) ) 148 { 149 errno = EILSEQ; 150 return errno; 151 } 152 153 if (sizeInBytes < (size_t)dstsize) 154 { 155 _RESET_STRING(string, sizeInBytes); 156 _RETURN_BUFFER_TOO_SMALL(string, sizeInBytes); 157 } 158 159 /* Allocate space for dst */ 160 __crt_scoped_stack_ptr<char> dst(_malloca_crt_t(char, dstsize)); 161 if (!dst) 162 { 163 errno = ENOMEM; 164 return errno; 165 } 166 167 /* Map src string to dst string in alternate case */ 168 if (__acrt_LCMapStringA( 169 plocinfo, 170 plocinfo->locinfo->locale_name[LC_CTYPE], 171 LCMAP_LOWERCASE, 172 string, 173 -1, 174 dst.get(), 175 dstsize, 176 plocinfo->locinfo->_public._locale_lc_codepage, 177 TRUE ) != 0) 178 { 179 /* copy dst string to return string */ 180 return strcpy_s(string, sizeInBytes, dst.get()); 181 } 182 else 183 { 184 return errno = EILSEQ; 185 } 186} 187 188extern "C" errno_t __cdecl _strlwr_s_l ( 189 char * string, 190 size_t sizeInBytes, 191 _locale_t plocinfo 192 ) 193{ 194 195 _LocaleUpdate _loc_update(plocinfo); 196 197 return _strlwr_s_l_stat(string, sizeInBytes, _loc_update.GetLocaleT()); 198} 199 200extern "C" errno_t __cdecl _strlwr_s( 201 char * string, 202 size_t sizeInBytes 203 ) 204{ 205 return _strlwr_s_l(string, sizeInBytes, nullptr); 206}