summary refs log tree commit diff
path: root/stdlib/strtod.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-05-01 13:55:18 +0000
committerRoland McGrath <roland@gnu.org>1996-05-01 13:55:18 +0000
commit75cd5204dd829d849a6e41380a64cf61d7f406d0 (patch)
tree8d821a60b9fd42bf4965b49faf5e6d13f7cebee3 /stdlib/strtod.c
parent5bd44955948a63ea9a71726fb2b8b54b970aeb66 (diff)
downloadglibc-75cd5204dd829d849a6e41380a64cf61d7f406d0.tar.gz
glibc-75cd5204dd829d849a6e41380a64cf61d7f406d0.tar.xz
glibc-75cd5204dd829d849a6e41380a64cf61d7f406d0.zip
Wed May 1 09:10:04 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
	* time/strftime.c: Use canonical autoconf nugget for time.h+sys/time.h
	include.

Mon Apr 29 02:48:26 1996  Ulrich Drepper  <drepper@cygnus.com>

	* ctype/ctype-info.c: (__ctype_width): New variable.
	(__ctype_names): Initialize correctly without offset.

	* locale/C-collate.c, locale/C-ctype.c,
	locale/C-messages.c, locale/C-monetary.c,
	locale/C-numeric.c, locale/C-time.c: Change copyright.

	* locale/C-ctype.c (_nl_C_LC_CTYPE_class32): Correct
	endianess for initialization value.

	* locale/lc-ctype.c (current): Add parameter for offset.
	(__ctype32_b, __ctype_width): Add initialization for these
	variables.

	* locale/programs/charmap.c: Finish support for WIDTH information.
	(new_width): New function.

	* locale/programs/charset.h (width_rule): new data structure.
	(charset_t): Add elements for width information.

	* locale/programs/ld-ctype.c (locale_ctype_t): Add element
	for width information.
	(allocate_arrays): Add new argument for charset.
	(ctype_finish): Make sure all characters named in charset
	width table are known to name table.
	(ctype_output): Correct handling of class and map name
	information and write out width information.
	(find_idx): Prepare for being called with NULL pointer as
	TABLE argument.  This means only allocate name entry.
	(allocate_arrays): Correct handling of array element -1.
	Because EOF == -1 the value of element 127 must *not* be
	mirrored here.
	Fill width information from charset tables.

	* locale/programs/localedef.c (main): Correct loop over all
	categories after change of order from Thu Mar 28 14:22:51 1996.
	Add new charset argument to call of `write_all_categories'.

	* locale/programs/locales.h (ctype_finish, ctype_output): New
	charset argument.

	* locale/programs/locfile.c (write_all_categories): Call
	`ctype_output' with additional argument charset.

	* posix/getconf.c (vars): Add _POSIX_SYNC_IO, _POSIX_ASYNC_IO,
	and _POSIX_PRIO_IO definitions.

	* posix/posix2_lim.h: Add definition of _POSIX2_CHARCLASS_NAME_MAX
	and CHARCLASS_NAME_MAX.

	* posix/unistd.h: Document _POSIX_SYNC_IO, _POSIX_ASYNC_IO,
	and _POSIX_PRIO_IO.

	* stdlib/grouping.h: Prepare for use in wide string functions.

	* stdlib/stdlib.h: Correct prototypes for __strto*_internal
	functions.

	* stdlib/strtod.c: Extend for use as `wcsto{f,d,ld}'.

	* stdlib/strtol.c: Extend for use as `wcsto{l,ul,q,uq}'.

	* string/strcoll.c: Extend for use as `wcscoll'.

	* string/strxfrm.c: Extend for use as `wcsxfrm'.

	* sysdeps/generic/confname.h: Add definition of _PC_SYNC_IO,
	_PC_ASYNC_IO, _PC_PRIO_IO and _SC_CHARCLASS_NAME_MAX.

	* sysdeps/generic/stpncpy.c: Correct return value.

	* sysdeps/posix/fpathconf.c: Add handling of _PC_SYNC_IO,
	_PC_ASYNC_IO, and _PC_PRIO_IO.

	* sysdeps/posix/sysconf.c: Add handling of _SC_REALTIME_SIGNALS,
	_SC_PRIORITY_SCHEDULING, _SC_TIMERS, _SC_ASYNCHRONOUS_IO,
	_SC_PRIORITIZED_IO, _SC_SYNCHRONIZED_IO, _SC_FSYNC,
	_SC_MAPPED_FILES, _SC_MEMLOCK, _SC_MEMLOCK_RANGE,
	_SC_MEMORY_PROTECTION, _SC_MESSAGE_PASSING, _SC_SEMAPHORES,
	_SC_SHARED_MEMORY_OBJECTS, and _SC_CHARCLASS_NAME_MAX.
	* sysdeps/stub/sysconf.c: Ditto.
	* sysdeps/unix/sysv/sysv4/sysconf.c: Ditto.

	* sysdeps/unix/sysv/linux/Dist: Add sys/sysctl.h.

	* sysdeps/unix/sysv/linux/Makefile [subdir == misc]
	(sysdep_routines): Add s_sysctl and sysctl.

	* sysdeps/unix/sysv/linux/sys/mman.h: Add declaration of mremap.

	* sysdeps/unix/sysv/linux/sys/socket.h: New file.  Wrapper
	around kernel header.

	* sysdeps/unix/sysv/linux/sys/sysctl.h: New file.  Define
	interface to `sysctl' function.

	* sysdeps/unix/sysv/linux/syscalls.list: Add mremap and _sysctl.

	* sysdeps/unix/sysv/linux/sysconf.c: Add handling of
	_SC_CHARCLASS_NAME_MAX.

	* sysdeps/unix/sysv/linux/sysctl.c: new file.  Implement caller
	of _sysctl system call.

	* sysvipc/Makefile (routines): Add ftok.

	* sysvipc/ftok.c: use variable `proj_id' not `id'.  Patch by
	David Mosberger-Tang.

	* wcsmbs/Makefile (routines): Add wcpcpy, wcpncpy, wcstol,
        wcstoul, wcstoq, wcstouq, wcstod, wcstold, wcstof, wcscoll,
        wcsxfrm, wcwidth, and wcswidth.

	* wcsmbs/wchar.h: Add declarations for wcpcpy, wcpncpy, wcstol,
        wcstoul, wcstoq, wcstouq, wcstod, wcstold, wcstof, wcscoll,
        wcsxfrm, wcwidth, and wcswidth.
	Declare internal interfaces for wcsto* functions.
	[OPTIMIZE]: Define inline functions for wcsto* functions to
	call internal interface functions.

	* wcsmbs/wcpcpy.c, wcsmbs/wcpncpy.c: New files.  Implement non-
	standard function equivalent to stpcpy/stpncpy.

	* wcsmbs/wcscoll.c: Implement `wcscoll' function by using
        `strcoll' implementation.

	* wcsmbs/wcscpy.c, wcsmbs/wcsncpy.c: Use wint_t instead of
        wchar_t.

	* wcsmbs/wcstod.c: Implement `wcstod' function by using `strtod'
        implementation.
	* wcsmbs/wcstof.c: Same for `wcstof'.
	* wcsmbs/wcstold.c: Same for `strtold'.

	* wcsmbs/wcstol.c: Implement `wcstol' function by using `strtol'
        implementation.
	* wcsmbs/wcstoq.c: Same for `wcstoq'.
	* wcsmbs/wcstoul.c: Same for `wcstoul'.
	* wcsmbs/wcstouq.c: Same for `wcstouq'.

	* wcsmbs/wcswidth.c: Implement `wcswidth' function from X/Open
        CAE.
	* wcsmbs/wcwidth.c: Ditto for `wcwidth'.
	* wcsmbs/wcwidth.h: Common function for definitions of above two
	functions.

	* wcsmbs/wcsxfrm.c: Implement `wcsxfrm function by using
        `strxfrm implementation.

	* wctype/wctype.c: Remove case for `wctype_t' being 16 bit type.

	* wctype/wctype.h (wint_t): Protect against multiple definition.
	(wctype_t): Always define as `unsigned long int'.

	* wctype.h: New file.  Wrapper around wctype/wctype.h.

	* hurd/hurdstartup.c (_hurd_split_args): Function removed.
	(_hurd_startup): Use argz functions.

	* hurd/hurdexec.c: Use argz functions.
Diffstat (limited to 'stdlib/strtod.c')
-rw-r--r--stdlib/strtod.c126
1 files changed, 77 insertions, 49 deletions
diff --git a/stdlib/strtod.c b/stdlib/strtod.c
index 51dc520c01..e262f3de83 100644
--- a/stdlib/strtod.c
+++ b/stdlib/strtod.c
@@ -1,6 +1,6 @@
 /* Read decimal floating point numbers.
 Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-Contributed by Ulrich Drepper.
+Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
 This file is part of the GNU C Library.
 
@@ -15,18 +15,39 @@ 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 the GNU C Library; see the file COPYING.LIB.	 If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
-/* Configuration part.  These macros are defined by `strtold.c' and `strtof.c'
-   to produce the `long double' and `float' versions of the reader.  */
+/* Configuration part.  These macros are defined by `strtold.c',
+   `strtof.c', `wcstod.c', `wcstold.c', and `wcstof.c' to produce the
+   `long double' and `float' versions of the reader.  */
 #ifndef FLOAT
-#define	FLOAT		double
-#define	FLT		DBL
-#define	STRTOF		strtod
-#define	MPN2FLOAT	__mpn_construct_double
-#define	FLOAT_HUGE_VAL	HUGE_VAL
+# define FLOAT		double
+# define FLT		DBL
+# ifdef USE_WIDE_CHAR
+#  define STRTOF	wcstod
+# else
+#  define STRTOF	strtod
+# endif
+# define MPN2FLOAT	__mpn_construct_double
+# define FLOAT_HUGE_VAL	HUGE_VAL
+#endif
+
+#ifdef USE_WIDE_CHAR
+# include <wctype.h>
+# include <wchar.h>
+# define STRING_TYPE wchar_t
+# define CHAR_TYPE wint_t
+# define L_(Ch) L##Ch
+# define ISSPACE(Ch) iswspace (Ch)
+# define TOLOWER(Ch) towlower (Ch)
+#else
+# define STRING_TYPE char
+# define CHAR_TYPE char
+# define L_(Ch) Ch
+# define ISSPACE(Ch) isspace (Ch)
+# define TOLOWER(Ch) tolower (Ch)
 #endif
 /* End of configuration part.  */
 
@@ -103,8 +124,9 @@ static const mp_limb _tens_in_limb[MAX_DIG_PER_LIMB + 1] =
 #define NDIG			(MAX_10_EXP - MIN_10_EXP + 2 * MANT_DIG)
 #define	RETURN_LIMB_SIZE		howmany (MANT_DIG, BITS_PER_MP_LIMB)
 
-#define RETURN(val,end) \
-    do { if (endptr != 0) *endptr = (char *) (end); return val; } while (0)
+#define RETURN(val,end)							      \
+    do { if (endptr != NULL) *endptr = (STRING_TYPE *) (end);		      \
+	 return val; } while (0)
 
 /* Maximum size necessary for mpn integers to hold floating point numbers.  */
 #define	MPNSIZE		(howmany (MAX_EXP + 2 * MANT_DIG, BITS_PER_MP_LIMB) \
@@ -206,8 +228,8 @@ round_and_return (mp_limb *retval, int exponent, int negative,
    character od the string that is not part of the integer as the function
    value.  If the EXPONENT is small enough to be taken as an additional
    factor for the resulting number (see code) multiply by it.  */
-static inline const char *
-str_to_mpn (const char *str, int digcnt, mp_limb *n, mp_size_t *nsize,
+static inline const STRING_TYPE *
+str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb *n, mp_size_t *nsize,
 	    int *exponent)
 {
   /* Number of digits for actual limb.  */
@@ -239,9 +261,9 @@ str_to_mpn (const char *str, int digcnt, mp_limb *n, mp_size_t *nsize,
       /* There might be thousands separators or radix characters in the string.
 	 But these all can be ignored because we know the format of the number
 	 is correct and we have an exact number of characters to read.  */
-      while (!isdigit (*str))
+      while (*str < L_('0') || *str > L_('9'))
 	++str;
-      low = low * 10 + *str++ - '0';
+      low = low * 10 + *str++ - L_('0');
       ++cnt;
     }
   while (--digcnt > 0);
@@ -311,8 +333,8 @@ __mpn_lshift_1 (mp_limb *ptr, mp_size_t size, unsigned int count, mp_limb limb)
    ERANGE and return HUGE_VAL with the approriate sign.  */
 FLOAT
 INTERNAL (STRTOF) (nptr, endptr, group)
-     const char *nptr;
-     char **endptr;
+     const STRING_TYPE *nptr;
+     STRING_TYPE **endptr;
      int group;
 {
   int negative;			/* The sign of the number.  */
@@ -330,15 +352,15 @@ INTERNAL (STRTOF) (nptr, endptr, group)
   int bits;
 
   /* Running pointer after the last character processed in the string.  */
-  const char *cp, *tp;
+  const STRING_TYPE *cp, *tp;
   /* Start of significant part of the number.  */
-  const char *startp, *start_of_digits;
+  const STRING_TYPE *startp, *start_of_digits;
   /* Points at the character following the integer and fractional digits.  */
-  const char *expp;
+  const STRING_TYPE *expp;
   /* Total number of digit and number of digits in integer part.  */
   int dig_no, int_no, lead_zero;
   /* Contains the last character read.  */
-  char c;
+  CHAR_TYPE c;
 
   /* The radix character of the current locale.  */
   wchar_t decimal;
@@ -386,32 +408,33 @@ INTERNAL (STRTOF) (nptr, endptr, group)
   /* Ignore leading white space.  */
   do
     c = *++cp;
-  while (isspace (c));
+  while (ISSPACE (c));
 
   /* Get sign of the result.  */
-  if (c == '-')
+  if (c == L_('-'))
     {
       negative = 1;
       c = *++cp;
     }
-  else if (c == '+')
+  else if (c == L_('+'))
     c = *++cp;
 
   /* Return 0.0 if no legal string is found.
      No character is used even if a sign was found.  */
-  if (!isdigit (c) && (c != decimal || !isdigit (cp[1])))
+  if ((c < L_('0') || c > L_('9'))
+      && (c != decimal || cp[1] < L_('0') || cp[1] > L_('9')))
     RETURN (0.0, nptr);
 
   /* Record the start of the digits, in case we will check their grouping.  */
   start_of_digits = startp = cp;
 
   /* Ignore leading zeroes.  This helps us to avoid useless computations.  */
-  while (c == '0' || (thousands != L'\0' && c == thousands))
+  while (c == L_('0') || (thousands != L'\0' && c == thousands))
     c = *++cp;
 
   /* If no other digit but a '0' is found the result is 0.0.
      Return current read pointer.  */
-  if (!isdigit (c) && c != decimal)
+  if ((c < L_('0') || c > L_('9')) && c != decimal)
     {
       tp = correctly_grouped_prefix (start_of_digits, cp, thousands, grouping);
       /* If TP is at the start of the digits, there was no correctly
@@ -428,7 +451,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
 	    so we can check all the grouping separators.  */
 	 grouping)
     {
-      if (isdigit (c))
+      if (c >= L_('0') && c <= L_('9'))
 	++dig_no;
       else if (thousands == L'\0' || c != thousands)
 	/* Not a digit or separator: end of the integer part.  */
@@ -458,7 +481,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
 	  cp = tp;
 	  dig_no = 0;
 	  for (tp = startp; tp < cp; ++tp)
-	    if (isdigit (*tp))
+	    if (*tp >= L_('0') && *tp <= L_('9'))
 	      ++dig_no;
 
 	  int_no = dig_no;
@@ -481,31 +504,35 @@ INTERNAL (STRTOF) (nptr, endptr, group)
   /* Read the fractional digits.  A special case are the 'american style'
      numbers like `16.' i.e. with decimal but without trailing digits.  */
   if (c == decimal)
-    while (isdigit (c = *++cp))
-      {
-	if (c != '0' && lead_zero == -1)
-	  lead_zero = dig_no - int_no;
-	++dig_no;
-      }
+    {
+      c = *++cp;
+      while (c >= L_('0') && c <= L_('9'))
+	{
+	  if (c != L_('0') && lead_zero == -1)
+	    lead_zero = dig_no - int_no;
+	  ++dig_no;
+	  c = *++cp;
+	}
+    }
 
   /* Remember start of exponent (if any).  */
   expp = cp;
 
   /* Read exponent.  */
-  if (tolower (c) == 'e')
+  if (TOLOWER (c) == L_('e'))
     {
       int exp_negative = 0;
 
       c = *++cp;
-      if (c == '-')
+      if (c == L_('-'))
 	{
 	  exp_negative = 1;
 	  c = *++cp;
 	}
-      else if (c == '+')
+      else if (c == L_('+'))
 	c = *++cp;
 
-      if (isdigit (c))
+      if (c >= L_('0') && c <= L_('9'))
 	{
 	  int exp_limit;
 
@@ -532,16 +559,16 @@ INTERNAL (STRTOF) (nptr, endptr, group)
 		  /* Accept all following digits as part of the exponent.  */
 		  do
 		    ++cp;
-		  while (isdigit (*cp));
+		  while (*cp >= L_('0') && *cp <= L_('9'));
 
 		  RETURN (retval, cp);
 		  /* NOTREACHED */
 		}
 
-	      exponent += c - '0';
+	      exponent += c - L_('0');
 	      c = *++cp;
 	    }
-	  while (isdigit (c));
+	  while (c >= L_('0') && c <= L_('9'));
 
 	  if (exp_negative)
 	    exponent = -exponent;
@@ -553,7 +580,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
   /* We don't want to have to work with trailing zeroes after the radix.  */
   if (dig_no > int_no)
     {
-      while (expp[-1] == '0')
+      while (expp[-1] == L_('0'))
 	{
 	  --expp;
 	  --dig_no;
@@ -565,7 +592,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
 
   /* The whole string is parsed.  Store the address of the next character.  */
   if (endptr)
-    *endptr = (char *) cp;
+    *endptr = (STRING_TYPE *) cp;
 
   if (dig_no == 0)
     return 0.0;
@@ -573,7 +600,8 @@ INTERNAL (STRTOF) (nptr, endptr, group)
   if (lead_zero)
     {
       /* Find the decimal point */
-      while (*startp != decimal) startp++;
+      while (*startp != decimal)
+	++startp;
       startp += lead_zero + 1;
       exponent -= lead_zero;
       dig_no -= lead_zero;
@@ -1131,8 +1159,8 @@ INTERNAL (STRTOF) (nptr, endptr, group)
 
 FLOAT
 STRTOF (nptr, endptr)
-     const char *nptr;
-     char **endptr;
+     const STRING_TYPE *nptr;
+     STRING_TYPE **endptr;
 {
   return INTERNAL (STRTOF) (nptr, endptr, 0);
 }