From a4b138e406d706b2bc1b0a06749903cb5cdd08b1 Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Mon, 20 Sep 2004 17:16:07 +0000 Subject: [PATCH] - Added strtoll() and strtoull(), with further changes to and . git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14729 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/GNUmakefile.68k | 4 +- library/GNUmakefile.os4 | 4 +- library/changes | 4 + library/include/limits.h | 8 +- library/include/stdlib.h | 7 +- library/smakefile | 4 +- library/stdlib_strtoll.c | 204 ++++++++++++++++++++++++++++++++++++++ library/stdlib_strtoull.c | 201 +++++++++++++++++++++++++++++++++++++ 8 files changed, 431 insertions(+), 5 deletions(-) create mode 100644 library/stdlib_strtoll.c create mode 100644 library/stdlib_strtoull.c diff --git a/library/GNUmakefile.68k b/library/GNUmakefile.68k index ebab325..9d093f5 100644 --- a/library/GNUmakefile.68k +++ b/library/GNUmakefile.68k @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.68k,v 1.8 2004-08-25 15:27:27 obarthel Exp $ +# $Id: GNUmakefile.68k,v 1.9 2004-09-20 17:16:06 obarthel Exp $ # # :ts=8 # @@ -307,6 +307,8 @@ C_LIB = \ stdlib_startup.o \ stdlib_strtol.o \ stdlib_strtoul.o \ + stdlib_strtoll.o \ + stdlib_strtoull.o \ stdlib_swapstack.o \ stdlib_sysbase.o \ stdlib_system.o \ diff --git a/library/GNUmakefile.os4 b/library/GNUmakefile.os4 index 45bd26a..5a24b06 100644 --- a/library/GNUmakefile.os4 +++ b/library/GNUmakefile.os4 @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.os4,v 1.6 2004-08-25 15:27:27 obarthel Exp $ +# $Id: GNUmakefile.os4,v 1.7 2004-09-20 17:16:06 obarthel Exp $ # # :ts=8 # @@ -302,6 +302,8 @@ C_LIB = \ stdlib_startup.o \ stdlib_strtol.o \ stdlib_strtoul.o \ + stdlib_strtoll.o \ + stdlib_strtoull.o \ stdlib_swapstack.o \ stdlib_system.o \ stdlib_termination_message.o \ diff --git a/library/changes b/library/changes index 8e6633d..1e76d5e 100644 --- a/library/changes +++ b/library/changes @@ -1,3 +1,7 @@ +- Added strtoll() and strtoull(), with further changes to + and . + + c.lib 1.175 (10.9.2004) - now tries to use the compiler supplied, machine specific diff --git a/library/include/limits.h b/library/include/limits.h index d9aea2c..3259f55 100644 --- a/library/include/limits.h +++ b/library/include/limits.h @@ -1,5 +1,5 @@ /* - * $Id: limits.h,v 1.2 2004-08-07 09:15:33 obarthel Exp $ + * $Id: limits.h,v 1.3 2004-09-20 17:16:07 obarthel Exp $ * * :ts=4 * @@ -58,6 +58,12 @@ /****************************************************************************/ +#define LLONG_MIN (-0x7fffffffffffffffLL-1) +#define LLONG_MAX 0x7fffffffffffffffLL +#define ULLONG_MAX 0xffffffffffffffffULL + +/****************************************************************************/ + #define PATH_MAX 1024 /****************************************************************************/ diff --git a/library/include/stdlib.h b/library/include/stdlib.h index 11046ee..b66f78e 100644 --- a/library/include/stdlib.h +++ b/library/include/stdlib.h @@ -1,5 +1,5 @@ /* - * $Id: stdlib.h,v 1.2 2004-08-07 09:15:33 obarthel Exp $ + * $Id: stdlib.h,v 1.3 2004-09-20 17:16:07 obarthel Exp $ * * :ts=4 * @@ -151,6 +151,11 @@ extern long atol(const char *str); /****************************************************************************/ +extern long long strtoll(const char *str, char **ptr, int base); +extern unsigned long long strtoull(const char *str, char **ptr, int base); + +/****************************************************************************/ + #if defined(__GNUC__) #if defined(alloca) #undef alloca diff --git a/library/smakefile b/library/smakefile index d610aa8..6d2ddd3 100644 --- a/library/smakefile +++ b/library/smakefile @@ -1,5 +1,5 @@ # -# $Id: smakefile,v 1.7 2004-08-25 15:27:27 obarthel Exp $ +# $Id: smakefile,v 1.8 2004-09-20 17:16:06 obarthel Exp $ # # :ts=8 # @@ -415,6 +415,8 @@ STDLIB_OBJ = \ stdlib_strtod.o \ stdlib_strtol.o \ stdlib_strtoul.o \ + stdlib_strtoll.o \ + stdlib_strtoull.o \ stdlib_swapstack.o \ stdlib_system.o \ stdlib_unsetenv.o \ diff --git a/library/stdlib_strtoll.c b/library/stdlib_strtoll.c new file mode 100644 index 0000000..61176fc --- /dev/null +++ b/library/stdlib_strtoll.c @@ -0,0 +1,204 @@ +/* + * $Id: stdlib_strtoll.c,v 1.1 2004-09-20 17:16:06 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2004 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _STDLIB_NULL_POINTER_CHECK_H +#include "stdlib_null_pointer_check.h" +#endif /* _STDLIB_NULL_POINTER_CHECK_H */ + +/****************************************************************************/ + +#ifndef _STDLIB_HEADERS_H +#include "stdlib_headers.h" +#endif /* _STDLIB_HEADERS_H */ + +/****************************************************************************/ + +#if defined(USE_64_BIT_INTS) + +/****************************************************************************/ + +long long +strtoll(const char *str, char **ptr, int base) +{ + BOOL is_negative; + long long result = 0; + long long new_sum; + long long sum; + char c; + + ENTER(); + + SHOWSTRING(str); + SHOWPOINTER(ptr); + SHOWVALUE(base); + + assert(str != NULL && base >= 0); + + #if defined(CHECK_FOR_NULL_POINTERS) + { + if(str == NULL) + { + SHOWMSG("invalid str parameter"); + + errno = EFAULT; + goto out; + } + } + #endif /* CHECK_FOR_NULL_POINTERS */ + + if(base < 0) + { + SHOWMSG("invalid base parameter"); + + errno = ERANGE; + goto out; + } + + /* Skip all leading blanks. */ + while((c = (*str)) != '\0') + { + if(NOT isspace(c)) + break; + + str++; + } + + /* The first character may be a sign. */ + if(c == '-') + { + /* It's a negative number. */ + is_negative = TRUE; + + str++; + } + else + { + /* It's not going to be negative. */ + is_negative = FALSE; + + /* But there may be a sign we will choose to + * ignore. + */ + if(c == '+') + str++; + } + + c = (*str); + + /* There may be a leading '0x' to indicate that what + * follows is a hexadecimal number. + */ + if(base == 0 || base == 16) + { + if((c == '0') && (str[1] == 'x' || str[1] == 'X')) + { + base = 16; + + str += 2; + + c = (*str); + } + } + + /* If we still don't know what base to use and the + * next letter to follow is a zero then this is + * probably a number in octal notation. + */ + if(base == 0) + { + if(c == '0') + base = 8; + else + base = 10; + } + + sum = 0; + + if(1 <= base && base <= 36) + { + while(c != '\0') + { + if('0' <= c && c <= '9') + c -= '0'; + else if ('a' <= c) + c -= 'a' - 10; + else if ('A' <= c) + c -= 'A' - 10; + else + break; + + /* Ignore invalid numbers. */ + if(c >= base) + break; + + new_sum = base * sum + c; + if(new_sum < sum) /* overflow? */ + { + errno = ERANGE; + + if(is_negative) + result = LONG_MIN; + else + result = LONG_MAX; + + goto out; + } + + sum = new_sum; + + str++; + + c = (*str); + } + } + + if(is_negative) + result = (-sum); + else + result = sum; + + out: + + /* If desired, remember where we stopped reading the + * number from the buffer. + */ + if(ptr != NULL) + (*ptr) = (char *)str; + + RETURN(result); + return(result); +} + +/****************************************************************************/ + +#endif /* USE_64_BIT_INTS */ diff --git a/library/stdlib_strtoull.c b/library/stdlib_strtoull.c new file mode 100644 index 0000000..fff438d --- /dev/null +++ b/library/stdlib_strtoull.c @@ -0,0 +1,201 @@ +/* + * $Id: stdlib_strtoull.c,v 1.1 2004-09-20 17:16:06 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2004 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _STDLIB_NULL_POINTER_CHECK_H +#include "stdlib_null_pointer_check.h" +#endif /* _STDLIB_NULL_POINTER_CHECK_H */ + +/****************************************************************************/ + +#ifndef _STDLIB_HEADERS_H +#include "stdlib_headers.h" +#endif /* _STDLIB_HEADERS_H */ + +/****************************************************************************/ + +#if defined(USE_64_BIT_INTS) + +/****************************************************************************/ + +unsigned long long +strtoull(const char *str, char **ptr, int base) +{ + BOOL is_negative; + unsigned long long result = 0; + unsigned long long new_sum; + unsigned long long sum; + char c; + + ENTER(); + + SHOWSTRING(str); + SHOWPOINTER(ptr); + SHOWVALUE(base); + + assert(str != NULL && base >= 0); + + #if defined(CHECK_FOR_NULL_POINTERS) + { + if(str == NULL) + { + SHOWMSG("invalid str parameter"); + + errno = EFAULT; + goto out; + } + } + #endif /* CHECK_FOR_NULL_POINTERS */ + + if(base < 0) + { + SHOWMSG("invalid base parameter"); + + errno = ERANGE; + goto out; + } + + /* Skip all leading blanks. */ + while((c = (*str)) != '\0') + { + if(NOT isspace(c)) + break; + + str++; + } + + /* The first character may be a sign. */ + if(c == '-') + { + /* It's a negative number. */ + is_negative = TRUE; + + str++; + } + else + { + /* It's not going to be negative. */ + is_negative = FALSE; + + /* But there may be a sign we will choose to + * ignore. + */ + if(c == '+') + str++; + } + + c = (*str); + + /* There may be a leading '0x' to indicate that what + * follows is a hexadecimal number. + */ + if(base == 0 || base == 16) + { + if((c == '0') && (str[1] == 'x' || str[1] == 'X')) + { + base = 16; + + str += 2; + + c = (*str); + } + } + + /* If we still don't know what base to use and the + * next letter to follow is a zero then this is + * probably a number in octal notation. + */ + if(base == 0) + { + if(c == '0') + base = 8; + else + base = 10; + } + + sum = 0; + + if(1 <= base && base <= 36) + { + while(c != '\0') + { + if('0' <= c && c <= '9') + c -= '0'; + else if ('a' <= c) + c -= 'a' - 10; + else if ('A' <= c) + c -= 'A' - 10; + else + break; + + /* Ignore invalid numbers. */ + if(c >= base) + break; + + new_sum = base * sum + c; + if(new_sum < sum) /* overflow? */ + { + errno = ERANGE; + + result = ULONG_MAX; + + goto out; + } + + sum = new_sum; + + str++; + + c = (*str); + } + } + + if(is_negative) + result = (-sum); + else + result = sum; + + out: + + /* If desired, remember where we stopped reading the + * number from the buffer. + */ + if(ptr != NULL) + (*ptr) = (char *)str; + + RETURN(result); + return(result); +} + +/****************************************************************************/ + +#endif /* USE_64_BIT_INTS */