1 // 2 // strtox.cpp 3 // 4 // Copyright (c) Microsoft Corporation. All rights reserved. 5 // 6 // The many string-to-integer conversion functions, including strtol, strtoul, 7 // strtoll, strtoull, wcstol, wcstoul, wcstoll, wcstoull, and various variations 8 // of these functions. All of these share a common implementation that converts 9 // a narrow or wide character string to a 32-bit or 64-bit signed or unsigned 10 // integer. 11 // 12 // The base must be zero or in the range [2,36]. If the base zero is passed, 13 // the functions attempt to determine the base from the prefix of the string: a 14 // prefix of "0" indicates an octal string, a prefix of "0x" or "0X" indicates a 15 // hexadecimal string, and any other character indicates base 10. 16 // 17 // If the end_ptr is non-null, then if the number is successfully parsed, the 18 // *end_ptr is set to point to the last digit of the number (note: it does NOT 19 // point one-past-the-end, STL style). 20 // 21 // The string format must be: 22 // 23 // [whitespace] [sign] [0|0x] [digits/letters] 24 // 25 // If the string does not start with a valid number, zero is returned and end_ptr 26 // is set to point to the initial character in the string. 27 // 28 // If the string starts with a valid number that is representable in the target 29 // integer type, the number is returned and end_ptr is set to point to the last 30 // character of the number. 31 // 32 // If the string starts with a valid number that is not representable in the 33 // target integer type, end_ptr is set to point to the last character of the 34 // number and a sentinel value is returned: 35 // 36 // 32-bit 64-bit 37 // Unsigned / too large: UINT_MAX _UI64_MAX 38 // Signed / too large: INT_MAX _I64_MAX 39 // Signed / too small: INT_MIN _I64_MIN 40 // 41 // See also atox.cpp, which defines the "simple" functions--the atox and wtox 42 // families of functions. 43 // 44 #define _ALLOW_OLD_VALIDATE_MACROS 45 #include <corecrt_internal.h> 46 #include <corecrt_internal_strtox.h> 47 #include <corecrt_wstdlib.h> 48 #include <ctype.h> 49 #include <errno.h> 50 #include <limits.h> 51 #include <locale.h> 52 #include <stdint.h> 53 #include <stdlib.h> 54 #include <inttypes.h> 55 56 57 58 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 59 // 60 // Narrow Strings => 32-bit Integers 61 // 62 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 63 extern "C" long __cdecl strtol( 64 char const* const string, 65 char** const end_ptr, 66 int const base 67 ) 68 { 69 return __crt_strtox::parse_integer_from_string<long>(string, end_ptr, base, nullptr); 70 } 71 72 extern "C" long __cdecl _strtol_l( 73 char const* const string, 74 char** const end_ptr, 75 int const base, 76 _locale_t const locale 77 ) 78 { 79 return __crt_strtox::parse_integer_from_string<long>(string, end_ptr, base, locale); 80 } 81 82 83 84 extern "C" unsigned long __cdecl strtoul( 85 char const* const string, 86 char** const end_ptr, 87 int const base 88 ) 89 { 90 return __crt_strtox::parse_integer_from_string<unsigned long>(string, end_ptr, base, nullptr); 91 } 92 93 extern "C" unsigned long __cdecl _strtoul_l( 94 char const* const string, 95 char** const end_ptr, 96 int const base, 97 _locale_t const locale 98 ) 99 { 100 return __crt_strtox::parse_integer_from_string<unsigned long>(string, end_ptr, base, locale); 101 } 102 103 104 105 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 106 // 107 // Narrow Strings => 64-bit Integers 108 // 109 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 110 extern "C" __int64 __cdecl _strtoi64( 111 char const* const string, 112 char** const end_ptr, 113 int const base 114 ) 115 { 116 return __crt_strtox::parse_integer_from_string<__int64>(string, end_ptr, base, nullptr); 117 } 118 119 extern "C" long long __cdecl strtoll( 120 char const* const string, 121 char** const end_ptr, 122 int const base 123 ) 124 { 125 return __crt_strtox::parse_integer_from_string<long long>(string, end_ptr, base, nullptr); 126 } 127 128 extern "C" intmax_t __cdecl strtoimax( 129 char const* const string, 130 char** const end_ptr, 131 int const base 132 ) 133 { 134 return __crt_strtox::parse_integer_from_string<intmax_t>(string, end_ptr, base, nullptr); 135 } 136 137 138 139 extern "C" __int64 __cdecl _strtoi64_l( 140 char const* const string, 141 char** const end_ptr, 142 int const base, 143 _locale_t const locale 144 ) 145 { 146 return __crt_strtox::parse_integer_from_string<__int64>(string, end_ptr, base, locale); 147 } 148 149 extern "C" long long __cdecl _strtoll_l( 150 char const* const string, 151 char** const end_ptr, 152 int const base, 153 _locale_t const locale 154 ) 155 { 156 return __crt_strtox::parse_integer_from_string<long long>(string, end_ptr, base, locale); 157 } 158 159 extern "C" intmax_t __cdecl _strtoimax_l( 160 char const* const string, 161 char** const end_ptr, 162 int const base, 163 _locale_t const locale 164 ) 165 { 166 return __crt_strtox::parse_integer_from_string<intmax_t>(string, end_ptr, base, locale); 167 } 168 169 170 171 extern "C" unsigned __int64 __cdecl _strtoui64( 172 char const* const string, 173 char** const end_ptr, 174 int const base 175 ) 176 { 177 return __crt_strtox::parse_integer_from_string<unsigned __int64>(string, end_ptr, base, nullptr); 178 } 179 180 extern "C" unsigned long long __cdecl strtoull( 181 char const* const string, 182 char** const end_ptr, 183 int const base 184 ) 185 { 186 return __crt_strtox::parse_integer_from_string<unsigned long long>(string, end_ptr, base, nullptr); 187 } 188 189 extern "C" uintmax_t __cdecl strtoumax( 190 char const* const string, 191 char** const end_ptr, 192 int const base 193 ) 194 { 195 return __crt_strtox::parse_integer_from_string<uintmax_t>(string, end_ptr, base, nullptr); 196 } 197 198 199 200 extern "C" unsigned __int64 __cdecl _strtoui64_l( 201 char const* const string, 202 char** const end_ptr, 203 int const base, 204 _locale_t const locale 205 ) 206 { 207 return __crt_strtox::parse_integer_from_string<unsigned __int64>(string, end_ptr, base, locale); 208 } 209 210 extern "C" unsigned long long __cdecl _strtoull_l( 211 char const* const string, 212 char** const end_ptr, 213 int const base, 214 _locale_t const locale 215 ) 216 { 217 return __crt_strtox::parse_integer_from_string<unsigned long long>(string, end_ptr, base, locale); 218 } 219 220 extern "C" uintmax_t __cdecl _strtoumax_l( 221 char const* const string, 222 char** const end_ptr, 223 int const base, 224 _locale_t const locale 225 ) 226 { 227 return __crt_strtox::parse_integer_from_string<uintmax_t>(string, end_ptr, base, locale); 228 } 229 230 231 232 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 233 // 234 // Wide Strings => 32-bit Integers 235 // 236 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 237 extern "C" long __cdecl wcstol( 238 wchar_t const* const string, 239 wchar_t** const end_ptr, 240 int const base 241 ) 242 { 243 return __crt_strtox::parse_integer_from_string<long>(string, end_ptr, base, nullptr); 244 } 245 246 extern "C" long __cdecl _wcstol_l( 247 wchar_t const* const string, 248 wchar_t** const end_ptr, 249 int const base, 250 _locale_t const locale 251 ) 252 { 253 return __crt_strtox::parse_integer_from_string<long>(string, end_ptr, base, locale); 254 } 255 256 extern "C" unsigned long __cdecl wcstoul( 257 wchar_t const* const string, 258 wchar_t** const end_ptr, 259 int const base 260 ) 261 { 262 return __crt_strtox::parse_integer_from_string<unsigned long>(string, end_ptr, base, nullptr); 263 } 264 265 extern "C" unsigned long __cdecl _wcstoul_l( 266 wchar_t const* const string, 267 wchar_t** const end_ptr, 268 int const base, 269 _locale_t const locale 270 ) 271 { 272 return __crt_strtox::parse_integer_from_string<unsigned long>(string, end_ptr, base, locale); 273 } 274 275 276 277 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 278 // 279 // Wide Strings => 64-bit Integers 280 // 281 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 282 extern "C" __int64 __cdecl _wcstoi64( 283 wchar_t const* const string, 284 wchar_t** const end_ptr, 285 int const base 286 ) 287 { 288 return __crt_strtox::parse_integer_from_string<__int64>(string, end_ptr, base, nullptr); 289 } 290 291 extern "C" long long __cdecl wcstoll( 292 wchar_t const* const string, 293 wchar_t** const end_ptr, 294 int const base 295 ) 296 { 297 return __crt_strtox::parse_integer_from_string<long long>(string, end_ptr, base, nullptr); 298 } 299 300 extern "C" intmax_t __cdecl wcstoimax( 301 wchar_t const* const string, 302 wchar_t** const end_ptr, 303 int const base 304 ) 305 { 306 return __crt_strtox::parse_integer_from_string<intmax_t>(string, end_ptr, base, nullptr); 307 } 308 309 310 311 extern "C" __int64 __cdecl _wcstoi64_l( 312 wchar_t const* const string, 313 wchar_t** const end_ptr, 314 int const base, 315 _locale_t const locale 316 ) 317 { 318 return __crt_strtox::parse_integer_from_string<__int64>(string, end_ptr, base, locale); 319 } 320 321 extern "C" long long __cdecl _wcstoll_l( 322 wchar_t const* const string, 323 wchar_t** const end_ptr, 324 int const base, 325 _locale_t const locale 326 ) 327 { 328 return __crt_strtox::parse_integer_from_string<long long>(string, end_ptr, base, locale); 329 } 330 331 extern "C" intmax_t __cdecl _wcstoimax_l( 332 wchar_t const* const string, 333 wchar_t** const end_ptr, 334 int const base, 335 _locale_t const locale 336 ) 337 { 338 return __crt_strtox::parse_integer_from_string<intmax_t>(string, end_ptr, base, locale); 339 } 340 341 342 343 extern "C" unsigned __int64 __cdecl _wcstoui64( 344 wchar_t const* const string, 345 wchar_t** const end_ptr, 346 int const base 347 ) 348 { 349 return __crt_strtox::parse_integer_from_string<unsigned __int64>(string, end_ptr, base, nullptr); 350 } 351 352 extern "C" unsigned long long __cdecl wcstoull( 353 wchar_t const* const string, 354 wchar_t** const end_ptr, 355 int const base 356 ) 357 { 358 return __crt_strtox::parse_integer_from_string<unsigned long long>(string, end_ptr, base, nullptr); 359 } 360 361 extern "C" uintmax_t __cdecl wcstoumax( 362 wchar_t const* const string, 363 wchar_t** const end_ptr, 364 int const base 365 ) 366 { 367 return __crt_strtox::parse_integer_from_string<uintmax_t>(string, end_ptr, base, nullptr); 368 } 369 370 371 372 extern "C" unsigned __int64 __cdecl _wcstoui64_l( 373 wchar_t const* const string, 374 wchar_t** const end_ptr, 375 int const base, 376 _locale_t const locale 377 ) 378 { 379 return __crt_strtox::parse_integer_from_string<unsigned __int64>(string, end_ptr, base, locale); 380 } 381 382 extern "C" unsigned long long __cdecl _wcstoull_l( 383 wchar_t const* const string, 384 wchar_t** const end_ptr, 385 int const base, 386 _locale_t const locale 387 ) 388 { 389 return __crt_strtox::parse_integer_from_string<unsigned long long>(string, end_ptr, base, locale); 390 } 391 392 extern "C" uintmax_t __cdecl _wcstoumax_l( 393 wchar_t const* const string, 394 wchar_t** const end_ptr, 395 int const base, 396 _locale_t const locale 397 ) 398 { 399 return __crt_strtox::parse_integer_from_string<uintmax_t>(string, end_ptr, base, locale); 400 } 401