1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

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 %%.
This commit is contained in:
Roland McGrath
1995-12-15 05:22:35 +00:00
parent faf92f2a62
commit 05be689b57
8 changed files with 183 additions and 59 deletions

View File

@ -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> 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, * posix/glob.c (glob_in_dir): Cast result of opendir to __ptr_t,

View File

@ -39,7 +39,7 @@ distribute := _itoa.h printf-parse.h
tests := tst-printf tstscanf test_rdwr test-popen tstgetln test-fseek \ tests := tst-printf tstscanf test_rdwr test-popen tstgetln test-fseek \
temptest tst-fileno test-fwrite \ temptest tst-fileno test-fwrite \
xbug errnobug \ xbug errnobug \
bug1 bug2 bug3 bug4 bug5 bug6 bug7 \ bug1 bug2 bug3 bug4 bug5 bug6 bug7 bug8 bug9 bug10 \
tfformat tiformat tstdiomisc tfformat tiformat tstdiomisc

26
stdio-common/bug10.c Normal file
View File

@ -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;
}

26
stdio-common/bug8.c Normal file
View File

@ -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;
}

22
stdio-common/bug9.c Normal file
View File

@ -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;
}

View File

@ -1,40 +1,49 @@
#include <stdio.h> #include <stdio.h>
void int
t1 () t1 ()
{ {
int n = -1; int n = -1;
sscanf ("abc ", "abc %n", &n); sscanf ("abc ", "abc %n", &n);
printf ("t1: count=%d\n", n); printf ("t1: count=%d\n", n);
return n != 5;
} }
void int
t2 () t2 ()
{ {
int result = 0;
int n; int n;
long N; long N;
int retval; int retval;
#define SCAN(INPUT, FORMAT, VAR) \ #define SCAN(INPUT, FORMAT, VAR, EXP_RES, EXP_VAL) \
VAR = -1; \ VAR = -1; \
retval = sscanf (INPUT, FORMAT, &VAR); \ retval = sscanf (INPUT, FORMAT, &VAR); \
printf ("sscanf (\"%s\", \"%s\", &x) => %d, x = %ld\n", \ printf ("sscanf (\"%s\", \"%s\", &x) => %d, x = %ld\n", \
INPUT, FORMAT, retval, VAR); INPUT, FORMAT, retval, VAR); \
result |= retval != EXP_RES || VAR != EXP_VAL
SCAN ("12345", "%ld", N); SCAN ("12345", "%ld", N, 1, 12345);
SCAN ("12345", "%llllld", N); SCAN ("12345", "%llllld", N, 0, -1);
SCAN ("12345", "%LLLLLd", N); SCAN ("12345", "%LLLLLd", N, 0, -1);
SCAN ("test ", "%*s%n", n); SCAN ("test ", "%*s%n", n, 0, 4);
SCAN ("test ", "%2*s%n", n); SCAN ("test ", "%2*s%n", n, 0, -1);
SCAN ("12 ", "%l2d", n); SCAN ("12 ", "%l2d", n, 0, -1);
SCAN ("12 ", "%2ld", N); SCAN ("12 ", "%2ld", N, 1, 12);
return result;
} }
int int
main () main ()
{ {
t1 (); int result = 0;
t2 ();
fflush (stdout); result |= t1 ();
return 0; result |= t2 ();
result |= fflush (stdout) == EOF;
return result;
} }

View File

@ -34,10 +34,6 @@ Cambridge, MA 02139, USA. */
#define LONGLONG long #define LONGLONG long
#endif #endif
#ifdef USE_IN_LIBIO
# include <libioP.h>
# include <libio.h>
/* Those are flags in the conversion format. */ /* Those are flags in the conversion format. */
# define LONG 0x01 /* l: long or double */ # define LONG 0x01 /* l: long or double */
# define LONGDBL 0x02 /* L: long long or long double */ # define LONGDBL 0x02 /* L: long long or long double */
@ -48,11 +44,15 @@ Cambridge, MA 02139, USA. */
# define WIDTH 0x40 /* width */ # define WIDTH 0x40 /* width */
#ifdef USE_IN_LIBIO
# include <libioP.h>
# include <libio.h>
# define va_list _IO_va_list # define va_list _IO_va_list
# define ungetc(c, s) _IO_ungetc (c, s) # 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)), \ # 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)), \ # define input_error() return ((errp != NULL && (*errp |= 1)), \
done == 0 ? EOF : done) done == 0 ? EOF : done)
@ -69,8 +69,8 @@ Cambridge, MA 02139, USA. */
} \ } \
} while (0) } while (0)
#else #else
# define inchar() ((c = getc(s)) == EOF ? EOF : (++read_in, c)) # define inchar() ((c = getc (s)), ++read_in, c)
# define conv_error() return (ungetc(c, s), done) # define conv_error() return (ungetc (c, s), done)
# define input_error() return (done == 0 ? EOF : done) # define input_error() return (done == 0 ? EOF : done)
# define memory_error() return ((errno = ENOMEM), EOF) # define memory_error() return ((errno = ENOMEM), EOF)
# define ARGCHECK(s, format) \ # 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 do_assign; /* Whether to do an assignment. */
register int width; /* Maximum field width. */ register int width; /* Maximum field width. */
int group_flag; /* %' modifier flag. */ int group_flag; /* %' modifier flag. */
#ifdef USE_IN_LIBIO
int flags; /* Trace flags for current format element. */ int flags; /* Trace flags for current format element. */
#endif
/* Type modifiers. */ /* Type modifiers. */
int is_short, is_long, is_long_double; int is_short, is_long, is_long_double;
@ -145,11 +143,15 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
/* Character-buffer pointer. */ /* Character-buffer pointer. */
register char *str, **strptr; register char *str, **strptr;
size_t strsize; 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. */ /* Workspace. */
char *tw; /* Temporary pointer. */ char *tw; /* Temporary pointer. */
char *wp = NULL; /* Workspace. */ char *wp = NULL; /* Workspace. */
size_t wpsize = 0; /* Currently used bytes in workspace. */
size_t wpmax = 0; /* Maximal size of workspace. */ size_t wpmax = 0; /* Maximal size of workspace. */
size_t wpsize; /* Currently used bytes in workspace. */
#define ADDW(Ch) \ #define ADDW(Ch) \
do \ do \
{ \ { \
@ -158,7 +160,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
char *old = wp; \ char *old = wp; \
wpmax = 200 > 2 * wpmax ? 200 : 2 * wpmax; \ wpmax = 200 > 2 * wpmax ? 200 : 2 * wpmax; \
wp = (char *) alloca (wpmax); \ wp = (char *) alloca (wpmax); \
if (wpsize > 0) \ if (old != NULL) \
memcpy (wp, old, wpsize); \ memcpy (wp, old, wpsize); \
} \ } \
wp[wpsize++] = (Ch); \ wp[wpsize++] = (Ch); \
@ -220,27 +222,37 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
fc = *f++; fc = *f++;
if (fc != '%') if (fc != '%')
{ {
/* Remember to skip spaces. */
if (isspace (fc))
{
skip_space = 1;
continue;
}
/* Characters other than format specs must just match. */ /* Characters other than format specs must just match. */
if (c == EOF) if (c == EOF)
input_error (); 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)) while (isspace (c))
inchar (); (void) inchar ();
continue; skip_space = 0;
} }
else if (c == fc) else if (c == fc)
(void) inchar (); (void) inchar ();
else else
conv_error (); conv_error ();
continue; continue;
} }
#ifdef USE_IN_LIBIO /* This is the start of the conversion string. */
/* That is the start of the coversion string. */
flags = 0; flags = 0;
#endif
/* Initialize state of modifiers. */ /* Initialize state of modifiers. */
argpos = 0; argpos = 0;
@ -248,6 +260,9 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
group_flag = 0; group_flag = 0;
is_short = is_long = is_long_double = malloc_string = 0; is_short = is_long = is_long_double = malloc_string = 0;
/* Prepare temporary buffer. */
wpsize = 0;
/* Check for a positional parameter specification. */ /* Check for a positional parameter specification. */
if (isdigit (*f)) if (isdigit (*f))
{ {
@ -270,9 +285,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
switch (*f++) switch (*f++)
{ {
case '*': case '*':
#ifdef USE_IN_LIBIO
flags = SUPPRESS; flags = SUPPRESS;
#endif
do_assign = 0; do_assign = 0;
break; break;
case '\'': case '\'':
@ -280,11 +293,9 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
break; break;
} }
#ifdef USE_IN_LIBIO
/* We have seen width. */ /* We have seen width. */
if (isdigit (*f)) if (isdigit (*f))
flags |= WIDTH; flags |= WIDTH;
#endif
/* Find the maximum field width. */ /* Find the maximum field width. */
width = 0; width = 0;
@ -303,44 +314,36 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
{ {
case 'h': case 'h':
/* int's are short int's. */ /* int's are short int's. */
#ifdef USE_IN_LIBIO
if (flags & ~(SUPPRESS | WIDTH)) if (flags & ~(SUPPRESS | WIDTH))
/* Signal illegal format element. */ /* Signal illegal format element. */
conv_error (); conv_error ();
flags |= SHORT; flags |= SHORT;
#endif
is_short = 1; is_short = 1;
break; break;
case 'l': case 'l':
if (is_long) if (is_long)
{ {
/* A double `l' is equivalent to an `L'. */ /* A double `l' is equivalent to an `L'. */
#ifdef USE_IN_LIBIO if ((flags & ~(SUPPRESS | WIDTH)))
if ((flags & ~(SUPPRESS | WIDTH)) && (flags & LONGDBL))
conv_error (); conv_error ();
flags &= ~LONG; flags &= ~LONG;
flags |= LONGDBL; flags |= LONGDBL;
#endif
is_longlong = 1; is_longlong = 1;
} }
else else
{ {
/* int's are long int's. */ /* int's are long int's. */
#ifdef USE_IN_LIBIO
flags |= LONG; flags |= LONG;
#endif
is_long = 1; is_long = 1;
} }
break; break;
case 'q': case 'q':
case 'L': case 'L':
/* double's are long double's, and int's are long long int's. */ /* double's are long double's, and int's are long long int's. */
#ifdef USE_IN_LIBIO
if (flags & ~(SUPPRESS | WIDTH)) if (flags & ~(SUPPRESS | WIDTH))
/* Signal illegal format element. */ /* Signal illegal format element. */
conv_error (); conv_error ();
flags |= LONGDBL; flags |= LONGDBL;
#endif
is_long_double = 1; is_long_double = 1;
break; break;
case 'a': case 'a':
@ -356,15 +359,20 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
/* Find the conversion specifier. */ /* Find the conversion specifier. */
fc = *f++; fc = *f++;
if (fc != '[' && fc != 'c' && fc != 'n') if (skip_space || (fc != '[' && fc != 'c' && fc != 'n'))
/* Eat whitespace. */ {
while (isspace (c)) /* Eat whitespace. */
(void) inchar (); while (isspace (c))
(void) inchar ();
skip_space = 0;
}
switch (fc) switch (fc)
{ {
case '%': /* Must match a literal '%'. */ case '%': /* Must match a literal '%'. */
if (c != fc) if (c != fc)
conv_error (); conv_error ();
inchar ();
break; break;
case 'n': /* Answer number of assignments done. */ case 'n': /* Answer number of assignments done. */
@ -444,7 +452,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
{ \ { \
/* We lose. Oh well. \ /* We lose. Oh well. \
Terminate the string and stop converting, \ 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'; \ (*strptr)[strsize] = '\0'; \
++done; \ ++done; \
conv_error (); \ conv_error (); \
@ -513,7 +521,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
} }
/* Look for a leading indication of base. */ /* Look for a leading indication of base. */
if (c == '0') if (width != 0 && c == '0')
{ {
if (width > 0) if (width > 0)
--width; --width;
@ -521,7 +529,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
(void) inchar (); (void) inchar ();
if (tolower (c) == 'x') if (width != 0 && tolower (c) == 'x')
{ {
if (base == 0) if (base == 0)
base = 16; base = 16;
@ -540,7 +548,7 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
base = 10; base = 10;
/* Read the number into workspace. */ /* Read the number into workspace. */
do while (c != EOF && width != 0)
{ {
if (base == 16 ? !isxdigit (c) : if (base == 16 ? !isxdigit (c) :
(!isdigit (c) || c - '0' >= base)) (!isdigit (c) || c - '0' >= base))
@ -548,8 +556,9 @@ __vfscanf (FILE *s, const char *format, va_list argptr)
ADDW (c); ADDW (c);
if (width > 0) if (width > 0)
--width; --width;
(void) inchar ();
} }
while (inchar () != EOF && width != 0);
if (wpsize == 0 || if (wpsize == 0 ||
(wpsize == 1 && (wp[0] == '+' || wp[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); return ((c == EOF || ungetc (c, s)), done);
} }

View File

@ -911,9 +911,9 @@ INTERNAL (STRTOF) (nptr, endptr, group)
{ {
if (num[0] >= d1) 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 the denominator but the one limb is bigger than the
high limb of the nominator. */ high limb of the numerator. */
n1 = 0; n1 = 0;
n0 = num[0]; n0 = num[0];
} }