This source file includes following definitions.
- strtol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #ifdef _LIBC
23 # define USE_NUMBER_GROUPING
24 #else
25 # include <config.h>
26 #endif
27
28 #include <ctype.h>
29 #include <errno.h>
30 #ifndef __set_errno
31 # define __set_errno(Val) errno = (Val)
32 #endif
33
34 #include <limits.h>
35 #include <stddef.h>
36 #include <stdlib.h>
37 #include <string.h>
38
39 #ifdef USE_NUMBER_GROUPING
40 # include "../locale/localeinfo.h"
41 #endif
42
43
44
45 #ifndef UNSIGNED
46 # define UNSIGNED 0
47 # define INT LONG int
48 #else
49 # define INT unsigned LONG int
50 #endif
51
52
53 #ifdef USE_IN_EXTENDED_LOCALE_MODEL
54 # undef strtol
55 # if UNSIGNED
56 # ifdef USE_WIDE_CHAR
57 # ifdef QUAD
58 # define strtol __wcstoull_l
59 # else
60 # define strtol __wcstoul_l
61 # endif
62 # else
63 # ifdef QUAD
64 # define strtol __strtoull_l
65 # else
66 # define strtol __strtoul_l
67 # endif
68 # endif
69 # else
70 # ifdef USE_WIDE_CHAR
71 # ifdef QUAD
72 # define strtol __wcstoll_l
73 # else
74 # define strtol __wcstol_l
75 # endif
76 # else
77 # ifdef QUAD
78 # define strtol __strtoll_l
79 # else
80 # define strtol __strtol_l
81 # endif
82 # endif
83 # endif
84 #else
85 # if UNSIGNED
86 # undef strtol
87 # ifdef USE_WIDE_CHAR
88 # ifdef QUAD
89 # define strtol wcstoull
90 # else
91 # define strtol wcstoul
92 # endif
93 # else
94 # ifdef QUAD
95 # define strtol strtoull
96 # else
97 # define strtol strtoul
98 # endif
99 # endif
100 # else
101 # ifdef USE_WIDE_CHAR
102 # undef strtol
103 # ifdef QUAD
104 # define strtol wcstoll
105 # else
106 # define strtol wcstol
107 # endif
108 # else
109 # ifdef QUAD
110 # undef strtol
111 # define strtol strtoll
112 # endif
113 # endif
114 # endif
115 #endif
116
117
118
119 #ifdef QUAD
120 # define LONG long long
121 # define STRTOL_LONG_MIN LLONG_MIN
122 # define STRTOL_LONG_MAX LLONG_MAX
123 # define STRTOL_ULONG_MAX ULLONG_MAX
124 # if __GNUC__ == 2 && __GNUC_MINOR__ < 7
125
126 static const unsigned long long int maxquad = ULLONG_MAX;
127 # undef STRTOL_ULONG_MAX
128 # define STRTOL_ULONG_MAX maxquad
129 # endif
130 #else
131 # define LONG long
132 # define STRTOL_LONG_MIN LONG_MIN
133 # define STRTOL_LONG_MAX LONG_MAX
134 # define STRTOL_ULONG_MAX ULONG_MAX
135 #endif
136
137
138 #ifdef USE_NUMBER_GROUPING
139 # define GROUP_PARAM_PROTO , int group
140 #else
141 # define GROUP_PARAM_PROTO
142 #endif
143
144
145
146
147
148 #ifdef USE_IN_EXTENDED_LOCALE_MODEL
149 # undef _NL_CURRENT
150 # define _NL_CURRENT(category, item) \
151 (current->values[_NL_ITEM_INDEX (item)].string)
152 # define LOCALE_PARAM , loc
153 # define LOCALE_PARAM_PROTO , __locale_t loc
154 #else
155 # define LOCALE_PARAM
156 # define LOCALE_PARAM_PROTO
157 #endif
158
159 #ifdef USE_WIDE_CHAR
160 # include <wchar.h>
161 # include <wctype.h>
162 # define L_(Ch) L##Ch
163 # define UCHAR_TYPE wint_t
164 # define STRING_TYPE wchar_t
165 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
166 # define ISSPACE(Ch) __iswspace_l ((Ch), loc)
167 # define ISALPHA(Ch) __iswalpha_l ((Ch), loc)
168 # define TOUPPER(Ch) __towupper_l ((Ch), loc)
169 # else
170 # define ISSPACE(Ch) iswspace (Ch)
171 # define ISALPHA(Ch) iswalpha (Ch)
172 # define TOUPPER(Ch) towupper (Ch)
173 # endif
174 #else
175 # define L_(Ch) Ch
176 # define UCHAR_TYPE unsigned char
177 # define STRING_TYPE char
178 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
179 # define ISSPACE(Ch) __isspace_l ((unsigned char) (Ch), loc)
180 # define ISALPHA(Ch) __isalpha_l ((unsigned char) (Ch), loc)
181 # define TOUPPER(Ch) __toupper_l ((unsigned char) (Ch), loc)
182 # else
183 # define ISSPACE(Ch) isspace ((unsigned char) (Ch))
184 # define ISALPHA(Ch) isalpha ((unsigned char) (Ch))
185 # define TOUPPER(Ch) toupper ((unsigned char) (Ch))
186 # endif
187 #endif
188
189 #ifdef USE_NUMBER_GROUPING
190 # define INTERNAL(X) INTERNAL1(X)
191 # define INTERNAL1(X) __##X##_internal
192 # define WEAKNAME(X) WEAKNAME1(X)
193 #else
194 # define INTERNAL(X) X
195 #endif
196
197 #ifdef USE_NUMBER_GROUPING
198
199 # include "grouping.h"
200 #endif
201
202
203
204
205
206
207
208
209
210
211 INT
212 INTERNAL (strtol) (const STRING_TYPE *nptr, STRING_TYPE **endptr,
213 int base GROUP_PARAM_PROTO LOCALE_PARAM_PROTO)
214 {
215 int negative;
216 register unsigned LONG int cutoff;
217 register unsigned int cutlim;
218 register unsigned LONG int i;
219 register const STRING_TYPE *s;
220 register UCHAR_TYPE c;
221 const STRING_TYPE *save, *end;
222 int overflow;
223
224 #ifdef USE_NUMBER_GROUPING
225 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
226 struct locale_data *current = loc->__locales[LC_NUMERIC];
227 # endif
228
229 wchar_t thousands = L'\0';
230
231
232 const char *grouping;
233
234 if (group)
235 {
236 grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
237 if (*grouping <= 0 || *grouping == CHAR_MAX)
238 grouping = NULL;
239 else
240 {
241
242 # if defined _LIBC || defined _HAVE_BTOWC
243 thousands = __btowc (*_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP));
244 if (thousands == WEOF)
245 thousands = L'\0';
246 # endif
247 if (thousands == L'\0')
248 grouping = NULL;
249 }
250 }
251 else
252 grouping = NULL;
253 #endif
254
255 if (base < 0 || base == 1 || base > 36)
256 {
257 __set_errno (EINVAL);
258 return 0;
259 }
260
261 save = s = nptr;
262
263
264 while (ISSPACE (*s))
265 ++s;
266 if (*s == L_('\0'))
267 goto noconv;
268
269
270 if (*s == L_('-'))
271 {
272 negative = 1;
273 ++s;
274 }
275 else if (*s == L_('+'))
276 {
277 negative = 0;
278 ++s;
279 }
280 else
281 negative = 0;
282
283
284 if (*s == L_('0'))
285 {
286 if ((base == 0 || base == 16) && TOUPPER (s[1]) == L_('X'))
287 {
288 s += 2;
289 base = 16;
290 }
291 else if ((base == 0 || base == 2) && TOUPPER (s[1]) == L_('B'))
292 {
293 s += 2;
294 base = 2;
295 }
296 else if (base == 0)
297 base = 8;
298 }
299 else if (base == 0)
300 base = 10;
301
302
303 save = s;
304
305 #ifdef USE_NUMBER_GROUPING
306 if (group)
307 {
308
309 end = s;
310 for (c = *end; c != L_('\0'); c = *++end)
311 if ((wchar_t) c != thousands
312 && ((wchar_t) c < L_('0') || (wchar_t) c > L_('9'))
313 && (!ISALPHA (c) || (int) (TOUPPER (c) - L_('A') + 10) >= base))
314 break;
315 if (*s == thousands)
316 end = s;
317 else
318 end = correctly_grouped_prefix (s, end, thousands, grouping);
319 }
320 else
321 #endif
322 end = NULL;
323
324 cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base;
325 cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base;
326
327 overflow = 0;
328 i = 0;
329 for (c = *s; c != L_('\0'); c = *++s)
330 {
331 if (s == end)
332 break;
333 if (c >= L_('0') && c <= L_('9'))
334 c -= L_('0');
335 else if (ISALPHA (c))
336 c = TOUPPER (c) - L_('A') + 10;
337 else
338 break;
339 if ((int) c >= base)
340 break;
341
342 if (i > cutoff || (i == cutoff && c > cutlim))
343 overflow = 1;
344 else
345 {
346 i *= (unsigned LONG int) base;
347 i += c;
348 }
349 }
350
351
352 if (s == save)
353 goto noconv;
354
355
356
357 if (endptr != NULL)
358 *endptr = (STRING_TYPE *) s;
359
360 #if !UNSIGNED
361
362
363 if (overflow == 0
364 && i > (negative
365 ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1
366 : (unsigned LONG int) STRTOL_LONG_MAX))
367 overflow = 1;
368 #endif
369
370 if (overflow)
371 {
372 __set_errno (ERANGE);
373 #if UNSIGNED
374 return STRTOL_ULONG_MAX;
375 #else
376 return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX;
377 #endif
378 }
379
380
381 return negative ? -i : i;
382
383 noconv:
384
385
386
387
388
389
390 if (endptr != NULL)
391 {
392 if (save - nptr >= 2
393 && (TOUPPER (save[-1]) == L_('X') || TOUPPER (save[-1]) == L_('B'))
394 && save[-2] == L_('0'))
395 *endptr = (STRING_TYPE *) &save[-1];
396 else
397
398 *endptr = (STRING_TYPE *) nptr;
399 }
400
401 return 0L;
402 }
403
404 #ifdef USE_NUMBER_GROUPING
405
406
407 INT
408 # ifdef weak_function
409 weak_function
410 # endif
411 strtol (const STRING_TYPE *nptr, STRING_TYPE **endptr,
412 int base LOCALE_PARAM_PROTO)
413 {
414 return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM);
415 }
416 #endif