Reactos
at master 400 lines 11 kB view raw
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//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 63extern "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 72extern "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 84extern "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 93extern "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//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 110extern "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 119extern "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 128extern "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 139extern "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 149extern "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 159extern "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 171extern "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 180extern "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 189extern "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 200extern "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 210extern "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 220extern "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//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 237extern "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 246extern "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 256extern "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 265extern "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//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 282extern "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 291extern "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 300extern "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 311extern "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 321extern "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 331extern "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 343extern "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 352extern "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 361extern "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 372extern "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 382extern "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 392extern "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}