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