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)
292 base = 8;
293 }
294 else if (base == 0)
295 base = 10;
296
297
298 save = s;
299
300 #ifdef USE_NUMBER_GROUPING
301 if (group)
302 {
303
304 end = s;
305 for (c = *end; c != L_('\0'); c = *++end)
306 if ((wchar_t) c != thousands
307 && ((wchar_t) c < L_('0') || (wchar_t) c > L_('9'))
308 && (!ISALPHA (c) || (int) (TOUPPER (c) - L_('A') + 10) >= base))
309 break;
310 if (*s == thousands)
311 end = s;
312 else
313 end = correctly_grouped_prefix (s, end, thousands, grouping);
314 }
315 else
316 #endif
317 end = NULL;
318
319 cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base;
320 cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base;
321
322 overflow = 0;
323 i = 0;
324 for (c = *s; c != L_('\0'); c = *++s)
325 {
326 if (s == end)
327 break;
328 if (c >= L_('0') && c <= L_('9'))
329 c -= L_('0');
330 else if (ISALPHA (c))
331 c = TOUPPER (c) - L_('A') + 10;
332 else
333 break;
334 if ((int) c >= base)
335 break;
336
337 if (i > cutoff || (i == cutoff && c > cutlim))
338 overflow = 1;
339 else
340 {
341 i *= (unsigned LONG int) base;
342 i += c;
343 }
344 }
345
346
347 if (s == save)
348 goto noconv;
349
350
351
352 if (endptr != NULL)
353 *endptr = (STRING_TYPE *) s;
354
355 #if !UNSIGNED
356
357
358 if (overflow == 0
359 && i > (negative
360 ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1
361 : (unsigned LONG int) STRTOL_LONG_MAX))
362 overflow = 1;
363 #endif
364
365 if (overflow)
366 {
367 __set_errno (ERANGE);
368 #if UNSIGNED
369 return STRTOL_ULONG_MAX;
370 #else
371 return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX;
372 #endif
373 }
374
375
376 return negative ? -i : i;
377
378 noconv:
379
380
381
382
383 if (endptr != NULL)
384 {
385 if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X')
386 && save[-2] == L_('0'))
387 *endptr = (STRING_TYPE *) &save[-1];
388 else
389
390 *endptr = (STRING_TYPE *) nptr;
391 }
392
393 return 0L;
394 }
395
396 #ifdef USE_NUMBER_GROUPING
397
398
399 INT
400 # ifdef weak_function
401 weak_function
402 # endif
403 strtol (const STRING_TYPE *nptr, STRING_TYPE **endptr,
404 int base LOCALE_PARAM_PROTO)
405 {
406 return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM);
407 }
408 #endif