From 43cc55b080e3c3b845c8310388f0645a7a1a82f7 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sun, 14 Mar 2010 15:10:16 +0000 Subject: [PATCH] Add strtod git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@2541 7fd9a85b-ad96-42d3-883c-3090e2eb8679 --- nuttx/ChangeLog | 3 + nuttx/Documentation/NuttX.html | 5 +- nuttx/include/stdlib.h | 3 +- nuttx/lib/Makefile | 2 +- nuttx/lib/dq_remlast.c | 4 - nuttx/lib/lib_strtod.c | 228 +++++++++++++++++++++++++++++++++ 6 files changed, 238 insertions(+), 7 deletions(-) create mode 100755 nuttx/lib/lib_strtod.c diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 52298e06d..b92eb2dd4 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -1057,3 +1057,6 @@ * arch/arm/src/sam3u/sam3u_pio.c - Fix an address calculation error that caused ports B & C to get mapped to the PIOA base address. This is an important bugfix! (a patch is available) + * arch/arm/src/lpc313x/lpc313x_boot.c - Fix an error in the vector + initialization was causing a memory fault. + * lib/lib_strtod.c - Add strtod() diff --git a/nuttx/Documentation/NuttX.html b/nuttx/Documentation/NuttX.html index 2e3127e68..a11204a97 100644 --- a/nuttx/Documentation/NuttX.html +++ b/nuttx/Documentation/NuttX.html @@ -8,7 +8,7 @@

NuttX RTOS

-

Last Updated: January 30, 2010

+

Last Updated: March 14, 2010

@@ -1688,6 +1688,9 @@ nuttx-5.2 2010-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> * arch/arm/src/sam3u/sam3u_pio.c - Fix an address calculation error that caused ports B & C to get mapped to the PIOA base address. This is an important bugfix! (a patch is available) + * arch/arm/src/lpc313x/lpc313x_boot.c - Fix an error in the vector + initialization was causing a memory fault. + * lib/lib_strtod.c - Add strtod() pascal-2.1 2010-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr> diff --git a/nuttx/include/stdlib.h b/nuttx/include/stdlib.h index 4dbdb645e..19ed91ec4 100644 --- a/nuttx/include/stdlib.h +++ b/nuttx/include/stdlib.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/stdlib.h * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -133,6 +133,7 @@ EXTERN double_t strtod(const char *, char **); #ifdef CONFIG_HAVE_LONG_LONG #define atoll(nptr) strtoll((nptr), NULL, 10); #endif +#define atof(nptr) strtod((nptr), NULL); /* Memory Management */ diff --git a/nuttx/lib/Makefile b/nuttx/lib/Makefile index f59aa3327..612c218ed 100644 --- a/nuttx/lib/Makefile +++ b/nuttx/lib/Makefile @@ -49,7 +49,7 @@ STRING_SRCS = lib_checkbase.c lib_isbasedigit.c lib_memset.c lib_memcpy.c \ lib_strdup.c lib_strerror.c lib_strlen.c lib_strncasecmp.c \ lib_strncat.c lib_strncmp.c lib_strncpy.c lib_strpbrk.c \ lib_strrchr.c lib_strspn.c lib_strstr.c lib_strtok.c lib_strtokr.c \ - lib_strtol.c lib_strtoll.c lib_strtoul.c lib_strtoull.c + lib_strtol.c lib_strtoll.c lib_strtoul.c lib_strtoull.c lib_strtod.c CTYPE_SRCS = diff --git a/nuttx/lib/dq_remlast.c b/nuttx/lib/dq_remlast.c index ed24c664f..8688c0960 100644 --- a/nuttx/lib/dq_remlast.c +++ b/nuttx/lib/dq_remlast.c @@ -33,10 +33,6 @@ * ****************************************************************************/ -/**************************************************************************** - * Compilation Switches - ****************************************************************************/ - /**************************************************************************** * Included Files ****************************************************************************/ diff --git a/nuttx/lib/lib_strtod.c b/nuttx/lib/lib_strtod.c new file mode 100755 index 000000000..777eb6ded --- /dev/null +++ b/nuttx/lib/lib_strtod.c @@ -0,0 +1,228 @@ +/**************************************************************************** + * lib/lib_strtod.c + * + * Convert string to double + * + * Copyright (C) 2002 Michael Ringgaard. All rights reserved. + * Copyright (C) 2006-2007 H. Peter Anvin. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/* These are predefined with GCC, but could be issues for other compilers. If + * not defined, an arbitrary big number is put in for now. These should be + * added to nuttx/compiler for your compiler. + */ + +#if !defined(__DBL_MIN_EXP__) || !defined(__DBL_MAX_EXP__) +# ifdef CONFIG_CPP_HAVE_WARNING +# warning "Size of exponent is unknown" +# endif +# undef __DBL_MIN_EXP__ +# define __DBL_MIN_EXP__ (-1021) +# undef __DBL_MAX_EXP__ +# define __DBL_MAX_EXP__ (1024) +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static inline int is_real(double x) +{ + const double_t infinite = 1.0/0.0; + return (x < infinite) && (x >= -infinite); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/***************************************************(************************ + * Name: strtod + * + * Description: + * Convert a string to a double value + * + ****************************************************************************/ + +double_t strtod(const char *str, char **endptr) +{ + double_t number; + int exponent; + int negative; + char *p = (char *) str; + double p10; + int n; + int num_digits; + int num_decimals; + const double_t infinite = 1.0/0.0; + + /* Skip leading whitespace */ + + while (isspace(*p)) + { + p++; + } + + /* Handle optional sign */ + + negative = 0; + switch (*p) + { + case '-': + negative = 1; /* Fall through to increment position */ + case '+': + p++; + } + + number = 0.; + exponent = 0; + num_digits = 0; + num_decimals = 0; + + /* Process string of digits */ + + while (isdigit(*p)) + { + number = number * 10. + (*p - '0'); + p++; + num_digits++; + } + + /* Process decimal part */ + + if (*p == '.') + { + p++; + + while (isdigit(*p)) + { + number = number * 10. + (*p - '0'); + p++; + num_digits++; + num_decimals++; + } + + exponent -= num_decimals; + } + + if (num_digits == 0) + { + errno = ERANGE; + return 0.0; + } + + /* Correct for sign */ + + if (negative) + { + number = -number; + } + + /* Process an exponent string */ + + if (*p == 'e' || *p == 'E') + { + /* Handle optional sign */ + + negative = 0; + switch(*++p) + { + case '-': + negative = 1; /* Fall through to increment pos */ + case '+': + p++; + } + + /* Process string of digits */ + + n = 0; + while (isdigit(*p)) + { + n = n * 10 + (*p - '0'); + p++; + } + + if (negative) + { + exponent -= n; + } + else + { + exponent += n; + } + } + + if (exponent < __DBL_MIN_EXP__ || + exponent > __DBL_MAX_EXP__) + { + errno = ERANGE; + return infinite; + } + + /* Scale the result */ + + p10 = 10.; + n = exponent; + if (n < 0) n = -n; + while (n) + { + if (n & 1) + { + if (exponent < 0) + { + number /= p10; + } + else + { + number *= p10; + } + } + n >>= 1; + p10 *= p10; + } + + if (!is_real(number)) errno = ERANGE; + if (endptr) *endptr = p; + + return number; +} +