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