diff options
-rw-r--r-- | libc/stdlib/Makefile | 20 | ||||
-rw-r--r-- | libc/stdlib/abs.c | 13 | ||||
-rw-r--r-- | libc/stdlib/stdlib.c | 448 | ||||
-rw-r--r-- | libc/stdlib/strto_l.c | 207 | ||||
-rw-r--r-- | libc/stdlib/strto_ll.c | 203 |
5 files changed, 454 insertions, 437 deletions
diff --git a/libc/stdlib/Makefile b/libc/stdlib/Makefile index aaf959bcc..63f2298e9 100644 --- a/libc/stdlib/Makefile +++ b/libc/stdlib/Makefile @@ -27,17 +27,17 @@ include $(TOPDIR)Rules.mak DIRS = $(MALLOC) ALL_SUBDIRS = malloc malloc-930716 malloc-simple -MSRC=strto_l.c -MOBJ=strtol.o strtoul.o strto_l.o atoi.o atol.o +MSRC = stdlib.c +MOBJ = abs.o labs.o atoi.o atol.o strtol.o strtoul.o _stdlib_strto_l.o -MSRC1=strto_ll.c -MOBJ1=strtoll.o strtoull.o strto_ll.o atoll.o +ifeq ($(HAS_LONG_LONG),true) + MOBJ += llabs.o atoll.o strtoll.o strtoull.o _stdlib_strto_ll.o +endif MSRC2=atexit.c MOBJ2=atexit.o on_exit.o __exit_handler.o exit.o - -CSRC = abort.c getenv.c mktemp.c qsort.c realpath.c abs.c bsearch.c \ +CSRC = abort.c getenv.c mktemp.c qsort.c realpath.c bsearch.c \ mkstemp.c putenv.c rand.c random.c setenv.c system.c div.c ldiv.c \ getpt.c ptsname.c grantpt.c unlockpt.c gcvt.c ifeq ($(HAS_FLOATING_POINT),true) @@ -45,11 +45,7 @@ ifeq ($(HAS_FLOATING_POINT),true) endif COBJS=$(patsubst %.c,%.o, $(CSRC)) - OBJS=$(MOBJ) $(MOBJ2) $(COBJS) -ifeq ($(HAS_LONG_LONG),true) - OBJS += $(MOBJ1) -endif all: $(OBJS) $(LIBC) @@ -62,10 +58,6 @@ $(MOBJ): $(MSRC) $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o $(STRIPTOOL) -x -R .note -R .comment $*.o -$(MOBJ1): $(MSRC1) - $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o - $(STRIPTOOL) -x -R .note -R .comment $*.o - $(MOBJ2): $(MSRC2) $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o $(STRIPTOOL) -x -R .note -R .comment $*.o diff --git a/libc/stdlib/abs.c b/libc/stdlib/abs.c deleted file mode 100644 index 044a334b1..000000000 --- a/libc/stdlib/abs.c +++ /dev/null @@ -1,13 +0,0 @@ -/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> - * This file is part of the Linux-8086 C library and is distributed - * under the GNU Library General Public License. - */ -#include <unistd.h> -#include <string.h> -#include <sys/types.h> - -int abs(int arg1) -{ - return arg1 > 0 ? arg1 : -arg1; -} - diff --git a/libc/stdlib/stdlib.c b/libc/stdlib/stdlib.c new file mode 100644 index 000000000..40286f0e5 --- /dev/null +++ b/libc/stdlib/stdlib.c @@ -0,0 +1,448 @@ +/* Copyright (C) 2002 Manuel Novoa III + * From my (incomplete) stdlib library for linux and (soon) elks. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! + * + * This code is currently under development. Also, I plan to port + * it to elks which is a 16-bit environment with a fairly limited + * compiler. Therefore, please refrain from modifying this code + * and, instead, pass any bug-fixes, etc. to me. Thanks. Manuel + * + * ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */ + +#define _ISOC99_SOURCE /* for ULLONG primarily... */ +#define _GNU_SOURCE +#include <stdlib.h> +#include <limits.h> +#include <stdint.h> +#include <inttypes.h> +#include <ctype.h> +#include <errno.h> +#include <assert.h> + +extern unsigned long +_stdlib_strto_l(register const char * __restrict str, + char ** __restrict endptr, int base, int sflag); +extern unsigned long long +_stdlib_strto_ll(register const char * __restrict str, + char ** __restrict endptr, int base, int sflag); + +/* TODO: gcc reports an error due to prototype conflicts. Don't include + * the header for the problem cases? */ +#define HEADER_ALIAS_PROBLEM + +/**********************************************************************/ +#ifdef L_abs + +#ifdef HEADER_ALIAS_PROBLEM +/* #if UINT_MAX < ULONG_MAX */ + +int abs(int j) +{ + return (j >= 0) ? j : -j; +} + +#endif /* UINT_MAX < ULONG_MAX */ + +#endif +/**********************************************************************/ +#ifdef L_labs + +#ifndef HEADER_ALIAS_PROBLEM +/* #if UINT_MAX == ULONG_MAX */ +strong_alias(labs,abs) +#endif + +#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) +strong_alias(labs,llabs) +#endif + +#if ULONG_MAX == UINTMAX_MAX +strong_alias(labs,imaxabs) +#endif + +long int labs(long int j) +{ + return (j >= 0) ? j : -j; +} + +#endif +/**********************************************************************/ +#ifdef L_llabs + +#if defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) + +#if (ULLONG_MAX == UINTMAX_MAX) +strong_alias(llabs,imaxabs) +#endif + +long long int llabs(long long int j) +{ + return (j >= 0) ? j : -j; +} + +#endif /* defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) */ + +#endif +/**********************************************************************/ +#ifdef L_atoi + +#ifdef HEADER_ALIAS_PROBLEM +/* #if UINT_MAX < ULONG_MAX */ + +int atoi(const char *nptr) +{ + return (int) strtol(nptr, (char **) NULL, 10); +} + +#endif /* UINT_MAX < ULONG_MAX */ + +#endif +/**********************************************************************/ +#ifdef L_atol + +#ifndef HEADER_ALIAS_PROBLEM +/* #if UINT_MAX == ULONG_MAX */ +strong_alias(atol,atoi) +#endif + +#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) +strong_alias(atol,atoll) +#endif + +long atol(const char *nptr) +{ + return strtol(nptr, (char **) NULL, 10); +} + +#endif +/**********************************************************************/ +#ifdef L_atoll + +#if defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) + +long long atoll(const char *nptr) +{ + return strtoll(nptr, (char **) NULL, 10); +} + +#endif /* defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) */ + +#endif +/**********************************************************************/ +#ifdef L_strtol + +#if ULONG_MAX == UINTMAX_MAX +strong_alias(strtol,strtoimax) +#endif + +#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) +strong_alias(strtol,strtoll) +#endif + +long strtol(const char * __restrict str, char ** __restrict endptr, int base) +{ + return _stdlib_strto_l(str, endptr, base, 1); +} + +#endif +/**********************************************************************/ +#ifdef L_strtoll + +#if defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) + +#if (ULLONG_MAX == UINTMAX_MAX) +strong_alias(strtoll,strtoimax) +#endif + +long long strtoll(const char * __restrict str, + char ** __restrict endptr, int base) +{ + return (long long) _stdlib_strto_ll(str, endptr, base, 1); +} + +#endif /* defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) */ + +#endif +/**********************************************************************/ +#ifdef L_strtoul + +#if ULONG_MAX == UINTMAX_MAX +strong_alias(strtoul,strtoumax) +#endif + +#if defined(ULLONG_MAX) && (ULLONG_MAX == ULONG_MAX) +strong_alias(strtoul,strtoull) +#endif + +unsigned long strtoul(const char * __restrict str, + char ** __restrict endptr, int base) +{ + return _stdlib_strto_l(str, endptr, base, 0); +} + +#endif +/**********************************************************************/ +#ifdef L_strtoull + +#if defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) + +#if (ULLONG_MAX == UINTMAX_MAX) +strong_alias(strtoull,strtoumax) +#endif + +unsigned long long strtoull(const char * __restrict str, + char ** __restrict endptr, int base) +{ + return _stdlib_strto_ll(str, endptr, base, 0); +} + +#endif /* defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) */ + +#endif +/**********************************************************************/ +/* Support routines follow */ +/**********************************************************************/ +/* Set if we want errno set appropriately. */ +/* NOTE: Implies _STRTO_ENDPTR below */ +#define _STRTO_ERRNO 1 + +/* Set if we want support for the endptr arg. */ +/* Implied by _STRTO_ERRNO. */ +#define _STRTO_ENDPTR 1 + +#if _STRTO_ERRNO +#undef _STRTO_ENDPTR +#define _STRTO_ENDPTR 1 +#define SET_ERRNO(X) __set_errno(X) +#else +#define SET_ERRNO(X) ((void)(X)) /* keep side effects */ +#endif + +/**********************************************************************/ +#ifdef L__stdlib_strto_l + +/* This is the main work fuction which handles both strtol (sflag = 1) and + * strtoul (sflag = 0). */ + +unsigned long _stdlib_strto_l(register const char * __restrict str, + char ** __restrict endptr, int base, int sflag) +{ + unsigned long number, cutoff; +#if _STRTO_ENDPTR + const char *fail_char; +#define SET_FAIL(X) fail_char = (X) +#else +#define SET_FAIL(X) ((void)(X)) /* Keep side effects. */ +#endif + unsigned char negative, digit, cutoff_digit; + + assert((sflag == 0) || (sflag == 1)); + + SET_FAIL(str); + + while (isspace(*str)) { /* Skip leading whitespace. */ + ++str; + } + + /* Handle optional sign. */ + negative = 0; + switch(*str) { + case '-': negative = 1; /* Fall through to increment str. */ + case '+': ++str; + } + + if (!(base & ~0x10)) { /* Either dynamic (base = 0) or base 16. */ + base += 10; /* Default is 10 (26). */ + if (*str == '0') { + SET_FAIL(++str); + base -= 2; /* Now base is 8 or 16 (24). */ + if ((0x20|(*str)) == 'x') { /* WARNING: assumes ascii. */ + ++str; + base += base; /* Base is 16 (16 or 48). */ + } + } + + if (base > 16) { /* Adjust in case base wasn't dynamic. */ + base = 16; + } + } + + number = 0; + + if (((unsigned)(base - 2)) < 35) { /* Legal base. */ + cutoff_digit = ULONG_MAX % base; + cutoff = ULONG_MAX / base; + do { + digit = (((unsigned char)(*str - '0')) <= 9) + ? (*str - '0') + : ((*str >= 'A') + ? (((0x20|(*str)) - 'a' + 10)) /* WARNING: assumes ascii. */ + : 40); + + if (digit >= base) { + break; + } + + SET_FAIL(++str); + + if ((number > cutoff) + || ((number == cutoff) && (digit > cutoff_digit))) { + number = ULONG_MAX; + negative &= sflag; + SET_ERRNO(ERANGE); + } else { + number = number * base + digit; + } + } while (1); + } + +#if _STRTO_ENDPTR + if (endptr) { + *endptr = (char *) fail_char; + } +#endif + + { + unsigned long tmp = ((negative) + ? ((unsigned long)(-(1+LONG_MIN)))+1 + : LONG_MAX); + if (sflag && (number > tmp)) { + number = tmp; + SET_ERRNO(ERANGE); + } + } + + return negative ? (unsigned long)(-((long)number)) : number; +} + +#endif +/**********************************************************************/ +#ifdef L__stdlib_strto_ll + +#if defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) + +/* This is the main work fuction which handles both strtoll (sflag = 1) and + * strtoull (sflag = 0). */ + +unsigned long long _stdlib_strto_ll(register const char * __restrict str, + char ** __restrict endptr, int base, + int sflag) +{ + unsigned long long number; +#if _STRTO_ENDPTR + const char *fail_char; +#define SET_FAIL(X) fail_char = (X) +#else +#define SET_FAIL(X) ((void)(X)) /* Keep side effects. */ +#endif + unsigned int n1; + unsigned char negative, digit; + + assert((sflag == 0) || (sflag == 1)); + + SET_FAIL(str); + + while (isspace(*str)) { /* Skip leading whitespace. */ + ++str; + } + + /* Handle optional sign. */ + negative = 0; + switch(*str) { + case '-': negative = 1; /* Fall through to increment str. */ + case '+': ++str; + } + + if (!(base & ~0x10)) { /* Either dynamic (base = 0) or base 16. */ + base += 10; /* Default is 10 (26). */ + if (*str == '0') { + SET_FAIL(++str); + base -= 2; /* Now base is 8 or 16 (24). */ + if ((0x20|(*str)) == 'x') { /* WARNING: assumes ascii. */ + ++str; + base += base; /* Base is 16 (16 or 48). */ + } + } + + if (base > 16) { /* Adjust in case base wasn't dynamic. */ + base = 16; + } + } + + number = 0; + + if (((unsigned)(base - 2)) < 35) { /* Legal base. */ + do { + digit = (((unsigned char)(*str - '0')) <= 9) + ? (*str - '0') + : ((*str >= 'A') + ? (((0x20|(*str)) - 'a' + 10)) /* WARNING: assumes ascii. */ + : 40); + + if (digit >= base) { + break; + } + + SET_FAIL(++str); + +#if 1 + /* Optional, but speeds things up in the usual case. */ + if (number <= (ULLONG_MAX >> 6)) { + number = number * base + digit; + } else +#endif + { + n1 = ((unsigned char) number) * base + digit; + number = (number >> CHAR_BIT) * base; + + if (number + (n1 >> CHAR_BIT) <= (ULLONG_MAX >> CHAR_BIT)) { + number = (number << CHAR_BIT) + n1; + } else { /* Overflow. */ + number = ULLONG_MAX; + negative &= sflag; + SET_ERRNO(ERANGE); + } + } + + } while (1); + } + +#if _STRTO_ENDPTR + if (endptr) { + *endptr = (char *) fail_char; + } +#endif + + { + unsigned long long tmp = ((negative) + ? ((unsigned long long)(-(1+LLONG_MIN)))+1 + : LLONG_MAX); + if (sflag && (number > tmp)) { + number = tmp; + SET_ERRNO(ERANGE); + } + } + + return negative ? (unsigned long long)(-((long long)number)) : number; +} + +#endif /* defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX) */ + +#endif +/**********************************************************************/ diff --git a/libc/stdlib/strto_l.c b/libc/stdlib/strto_l.c deleted file mode 100644 index 666433927..000000000 --- a/libc/stdlib/strto_l.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (C) 2000 Manuel Novoa III - * - * Notes: - * - * The primary objective of this implementation was minimal size. - * - * Note: Assumes char layout 0-9.*A-Z.*a-z for ordinals values. - * - * There are a couple of compile-time options below. - * - */ - -/*****************************************************************************/ -/* OPTIONS */ -/*****************************************************************************/ - -/* Set if we want errno set appropriately. */ -/* NOTE: Implies _STRTO_ENDPTR below */ -#define _STRTO_ERRNO 0 - -/* Set if we want support for the endptr arg. */ -/* Implied by _STRTO_ERRNO. */ -#define _STRTO_ENDPTR 1 - -/*****************************************************************************/ -/* Don't change anything that follows. */ -/*****************************************************************************/ - -#if _STRTO_ERRNO -#undef _STRTO_ENDPTR -#define _STRTO_ENDPTR 1 -#endif - -/*****************************************************************************/ - -/* Are there actually any machines where this might fail? */ -#if 'A' > 'a' -#error ordering assumption violated : 'A' > 'a' -#endif - -#include <stdlib.h> -#include <limits.h> -#include <ctype.h> - -#if _STRTO_ERRNO -#include <errno.h> -#endif - -unsigned long _strto_l(const char *str, char **endptr, int base, int uflag); - -#if L_strto_l - -/* - * This is the main work fuction which handles both strtol (uflag = 0) and - * strtoul (uflag = 1). - */ - -unsigned long _strto_l(const char *str, char **endptr, int base, int uflag) -{ - unsigned long number = 0; - unsigned long cutoff; - char *pos = (char *) str; -#if _STRTO_ENDPTR - char *fail_char = (char *) str; -#endif - int digit, cutoff_digit; - int negative; - - while (isspace(*pos)) { /* skip leading whitespace */ - ++pos; - } - - /* handle optional sign */ - negative = 0; - switch(*pos) { - case '-': negative = 1; /* fall through to increment pos */ - case '+': ++pos; - } - - if ((base == 16) && (*pos == '0')) { /* handle option prefix */ - ++pos; -#if _STRTO_ENDPTR - fail_char = pos; -#endif - if ((*pos == 'x') || (*pos == 'X')) { - ++pos; - } - } - - if (base == 0) { /* dynamic base */ - base = 10; /* default is 10 */ - if (*pos == '0') { - ++pos; - base -= 2; /* now base is 8 (or 16) */ -#if _STRTO_ENDPTR - fail_char = pos; -#endif - if ((*pos == 'x') || (*pos == 'X')) { - base += 8; /* base is 16 */ - ++pos; - } - } - } - - if ((base < 2) || (base > 36)) { /* illegal base */ - goto DONE; - } - - cutoff_digit = ULONG_MAX % base; - cutoff = ULONG_MAX / base; - - while (1) { - digit = 40; - if ((*pos >= '0') && (*pos <= '9')) { - digit = (*pos - '0'); - } else if (*pos >= 'a') { - digit = (*pos - 'a' + 10); - } else if (*pos >= 'A') { - digit = (*pos - 'A' + 10); - } else break; - - if (digit >= base) { - break; - } - - ++pos; -#if _STRTO_ENDPTR - fail_char = pos; -#endif - - /* adjust number, with overflow check */ - if ((number > cutoff) - || ((number == cutoff) && (digit > cutoff_digit))) { - number = ULONG_MAX; - if (uflag) { - negative = 0; /* since unsigned returns ULONG_MAX */ - } -#if _STRTO_ERRNO - __set_errno(ERANGE); -#endif - } else { - number = number * base + digit; - } - - } - - DONE: -#if _STRTO_ENDPTR - if (endptr) { - *endptr = fail_char; - } -#endif - - if (negative) { - if (!uflag && (number > ((unsigned long)(-(1+LONG_MIN)))+1)) { -#if _STRTO_ERRNO - __set_errno(ERANGE); -#endif - return (unsigned long) LONG_MIN; - } - return (unsigned long)(-((long)number)); - } else { - if (!uflag && (number > (unsigned long) LONG_MAX)) { -#if _STRTO_ERRNO - __set_errno(ERANGE); -#endif - return LONG_MAX; - } - return number; - } -} - -#endif - -#if L_strtoul - -unsigned long strtoul(const char *str, char **endptr, int base) -{ - return _strto_l(str, endptr, base, 1); -} - -#endif - -#if L_strtol -long strtol(const char *str, char **endptr, int base) -{ - return _strto_l(str, endptr, base, 0); -} - -#endif - -#ifdef L_atoi -int atoi(const char *str) -{ - return((int)_strto_l((str),(char**)0,10, 0)); - -} -#endif - -#ifdef L_atol -long atol(const char *str) -{ - return(_strto_l((str),(char**)0,10, 0)); -} -#endif - diff --git a/libc/stdlib/strto_ll.c b/libc/stdlib/strto_ll.c deleted file mode 100644 index 76a1a95b3..000000000 --- a/libc/stdlib/strto_ll.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2000 Manuel Novoa III - * - * Notes: - * - * The primary objective of this implementation was minimal size. - * - * Note: Assumes char layout 0-9.*A-Z.*a-z for ordinals values. - * - * There are a couple of compile-time options below. - * - */ - -/*****************************************************************************/ -/* OPTIONS */ -/*****************************************************************************/ - -/* Set if we want errno set appropriately. */ -/* NOTE: Implies _STRTO_ENDPTR below */ -#define _STRTO_ERRNO 0 - -/* Set if we want support for the endptr arg. */ -/* Implied by _STRTO_ERRNO. */ -#define _STRTO_ENDPTR 1 - -/*****************************************************************************/ -/* Don't change anything that follows. */ -/*****************************************************************************/ - -#if _STRTO_ERRNO -#undef _STRTO_ENDPTR -#define _STRTO_ENDPTR 1 -#endif - -/*****************************************************************************/ - -/* Are there actually any machines where this might fail? */ -#if 'A' > 'a' -#error ordering assumption violated : 'A' > 'a' -#endif - -#include <stdlib.h> -#define __USE_GNU -#include <limits.h> -#include <ctype.h> - -#if _STRTO_ERRNO -#include <errno.h> -#endif - -unsigned long long _strto_ll(const char *str, char **endptr, int base, int uflag); - -#if L_strto_ll - -/* - * This is the main work fuction which handles both strtol (uflag = 0) and - * strtoul (uflag = 1). - */ - -unsigned long long _strto_ll(const char *str, char **endptr, int base, int uflag) -{ - unsigned long long number = 0; - unsigned long long cutoff; - char *pos = (char *) str; -#if _STRTO_ENDPTR - char *fail_char = (char *) str; -#endif - int digit, cutoff_digit; - int negative; - - while (isspace(*pos)) { /* skip leading whitespace */ - ++pos; - } - - /* handle optional sign */ - negative = 0; - switch(*pos) { - case '-': negative = 1; /* fall through to increment pos */ - case '+': ++pos; - } - - if ((base == 16) && (*pos == '0')) { /* handle option prefix */ - ++pos; -#if _STRTO_ENDPTR - fail_char = pos; -#endif - if ((*pos == 'x') || (*pos == 'X')) { - ++pos; - } - } - - if (base == 0) { /* dynamic base */ - base = 10; /* default is 10 */ - if (*pos == '0') { - ++pos; - base -= 2; /* now base is 8 (or 16) */ -#if _STRTO_ENDPTR - fail_char = pos; -#endif - if ((*pos == 'x') || (*pos == 'X')) { - base += 8; /* base is 16 */ - ++pos; - } - } - } - - if ((base < 2) || (base > 36)) { /* illegal base */ - goto DONE; - } - - cutoff_digit = ULONG_LONG_MAX % base; - cutoff = ULONG_LONG_MAX / base; - - while (1) { - digit = 40; - if ((*pos >= '0') && (*pos <= '9')) { - digit = (*pos - '0'); - } else if (*pos >= 'a') { - digit = (*pos - 'a' + 10); - } else if (*pos >= 'A') { - digit = (*pos - 'A' + 10); - } else break; - - if (digit >= base) { - break; - } - - ++pos; -#if _STRTO_ENDPTR - fail_char = pos; -#endif - - /* adjust number, with overflow check */ - if ((number > cutoff) - || ((number == cutoff) && (digit > cutoff_digit))) { - number = ULONG_LONG_MAX; - if (uflag) { - negative = 0; /* since unsigned returns ULONG_LONG_MAX */ - } -#if _STRTO_ERRNO - __set_errno(ERANGE); -#endif - } else { - number = number * base + digit; - } - - } - - DONE: -#if _STRTO_ENDPTR - if (endptr) { - *endptr = fail_char; - } -#endif - - if (negative) { - if (!uflag && (number > ((unsigned long long)(-(1+LONG_LONG_MIN)))+1)) { -#if _STRTO_ERRNO - __set_errno(ERANGE); -#endif - return (unsigned long long) LONG_LONG_MIN; - } - return (unsigned long long)(-((long long)number)); - } else { - if (!uflag && (number > (unsigned long long) LONG_LONG_MAX)) { -#if _STRTO_ERRNO - __set_errno(ERANGE); -#endif - return LONG_LONG_MAX; - } - return number; - } -} - -#endif - -#if L_strtoull - -unsigned long long strtoull(const char *str, char **endptr, int base) -{ - return _strto_ll(str, endptr, base, 1); -} - -#endif - -#if L_strtoll - -long long strtoll(const char *str, char **endptr, int base) -{ - return _strto_ll(str, endptr, base, 0); -} - -#endif - -#ifdef L_atoll -long long atoll(const char *str) -{ - return(_strto_ll((str),(char**)0,10,0)); -} -#endif - - - |