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 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
strtol(char const * const string,char ** const end_ptr,int const base)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
_strtol_l(char const * const string,char ** const end_ptr,int const base,_locale_t const locale)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
strtoul(char const * const string,char ** const end_ptr,int const base)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
_strtoul_l(char const * const string,char ** const end_ptr,int const base,_locale_t const locale)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 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
_strtoi64(char const * const string,char ** const end_ptr,int const base)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
strtoll(char const * const string,char ** const end_ptr,int const base)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
strtoimax(char const * const string,char ** const end_ptr,int const base)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
_strtoi64_l(char const * const string,char ** const end_ptr,int const base,_locale_t const locale)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
_strtoll_l(char const * const string,char ** const end_ptr,int const base,_locale_t const locale)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
_strtoimax_l(char const * const string,char ** const end_ptr,int const base,_locale_t const locale)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
_strtoui64(char const * const string,char ** const end_ptr,int const base)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
strtoull(char const * const string,char ** const end_ptr,int const base)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
strtoumax(char const * const string,char ** const end_ptr,int const base)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
_strtoui64_l(char const * const string,char ** const end_ptr,int const base,_locale_t const locale)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
_strtoull_l(char const * const string,char ** const end_ptr,int const base,_locale_t const locale)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
_strtoumax_l(char const * const string,char ** const end_ptr,int const base,_locale_t const locale)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 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
wcstol(wchar_t const * const string,wchar_t ** const end_ptr,int const base)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
_wcstol_l(wchar_t const * const string,wchar_t ** const end_ptr,int const base,_locale_t const locale)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
wcstoul(wchar_t const * const string,wchar_t ** const end_ptr,int const base)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
_wcstoul_l(wchar_t const * const string,wchar_t ** const end_ptr,int const base,_locale_t const locale)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 //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
_wcstoi64(wchar_t const * const string,wchar_t ** const end_ptr,int const base)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
wcstoll(wchar_t const * const string,wchar_t ** const end_ptr,int const base)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
wcstoimax(wchar_t const * const string,wchar_t ** const end_ptr,int const base)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
_wcstoi64_l(wchar_t const * const string,wchar_t ** const end_ptr,int const base,_locale_t const locale)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
_wcstoll_l(wchar_t const * const string,wchar_t ** const end_ptr,int const base,_locale_t const locale)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
_wcstoimax_l(wchar_t const * const string,wchar_t ** const end_ptr,int const base,_locale_t const locale)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
_wcstoui64(wchar_t const * const string,wchar_t ** const end_ptr,int const base)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
wcstoull(wchar_t const * const string,wchar_t ** const end_ptr,int const base)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
wcstoumax(wchar_t const * const string,wchar_t ** const end_ptr,int const base)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
_wcstoui64_l(wchar_t const * const string,wchar_t ** const end_ptr,int const base,_locale_t const locale)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
_wcstoull_l(wchar_t const * const string,wchar_t ** const end_ptr,int const base,_locale_t const locale)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
_wcstoumax_l(wchar_t const * const string,wchar_t ** const end_ptr,int const base,_locale_t const locale)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