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