Update.
[glibc.git] / stdlib / strtol.c
blob93df6ab6618c8e6d46d81aa8d98c87748915295c
1 /* Convert string representation of a number into an integer value.
2 Copyright (C) 1991, 92, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
20 #if HAVE_CONFIG_H
21 # include <config.h>
22 #endif
24 #ifdef _LIBC
25 # define USE_NUMBER_GROUPING
26 # define STDC_HEADERS
27 # define HAVE_LIMITS_H
28 #endif
30 #include <ctype.h>
31 #include <errno.h>
32 #ifndef errno
33 extern int errno;
34 #endif
35 #ifndef __set_errno
36 # define __set_errno(Val) errno = (Val)
37 #endif
39 #ifdef HAVE_LIMITS_H
40 # include <limits.h>
41 #endif
43 #ifdef STDC_HEADERS
44 # include <stddef.h>
45 # include <stdlib.h>
46 # include <string.h>
47 #else
48 # ifndef NULL
49 # define NULL 0
50 # endif
51 #endif
53 #ifdef USE_NUMBER_GROUPING
54 # include "../locale/localeinfo.h"
55 #endif
57 /* Nonzero if we are defining `strtoul' or `strtoull', operating on
58 unsigned integers. */
59 #ifndef UNSIGNED
60 # define UNSIGNED 0
61 # define INT LONG int
62 #else
63 # define INT unsigned LONG int
64 #endif
66 /* Determine the name. */
67 #ifdef USE_IN_EXTENDED_LOCALE_MODEL
68 # if UNSIGNED
69 # ifdef USE_WIDE_CHAR
70 # ifdef QUAD
71 # define strtol __wcstoull_l
72 # else
73 # define strtol __wcstoul_l
74 # endif
75 # else
76 # ifdef QUAD
77 # define strtol __strtoull_l
78 # else
79 # define strtol __strtoul_l
80 # endif
81 # endif
82 # else
83 # ifdef USE_WIDE_CHAR
84 # ifdef QUAD
85 # define strtol __wcstoll_l
86 # else
87 # define strtol __wcstol_l
88 # endif
89 # else
90 # ifdef QUAD
91 # define strtol __strtoll_l
92 # else
93 # define strtol __strtol_l
94 # endif
95 # endif
96 # endif
97 #else
98 # if UNSIGNED
99 # ifdef USE_WIDE_CHAR
100 # ifdef QUAD
101 # define strtol wcstoull
102 # else
103 # define strtol wcstoul
104 # endif
105 # else
106 # ifdef QUAD
107 # define strtol strtoull
108 # else
109 # define strtol strtoul
110 # endif
111 # endif
112 # else
113 # ifdef USE_WIDE_CHAR
114 # ifdef QUAD
115 # define strtol wcstoll
116 # else
117 # define strtol wcstol
118 # endif
119 # else
120 # ifdef QUAD
121 # define strtol strtoll
122 # endif
123 # endif
124 # endif
125 #endif
127 /* If QUAD is defined, we are defining `strtoll' or `strtoull',
128 operating on `long long int's. */
129 #ifdef QUAD
130 # define LONG long long
131 # define STRTOL_LONG_MIN LONG_LONG_MIN
132 # define STRTOL_LONG_MAX LONG_LONG_MAX
133 # define STRTOL_ULONG_MAX ULONG_LONG_MAX
134 # if __GNUC__ == 2 && __GNUC_MINOR__ < 7
135 /* Work around gcc bug with using this constant. */
136 static const unsigned long long int maxquad = ULONG_LONG_MAX;
137 # undef STRTOL_ULONG_MAX
138 # define STRTOL_ULONG_MAX maxquad
139 # endif
140 #else
141 # define LONG long
143 # ifndef ULONG_MAX
144 # define ULONG_MAX ((unsigned long) ~(unsigned long) 0)
145 # endif
146 # ifndef LONG_MAX
147 # define LONG_MAX ((long int) (ULONG_MAX >> 1))
148 # endif
149 # define STRTOL_LONG_MIN LONG_MIN
150 # define STRTOL_LONG_MAX LONG_MAX
151 # define STRTOL_ULONG_MAX ULONG_MAX
152 #endif
155 /* We use this code also for the extended locale handling where the
156 function gets as an additional argument the locale which has to be
157 used. To access the values we have to redefine the _NL_CURRENT
158 macro. */
159 #ifdef USE_IN_EXTENDED_LOCALE_MODEL
160 # undef _NL_CURRENT
161 # define _NL_CURRENT(category, item) \
162 (current->values[_NL_ITEM_INDEX (item)].string)
163 # define LOCALE_PARAM , loc
164 # define LOCALE_PARAM_DECL __locale_t loc;
165 #else
166 # define LOCALE_PARAM
167 # define LOCALE_PARAM_DECL
168 #endif
170 #if defined _LIBC || defined HAVE_WCHAR_H
171 # include <wchar.h>
172 #endif
174 #ifdef USE_WIDE_CHAR
175 # include <wctype.h>
176 # define L_(Ch) L##Ch
177 # define UCHAR_TYPE wint_t
178 # define STRING_TYPE wchar_t
179 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
180 # define ISSPACE(Ch) __iswspace_l ((Ch), loc)
181 # define ISALPHA(Ch) __iswalpha_l ((Ch), loc)
182 # define TOUPPER(Ch) __towupper_l ((Ch), loc)
183 # else
184 # define ISSPACE(Ch) iswspace (Ch)
185 # define ISALPHA(Ch) iswalpha (Ch)
186 # define TOUPPER(Ch) towupper (Ch)
187 # endif
188 # else
189 # if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
190 # define IN_CTYPE_DOMAIN(c) 1
191 # else
192 # define IN_CTYPE_DOMAIN(c) isascii(c)
193 # endif
194 # define L_(Ch) Ch
195 # define UCHAR_TYPE unsigned char
196 # define STRING_TYPE char
197 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
198 # define ISSPACE(Ch) __isspace_l ((Ch), loc)
199 # define ISALPHA(Ch) __isalpha_l ((Ch), loc)
200 # define TOUPPER(Ch) __toupper_l ((Ch), loc)
201 # else
202 # define ISSPACE(Ch) (IN_CTYPE_DOMAIN (Ch) && isspace (Ch))
203 # define ISALPHA(Ch) (IN_CTYPE_DOMAIN (Ch) && isalpha (Ch))
204 # define TOUPPER(Ch) (IN_CTYPE_DOMAIN (Ch) ? toupper (Ch) : (Ch))
205 # endif
206 #endif
208 #ifdef __STDC__
209 # define INTERNAL(X) INTERNAL1(X)
210 # define INTERNAL1(X) __##X##_internal
211 # define WEAKNAME(X) WEAKNAME1(X)
212 #else
213 # define INTERNAL(X) __/**/X/**/_internal
214 #endif
216 #ifdef USE_NUMBER_GROUPING
217 /* This file defines a function to check for correct grouping. */
218 # include "grouping.h"
219 #endif
223 /* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
224 If BASE is 0 the base is determined by the presence of a leading
225 zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
226 If BASE is < 2 or > 36, it is reset to 10.
227 If ENDPTR is not NULL, a pointer to the character after the last
228 one converted is stored in *ENDPTR. */
231 INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM)
232 const STRING_TYPE *nptr;
233 STRING_TYPE **endptr;
234 int base;
235 int group;
236 LOCALE_PARAM_DECL
238 int negative;
239 register unsigned LONG int cutoff;
240 register unsigned int cutlim;
241 register unsigned LONG int i;
242 register const STRING_TYPE *s;
243 register UCHAR_TYPE c;
244 const STRING_TYPE *save, *end;
245 int overflow;
247 #ifdef USE_NUMBER_GROUPING
248 # ifdef USE_IN_EXTENDED_LOCALE_MODEL
249 struct locale_data *current = loc->__locales[LC_NUMERIC];
250 # endif
251 /* The thousands character of the current locale. */
252 wchar_t thousands = L'\0';
253 /* The numeric grouping specification of the current locale,
254 in the format described in <locale.h>. */
255 const char *grouping;
257 if (group)
259 grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
260 if (*grouping <= 0 || *grouping == CHAR_MAX)
261 grouping = NULL;
262 else
264 /* Figure out the thousands separator character. */
265 # if defined _LIBC || defined _HAVE_BTOWC
266 thousands = __btowc (*_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP));
267 if (thousands == WEOF)
268 thousands = L'\0';
269 # endif
270 if (thousands == L'\0')
271 grouping = NULL;
274 else
275 grouping = NULL;
276 #endif
278 if (base < 0 || base == 1 || base > 36)
280 __set_errno (EINVAL);
281 return 0;
284 save = s = nptr;
286 /* Skip white space. */
287 while (ISSPACE (*s))
288 ++s;
289 if (*s == L_('\0'))
290 goto noconv;
292 /* Check for a sign. */
293 if (*s == L_('-'))
295 negative = 1;
296 ++s;
298 else if (*s == L_('+'))
300 negative = 0;
301 ++s;
303 else
304 negative = 0;
306 /* Recognize number prefix and if BASE is zero, figure it out ourselves. */
307 if (*s == L_('0'))
309 if (TOUPPER (s[1]) == L_('X'))
311 s += 2;
312 base = 16;
314 else if (base == 0)
315 base = 8;
317 else if (base == 0)
318 base = 10;
320 /* Save the pointer so we can check later if anything happened. */
321 save = s;
323 #ifdef USE_NUMBER_GROUPING
324 if (group)
326 /* Find the end of the digit string and check its grouping. */
327 end = s;
328 for (c = *end; c != L_('\0'); c = *++end)
329 if ((wchar_t) c != thousands
330 && ((wchar_t) c < L_('0') || (wchar_t) c > L_('9'))
331 && (!ISALPHA (c) || (int) (TOUPPER (c) - L_('A') + 10) >= base))
332 break;
333 if (*s == thousands)
334 end = s;
335 else
336 end = correctly_grouped_prefix (s, end, thousands, grouping);
338 else
339 #endif
340 end = NULL;
342 cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base;
343 cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base;
345 overflow = 0;
346 i = 0;
347 for (c = *s; c != L_('\0'); c = *++s)
349 if (s == end)
350 break;
351 if (c >= L_('0') && c <= L_('9'))
352 c -= L_('0');
353 else if (ISALPHA (c))
354 c = TOUPPER (c) - L_('A') + 10;
355 else
356 break;
357 if ((int) c >= base)
358 break;
359 /* Check for overflow. */
360 if (i > cutoff || (i == cutoff && c > cutlim))
361 overflow = 1;
362 else
364 i *= (unsigned LONG int) base;
365 i += c;
369 /* Check if anything actually happened. */
370 if (s == save)
371 goto noconv;
373 /* Store in ENDPTR the address of one character
374 past the last character we converted. */
375 if (endptr != NULL)
376 *endptr = (STRING_TYPE *) s;
378 #if !UNSIGNED
379 /* Check for a value that is within the range of
380 `unsigned LONG int', but outside the range of `LONG int'. */
381 if (overflow == 0
382 && i > (negative
383 ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1
384 : (unsigned LONG int) STRTOL_LONG_MAX))
385 overflow = 1;
386 #endif
388 if (overflow)
390 __set_errno (ERANGE);
391 #if UNSIGNED
392 return STRTOL_ULONG_MAX;
393 #else
394 return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX;
395 #endif
398 /* Return the result of the appropriate sign. */
399 return negative ? -i : i;
401 noconv:
402 /* We must handle a special case here: the base is 0 or 16 and the
403 first two characters are '0' and 'x', but the rest are no
404 hexadecimal digits. This is no error case. We return 0 and
405 ENDPTR points to the `x`. */
406 if (endptr != NULL)
408 if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X')
409 && save[-2] == L_('0'))
410 *endptr = (STRING_TYPE *) &save[-1];
411 else
412 /* There was no number to convert. */
413 *endptr = (STRING_TYPE *) nptr;
416 return 0L;
419 /* External user entry point. */
421 #if _LIBC - 0 == 0
422 # undef PARAMS
423 # if defined (__STDC__) && __STDC__
424 # define PARAMS(Args) Args
425 # else
426 # define PARAMS(Args) ()
427 # endif
429 /* Prototype. */
430 INT strtol PARAMS ((const STRING_TYPE *nptr, STRING_TYPE **endptr, int base));
431 #endif
435 #ifdef weak_function
436 weak_function
437 #endif
438 strtol (nptr, endptr, base LOCALE_PARAM)
439 const STRING_TYPE *nptr;
440 STRING_TYPE **endptr;
441 int base;
442 LOCALE_PARAM_DECL
444 return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM);