From e01d58319deb469c050e85d4921f2564feb107a4 Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Sat, 7 May 2005 13:21:49 +0000 Subject: [PATCH] - Added strtof(), llabs(), lldiv(), vsscanf() and vscanf() for C99. - strftime() now supports %C, %n, %r, %R, %t, %T, %u, %V, and %z for C99. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14930 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/GNUmakefile.68k | 9 +- library/GNUmakefile.os4 | 9 +- library/changes | 6 +- library/include/stdio.h | 4 +- library/include/stdlib.h | 41 +++-- library/smakefile | 5 +- library/stdio_scanf.c | 4 +- library/stdio_sscanf.c | 20 +-- library/stdio_vscanf.c | 78 ++++++++++ library/stdio_vsscanf.c | 92 +++++++++++ library/stdlib_llabs.c | 48 ++++++ library/stdlib_lldiv.c | 51 +++++++ library/stdlib_strtof.c | 323 +++++++++++++++++++++++++++++++++++++++ library/time_strftime.c | 86 ++++++++++- 14 files changed, 739 insertions(+), 37 deletions(-) create mode 100644 library/stdio_vscanf.c create mode 100644 library/stdio_vsscanf.c create mode 100644 library/stdlib_llabs.c create mode 100644 library/stdlib_lldiv.c create mode 100644 library/stdlib_strtof.c diff --git a/library/GNUmakefile.68k b/library/GNUmakefile.68k index 6d351cf..b382963 100644 --- a/library/GNUmakefile.68k +++ b/library/GNUmakefile.68k @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.68k,v 1.49 2005-04-24 14:04:36 obarthel Exp $ +# $Id: GNUmakefile.68k,v 1.50 2005-05-07 13:21:49 obarthel Exp $ # # :ts=8 # @@ -269,6 +269,8 @@ C_LIB = \ stdio_vsnprintf_hook_entry.o \ stdio_vsprintf.o \ stdio_vsprintf_hook_entry.o \ + stdio_vsscanf.o \ + stdio_vscanf.o \ stdlib_abort.o \ stdlib_abs.o \ stdlib_alloca.o \ @@ -300,7 +302,9 @@ C_LIB = \ stdlib_init_exit.o \ stdlib_isresident.o \ stdlib_labs.o \ + stdlib_llabs.o \ stdlib_ldiv.o \ + stdlib_lldiv.o \ stdlib_machine_test.o \ stdlib_main.o \ stdlib_malloc.o \ @@ -553,11 +557,14 @@ MATH_LIB = \ stdio_vasprintf.o \ stdio_vfprintf.o \ stdio_vfscanf.o \ + stdio_vsscanf.o \ + stdio_vscanf.o \ stdio_vprintf.o \ stdio_vsnprintf.o \ stdio_vsprintf.o \ stdlib_atof.o \ stdlib_strtod.o \ + stdlib_strtof.o \ time_difftime.o MATH_LIB_881 = \ diff --git a/library/GNUmakefile.os4 b/library/GNUmakefile.os4 index c89def8..f50da1b 100644 --- a/library/GNUmakefile.os4 +++ b/library/GNUmakefile.os4 @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.os4,v 1.52 2005-04-16 10:11:26 obarthel Exp $ +# $Id: GNUmakefile.os4,v 1.53 2005-05-07 13:21:49 obarthel Exp $ # # :ts=8 # @@ -262,6 +262,8 @@ C_LIB = \ stdio_vasprintf_hook_entry.o \ stdio_vfprintf.o \ stdio_vfscanf.o \ + stdio_vsscanf.o \ + stdio_vscanf.o \ stdio_vprintf.o \ stdio_vsnprintf.o \ stdio_vsnprintf_hook_entry.o \ @@ -298,7 +300,9 @@ C_LIB = \ stdlib_init_exit.o \ stdlib_isresident.o \ stdlib_labs.o \ + stdlib_llabs.o \ stdlib_ldiv.o \ + stdlib_lldiv.o \ stdlib_machine_test.o \ stdlib_main.o \ stdlib_malloc.o \ @@ -559,11 +563,14 @@ MATH_LIB = \ stdio_vasprintf.o \ stdio_vfprintf.o \ stdio_vfscanf.o \ + stdio_vsscanf.o \ + stdio_vscanf.o \ stdio_vprintf.o \ stdio_vsnprintf.o \ stdio_vsprintf.o \ stdlib_atof.o \ stdlib_strtod.o \ + stdlib_strtof.o \ time_difftime.o # All objects files which make up libnet.a diff --git a/library/changes b/library/changes index 45109be..f6b02f5 100644 --- a/library/changes +++ b/library/changes @@ -13,7 +13,7 @@ - Fixed two linker errors which were caused by duplicate symbol definitions. -- Added code to the startup routine which allows you to monitor where command +- Added code to the startup routine which allows you to monitor where a command was started from and which parameters it was invoked with. - If fread()/fwrite() fail to read/write any data because either the number @@ -23,6 +23,10 @@ - The libunix.a flavour of system() no longer attempts to translate the name of a command unless it contains path separator characters. +- Added strtof(), llabs(), lldiv(), vsscanf() and vscanf() for C99. + +- strftime() now supports %C, %n, %r, %R, %t, %T, %u, %V, and %z for C99. + c.lib 1.191 (9.4.2005) diff --git a/library/include/stdio.h b/library/include/stdio.h index 4c58941..3b9327a 100644 --- a/library/include/stdio.h +++ b/library/include/stdio.h @@ -1,5 +1,5 @@ /* - * $Id: stdio.h,v 1.11 2005-04-04 10:10:02 obarthel Exp $ + * $Id: stdio.h,v 1.12 2005-05-07 13:21:49 obarthel Exp $ * * :ts=4 * @@ -424,6 +424,8 @@ extern int __vasprintf(const char *file,int line,char **ret,const char *format,v /****************************************************************************/ extern int vfscanf(FILE *stream, const char *format, va_list arg); +extern int vsscanf(const char *s, const char *format, va_list arg); +extern int vscanf(const char *format,va_list arg); /****************************************************************************/ diff --git a/library/include/stdlib.h b/library/include/stdlib.h index 0c7aeea..e6fcdbd 100644 --- a/library/include/stdlib.h +++ b/library/include/stdlib.h @@ -1,5 +1,5 @@ /* - * $Id: stdlib.h,v 1.9 2005-04-03 10:22:48 obarthel Exp $ + * $Id: stdlib.h,v 1.10 2005-05-07 13:21:49 obarthel Exp $ * * :ts=4 * @@ -153,16 +153,6 @@ extern int rand_r(unsigned int * seed); /****************************************************************************/ -/* These functions are unavailable under SAS/C for lack of a - "long long" data type. */ -#if ! defined(__SASC) -extern long long strtoll(const char *str, char **ptr, int base); -extern unsigned long long strtoull(const char *str, char **ptr, int base); -extern long long atoll(const char *str); -#endif /* __SASC */ - -/****************************************************************************/ - #if defined(__GNUC__) #undef alloca #define alloca(size) __builtin_alloca(size) @@ -192,6 +182,35 @@ extern char * mkdtemp(char *name_template); /****************************************************************************/ +/* These functions and data structures are unavailable under SAS/C for lack + of a "long long" data type. */ +#if ! defined(__SASC) + +/****************************************************************************/ + +extern long long strtoll(const char *str, char **ptr, int base); +extern unsigned long long strtoull(const char *str, char **ptr, int base); +extern long long atoll(const char *str); + +/****************************************************************************/ + +typedef struct { long long quot; long long rem; } lldiv_t; + +/****************************************************************************/ + +extern long long llabs(long long x); +extern lldiv_t lldiv(long long n,long long d); + +/****************************************************************************/ + +#endif /* __SASC */ + +/****************************************************************************/ + +extern float strtof(const char *str, char ** ptr); + +/****************************************************************************/ + extern void _Exit(int status); /****************************************************************************/ diff --git a/library/smakefile b/library/smakefile index e5a353c..cb0b8f7 100644 --- a/library/smakefile +++ b/library/smakefile @@ -1,5 +1,5 @@ # -# $Id: smakefile,v 1.37 2005-04-03 10:22:47 obarthel Exp $ +# $Id: smakefile,v 1.38 2005-05-07 13:21:49 obarthel Exp $ # # :ts=8 # @@ -362,6 +362,8 @@ STDIO_OBJ = \ stdio_vasprintf_hook_entry.o \ stdio_vfprintf.o \ stdio_vfscanf.o \ + stdio_vsscanf.o \ + stdio_vscanf.o \ stdio_vprintf.o \ stdio_vsnprintf.o \ stdio_vsnprintf_hook_entry.o \ @@ -432,6 +434,7 @@ STDLIB_OBJ = \ stdlib_stack_usage.o \ stdlib_stacksize.o \ stdlib_strtod.o \ + stdlib_strtof.o \ stdlib_strtol.o \ stdlib_strtoul.o \ stdlib_strtoll.o \ diff --git a/library/stdio_scanf.c b/library/stdio_scanf.c index ea0ed49..5921633 100644 --- a/library/stdio_scanf.c +++ b/library/stdio_scanf.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_scanf.c,v 1.6 2005-04-24 08:46:37 obarthel Exp $ + * $Id: stdio_scanf.c,v 1.7 2005-05-07 13:21:49 obarthel Exp $ * * :ts=4 * @@ -71,7 +71,7 @@ scanf(const char *format, ...) #endif /* CHECK_FOR_NULL_POINTERS */ va_start(arg,format); - result = vfscanf(stdin,format,arg); + result = vscanf(format,arg); va_end(arg); out: diff --git a/library/stdio_sscanf.c b/library/stdio_sscanf.c index c576f0b..0c2d585 100644 --- a/library/stdio_sscanf.c +++ b/library/stdio_sscanf.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_sscanf.c,v 1.7 2005-04-03 10:22:47 obarthel Exp $ + * $Id: stdio_sscanf.c,v 1.8 2005-05-07 13:21:49 obarthel Exp $ * * :ts=4 * @@ -46,9 +46,7 @@ int sscanf(const char *s,const char *format, ...) { - struct iob string_iob; int result = EOF; - char local_buffer[32]; va_list arg; ENTER(); @@ -58,9 +56,6 @@ sscanf(const char *s,const char *format, ...) assert( s != NULL && format != NULL ); - if(__check_abort_enabled) - __check_abort(); - #if defined(CHECK_FOR_NULL_POINTERS) { if(s == NULL || format == NULL) @@ -73,19 +68,8 @@ sscanf(const char *s,const char *format, ...) } #endif /* CHECK_FOR_NULL_POINTERS */ - __initialize_iob(&string_iob,__sscanf_hook_entry, - NULL, - local_buffer,sizeof(local_buffer), - -1, - -1, - IOBF_IN_USE | IOBF_READ | IOBF_BUFFER_MODE_FULL | IOBF_INTERNAL, - NULL); - - string_iob.iob_String = (STRPTR)s; - string_iob.iob_StringLength = strlen(s); - va_start(arg,format); - result = vfscanf((FILE *)&string_iob,format,arg); + result = vsscanf(s,format,arg); va_end(arg); out: diff --git a/library/stdio_vscanf.c b/library/stdio_vscanf.c new file mode 100644 index 0000000..d261ce1 --- /dev/null +++ b/library/stdio_vscanf.c @@ -0,0 +1,78 @@ +/* + * $Id: stdio_vscanf.c,v 1.1 2005-05-07 13:21:49 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 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 _STDIO_HEADERS_H +#include "stdio_headers.h" +#endif /* _STDIO_HEADERS_H */ + +/****************************************************************************/ + +int +vscanf(const char *format,va_list arg) +{ + int result = EOF; + + ENTER(); + + SHOWSTRING(format); + + assert(format != NULL); + + if(__check_abort_enabled) + __check_abort(); + + #if defined(CHECK_FOR_NULL_POINTERS) + { + if(format == NULL) + { + SHOWMSG("invalid format parameter"); + + __set_errno(EFAULT); + goto out; + } + } + #endif /* CHECK_FOR_NULL_POINTERS */ + + result = vfscanf(stdin,format,arg); + + out: + + RETURN(result); + return(result); +} diff --git a/library/stdio_vsscanf.c b/library/stdio_vsscanf.c new file mode 100644 index 0000000..af88d0a --- /dev/null +++ b/library/stdio_vsscanf.c @@ -0,0 +1,92 @@ +/* + * $Id: stdio_vsscanf.c,v 1.1 2005-05-07 13:21:49 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 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 _STDIO_HEADERS_H +#include "stdio_headers.h" +#endif /* _STDIO_HEADERS_H */ + +/****************************************************************************/ + +int +vsscanf(const char *s,const char *format,va_list arg) +{ + struct iob string_iob; + char local_buffer[32]; + int result = EOF; + + ENTER(); + + SHOWSTRING(s); + SHOWSTRING(format); + + assert( s != NULL && format != NULL ); + + if(__check_abort_enabled) + __check_abort(); + + #if defined(CHECK_FOR_NULL_POINTERS) + { + if(s == NULL || format == NULL) + { + SHOWMSG("invalid parameters"); + + __set_errno(EFAULT); + goto out; + } + } + #endif /* CHECK_FOR_NULL_POINTERS */ + + __initialize_iob(&string_iob,__sscanf_hook_entry, + NULL, + local_buffer,sizeof(local_buffer), + -1, + -1, + IOBF_IN_USE | IOBF_READ | IOBF_BUFFER_MODE_FULL | IOBF_INTERNAL, + NULL); + + string_iob.iob_String = (STRPTR)s; + string_iob.iob_StringLength = strlen(s); + + result = vfscanf((FILE *)&string_iob,format,arg); + + out: + + RETURN(result); + return(result); +} diff --git a/library/stdlib_llabs.c b/library/stdlib_llabs.c new file mode 100644 index 0000000..296eeb0 --- /dev/null +++ b/library/stdlib_llabs.c @@ -0,0 +1,48 @@ +/* + * $Id: stdlib_llabs.c,v 1.1 2005-05-07 13:21:49 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 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_HEADERS_H +#include "stdlib_headers.h" +#endif /* _STDLIB_HEADERS_H */ + +/****************************************************************************/ + +long long +llabs(long long x) +{ + long long result; + + result = (x < 0) ? (-x) : x; + + return(result); +} diff --git a/library/stdlib_lldiv.c b/library/stdlib_lldiv.c new file mode 100644 index 0000000..f613a78 --- /dev/null +++ b/library/stdlib_lldiv.c @@ -0,0 +1,51 @@ +/* + * $Id: stdlib_lldiv.c,v 1.1 2005-05-07 13:21:49 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 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_HEADERS_H +#include "stdlib_headers.h" +#endif /* _STDLIB_HEADERS_H */ + +/****************************************************************************/ + +lldiv_t +lldiv(long long n,long long d) +{ + lldiv_t result; + + assert( d != 0 ); + + result.quot = n / d; + result.rem = n % d; + + return(result); +} diff --git a/library/stdlib_strtof.c b/library/stdlib_strtof.c new file mode 100644 index 0000000..4fb6660 --- /dev/null +++ b/library/stdlib_strtof.c @@ -0,0 +1,323 @@ +/* + * $Id: stdlib_strtof.c,v 1.1 2005-05-07 13:21:49 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 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 */ + +#ifndef _LOCALE_HEADERS_H +#include "locale_headers.h" +#endif /* _LOCALE_HEADERS_H */ + +/****************************************************************************/ + +#ifndef _MATH_FP_SUPPORT_H +#include "math_fp_support.h" +#endif /* _MATH_FP_SUPPORT_H */ + +/****************************************************************************/ + +#if defined(FLOATING_POINT_SUPPORT) + +/****************************************************************************/ + +#ifndef _MATH_HEADERS_H +#include "math_headers.h" +#endif /* _MATH_HEADERS_H */ + +/****************************************************************************/ + +float +strtof(const char *str, char ** ptr) +{ + float sum = 0.0; + float new_sum; + float result; + int decimal_point_matches; + int is_negative; + int error = 0; + char c; + + ENTER(); + + SHOWSTRING(str); + SHOWPOINTER(ptr); + + assert( str != NULL ); + + #if defined(CHECK_FOR_NULL_POINTERS) + { + if(str == NULL) + { + SHOWMSG("invalid str parameter"); + + __set_errno(EFAULT); + + result = __get_huge_val(); + goto out; + } + } + #endif /* CHECK_FOR_NULL_POINTERS */ + + /* Skip all leading blanks. */ + while((c = (*str)) != '\0') + { + if(NOT isspace(c)) + break; + + str++; + } + + /* The first character may be a sign. */ + if((*str) == '-') + { + /* It's a negative number. */ + is_negative = 1; + + str++; + } + else + { + /* It's not going to be negative. */ + is_negative = 0; + + /* But there may be a sign we will choose to + * ignore. + */ + if((*str) == '+') + str++; + } + + /* We begin by trying to convert all the digits + * preceding the decimal point. + */ + while((c = (*str)) != '\0') + { + if('0' <= c && c <= '9') + { + str++; + + if(error == 0) + { + new_sum = (10 * sum) + (c - '0'); + if(new_sum < sum) /* overflow? */ + error = ERANGE; + else + sum = new_sum; + } + } + else + { + break; + } + } + + /* Did we find the decimal point? We accept both the + * locale configured decimal point and the plain old + * dot. + */ + decimal_point_matches = 0; + + __locale_lock(); + + if(__locale_table[LC_NUMERIC] != NULL) + { + char * point; + + point = (char *)__locale_table[LC_NUMERIC]->loc_DecimalPoint; + if((*point) == (*str)) + { + decimal_point_matches = 1; + + /* Skip the decimal point. */ + str++; + } + } + + __locale_unlock(); + + if(NOT decimal_point_matches) + { + if((*str) == '.') + { + decimal_point_matches = 1; + + /* Skip the decimal point. */ + str++; + } + } + + if(decimal_point_matches) + { + float divisor = 0.1; + + /* Process all digits following the decimal point. */ + while((c = (*str)) != '\0') + { + if('0' <= c && c <= '9') + { + str++; + + if(error == 0 && divisor != 0.0) + { + new_sum = sum + (c - '0') * divisor; + if(new_sum < sum) /* overflow? */ + error = ERANGE; + else + sum = new_sum; + + divisor = divisor / 10.0; + } + } + else + { + break; + } + } + } + + /* If there is a scale indicator attached, process it. */ + if((*str) == 'e' || (*str) == 'E') + { + int exponent_is_negative; + int new_exponent; + int exponent = 0; + + /* Skip the indicator. */ + str++; + + /* Take care of the exponent's sign. */ + if((*str) == '-') + { + exponent_is_negative = 1; + str++; + } + else + { + exponent_is_negative = 0; + + if((*str) == '+') + str++; + } + + /* Again, process all digits to follow. */ + while((c = (*str)) != '\0') + { + if('0' <= c && c <= '9') + { + str++; + + if(error == 0) + { + new_exponent = (10 * exponent) + (c - '0'); + if(new_exponent < exponent) /* overflow? */ + error = ERANGE; + else + exponent = new_exponent; + } + } + else + { + break; + } + } + + /* If the exponent is valid, scale the number + * accordingly. + */ + if(exponent != 0) + { + if(exponent_is_negative) + { + float divisor; + + /* A negative exponent means division. */ + divisor = pow(10.0,(float)exponent); + if(divisor != 0.0) + { + new_sum = sum / divisor; + if(new_sum == 0.0 && sum != 0.0) + error = ERANGE; + else + sum = new_sum; + } + else + { + error = ERANGE; + } + } + else + { + /* A positive exponent means multiplication. */ + new_sum = sum * pow(10.0,(float)exponent); + if(new_sum < sum) + error = ERANGE; + else + sum = new_sum; + } + } + } + + if(error != 0) + { + __set_errno(error); + + sum = __get_huge_val(); + } + + if(is_negative) + sum = (-sum); + + result = sum; + + /* If desired, remember where we stopped reading the + * number from the buffer. + */ + if(ptr != NULL) + (*ptr) = (char *)str; + + out: + + RETURN(result); + return(result); +} + +/****************************************************************************/ + +#endif /* FLOATING_POINT_SUPPORT */ diff --git a/library/time_strftime.c b/library/time_strftime.c index ebf6811..5705ad5 100644 --- a/library/time_strftime.c +++ b/library/time_strftime.c @@ -1,5 +1,5 @@ /* - * $Id: time_strftime.c,v 1.9 2005-02-27 21:58:21 obarthel Exp $ + * $Id: time_strftime.c,v 1.10 2005-05-07 13:21:49 obarthel Exp $ * * :ts=4 * @@ -105,6 +105,8 @@ store_string_via_hook(const char * string,int len,struct Hook * hook) STATIC VOID format_date(const char *format,const struct tm *tm,struct Hook * hook) { + int gmt_offset; + int week_number; char buffer[40]; const char * str; char c; @@ -187,6 +189,13 @@ format_date(const char *format,const struct tm *tm,struct Hook * hook) format_date("%a %b %d %H:%M:%S %Y",tm,hook); break; + /* The last two digits of a year (C99). */ + case 'C': + + __number_to_string((unsigned int)(tm->tm_year % 100),buffer,sizeof(buffer),2); + store_string_via_hook(buffer,2,hook); + break; + /* Day of the month ("01"-"31"). */ case 'd': @@ -239,6 +248,12 @@ format_date(const char *format,const struct tm *tm,struct Hook * hook) store_string_via_hook(buffer,2,hook); break; + /* Line feed character (C99). */ + case 'n': + + store_string_via_hook("\n",1,hook); + break; + /* 'Ante meridiem'/'Post meridiem' indicator. */ case 'p': @@ -247,6 +262,18 @@ format_date(const char *format,const struct tm *tm,struct Hook * hook) store_string_via_hook((tm->tm_hour < 12) ? "AM" :" PM",2,hook); break; + /* 12 hour clock time (C99). */ + case 'r': + + format_date("%I:%M:%S %p",tm,hook); + break; + + /* Locale-specific time (C99). */ + case 'R': + + format_date("%H:%M",tm,hook); + break; + /* Seconds ("00"-"59"). */ case 'S': @@ -256,6 +283,27 @@ format_date(const char *format,const struct tm *tm,struct Hook * hook) store_string_via_hook(buffer,2,hook); break; + /* Horizontal tabulator character (C99). */ + case 't': + + store_string_via_hook("\t",1,hook); + break; + + /* ISO 8601 time format (C99). */ + case 'T': + + format_date("%H:%M:%S",tm,hook); + break; + + /* ISO 8601 week day number ("1"-"7"; 1 is Monday; C99). */ + case 'u': + + assert( 0 <= tm->tm_wday && tm->tm_wday <= 6 ); + + __number_to_string((unsigned int)(tm->tm_wday > 0 ? tm->tm_wday : 7),buffer,sizeof(buffer),0); + store_string_via_hook(buffer,1,hook); + break; + /* Week number of the year; first week is the one that contains * the first Sunday of the year ("00"-"53"). */ @@ -265,6 +313,17 @@ format_date(const char *format,const struct tm *tm,struct Hook * hook) store_string_via_hook(buffer,2,hook); break; + /* ISO 8601 week number ("01"-"53"; C99). */ + case 'V': + + week_number = (tm->tm_yday + 7 - ((tm->tm_wday + 6) % 7)) / 7; + if(week_number < 1) + week_number = 53; + + __number_to_string(week_number,buffer,sizeof(buffer),2); + store_string_via_hook(buffer,2,hook); + break; + /* Week day ("0"-"6"). */ case 'w': @@ -313,6 +372,31 @@ format_date(const char *format,const struct tm *tm,struct Hook * hook) store_string_via_hook(buffer,-1,hook); break; + /* ISO 8601 offset of time zone from UTC (C99). */ + case 'z': + + __locale_lock(); + + if(__default_locale != NULL) + { + gmt_offset = __default_locale->loc_GMTOffset; + if(gmt_offset < 0) + gmt_offset = (-gmt_offset); + else if (gmt_offset > 0) + store_string_via_hook("-",1,hook); + } + else + { + gmt_offset = 0; + } + + __locale_unlock(); + + __number_to_string((unsigned int)gmt_offset,buffer,sizeof(buffer),0); + store_string_via_hook(buffer,-1,hook); + + break; + /* Time zone name. */ case 'Z':