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