Reactos
at master 310 lines 13 kB view raw
1// 2// ctype.h 3// 4// Copyright (c) Microsoft Corporation. All rights reserved. 5// 6// This file declares the narrow character (char) classification functionality. 7// 8#pragma once 9#ifndef _INC_CTYPE // include guard for 3rd party interop 10#define _INC_CTYPE 11 12#include <corecrt.h> 13#include <corecrt_wctype.h> 14 15#pragma warning(push) 16#pragma warning(disable: _UCRT_DISABLED_WARNINGS) 17_UCRT_DISABLE_CLANG_WARNINGS 18 19_CRT_BEGIN_C_HEADER 20#if !defined __midl && !defined RC_INVOKED 21 22 23 24//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25// 26// Character Classification Function Declarations 27// 28//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 29_Check_return_ _ACRTIMP int __cdecl _isctype(_In_ int _C, _In_ int _Type); 30_Check_return_ _ACRTIMP int __cdecl _isctype_l(_In_ int _C, _In_ int _Type, _In_opt_ _locale_t _Locale); 31_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl isalpha(_In_ int _C); 32_Check_return_ _ACRTIMP int __cdecl _isalpha_l(_In_ int _C, _In_opt_ _locale_t _Locale); 33_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl isupper(_In_ int _C); 34_Check_return_ _ACRTIMP int __cdecl _isupper_l(_In_ int _C, _In_opt_ _locale_t _Locale); 35_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl islower(_In_ int _C); 36_Check_return_ _ACRTIMP int __cdecl _islower_l(_In_ int _C, _In_opt_ _locale_t _Locale); 37 38_When_(_Param_(1) == 0, _Post_equal_to_(0)) 39_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl isdigit(_In_ int _C); 40 41_Check_return_ _ACRTIMP int __cdecl _isdigit_l(_In_ int _C, _In_opt_ _locale_t _Locale); 42_Check_return_ _ACRTIMP int __cdecl isxdigit(_In_ int _C); 43_Check_return_ _ACRTIMP int __cdecl _isxdigit_l(_In_ int _C, _In_opt_ _locale_t _Locale); 44 45_When_(_Param_(1) == 0, _Post_equal_to_(0)) 46_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl isspace(_In_ int _C); 47 48_Check_return_ _ACRTIMP int __cdecl _isspace_l(_In_ int _C, _In_opt_ _locale_t _Locale); 49_Check_return_ _ACRTIMP int __cdecl ispunct(_In_ int _C); 50_Check_return_ _ACRTIMP int __cdecl _ispunct_l(_In_ int _C, _In_opt_ _locale_t _Locale); 51_Check_return_ _ACRTIMP int __cdecl isblank(_In_ int _C); 52_Check_return_ _ACRTIMP int __cdecl _isblank_l(_In_ int _C, _In_opt_ _locale_t _Locale); 53_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl isalnum(_In_ int _C); 54_Check_return_ _ACRTIMP int __cdecl _isalnum_l(_In_ int _C, _In_opt_ _locale_t _Locale); 55_Check_return_ _ACRTIMP int __cdecl isprint(_In_ int _C); 56_Check_return_ _ACRTIMP int __cdecl _isprint_l(_In_ int _C, _In_opt_ _locale_t _Locale); 57_Check_return_ _ACRTIMP int __cdecl isgraph(_In_ int _C); 58_Check_return_ _ACRTIMP int __cdecl _isgraph_l(_In_ int _C, _In_opt_ _locale_t _Locale); 59_Check_return_ _ACRTIMP int __cdecl iscntrl(_In_ int _C); 60_Check_return_ _ACRTIMP int __cdecl _iscntrl_l(_In_ int _C, _In_opt_ _locale_t _Locale); 61 62_When_(_Param_(1) == 0, _Post_equal_to_(0)) 63_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl toupper(_In_ int _C); 64 65_When_(_Param_(1) == 0, _Post_equal_to_(0)) 66_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl tolower(_In_ int _C); 67 68_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl _tolower(_In_ int _C); 69_Check_return_ _ACRTIMP int __cdecl _tolower_l(_In_ int _C, _In_opt_ _locale_t _Locale); 70_Check_return_ _CRT_JIT_INTRINSIC _ACRTIMP int __cdecl _toupper(_In_ int _C); 71_Check_return_ _ACRTIMP int __cdecl _toupper_l(_In_ int _C, _In_opt_ _locale_t _Locale); 72 73_Check_return_ _ACRTIMP int __cdecl __isascii(_In_ int _C); 74_Check_return_ _ACRTIMP int __cdecl __toascii(_In_ int _C); 75_Check_return_ _ACRTIMP int __cdecl __iscsymf(_In_ int _C); 76_Check_return_ _ACRTIMP int __cdecl __iscsym(_In_ int _C); 77 78 79 80//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 81// 82// Character Classification Macro Definitions 83// 84//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 85__inline int __CRTDECL __acrt_locale_get_ctype_array_value( 86 _In_reads_(_Char_value + 1) unsigned short const * const _Locale_pctype_array, 87 _In_range_(-1, 255) int const _Char_value, 88 _In_ int const _Mask 89 ) 90{ 91 // The C Standard specifies valid input to a ctype function ranges from -1 to 255. 92 // To avoid undefined behavior, we should check this range for all accesses. 93 // Note _locale_pctype array does extend to -127 to support accessing 94 // _pctype directly with signed chars. 95 96 if (_Char_value >= -1 && _Char_value <= 255) 97 { 98 return _Locale_pctype_array[_Char_value] & _Mask; 99 } 100 101 return 0; 102} 103 104#ifndef _CTYPE_DISABLE_MACROS 105 106 // Maximum number of bytes in multi-byte character in the current locale 107 // (also defined in stdlib.h). 108 #ifndef MB_CUR_MAX 109 #if defined _CRT_DISABLE_PERFCRIT_LOCKS && !defined _DLL 110 #define MB_CUR_MAX __mb_cur_max 111 #else 112 #define MB_CUR_MAX ___mb_cur_max_func() 113 #endif 114 115 #ifdef _CRT_DECLARE_GLOBAL_VARIABLES_DIRECTLY 116 extern int __mb_cur_max; 117 #else 118 #define __mb_cur_max (___mb_cur_max_func()) 119 #endif 120 121 // MB_LEN_MAX = 5 in limits.h but we do not include that header here so use 5 122 // directly. 123 _Post_satisfies_(return > 0 && return < 5) 124 _ACRTIMP int __cdecl ___mb_cur_max_func(void); 125 _Post_satisfies_(return > 0 && return < 5) 126 _ACRTIMP int __cdecl ___mb_cur_max_l_func(_locale_t _Locale); 127 #endif 128 129 // In the debug CRT, we make all calls through the validation function to catch 130 // invalid integer inputs that yield undefined behavior. 131 #ifdef _DEBUG 132 _ACRTIMP int __cdecl _chvalidator(_In_ int _Ch, _In_ int _Mask); 133 #define __chvalidchk(a, b) _chvalidator(a, b) 134 #else 135 136 #define __chvalidchk(a, b) (__acrt_locale_get_ctype_array_value(__PCTYPE_FUNC, (a), (b))) 137 #endif 138 139 140 141 #define __ascii_isalpha(c) ( __chvalidchk(c, _ALPHA)) 142 #define __ascii_isdigit(c) ( __chvalidchk(c, _DIGIT)) 143 144 #ifdef _CRT_DEFINE_ASCII_CTYPE_MACROS 145 #define __ascii_tolower(c) ( (((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c) ) 146 #define __ascii_toupper(c) ( (((c) >= 'a') && ((c) <= 'z')) ? ((c) - 'a' + 'A') : (c) ) 147 #define __ascii_iswalpha(c) ( ('A' <= (c) && (c) <= 'Z') || ( 'a' <= (c) && (c) <= 'z')) 148 #define __ascii_iswdigit(c) ( '0' <= (c) && (c) <= '9') 149 #define __ascii_towlower(c) ( (((c) >= L'A') && ((c) <= L'Z')) ? ((c) - L'A' + L'a') : (c) ) 150 #define __ascii_towupper(c) ( (((c) >= L'a') && ((c) <= L'z')) ? ((c) - L'a' + L'A') : (c) ) 151 #else 152 __forceinline int __CRTDECL __ascii_tolower(int const _C) 153 { 154 if (_C >= 'A' && _C <= 'Z') 155 { 156 return _C - ('A' - 'a'); 157 } 158 return _C; 159 } 160 161 __forceinline int __CRTDECL __ascii_toupper(int const _C) 162 { 163 if (_C >= 'a' && _C <= 'z') 164 { 165 return _C - ('a' - 'A'); 166 } 167 return _C; 168 } 169 170 __forceinline int __CRTDECL __ascii_iswalpha(int const _C) 171 { 172 return (_C >= 'A' && _C <= 'Z') || (_C >= 'a' && _C <= 'z'); 173 } 174 175 __forceinline int __CRTDECL __ascii_iswdigit(int const _C) 176 { 177 return _C >= '0' && _C <= '9'; 178 } 179 180 __forceinline int __CRTDECL __ascii_towlower(int const _C) 181 { 182 return __ascii_tolower(_C); 183 } 184 185 __forceinline int __CRTDECL __ascii_towupper(int const _C) 186 { 187 return __ascii_toupper(_C); 188 } 189 #endif 190 191 192 193 #if defined _CRT_DISABLE_PERFCRIT_LOCKS && !defined _DLL && !defined __cplusplus 194 #define isalpha(c) (MB_CUR_MAX > 1 ? _isctype(c, _ALPHA) : __chvalidchk(c, _ALPHA)) 195 #define isupper(c) (MB_CUR_MAX > 1 ? _isctype(c, _UPPER) : __chvalidchk(c, _UPPER)) 196 #define islower(c) (MB_CUR_MAX > 1 ? _isctype(c, _LOWER) : __chvalidchk(c, _LOWER)) 197 #define isdigit(c) (MB_CUR_MAX > 1 ? _isctype(c, _DIGIT) : __chvalidchk(c, _DIGIT)) 198 #define isxdigit(c) (MB_CUR_MAX > 1 ? _isctype(c, _HEX) : __chvalidchk(c, _HEX)) 199 #define isspace(c) (MB_CUR_MAX > 1 ? _isctype(c, _SPACE) : __chvalidchk(c, _SPACE)) 200 #define ispunct(c) (MB_CUR_MAX > 1 ? _isctype(c, _PUNCT) : __chvalidchk(c, _PUNCT)) 201 #define isblank(c) (MB_CUR_MAX > 1 ? (((c) == '\t') ? _BLANK : _isctype(c, _BLANK)) : (((c) == '\t') ? _BLANK : __chvalidchk(c, _BLANK))) 202 #define isalnum(c) (MB_CUR_MAX > 1 ? _isctype(c, _ALPHA | _DIGIT) : __chvalidchk(c, (_ALPHA | _DIGIT))) 203 #define isprint(c) (MB_CUR_MAX > 1 ? _isctype(c, _BLANK | _PUNCT | _ALPHA | _DIGIT) : __chvalidchk(c, (_BLANK | _PUNCT | _ALPHA | _DIGIT))) 204 #define isgraph(c) (MB_CUR_MAX > 1 ? _isctype(c, _PUNCT | _ALPHA | _DIGIT) : __chvalidchk(c, (_PUNCT | _ALPHA | _DIGIT))) 205 #define iscntrl(c) (MB_CUR_MAX > 1 ? _isctype(c, _CONTROL) : __chvalidchk(c, _CONTROL)) 206 #endif 207 208 __inline __crt_locale_data_public* __CRTDECL __acrt_get_locale_data_prefix(void const volatile* const _LocalePointers) 209 { 210 _locale_t const _TypedLocalePointers = (_locale_t)_LocalePointers; 211 return (__crt_locale_data_public*)_TypedLocalePointers->locinfo; 212 } 213 214 #ifdef _DEBUG 215 _ACRTIMP int __cdecl _chvalidator_l(_In_opt_ _locale_t, _In_ int _Ch, _In_ int _Mask); 216 #endif 217 218 __inline int __CRTDECL _chvalidchk_l( 219 _In_ int const _C, 220 _In_ int const _Mask, 221 _In_opt_ _locale_t const _Locale 222 ) 223 { 224 #ifdef _DEBUG 225 return _chvalidator_l(_Locale, _C, _Mask); 226 #else 227 if (!_Locale) 228 { 229 return __chvalidchk(_C, _Mask); 230 } 231 232 return __acrt_locale_get_ctype_array_value(__acrt_get_locale_data_prefix(_Locale)->_locale_pctype, _C, _Mask); 233 #endif 234 } 235 236 #define __ascii_isalpha_l(c, locale) (_chvalidchk_l(c, _ALPHA, locale)) 237 #define __ascii_isdigit_l(c, locale) (_chvalidchk_l(c, _DIGIT, locale)) 238 239 __inline int __CRTDECL _ischartype_l( 240 _In_ int const _C, 241 _In_ int const _Mask, 242 _In_opt_ _locale_t const _Locale 243 ) 244 { 245 if (!_Locale) 246 { 247 return _chvalidchk_l(_C, _Mask, 0); 248 } 249 250 if (_C >= -1 && _C <= 255) 251 { 252 return __acrt_get_locale_data_prefix(_Locale)->_locale_pctype[_C] & _Mask; 253 } 254 255 if (__acrt_get_locale_data_prefix(_Locale)->_locale_mb_cur_max > 1) 256 { 257 return _isctype_l(_C, _Mask, _Locale); 258 } 259 260 return 0; // >0xFF and SBCS locale 261 } 262 263 #define _isalpha_l(c, locale) _ischartype_l(c, _ALPHA, locale) 264 #define _isupper_l(c, locale) _ischartype_l(c, _UPPER, locale) 265 #define _islower_l(c, locale) _ischartype_l(c, _LOWER, locale) 266 #define _isdigit_l(c, locale) _ischartype_l(c, _DIGIT, locale) 267 #define _isxdigit_l(c, locale) _ischartype_l(c, _HEX, locale) 268 #define _isspace_l(c, locale) _ischartype_l(c, _SPACE, locale) 269 #define _ispunct_l(c, locale) _ischartype_l(c, _PUNCT, locale) 270 #define _isblank_l(c, locale) (((c) == '\t') ? _BLANK : _ischartype_l(c, _BLANK, locale)) 271 #define _isalnum_l(c, locale) _ischartype_l(c, _ALPHA | _DIGIT, locale) 272 #define _isprint_l(c, locale) _ischartype_l(c, _BLANK | _PUNCT | _ALPHA | _DIGIT, locale) 273 #define _isgraph_l(c, locale) _ischartype_l(c, _PUNCT | _ALPHA | _DIGIT, locale) 274 #define _iscntrl_l(c, locale) _ischartype_l(c, _CONTROL, locale) 275 276 #define _tolower(c) ((c) - 'A' + 'a') 277 #define _toupper(c) ((c) - 'a' + 'A') 278 279 #define __isascii(c) ((unsigned)(c) < 0x80) 280 #define __toascii(c) ((c) & 0x7f) 281 282 283 // Microsoft C version 2.0 extended ctype macros 284 #define __iscsymf(c) (isalpha(c) || ((c) == '_')) 285 #define __iscsym(c) (isalnum(c) || ((c) == '_')) 286 #define __iswcsymf(c) (iswalpha(c) || ((c) == '_')) 287 #define __iswcsym(c) (iswalnum(c) || ((c) == '_')) 288 289 #define _iscsymf_l(c, p) (_isalpha_l(c, p) || ((c) == '_')) 290 #define _iscsym_l(c, p) (_isalnum_l(c, p) || ((c) == '_')) 291 #define _iswcsymf_l(c, p) (iswalpha(c) || ((c) == '_')) 292 #define _iswcsym_l(c, p) (iswalnum(c) || ((c) == '_')) 293 294#endif // _CTYPE_DISABLE_MACROS 295 296 297#if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES 298 #define isascii __isascii 299 #define toascii __toascii 300 #define iscsymf __iscsymf 301 #define iscsym __iscsym 302#endif 303 304 305 306#endif // !defined __midl && !defined RC_INVOKED 307_CRT_END_C_HEADER 308_UCRT_RESTORE_CLANG_WARNINGS 309#pragma warning(pop) // _UCRT_DISABLED_WARNINGS 310#endif // _INC_CTYPE