Fri Dec 15 04:41:22 1995 Ulrich Drepper <drepper@gnu.ai.mit.edu> cvs/libc-951215
authorRoland McGrath <roland@gnu.org>
Fri, 15 Dec 1995 05:22:35 +0000 (05:22 +0000)
committerRoland McGrath <roland@gnu.org>
Fri, 15 Dec 1995 05:22:35 +0000 (05:22 +0000)
* stdio-common/Makefile (tests): Add bug10.
* stdio-common/bug10.c: New file.  From HJ Lu.

* stdio-common/tstdiomisc.c: Make more test-suite like: exit
status tells about successful run.

* stdio-common/vfscanf.c [!USE_IN_LIBIO]: Use `flags' to check
format correctness.
Correct handling of trailing white spaces in format + EOF.

Fri Dec 15 01:31:56 1995  Ulrich Drepper  <drepper@gnu.ai.mit.edu>

* stdio-common/Makefile (tests): Add bug8 and bug9.
* stdio-common/bug8.c, stdio-common/bug9.c: New tests.

* stdio-common/vfscanf.c: Fix bug in dynamic buffer handling.

* stdlib/strtod.c: Correct spelling: nominator -> numerator.
Thanks to Jim Meyering.

Sat Nov 25 06:05:12 1995  H.J. Lu  <hjl@nynexst.com>

* stdio-common/vfscanf.c: Always check width !=0.
Correctly handle %%.

ChangeLog
stdio-common/Makefile
stdio-common/bug10.c [new file with mode: 0644]
stdio-common/bug8.c [new file with mode: 0644]
stdio-common/bug9.c [new file with mode: 0644]
stdio-common/tstdiomisc.c
stdio-common/vfscanf.c
stdlib/strtod.c

index 35559b7..d09be84 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+Fri Dec 15 04:41:22 1995  Ulrich Drepper  <drepper@gnu.ai.mit.edu>
+
+       * stdio-common/Makefile (tests): Add bug10.
+       * stdio-common/bug10.c: New file.  From HJ Lu.
+
+       * stdio-common/tstdiomisc.c: Make more test-suite like: exit
+       status tells about successful run.
+
+       * stdio-common/vfscanf.c [!USE_IN_LIBIO]: Use `flags' to check
+       format correctness.
+       Correct handling of trailing white spaces in format + EOF.
+
+Fri Dec 15 01:31:56 1995  Ulrich Drepper  <drepper@gnu.ai.mit.edu>
+
+       * stdio-common/Makefile (tests): Add bug8 and bug9.
+       * stdio-common/bug8.c, stdio-common/bug9.c: New tests.
+
+       * stdio-common/vfscanf.c: Fix bug in dynamic buffer handling.
+
+       * stdlib/strtod.c: Correct spelling: nominator -> numerator.
+       Thanks to Jim Meyering.
+
+Sat Nov 25 06:05:12 1995  H.J. Lu  <hjl@nynexst.com>
+
+       * stdio-common/vfscanf.c: Always check width !=0.
+       Correctly handle %%.
 Thu Dec 14 02:28:22 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>
 
        * posix/glob.c (glob_in_dir): Cast result of opendir to __ptr_t,
index 8ae8b48..a718db6 100644 (file)
@@ -39,7 +39,7 @@ 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 bug8 bug9 bug10 \
         tfformat tiformat tstdiomisc
 
 
diff --git a/stdio-common/bug10.c b/stdio-common/bug10.c
new file mode 100644 (file)
index 0000000..3e1477d
--- /dev/null
@@ -0,0 +1,26 @@
+#include <stdio.h>
+int main(int arc, char *argv)
+{
+  int n, res;
+  unsigned int val;
+  char *s;
+  int result = 0;
+
+  s = "111";
+
+  n = 0;
+  res = sscanf(s, "%u %n", &val, &n);
+
+  printf("Result of sscanf = %d\n", res);
+  printf("Scanned format %%u = %u\n", val);
+  printf("Possibly scanned format %%n = %d\n", n);
+  result |= res != 1 || val != 111 || n != 3;
+
+
+  result |= sscanf ("", " %n", &n) == EOF;
+
+  puts (result ? "Test failed" : "All tests passed");
+
+  return result;
+}
+
diff --git a/stdio-common/bug8.c b/stdio-common/bug8.c
new file mode 100644 (file)
index 0000000..39a4185
--- /dev/null
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <string.h>
+
+main()
+{
+    char buf[100];
+    int point, x, y;
+    int status = 0;
+
+    sscanf("0x10 10", "%x %x", &x, &y);
+    sprintf(buf, "%d %d", x, y);
+    puts (buf);
+    status |= strcmp (buf, "16 16");
+    sscanf("P012349876", "P%1d%4d%4d", &point, &x, &y);
+    sprintf(buf, "%d %d %d", point, x, y);
+    status |= strcmp (buf, "0 1234 9876");
+    puts (buf);
+    sscanf("P112349876", "P%1d%4d%4d", &point, &x, &y);
+    sprintf(buf, "%d %d %d", point, x, y);
+    status |= strcmp (buf, "1 1234 9876");
+    puts (buf);
+
+    puts (status ? "Test failed" : "Test passed");
+
+    return status;
+} 
diff --git a/stdio-common/bug9.c b/stdio-common/bug9.c
new file mode 100644 (file)
index 0000000..5a7166c
--- /dev/null
@@ -0,0 +1,22 @@
+#include <stdio.h>
+#include <string.h>
+
+int
+main()
+{
+  char buf[100];
+  int a, b;
+  int status = 0;
+
+  sscanf ("12ab", "%dab%n", &a, &b);
+  sprintf (buf, "%d, %d", a, b);
+  puts (buf);
+  status |= strcmp (buf, "12, 4");
+
+  sscanf ("12ab100", "%dab%n100", &a, &b);
+  sprintf (buf, "%d, %d", a, b);
+  puts (buf);
+  status |= strcmp (buf, "12, 4");
+
+  return status;
+}
index 0bd5515..66e1fe3 100644 (file)
@@ -1,40 +1,49 @@
 #include <stdio.h>
 
-void
+int
 t1 ()
 {
   int n = -1;
   sscanf ("abc  ", "abc %n", &n);
   printf ("t1: count=%d\n", n);
+
+  return n != 5;
 }
 
-void
+int
 t2 ()
 {
+  int result = 0;
   int n;
   long N;
   int retval;
-#define SCAN(INPUT, FORMAT, VAR) \
+#define SCAN(INPUT, FORMAT, VAR, EXP_RES, EXP_VAL) \
   VAR = -1; \
   retval = sscanf (INPUT, FORMAT,  &VAR); \
   printf ("sscanf (\"%s\", \"%s\", &x) => %d, x = %ld\n", \
-         INPUT, FORMAT, retval, VAR);
-
-  SCAN ("12345", "%ld", N);
-  SCAN ("12345", "%llllld", N);
-  SCAN ("12345", "%LLLLLd", N);
-  SCAN ("test ", "%*s%n",  n);
-  SCAN ("test ",   "%2*s%n",  n);
-  SCAN ("12 ",   "%l2d",  n);
-  SCAN ("12 ",   "%2ld",  N);
+         INPUT, FORMAT, retval, VAR); \
+  result |= retval != EXP_RES || VAR != EXP_VAL
+
+  SCAN ("12345", "%ld", N, 1, 12345);
+  SCAN ("12345", "%llllld", N, 0, -1);
+  SCAN ("12345", "%LLLLLd", N, 0, -1);
+  SCAN ("test ", "%*s%n",  n, 0, 4);
+  SCAN ("test ",   "%2*s%n",  n, 0, -1);
+  SCAN ("12 ",   "%l2d",  n, 0, -1);
+  SCAN ("12 ",   "%2ld",  N, 1, 12);
+
+  return result;
 }
 
 int
 main ()
 {
-  t1 ();
-  t2 ();
+  int result = 0;
+
+  result |= t1 ();
+  result |= t2 ();
+
+  result |= fflush (stdout) == EOF;
 
-  fflush (stdout);
-  return 0;
+  return result;
 }
index 76c9936..df68260 100644 (file)
@@ -34,10 +34,6 @@ Cambridge, MA 02139, USA.  */
 #define        LONGLONG        long
 #endif
 
-#ifdef USE_IN_LIBIO
-# include <libioP.h>
-# include <libio.h>
-
 /* Those are flags in the conversion format. */
 # define LONG          0x01    /* l: long or double */
 # define LONGDBL       0x02    /* L: long long or long double */
@@ -48,11 +44,15 @@ Cambridge, MA 02139, USA.  */
 # define WIDTH         0x40    /* width */
 
 
+#ifdef USE_IN_LIBIO
+# include <libioP.h>
+# include <libio.h>
+
 # define va_list       _IO_va_list
 # define ungetc(c, s)  _IO_ungetc (c, s)
-# define inchar()      ((c = _IO_getc(s)), ++read_in, c)
+# define inchar()      ((c = _IO_getc (s)), ++read_in, c)
 # define conv_error()  return ((errp != NULL && (*errp |= 2)), \
-                               (c == EOF || _IO_ungetc(c, s)), done)
+                               (c == EOF || _IO_ungetc (c, s)), done)
 
 # define input_error() return ((errp != NULL && (*errp |= 1)), \
                                done == 0 ? EOF : done)
@@ -69,8 +69,8 @@ Cambridge, MA 02139, USA.  */
        }                                                                    \
     } while (0)
 #else
-# define inchar()      ((c = getc(s)) == EOF ? EOF : (++read_in, c))
-# define conv_error()  return (ungetc(c, s), done)
+# define inchar()      ((c = getc (s)), ++read_in, c)
+# define conv_error()  return (ungetc (c, s), done)
 # define input_error() return (done == 0 ? EOF : done)
 # define memory_error()        return ((errno = ENOMEM), EOF)
 # define ARGCHECK(s, format)                                                \
@@ -111,9 +111,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
   register int do_assign;      /* Whether to do an assignment.  */
   register int width;          /* Maximum field width.  */
   int group_flag;              /* %' modifier flag.  */
-#ifdef USE_IN_LIBIO
   int flags;                   /* Trace flags for current format element.  */
-#endif
 
   /* Type modifiers.  */
   int is_short, is_long, is_long_double;
@@ -145,11 +143,15 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
   /* Character-buffer pointer.  */
   register char *str, **strptr;
   size_t strsize;
+  /* We must not react on white spaces immediately because they can
+     possibly be matched even if in the input stream no character is
+     available anymore.  */
+  int skip_space = 0;
   /* Workspace.  */
   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.  */
+  size_t wpsize;               /* Currently used bytes in workspace.  */
 #define ADDW(Ch)                                                           \
   do                                                                       \
     {                                                                      \
@@ -158,7 +160,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
          char *old = wp;                                                   \
          wpmax = 200 > 2 * wpmax ? 200 : 2 * wpmax;                        \
          wp = (char *) alloca (wpmax);                                     \
-         if (wpsize > 0)                                                   \
+         if (old != NULL)                                                  \
            memcpy (wp, old, wpsize);                                       \
        }                                                                   \
       wp[wpsize++] = (Ch);                                                 \
@@ -220,27 +222,37 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
       fc = *f++;
       if (fc != '%')
        {
+         /* Remember to skip spaces.  */
+         if (isspace (fc))
+           {
+             skip_space = 1;
+             continue;
+           }
+
          /* Characters other than format specs must just match.  */
          if (c == EOF)
            input_error ();
-         if (isspace (fc))
+
+         /* We saw an white space as the last character in the format
+            string.  Now it's time to skip all leading white
+            spaces.  */
+         if (skip_space)
            {
-             /* Whitespace characters match any amount of whitespace.  */
              while (isspace (c))
-               inchar ();
-             continue;
+               (void) inchar ();
+             skip_space = 0;
            }
+
          else if (c == fc)
            (void) inchar ();
          else
            conv_error ();
+
          continue;
        }
 
-#ifdef USE_IN_LIBIO
-      /* That is the start of the coversion string. */
+      /* This is the start of the conversion string. */
       flags = 0;
-#endif
 
       /* Initialize state of modifiers.  */
       argpos = 0;
@@ -248,6 +260,9 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
       group_flag = 0;
       is_short = is_long = is_long_double = malloc_string = 0;
 
+      /* Prepare temporary buffer.  */
+      wpsize = 0;
+
       /* Check for a positional parameter specification.  */
       if (isdigit (*f))
        {
@@ -270,9 +285,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
        switch (*f++)
          {
          case '*':
-#ifdef USE_IN_LIBIO
            flags = SUPPRESS;
-#endif
            do_assign = 0;
            break;
          case '\'':
@@ -280,11 +293,9 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
            break;
          }
 
-#ifdef USE_IN_LIBIO
       /* We have seen width. */
       if (isdigit (*f))
        flags |= WIDTH;
-#endif
 
       /* Find the maximum field width.  */
       width = 0;
@@ -303,44 +314,36 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
          {
          case 'h':
            /* int's are short int's.  */
-#ifdef USE_IN_LIBIO
            if (flags & ~(SUPPRESS | WIDTH))
              /* Signal illegal format element.  */
              conv_error ();
            flags |= SHORT;
-#endif
            is_short = 1;
            break;
          case 'l':
            if (is_long)
              {
                /* A double `l' is equivalent to an `L'.  */
-#ifdef USE_IN_LIBIO
-               if ((flags & ~(SUPPRESS | WIDTH)) && (flags & LONGDBL))
+               if ((flags & ~(SUPPRESS | WIDTH)))
                  conv_error ();
                flags &= ~LONG;
                flags |= LONGDBL;
-#endif
                is_longlong = 1;
              }
            else
              {
                /* int's are long int's.  */
-#ifdef USE_IN_LIBIO
                flags |= LONG;
-#endif
                is_long = 1;
              }
            break;
          case 'q':
          case 'L':
            /* double's are long double's, and int's are long long int's.  */
-#ifdef USE_IN_LIBIO
            if (flags & ~(SUPPRESS | WIDTH))
              /* Signal illegal format element.  */
              conv_error ();
            flags |= LONGDBL;
-#endif
            is_long_double = 1;
            break;
          case 'a':
@@ -356,15 +359,20 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
 
       /* Find the conversion specifier.  */
       fc = *f++;
-      if (fc != '[' && fc != 'c' && fc != 'n')
-       /* Eat whitespace.  */
-       while (isspace (c))
-         (void) inchar ();
+      if (skip_space || (fc != '[' && fc != 'c' && fc != 'n'))
+       {
+         /* Eat whitespace.  */
+         while (isspace (c))
+           (void) inchar ();
+         skip_space = 0;
+       }
+
       switch (fc)
        {
        case '%':       /* Must match a literal '%'.  */
          if (c != fc)
            conv_error ();
+         inchar ();
          break;
 
        case 'n':       /* Answer number of assignments done.  */
@@ -444,7 +452,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
                            {                                                 \
                              /* We lose.  Oh well.                           \
                                 Terminate the string and stop converting,    \
-                                so at least we don't swallow any input.  */  \
+                                so at least we don't skip any input.  */  \
                              (*strptr)[strsize] = '\0';                      \
                              ++done;                                         \
                              conv_error ();                                  \
@@ -513,7 +521,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
            }
 
          /* Look for a leading indication of base.  */
-         if (c == '0')
+         if (width != 0 && c == '0')
            {
              if (width > 0)
                --width;
@@ -521,7 +529,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
 
              (void) inchar ();
 
-             if (tolower (c) == 'x')
+             if (width != 0 && tolower (c) == 'x')
                {
                  if (base == 0)
                    base = 16;
@@ -540,7 +548,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
            base = 10;
 
          /* Read the number into workspace.  */
-         do
+         while (c != EOF && width != 0)
            {
              if (base == 16 ? !isxdigit (c) :
                  (!isdigit (c) || c - '0' >= base))
@@ -548,8 +556,9 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
              ADDW (c);
              if (width > 0)
                --width;
+
+             (void) inchar ();
            }
-         while (inchar () != EOF && width != 0);
 
          if (wpsize == 0 ||
              (wpsize == 1 && (wp[0] == '+' || wp[0] == '-')))
@@ -739,6 +748,12 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
        }
     }
 
+  /* The last thing we saw int the format string was a white space.
+     Consume the last white spaces.  */
+  if (skip_space)
+    while (isspace (c))
+      (void) inchar ();
+
   return ((c == EOF || ungetc (c, s)), done);
 }
 
index 8ce6e4d..4104a98 100644 (file)
@@ -911,9 +911,9 @@ INTERNAL (STRTOF) (nptr, endptr, group)
            {
              if (num[0] >= d1)
                {
-                 /* The nominator of the number occupies fewer bits than
+                 /* The numerator of the number occupies fewer bits than
                     the denominator but the one limb is bigger than the
-                    high limb of the nominator.  */
+                    high limb of the numerator.  */
                  n1 = 0;
                  n0 = num[0];
                }