xref: /reactos/sdk/lib/ucrt/convert/strtox.cpp (revision 04e0dc4a)
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