]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Tue Dec 5 02:27:32 1995 Ulrich Drepper <drepper@gnu.ai.mit.edu>
authorRoland McGrath <roland@gnu.org>
Tue, 5 Dec 1995 03:35:55 +0000 (03:35 +0000)
committerRoland McGrath <roland@gnu.org>
Tue, 5 Dec 1995 03:35:55 +0000 (03:35 +0000)
* libio/Makefile [routines]: Remove iofscanf, add iopopen, pclose.

* libio/iofscanf.c: Remove file.

* libio/iogetdelim.c (_IO_getdelim): Correct stupid bug at string
        termination.

* libio/iopopen.c: New file from GNU libio.

* libio/memstream.c: Fixed bug in fclose handling.  Instead of
providing a close callback we need a finish callback.

* libio/pclose.c: New file.  Derived from popen.c in GNU libio.

* posix/gnu/types.h: Fixed typo.

* stdio-common/errnobug.c: fputs returns EOF in error case.  Do
not test for != 0.

* stdio-common/printf-parse.h (parse_one_spec): Do not force
padding with ' ' if precision is given.  Fix by HJ Lu.

* stdio-common/printf_fp.c: Fix comment.

* stdio-common/tfformat.c, stdio-common/tiformat.c,
stdio-common/tstdiomisc.c: New files from GNU libio test suite.

* stdio-common/tstgetln.c: Provide ssize_t type when testing
libio.

* stdio-common/vfprintf.c (outchar): Use PUTC instead of putc.
(vfprintf): Cleasr args_type array before using it.
When printing 0 as an integer with precision 0 nothing must be
written for the number.
Based on patch by HJ Lu.

* stdio-common/vfscanf.c: Remove fixed input buffer.  Now we
        have a dynamically extended buffer.

* stdlib/strtod.c: Merge with version in Linux libc.  This fixes
        some bugs with handling of very small numbers and has different
        solution for formaer patches.

* sysdeps/i386/i586/add_n.S, sysdeps/i386/i586/sub_n.S: Rename
        macros r1 and r2 to t1, and t2 resp.  This is necessary because
        glibc headers also define r1.
Tue Dec  5 02:27:32 1995  Ulrich Drepper  <drepper@gnu.ai.mit.edu>

* libio/Makefile [routines]: Remove iofscanf, add iopopen, pclose.

* libio/iofscanf.c: Remove file.

* libio/iogetdelim.c (_IO_getdelim): Correct stupid bug at string
        termination.

* libio/iopopen.c: New file from GNU libio.

* libio/memstream.c: Fixed bug in fclose handling.  Instead of
providing a close callback we need a finish callback.

* libio/pclose.c: New file.  Derived from popen.c in GNU libio.

* posix/gnu/types.h: Fixed typo.

* stdio-common/errnobug.c: fputs returns EOF in error case.  Do
not test for != 0.

* stdio-common/printf-parse.h (parse_one_spec): Do not force
padding with ' ' if precision is given.  Fix by HJ Lu.

* stdio-common/printf_fp.c: Fix comment.

* stdio-common/tfformat.c, stdio-common/tiformat.c,
stdio-common/tstdiomisc.c: New files from GNU libio test suite.

* stdio-common/tstgetln.c: Provide ssize_t type when testing
libio.

* stdio-common/vfprintf.c (outchar): Use PUTC instead of putc.
(vfprintf): Cleasr args_type array before using it.
When printing 0 as an integer with precision 0 nothing must be
written for the number.
Based on patch by HJ Lu.

* stdio-common/vfscanf.c: Remove fixed input buffer.  Now we
        have a dynamically extended buffer.

* stdlib/strtod.c: Merge with version in Linux libc.  This fixes
        some bugs with handling of very small numbers and has different
        solution for formaer patches.

* sysdeps/i386/i586/add_n.S, sysdeps/i386/i586/sub_n.S: Rename
        macros r1 and r2 to t1, and t2 resp.  This is necessary because
        glibc headers also define r1.

16 files changed:
ChangeLog
libio/Makefile
libio/iofscanf.c [deleted file]
libio/iogetdelim.c
libio/memstream.c
posix/gnu/types.h
stdio-common/Makefile
stdio-common/errnobug.c
stdio-common/printf-parse.h
stdio-common/printf_fp.c
stdio-common/tstgetln.c
stdio-common/vfprintf.c
stdio-common/vfscanf.c
stdlib/strtod.c
sysdeps/i386/i586/add_n.S
sysdeps/i386/i586/sub_n.S

index a58c2d572f866e9f4969d7fc10d090ea6e51214b..28a803280f24bb49a4913680c7b7ad177871659c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,52 @@
+Tue Dec  5 02:27:32 1995  Ulrich Drepper  <drepper@gnu.ai.mit.edu>
+
+       * libio/Makefile [routines]: Remove iofscanf, add iopopen, pclose.
+
+       * libio/iofscanf.c: Remove file.
+
+       * libio/iogetdelim.c (_IO_getdelim): Correct stupid bug at string
+        termination.
+
+       * libio/iopopen.c: New file from GNU libio.
+
+       * libio/memstream.c: Fixed bug in fclose handling.  Instead of
+       providing a close callback we need a finish callback.
+
+       * libio/pclose.c: New file.  Derived from popen.c in GNU libio.
+
+       * posix/gnu/types.h: Fixed typo.
+
+       * stdio-common/errnobug.c: fputs returns EOF in error case.  Do
+       not test for != 0.
+
+       * stdio-common/printf-parse.h (parse_one_spec): Do not force
+       padding with ' ' if precision is given.  Fix by HJ Lu.
+
+       * stdio-common/printf_fp.c: Fix comment.
+
+       * stdio-common/tfformat.c, stdio-common/tiformat.c,
+       stdio-common/tstdiomisc.c: New files from GNU libio test suite.
+
+       * stdio-common/tstgetln.c: Provide ssize_t type when testing
+       libio.
+
+       * stdio-common/vfprintf.c (outchar): Use PUTC instead of putc.
+       (vfprintf): Cleasr args_type array before using it.
+       When printing 0 as an integer with precision 0 nothing must be
+       written for the number.
+       Based on patch by HJ Lu.
+
+       * stdio-common/vfscanf.c: Remove fixed input buffer.  Now we
+        have a dynamically extended buffer.
+
+       * stdlib/strtod.c: Merge with version in Linux libc.  This fixes
+        some bugs with handling of very small numbers and has different
+        solution for formaer patches.
+
+       * sysdeps/i386/i586/add_n.S, sysdeps/i386/i586/sub_n.S: Rename
+        macros r1 and r2 to t1, and t2 resp.  This is necessary because
+        glibc headers also define r1.
+
 Mon Dec  4 12:10:28 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
        * stdlib/gen-mpn-copy (translations): Updated for new layout in
index 8d09a5eccef287b872b1382b3436b6d0ccc8c415..02426a79c211df3dd6577c3fd578c30e9bbcd626 100644 (file)
@@ -25,14 +25,14 @@ headers     := stdio.h libio.h
 
 routines       :=                                                            \
        filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen      \
-       iofopncook iofprintf iofputs iofread iofscanf iofsetpos ioftell       \
-       iofwrite iogetdelim iogetline iogets iopadn ioprims ioputs            \
+       iofopncook iofprintf iofputs iofread iofsetpos ioftell                \
+       iofwrite iogetdelim iogetline iogets iopadn iopopen ioprims ioputs    \
        ioseekoff ioseekpos iosetbuffer iosetvbuf iosprintf ioungetc          \
        iovsprintf iovsscanf                                                  \
                                                                              \
        clearerr feof ferror fgetc fileno fputc freopen fseek getc getchar    \
-       memstream putc putchar rewind setbuf setlinebuf vasprintf vdprintf    \
-       vscanf vsnprintf                                                      \
+       memstream pclose putc putchar rewind setbuf setlinebuf vasprintf      \
+       vdprintf vscanf vsnprintf                                             \
                                                                              \
        libc_fatal
 
diff --git a/libio/iofscanf.c b/libio/iofscanf.c
deleted file mode 100644 (file)
index 512d5e5..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-Copyright (C) 1993, 1995 Free Software Foundation
-
-This file is part of the GNU IO Library.  This library is free
-software; you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, 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 General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this library; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-As a special exception, if you link this library with files
-compiled with a GNU compiler to produce an executable, this does not cause
-the resulting executable to be covered by the GNU General Public License.
-This exception does not however invalidate any other reasons why
-the executable file might be covered by the GNU General Public License. */
-
-#include "libioP.h"
-
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-int
-_IO_fscanf
-#ifdef __STDC__
-  (_IO_FILE *fp, const char* format, ...)
-#else
-(fp, format, va_alist) _IO_FILE *fp; char *format; va_dcl
-#endif
-{
-  int ret;
-  va_list args;
-  CHECK_FILE (fp, EOF);
-  _IO_va_start (args, format);
-  ret = _IO_vfscanf (fp, format, args, NULL);
-  va_end (args);
-  return ret;
-}
-
-weak_alias (_IO_fscanf, fscanf)
index a6894a5ae6e9a36c61622d080ec45ffb1f541653..ecb360b1f5eba407e14b26616c45a71f61651c98 100644 (file)
@@ -79,11 +79,11 @@ _IO_getdelim (lineptr, n, delimiter, fp)
       t = (char *) memchr ((void *) fp->_IO_read_ptr, delimiter, len);
       if (t != NULL)
        len = (t - fp->_IO_read_ptr) + 1;
-      /* make enough space for len+1 (for final NUL) bytes. */
+      /* Make enough space for len+1 (for final NUL) bytes.  */
       needed = cur_len + len + 1;
       if (needed > *n)
        {
-         if (t == NULL && needed < 2 * *n)
+         if (needed < 2 * *n)
            needed = 2 * *n;  /* Be generous. */
          *n = needed;
          *lineptr = (char *) realloc (*lineptr, needed);
@@ -97,7 +97,7 @@ _IO_getdelim (lineptr, n, delimiter, fp)
        break;
       len = fp->_IO_read_end - fp->_IO_read_ptr;
     }
-  lineptr[cur_len] = '\0';
+  (*lineptr)[cur_len] = '\0';
   return cur_len;
 }
 
index b1cefb09590cd608359e407463c37327bf44f33f..71519a51906ac210cd86f199d19ee1f576e06f25 100644 (file)
@@ -30,13 +30,13 @@ struct _IO_FILE_memstream
 
 
 static int _IO_mem_sync __P ((_IO_FILE* fp));
-static int _IO_mem_close __P ((_IO_FILE* fp));
+static void _IO_mem_finish __P ((_IO_FILE* fp));
 
 
 static const struct _IO_jump_t _IO_mem_jumps =
 {
   JUMP_INIT_DUMMY,
-  JUMP_INIT (finish, _IO_str_finish),
+  JUMP_INIT (finish, _IO_mem_finish),
   JUMP_INIT (overflow, _IO_str_overflow),
   JUMP_INIT (underflow, _IO_str_underflow),
   JUMP_INIT (uflow, _IO_default_uflow),
@@ -51,7 +51,7 @@ static const struct _IO_jump_t _IO_mem_jumps =
   JUMP_INIT (read, _IO_default_read),
   JUMP_INIT (write, _IO_default_write),
   JUMP_INIT (seek, _IO_default_seek),
-  JUMP_INIT (close, _IO_mem_close),
+  JUMP_INIT (close, _IO_default_close),
   JUMP_INIT (stat, _IO_default_stat)
 };
 
@@ -79,6 +79,9 @@ open_memstream (bufloc, sizeloc)
   fp->_sf._s._allocate_buffer = (_IO_alloc_type) malloc;
   fp->_sf._s._free_buffer = (_IO_free_type) free;
 
+  fp->bufloc = bufloc;
+  fp->sizeloc = sizeloc;
+
   return &fp->_sf._f;
 }
 
@@ -102,28 +105,28 @@ _IO_mem_sync (fp)
   else
     *fp->_IO_write_ptr = '\0';
 
-  *mp->bufloc = fp->_IO_buf_base;
-  *mp->sizeloc = _IO_blen (fp);
+  *mp->bufloc = fp->_IO_write_base;
+  *mp->sizeloc = fp->_IO_write_ptr - fp->_IO_write_base;
 
   return 0;
 }
 
 
-static int _IO_mem_close (fp)
+static void
+_IO_mem_finish (fp)
      _IO_FILE* fp;
 {
   struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
-  int res;
 
-  res = _IO_default_close (fp);
-  if (res < 0)
-    return res;
+  *mp->bufloc = (char *) realloc (fp->_IO_write_base,
+                                 fp->_IO_write_ptr - fp->_IO_write_base + 1);
+  if (*mp->bufloc != NULL)
+    {
+      (*mp->bufloc)[fp->_IO_write_ptr - fp->_IO_write_base] = '\0';
+      *mp->sizeloc = fp->_IO_write_ptr - fp->_IO_write_base;
+    }
 
-  *mp->bufloc = (char *) realloc (fp->_IO_buf_base, _IO_blen (fp) + 1);
-  if (*mp->bufloc == NULL)
-    return -1;
-  (*mp->bufloc)[_IO_blen (fp)] = '\0';
-  *mp->sizeloc = _IO_blen (fp);
+  fp->_IO_buf_base = NULL;
 
-  return 0;
+  _IO_default_finish (fp);
 }
index 30f753f72d80298f7cbf7bdc8986f8af25634b0f..2a40702c51c5c276c1f2557a2cec3234659d6662 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1994, 1995 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -13,7 +13,7 @@ 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, 1992 Free Software Foundation, Inc., 675 Mass Ave,
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #ifndef        _GNU_TYPES_H
index 3afb555458302ed11bc6f8a253cb9075ba29e266..8ae8b48e1da6ca2dde9a1091dd1319ae6aed99c8 100644 (file)
@@ -39,7 +39,8 @@ distribute := _itoa.h printf-parse.h
 tests := tst-printf tstscanf test_rdwr test-popen tstgetln test-fseek \
         temptest tst-fileno test-fwrite \
         xbug errnobug \
-        bug1 bug2 bug3 bug4 bug5 bug6 bug7
+        bug1 bug2 bug3 bug4 bug5 bug6 bug7 \
+        tfformat tiformat tstdiomisc
 
 
 include ../Rules
index cf17be30a2ea99f8c76ac81b158ed46f6e1e833b..d1122e4e9bd063728103c629982ec206384763b0 100644 (file)
@@ -1,5 +1,5 @@
 /* Regression test for reported old bug that errno is clobbered
-   by the first successful output to a stream on an unseekable object. 
+   by the first successful output to a stream on an unseekable object.
 Copyright (C) 1995 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
@@ -43,7 +43,7 @@ main (void)
     }
 
   errno = 0;
-  if (fputs ("fnord", f))
+  if (fputs ("fnord", f) == EOF)
     {
       perror ("fputs");
       return 1;
index 0f6e9e287b6cbcfd71c420b8f85f09e2a58d9525..9abbdba18713d0c7198685ef989794756070df77 100644 (file)
@@ -32,7 +32,7 @@ Cambridge, MA 02139, USA.  */
 
 struct printf_spec
   {
-    /* Information parsed from the format spec.  */ 
+    /* Information parsed from the format spec.  */
     struct printf_info info;
 
     /* Pointers into the format string for the end of this format
@@ -260,10 +260,6 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
       else
        /* "%.?" is treated like "%.0?".  */
        spec->info.prec = 0;
-
-      /* If there was a precision specified, ignore the 0 flag and always
-        pad with spaces.  */
-      spec->info.pad = ' ';
     }
 
   /* Check for type modifiers.  */
@@ -364,7 +360,7 @@ parse_one_spec (const char *format, size_t posn, struct printf_spec *spec,
          break;
        }
 
-      if (spec->data_arg == -1 && spec->ndata_args > 0) 
+      if (spec->data_arg == -1 && spec->ndata_args > 0)
        {
          /* There are args consumed, but no positional spec.
             Use the next sequential arg position.  */
index 31c009e891cce2be28ba40ee7efdfd9cdb82901c..44f501f2066187745d5bf989556de8ad8fa86ffd 100644 (file)
@@ -345,7 +345,7 @@ __printf_fp (fp, info, args)
   scalesize = 0;
   if (exponent > 2)
     {
-      /* |FP| >= 1.0.  */
+      /* |FP| >= 8.0.  */
       int scaleexpo = 0;
       int explog = LDBL_MAX_10_EXP_LOG;
       int exp10 = 0;
index ea8ea817da4eed33a105c170a5eb0552a38d378a..a35be272e9e3353d62f0e68409e8955357391618 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1995 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
 
 The GNU C Library is free software; you can redistribute it and/or
@@ -19,6 +19,10 @@ Cambridge, MA 02139, USA.  */
 #include <ansidecl.h>
 #include <stdio.h>
 
+#ifdef USE_IN_LIBIO
+# define ssize_t _IO_ssize_t
+#endif
+
 int
 DEFUN_VOID(main)
 {
index c73661973add631f1d004957ecdc16682f05175a..08a488ce810576fdf76896d71676debb44d3b53c 100644 (file)
@@ -96,7 +96,7 @@ ssize_t __printf_pad __P ((FILE *, char pad, size_t n));
   do                                                                         \
     {                                                                        \
       register const int outc = (x);                                         \
-      if (putc (outc, s) == EOF)                                             \
+      if (PUTC (outc, s) == EOF)                                             \
        return -1;                                                            \
       else                                                                   \
        ++done;                                                               \
@@ -230,11 +230,12 @@ vfprintf (s, format, ap)
 
   /* Allocate memory for the argument descriptions.  */
   args_type = alloca (nargs * sizeof (int));
+  memset (args_type, 0, nargs * sizeof (int));
   args_value = alloca (nargs * sizeof (union printf_arg));
 
-  /* XXX Could do sanity check here:
-     Initialize args_type elts to zero.
-     If any is still zero after this loop, format is invalid.  */
+  /* XXX Could do sanity check here: If any element in ARGS_TYPE is
+     still zero after this loop, format is invalid.  For now we simply
+     use 0 as the value.  */
 
   /* Fill in the types of all the arguments.  */
   for (cnt = 0; cnt < nspecs; ++cnt)
@@ -287,6 +288,8 @@ vfprintf (s, format, ap)
       default:
        if ((args_type[cnt] & PA_FLAG_PTR) != 0)
          args_value[cnt].pa_pointer = va_arg (ap, void *);
+       else
+         args_value[cnt].pa_long_double = 0.0;
        break;
       }
 
@@ -420,15 +423,27 @@ vfprintf (s, format, ap)
               char *const workend = &work[sizeof(work) - 1];
               register char *w;
 
-              /* Supply a default precision if none was given.  */
               if (specs[cnt].info.prec == -1)
-                specs[cnt].info.prec = 1;
-
-              /* Put the number in WORK.  */
-              w = _itoa (num, workend + 1, base, specs[cnt].info.spec == 'X');
-             w -= 1;
-              if (specs[cnt].info.group && grouping)
-                w = group_number (w, workend, grouping, thousands_sep);
+                 /* Supply a default precision if none was given.  */
+                 specs[cnt].info.prec = 1;
+             else
+               /* We have to take care for the '0' flag.  If a
+                  precision is given it must be ignored.  */
+               specs[cnt].info.pad = ' ';
+
+             /* If the precision is 0 and the number is 0 nothing has
+                to be written for the number.  */
+             if (specs[cnt].info.prec == 0 && num == 0)
+               w = workend;
+             else
+               {
+                 /* Put the number in WORK.  */
+                 w = _itoa (num, workend + 1, base,
+                            specs[cnt].info.spec == 'X');
+                 w -= 1;
+                 if (specs[cnt].info.group && grouping)
+                   w = group_number (w, workend, grouping, thousands_sep);
+               }
               specs[cnt].info.width -= workend - w;
               specs[cnt].info.prec -= workend - w;
 
@@ -618,8 +633,18 @@ vfprintf (s, format, ap)
 }
 
 #ifdef USE_IN_LIBIO
-#undef vfprintf
+# undef vfprintf
+# ifdef strong_alias
+/* This is for glibc.  */
 strong_alias (_IO_vfprintf, vfprintf)
+# else
+#  if defined __ELF__ || defined __GNU_LIBRARY__
+#   include <gnu-stabs.h>
+#   ifdef weak_alias
+weak_alias (_IO_vfprintf, vfprintf);
+#   endif
+#  endif
+# endif
 #endif
 
 
index b0e48df4f88826ecf9cbd84d50b6b255e86143ec..76c9936abef6d7f7649ab0d3d28f7b1f77a6243b 100644 (file)
@@ -132,6 +132,8 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
   int base;
   /* Signedness for integral numbers.  */
   int number_signed;
+  /* Decimal point character.  */
+  wchar_t decimal;
   /* Integral holding variables.  */
   union
     {
@@ -144,9 +146,24 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
   register char *str, **strptr;
   size_t strsize;
   /* Workspace.  */
-  char work[200];
-  char *w;                     /* Pointer into WORK.  */
-  wchar_t decimal;             /* Decimal point character.  */
+  char *tw;                    /* Temporary pointer.  */
+  char *wp = NULL;             /* Workspace.  */
+  size_t wpsize = 0;           /* Currently used bytes in workspace.  */
+  size_t wpmax = 0;            /* Maximal size of workspace.  */
+#define ADDW(Ch)                                                           \
+  do                                                                       \
+    {                                                                      \
+      if (wpsize == wpmax)                                                 \
+       {                                                                   \
+         char *old = wp;                                                   \
+         wpmax = 200 > 2 * wpmax ? 200 : 2 * wpmax;                        \
+         wp = (char *) alloca (wpmax);                                     \
+         if (wpsize > 0)                                                   \
+           memcpy (wp, old, wpsize);                                       \
+       }                                                                   \
+      wp[wpsize++] = (Ch);                                                 \
+    }                                                                      \
+  while (0)
 
   ARGCHECK (s, format);
 
@@ -338,7 +355,6 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
        conv_error ();
 
       /* Find the conversion specifier.  */
-      w = work;
       fc = *f++;
       if (fc != '[' && fc != 'c' && fc != 'n')
        /* Eat whitespace.  */
@@ -490,7 +506,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
          /* Check for a sign.  */
          if (c == '-' || c == '+')
            {
-             *w++ = c;
+             ADDW (c);
              if (width > 0)
                --width;
              (void) inchar ();
@@ -501,7 +517,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
            {
              if (width > 0)
                --width;
-             *w++ = '0';
+             ADDW ('0');
 
              (void) inchar ();
 
@@ -523,40 +539,40 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
          if (base == 0)
            base = 10;
 
-         /* Read the number into WORK.  */
+         /* Read the number into workspace.  */
          do
            {
              if (base == 16 ? !isxdigit (c) :
                  (!isdigit (c) || c - '0' >= base))
                break;
-             *w++ = c;
+             ADDW (c);
              if (width > 0)
                --width;
            }
          while (inchar () != EOF && width != 0);
 
-         if (w == work ||
-             (w - work == 1 && (work[0] == '+' || work[0] == '-')))
+         if (wpsize == 0 ||
+             (wpsize == 1 && (wp[0] == '+' || wp[0] == '-')))
            /* There was no number.  */
            conv_error ();
 
          /* Convert the number.  */
-         *w = '\0';
+         ADDW ('\0');
          if (is_longlong)
            {
              if (number_signed)
-               num.q = __strtoq_internal (work, &w, base, group_flag);
+               num.q = __strtoq_internal (wp, &tw, base, group_flag);
              else
-               num.uq = __strtouq_internal (work, &w, base, group_flag);
+               num.uq = __strtouq_internal (wp, &tw, base, group_flag);
            }
          else
            {
              if (number_signed)
-               num.l = __strtol_internal (work, &w, base, group_flag);
+               num.l = __strtol_internal (wp, &tw, base, group_flag);
              else
-               num.ul = __strtoul_internal (work, &w, base, group_flag);
+               num.ul = __strtoul_internal (wp, &tw, base, group_flag);
            }
-         if (w == work)
+         if (wp == tw)
            conv_error ();
 
          if (do_assign)
@@ -599,7 +615,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
          /* Check for a sign.  */
          if (c == '-' || c == '+')
            {
-             *w++ = c;
+             ADDW (c);
              if (inchar () == EOF)
                /* EOF is only an input error before we read any chars.  */
                conv_error ();
@@ -611,17 +627,18 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
          do
            {
              if (isdigit (c))
-               *w++ = c;
-             else if (got_e && w[-1] == 'e' && (c == '-' || c == '+'))
-               *w++ = c;
+               ADDW (c);
+             else if (got_e && wp[wpsize - 1] == 'e'
+                      && (c == '-' || c == '+'))
+               ADDW (c);
              else if (!got_e && tolower (c) == 'e')
                {
-                 *w++ = 'e';
+                 ADDW ('e');
                  got_e = got_dot = 1;
                }
              else if (c == decimal && !got_dot)
                {
-                 *w++ = c;
+                 ADDW (c);
                  got_dot = 1;
                }
              else
@@ -630,33 +647,34 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
                --width;
            } while (inchar () != EOF && width != 0);
 
-         if (w == work)
+         if (wpsize == 0)
            conv_error();
-         if (w[-1] == '-' || w[-1] == '+' || w[-1] == 'e')
+         if (wp[wpsize - 1] == '-' || wp[wpsize - 1] == '+'
+             || wp[wpsize - 1] == 'e')
            conv_error ();
 
          /* Convert the number.  */
-         *w = '\0';
+         ADDW ('\0');
          if (is_long_double)
            {
-             long double d = __strtold_internal (work, &w, group_flag);
-             if (do_assign && w != work)
+             long double d = __strtold_internal (wp, &tw, group_flag);
+             if (do_assign && tw != wp)
                *ARG (long double *) = d;
            }
          else if (is_long)
            {
-             double d = __strtod_internal (work, &w, group_flag);
-             if (do_assign && w != work)
+             double d = __strtod_internal (wp, &tw, group_flag);
+             if (do_assign && tw != wp)
                *ARG (double *) = d;
            }
          else
            {
-             float d = __strtof_internal (work, &w, group_flag);
-             if (do_assign && w != work)
+             float d = __strtof_internal (wp, &tw, group_flag);
+             if (do_assign && tw != wp)
                *ARG (float *) = d;
            }
 
-         if (w == work)
+         if (tw == wp)
            conv_error ();
 
          if (do_assign)
@@ -680,23 +698,23 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
          while ((fc = *f++) != '\0' && fc != ']')
            {
              if (fc == '-' && *f != '\0' && *f != ']' &&
-                 w > work && w[-1] <= *f)
+                 wpsize > 0 && wp[wpsize - 1] <= *f)
                /* Add all characters from the one before the '-'
                   up to (but not including) the next format char.  */
-               for (fc = w[-1] + 1; fc < *f; ++fc)
-                 *w++ = fc;
+               for (fc = wp[wpsize - 1] + 1; fc < *f; ++fc)
+                 ADDW (fc);
              else
                /* Add the character to the list.  */
-               *w++ = fc;
+               ADDW (fc);
            }
          if (fc == '\0')
            conv_error();
 
-         *w = '\0';
+         ADDW ('\0');
          num.ul = read_in;
          do
            {
-             if ((strchr (work, c) == NULL) != not_in)
+             if ((strchr (wp, c) == NULL) != not_in)
                break;
              STRING_ADD_CHAR (c);
              if (width > 0)
index e60617ffac337d454e9a3242b1f4f7708e5f5814..8ce6e4d01692387474737bf2bdc505e56241b8b8 100644 (file)
@@ -359,7 +359,10 @@ INTERNAL (STRTOF) (nptr, endptr, group)
        }
     }
   else
-    grouping = NULL;
+    {
+      grouping = NULL;
+      thousands = L'\0';
+    }
 
   /* Find the locale's decimal point character.  */
   if (mbtowc (&decimal, _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT),
@@ -373,7 +376,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
   bits = 0;
 
   /* Parse string to get maximal legal prefix.  We need the number of
-     characters of the interger part, the fractional part and the exponent.  */
+     characters of the integer part, the fractional part and the exponent.  */
   cp = nptr - 1;
   /* Ignore leading white space.  */
   do
@@ -470,7 +473,8 @@ INTERNAL (STRTOF) (nptr, endptr, group)
   int_no = dig_no;
   lead_zero = int_no == 0 ? -1 : 0;
 
-  /* Read the fractional digits.  */
+  /* 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)
     {
       if (isdigit (cp[1]))
@@ -506,11 +510,18 @@ INTERNAL (STRTOF) (nptr, endptr, group)
 
       if (isdigit (c))
        {
+         int exp_limit;
+
+         /* Get the exponent limit. */
+         exp_limit = exp_negative ?
+               -MIN_10_EXP + MANT_DIG - int_no :
+               MAX_10_EXP - int_no + lead_zero;
+
          do
            {
-             if ((!exp_negative && exponent * 10 + int_no > MAX_10_EXP)
-                 || (exp_negative
-                     && exponent * 10 + int_no > -MIN_10_EXP + MANT_DIG))
+             exponent *= 10;
+
+             if (exponent > exp_limit)
                /* The exponent is too large/small to represent a valid
                   number.  */
                {
@@ -530,7 +541,6 @@ INTERNAL (STRTOF) (nptr, endptr, group)
                  /* NOTREACHED */
                }
 
-             exponent *= 10;
              exponent += c - '0';
              c = *++cp;
            }
@@ -563,6 +573,15 @@ INTERNAL (STRTOF) (nptr, endptr, group)
   if (dig_no == 0)
     return 0.0;
 
+  if (lead_zero)
+    {
+      /* Find the decimal point */
+      while (*startp != decimal) startp++;
+      startp += lead_zero + 1;
+      exponent -= lead_zero;
+      dig_no -= lead_zero;
+    }
+
   /* Now we have the number of digits in total and the integer digits as well
      as the exponent and its sign.  We can decide whether the read digits are
      really integer digits or belong to the fractional part; i.e. we normalize
@@ -580,7 +599,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
       return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
     }
 
-  if (exponent - MAX(0, lead_zero) < MIN_10_EXP - (DIG + 1))
+  if (exponent < MIN_10_EXP - (DIG + 1))
     {
       errno = ERANGE;
       return 0.0;
@@ -728,7 +747,7 @@ INTERNAL (STRTOF) (nptr, endptr, group)
     /* We construct a fraction and the result of the division gives us
        the needed digits.  The denominator is 1.0 multiplied by the
        exponent of the lowest digit; i.e. 0.123 gives 123 / 1000 and
-       123e6 gives 123 / 1000000.  */
+       123e-6 gives 123 / 1000000.  */
 
     int expbit;
     int cnt;
@@ -748,9 +767,9 @@ INTERNAL (STRTOF) (nptr, endptr, group)
        digits we should have enough bits for the result.  The remaining
        decimal digits give us the information that more bits are following.
        This can be used while rounding.  (One added as a safety margin.)  */
-    if (dig_no - int_no - lead_zero > (MANT_DIG - bits + 2) / 3 + 1)
+    if (dig_no - int_no > (MANT_DIG - bits + 2) / 3 + 1)
       {
-        dig_no = int_no + lead_zero + (MANT_DIG - bits + 2) / 3 + 1;
+        dig_no = int_no + (MANT_DIG - bits + 2) / 3 + 1;
         more_bits = 1;
       }
     else
@@ -789,14 +808,6 @@ INTERNAL (STRTOF) (nptr, endptr, group)
     if (psrc == num)
       memcpy (den, num, densize * sizeof (mp_limb));
 
-    /* If we have leading zeroes now reduce the number of significant digits
-       and set the pointer to the first non-0 digit.  */
-    if (lead_zero > 0)
-      {
-       startp += lead_zero + 1;        /* +1 for radix character */
-       dig_no -= lead_zero;
-      }
-
     /* Read the fractional digits from the string.  */
     (void) str_to_mpn (startp, dig_no - int_no, num, &numsize, &exponent);
 
@@ -898,23 +909,34 @@ INTERNAL (STRTOF) (nptr, endptr, group)
 
          if (numsize < densize)
            {
-             if (bits <= 0)
-               exponent -= BITS_PER_MP_LIMB;
+             if (num[0] >= d1)
+               {
+                 /* The nominator of the number occupies fewer bits than
+                    the denominator but the one limb is bigger than the
+                    high limb of the nominator.  */
+                 n1 = 0;
+                 n0 = num[0];
+               }
              else
                {
-                 if (bits + BITS_PER_MP_LIMB <= MANT_DIG)
-                   __mpn_lshift_1 (retval, RETURN_LIMB_SIZE,
-                                   BITS_PER_MP_LIMB, 0);
+                 if (bits <= 0)
+                   exponent -= BITS_PER_MP_LIMB;
                  else
                    {
-                     used = MANT_DIG - bits;
-                     if (used > 0)
-                       __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, 0);
+                     if (bits + BITS_PER_MP_LIMB <= MANT_DIG)
+                       __mpn_lshift_1 (retval, RETURN_LIMB_SIZE,
+                                       BITS_PER_MP_LIMB, 0);
+                     else
+                       {
+                         used = MANT_DIG - bits;
+                         if (used > 0)
+                           __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, 0);
+                       }
+                     bits += BITS_PER_MP_LIMB;
                    }
-                 bits += BITS_PER_MP_LIMB;
+                 n1 = num[0];
+                 n0 = 0;
                }
-             n1 = num[0];
-             n0 = 0;
            }
          else
            {
index 9be45ed93b17988f64f86b006e82060a03a213c0..f52f9c60bcb3c18949c326d535ae8dd56e2c18b3 100644 (file)
@@ -27,16 +27,16 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
    size                (sp + 16)
 */
 
-#define r1     %eax
-#define r2     %edx
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+#define t1     %eax
+#define t2     %edx
 #define src1   %esi
 #define src2   %ebp
 #define dst    %edi
 #define x      %ebx
 
-#include "sysdep.h"
-#include "asm-syntax.h"
-
 .text
        ALIGN (3)
        .globl C_SYMBOL_NAME(__mpn_add_n)
@@ -54,77 +54,77 @@ C_SYMBOL_NAME(__mpn_add_n:)
        movl    (src2),x
 
        decl    %ecx
-       movl    %ecx,r2
+       movl    %ecx,t2
        shrl    $3,%ecx
-       andl    $7,r2
+       andl    $7,t2
        testl   %ecx,%ecx               /* zero carry flag */
        jz      Lend
-       pushl   r2
+       pushl   t2
 
        ALIGN (3)
 Loop:  movl    28(dst),%eax            /* fetch destination cache line */
        leal    32(dst),dst
 
-L1:    movl    (src1),r1
-       movl    4(src1),r2
-       adcl    x,r1
+L1:    movl    (src1),t1
+       movl    4(src1),t2
+       adcl    x,t1
        movl    4(src2),x
-       adcl    x,r2
+       adcl    x,t2
        movl    8(src2),x
-       movl    r1,-32(dst)
-       movl    r2,-28(dst)
+       movl    t1,-32(dst)
+       movl    t2,-28(dst)
 
-L2:    movl    8(src1),r1
-       movl    12(src1),r2
-       adcl    x,r1
+L2:    movl    8(src1),t1
+       movl    12(src1),t2
+       adcl    x,t1
        movl    12(src2),x
-       adcl    x,r2
+       adcl    x,t2
        movl    16(src2),x
-       movl    r1,-24(dst)
-       movl    r2,-20(dst)
+       movl    t1,-24(dst)
+       movl    t2,-20(dst)
 
-L3:    movl    16(src1),r1
-       movl    20(src1),r2
-       adcl    x,r1
+L3:    movl    16(src1),t1
+       movl    20(src1),t2
+       adcl    x,t1
        movl    20(src2),x
-       adcl    x,r2
+       adcl    x,t2
        movl    24(src2),x
-       movl    r1,-16(dst)
-       movl    r2,-12(dst)
+       movl    t1,-16(dst)
+       movl    t2,-12(dst)
 
-L4:    movl    24(src1),r1
-       movl    28(src1),r2
-       adcl    x,r1
+L4:    movl    24(src1),t1
+       movl    28(src1),t2
+       adcl    x,t1
        movl    28(src2),x
-       adcl    x,r2
+       adcl    x,t2
        movl    32(src2),x
-       movl    r1,-8(dst)
-       movl    r2,-4(dst)
+       movl    t1,-8(dst)
+       movl    t2,-4(dst)
 
        leal    32(src1),src1
        leal    32(src2),src2
        decl    %ecx
        jnz     Loop
 
-       popl    r2
+       popl    t2
 Lend:
-       decl    r2                      /* test r2 w/o clobbering carry */
+       decl    t2                      /* test t2 w/o clobbering carry */
        js      Lend2
-       incl    r2
+       incl    t2
 Loop2:
        leal    4(dst),dst
-       movl    (src1),r1
-       adcl    x,r1
+       movl    (src1),t1
+       adcl    x,t1
        movl    4(src2),x
-       movl    r1,-4(dst)
+       movl    t1,-4(dst)
        leal    4(src1),src1
        leal    4(src2),src2
-       decl    r2
+       decl    t2
        jnz     Loop2
 Lend2:
-       movl    (src1),r1
-       adcl    x,r1
-       movl    r1,(dst)
+       movl    (src1),t1
+       adcl    x,t1
+       movl    t1,(dst)
 
        sbbl    %eax,%eax
        negl    %eax
index 1382e665f67f73348b52370cdec19bcdb5546802..9c964a82f3f8671c3b821c6a15f440e91393c5c4 100644 (file)
@@ -27,16 +27,16 @@ the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
    size                (sp + 16)
 */
 
-#define r1     %eax
-#define r2     %edx
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+#define t1     %eax
+#define t2     %edx
 #define src1   %esi
 #define src2   %ebp
 #define dst    %edi
 #define x      %ebx
 
-#include "sysdep.h"
-#include "asm-syntax.h"
-
 .text
        ALIGN (3)
        .globl C_SYMBOL_NAME(__mpn_sub_n)
@@ -54,77 +54,77 @@ C_SYMBOL_NAME(__mpn_sub_n:)
        movl    (src2),x
 
        decl    %ecx
-       movl    %ecx,r2
+       movl    %ecx,t2
        shrl    $3,%ecx
-       andl    $7,r2
+       andl    $7,t2
        testl   %ecx,%ecx               /* zero carry flag */
        jz      Lend
-       pushl   r2
+       pushl   t2
 
        ALIGN (3)
 Loop:  movl    28(dst),%eax            /* fetch destination cache line */
        leal    32(dst),dst
 
-L1:    movl    (src1),r1
-       movl    4(src1),r2
-       sbbl    x,r1
+L1:    movl    (src1),t1
+       movl    4(src1),t2
+       sbbl    x,t1
        movl    4(src2),x
-       sbbl    x,r2
+       sbbl    x,t2
        movl    8(src2),x
-       movl    r1,-32(dst)
-       movl    r2,-28(dst)
+       movl    t1,-32(dst)
+       movl    t2,-28(dst)
 
-L2:    movl    8(src1),r1
-       movl    12(src1),r2
-       sbbl    x,r1
+L2:    movl    8(src1),t1
+       movl    12(src1),t2
+       sbbl    x,t1
        movl    12(src2),x
-       sbbl    x,r2
+       sbbl    x,t2
        movl    16(src2),x
-       movl    r1,-24(dst)
-       movl    r2,-20(dst)
+       movl    t1,-24(dst)
+       movl    t2,-20(dst)
 
-L3:    movl    16(src1),r1
-       movl    20(src1),r2
-       sbbl    x,r1
+L3:    movl    16(src1),t1
+       movl    20(src1),t2
+       sbbl    x,t1
        movl    20(src2),x
-       sbbl    x,r2
+       sbbl    x,t2
        movl    24(src2),x
-       movl    r1,-16(dst)
-       movl    r2,-12(dst)
+       movl    t1,-16(dst)
+       movl    t2,-12(dst)
 
-L4:    movl    24(src1),r1
-       movl    28(src1),r2
-       sbbl    x,r1
+L4:    movl    24(src1),t1
+       movl    28(src1),t2
+       sbbl    x,t1
        movl    28(src2),x
-       sbbl    x,r2
+       sbbl    x,t2
        movl    32(src2),x
-       movl    r1,-8(dst)
-       movl    r2,-4(dst)
+       movl    t1,-8(dst)
+       movl    t2,-4(dst)
 
        leal    32(src1),src1
        leal    32(src2),src2
        decl    %ecx
        jnz     Loop
 
-       popl    r2
+       popl    t2
 Lend:
-       decl    r2                      /* test r2 w/o clobbering carry */
+       decl    t2                      /* test t2 w/o clobbering carry */
        js      Lend2
-       incl    r2
+       incl    t2
 Loop2:
        leal    4(dst),dst
-       movl    (src1),r1
-       sbbl    x,r1
+       movl    (src1),t1
+       sbbl    x,t1
        movl    4(src2),x
-       movl    r1,-4(dst)
+       movl    t1,-4(dst)
        leal    4(src1),src1
        leal    4(src2),src2
-       decl    r2
+       decl    t2
        jnz     Loop2
 Lend2:
-       movl    (src1),r1
-       sbbl    x,r1
-       movl    r1,(dst)
+       movl    (src1),t1
+       sbbl    x,t1
+       movl    t1,(dst)
 
        sbbl    %eax,%eax
        negl    %eax