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