diff mbox series

[v2,1/2] Add scanf/vfscanf/vscanf tests of long double without <stdio.h>

Message ID 20240524204844.3322444-2-hjl.tools@gmail.com
State New
Headers show
Series Make __nldbl__IO_vfscanf a compat symbol [BZ #31776] | expand

Commit Message

H.J. Lu May 24, 2024, 8:48 p.m. UTC
Update test-fscanf.c to add scanf/vfscanf/vscanf tests of long double
without including <stdio.h>.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 stdio-common/test-fscanf.c     | 55 ++++++++++++++++++++++++++++++++--
 stdio-common/test-fscanf.input |  3 ++
 2 files changed, 56 insertions(+), 2 deletions(-)

Comments

H.J. Lu May 24, 2024, 11 p.m. UTC | #1
On Fri, May 24, 2024 at 1:48 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> Update test-fscanf.c to add scanf/vfscanf/vscanf tests of long double
> without including <stdio.h>.
>
> Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
> ---
>  stdio-common/test-fscanf.c     | 55 ++++++++++++++++++++++++++++++++--
>  stdio-common/test-fscanf.input |  3 ++
>  2 files changed, 56 insertions(+), 2 deletions(-)
>
> diff --git a/stdio-common/test-fscanf.c b/stdio-common/test-fscanf.c
> index f2c4250b51..26477300a5 100644
> --- a/stdio-common/test-fscanf.c
> +++ b/stdio-common/test-fscanf.c
> @@ -1,4 +1,4 @@
> -/* Test fscanf of long double without <stdio.h>.
> +/* Test fscanf/scanf/vfscanf/vscanf of long double without <stdio.h>.
>     Copyright (C) 2024 Free Software Foundation, Inc.
>     This file is part of the GNU C Library.
>
> @@ -16,11 +16,39 @@
>     License along with the GNU C Library; if not, see
>     <https://www.gnu.org/licenses/>.  */
>
> +#include <stdarg.h>
>  #include <string.h>
>
> +#ifndef EXPECTED_LONG_DOUBLE_VALUE
> +# define EXPECTED_LONG_DOUBLE_VALUE 24.5
> +#endif
> +
>  struct FILE;
>  extern struct FILE *stdin;
>  extern int fscanf (struct FILE *, const char *, ...);
> +extern int scanf (const char *, ...);
> +extern int vfscanf (struct FILE *, const char *, va_list);
> +extern int vscanf (const char *, va_list);
> +
> +static int
> +wrap_vfscanf (struct FILE *fp, const char *format, ...)
> +{
> +  va_list ap;
> +  va_start (ap, format);
> +  int ret = vfscanf (fp, format, ap);
> +  va_end (ap);
> +  return ret;
> +}
> +
> +static int
> +wrap_vscanf (const char *format, ...)
> +{
> +  va_list ap;
> +  va_start (ap, format);
> +  int ret = vscanf (format, ap);
> +  va_end (ap);
> +  return ret;
> +}
>
>  int
>  main (void)
> @@ -29,8 +57,31 @@ main (void)
>    long double x;
>    char name[50];
>    n = fscanf (stdin, "%d%Lf%s", &i, &x, name);

The scanf long double tests don't work on ppc64le.  Peter,
does it work for you?

> +  if (n != 3
> +      || i != 25
> +      || x != EXPECTED_LONG_DOUBLE_VALUE
> +      || strcmp (name, "thompson"))
> +    return 1;
> +
> +  n = scanf ("%d%Lf%s", &i, &x, name);
> +  if (n != 3
> +      || i != 25
> +      || x != EXPECTED_LONG_DOUBLE_VALUE
> +      || strcmp (name, "thompson"))
> +    return 1;
> +
> +  n = wrap_vfscanf (stdin, "%d%Lf%s", &i, &x, name);
> +  if (n != 3
> +      || i != 25
> +      || x != EXPECTED_LONG_DOUBLE_VALUE
> +      || strcmp (name, "thompson"))
> +    return 1;
>
> -  if (n != 3 || i != 25 || x != 24.5 || strcmp (name, "thompson"))
> +  n = wrap_vscanf ("%d%Lf%s", &i, &x, name);
> +  if (n != 3
> +      || i != 25
> +      || x != EXPECTED_LONG_DOUBLE_VALUE
> +      || strcmp (name, "thompson"))
>      return 1;
>
>    return 0;
> diff --git a/stdio-common/test-fscanf.input b/stdio-common/test-fscanf.input
> index 69322cc51a..20859d314a 100644
> --- a/stdio-common/test-fscanf.input
> +++ b/stdio-common/test-fscanf.input
> @@ -1 +1,4 @@
>  25 24.5 thompson
> +25 24.5 thompson
> +25 24.5 thompson
> +25 24.5 thompson
> --
> 2.45.1
>
H.J. Lu May 24, 2024, 11:09 p.m. UTC | #2
On Fri, May 24, 2024 at 4:00 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Fri, May 24, 2024 at 1:48 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> >
> > Update test-fscanf.c to add scanf/vfscanf/vscanf tests of long double
> > without including <stdio.h>.
> >
> > Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
> > ---
> >  stdio-common/test-fscanf.c     | 55 ++++++++++++++++++++++++++++++++--
> >  stdio-common/test-fscanf.input |  3 ++
> >  2 files changed, 56 insertions(+), 2 deletions(-)
> >
> > diff --git a/stdio-common/test-fscanf.c b/stdio-common/test-fscanf.c
> > index f2c4250b51..26477300a5 100644
> > --- a/stdio-common/test-fscanf.c
> > +++ b/stdio-common/test-fscanf.c
> > @@ -1,4 +1,4 @@
> > -/* Test fscanf of long double without <stdio.h>.
> > +/* Test fscanf/scanf/vfscanf/vscanf of long double without <stdio.h>.
> >     Copyright (C) 2024 Free Software Foundation, Inc.
> >     This file is part of the GNU C Library.
> >
> > @@ -16,11 +16,39 @@
> >     License along with the GNU C Library; if not, see
> >     <https://www.gnu.org/licenses/>.  */
> >
> > +#include <stdarg.h>
> >  #include <string.h>
> >
> > +#ifndef EXPECTED_LONG_DOUBLE_VALUE
> > +# define EXPECTED_LONG_DOUBLE_VALUE 24.5
> > +#endif
> > +
> >  struct FILE;
> >  extern struct FILE *stdin;
> >  extern int fscanf (struct FILE *, const char *, ...);
> > +extern int scanf (const char *, ...);
> > +extern int vfscanf (struct FILE *, const char *, va_list);
> > +extern int vscanf (const char *, va_list);
> > +
> > +static int
> > +wrap_vfscanf (struct FILE *fp, const char *format, ...)
> > +{
> > +  va_list ap;
> > +  va_start (ap, format);
> > +  int ret = vfscanf (fp, format, ap);
> > +  va_end (ap);
> > +  return ret;
> > +}
> > +
> > +static int
> > +wrap_vscanf (const char *format, ...)
> > +{
> > +  va_list ap;
> > +  va_start (ap, format);
> > +  int ret = vscanf (format, ap);
> > +  va_end (ap);
> > +  return ret;
> > +}
> >
> >  int
> >  main (void)
> > @@ -29,8 +57,31 @@ main (void)
> >    long double x;
> >    char name[50];
> >    n = fscanf (stdin, "%d%Lf%s", &i, &x, name);
>
> The scanf long double tests don't work on ppc64le.  Peter,
> does it work for you?

Without <stdio.h>, vfscanf is used and with <stdio.h>
__isoc23_vfscanfieee128 is used.   I will remove
stdio-common/test-fscanf.c since it doesn't work on all
targets.

> > +  if (n != 3
> > +      || i != 25
> > +      || x != EXPECTED_LONG_DOUBLE_VALUE
> > +      || strcmp (name, "thompson"))
> > +    return 1;
> > +
> > +  n = scanf ("%d%Lf%s", &i, &x, name);
> > +  if (n != 3
> > +      || i != 25
> > +      || x != EXPECTED_LONG_DOUBLE_VALUE
> > +      || strcmp (name, "thompson"))
> > +    return 1;
> > +
> > +  n = wrap_vfscanf (stdin, "%d%Lf%s", &i, &x, name);
> > +  if (n != 3
> > +      || i != 25
> > +      || x != EXPECTED_LONG_DOUBLE_VALUE
> > +      || strcmp (name, "thompson"))
> > +    return 1;
> >
> > -  if (n != 3 || i != 25 || x != 24.5 || strcmp (name, "thompson"))
> > +  n = wrap_vscanf ("%d%Lf%s", &i, &x, name);
> > +  if (n != 3
> > +      || i != 25
> > +      || x != EXPECTED_LONG_DOUBLE_VALUE
> > +      || strcmp (name, "thompson"))
> >      return 1;
> >
> >    return 0;
> > diff --git a/stdio-common/test-fscanf.input b/stdio-common/test-fscanf.input
> > index 69322cc51a..20859d314a 100644
> > --- a/stdio-common/test-fscanf.input
> > +++ b/stdio-common/test-fscanf.input
> > @@ -1 +1,4 @@
> >  25 24.5 thompson
> > +25 24.5 thompson
> > +25 24.5 thompson
> > +25 24.5 thompson
> > --
> > 2.45.1
> >
>
>
> --
> H.J.
Joseph Myers May 28, 2024, 7:45 p.m. UTC | #3
On Fri, 24 May 2024, H.J. Lu wrote:

> Without <stdio.h>, vfscanf is used and with <stdio.h>
> __isoc23_vfscanfieee128 is used.   I will remove
> stdio-common/test-fscanf.c since it doesn't work on all
> targets.

In principle, if we want such things to work, we'd could arrange for 
stdc-predef.h to include appropriate uses of "#pragma redefine_extname" 
(conditioned only on predefined macros, not anything defined in 
<features.h> as this is before <features.h> is included) - that pragma can 
remap identifiers that haven't been declared yet.  (That would probably 
only be practical if we used generated files for installed headers, 
previously discussed as of potential use for various reasons, rather than 
trying to duplicate the conditionals and keep them consistent.)

In practice it might be better to propose removing the "Provided that a 
library function can be declared without reference to any type defined in 
a header, it is also permissible to declare the function and use it 
without including its associated header." rule from ISO C (and the 
similarly-worded rule from POSIX, which has already been limited to "For 
functions from the ISO C standard only" in the 2024 edition of POSIX), as 
of questionable utility and not working reliably in practice.

I suspect that compilers without asm redirection support don't really work 
reliably with glibc headers anyway and that libnldbl_nonshared.a could 
reasonably be removed.
diff mbox series

Patch

diff --git a/stdio-common/test-fscanf.c b/stdio-common/test-fscanf.c
index f2c4250b51..26477300a5 100644
--- a/stdio-common/test-fscanf.c
+++ b/stdio-common/test-fscanf.c
@@ -1,4 +1,4 @@ 
-/* Test fscanf of long double without <stdio.h>.
+/* Test fscanf/scanf/vfscanf/vscanf of long double without <stdio.h>.
    Copyright (C) 2024 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,11 +16,39 @@ 
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <stdarg.h>
 #include <string.h>
 
+#ifndef EXPECTED_LONG_DOUBLE_VALUE
+# define EXPECTED_LONG_DOUBLE_VALUE 24.5
+#endif
+
 struct FILE;
 extern struct FILE *stdin;
 extern int fscanf (struct FILE *, const char *, ...);
+extern int scanf (const char *, ...);
+extern int vfscanf (struct FILE *, const char *, va_list);
+extern int vscanf (const char *, va_list);
+
+static int
+wrap_vfscanf (struct FILE *fp, const char *format, ...)
+{
+  va_list ap;
+  va_start (ap, format);
+  int ret = vfscanf (fp, format, ap);
+  va_end (ap);
+  return ret;
+}
+
+static int
+wrap_vscanf (const char *format, ...)
+{
+  va_list ap;
+  va_start (ap, format);
+  int ret = vscanf (format, ap);
+  va_end (ap);
+  return ret;
+}
 
 int
 main (void)
@@ -29,8 +57,31 @@  main (void)
   long double x;
   char name[50];
   n = fscanf (stdin, "%d%Lf%s", &i, &x, name);
+  if (n != 3
+      || i != 25
+      || x != EXPECTED_LONG_DOUBLE_VALUE
+      || strcmp (name, "thompson"))
+    return 1;
+
+  n = scanf ("%d%Lf%s", &i, &x, name);
+  if (n != 3
+      || i != 25
+      || x != EXPECTED_LONG_DOUBLE_VALUE
+      || strcmp (name, "thompson"))
+    return 1;
+
+  n = wrap_vfscanf (stdin, "%d%Lf%s", &i, &x, name);
+  if (n != 3
+      || i != 25
+      || x != EXPECTED_LONG_DOUBLE_VALUE
+      || strcmp (name, "thompson"))
+    return 1;
 
-  if (n != 3 || i != 25 || x != 24.5 || strcmp (name, "thompson"))
+  n = wrap_vscanf ("%d%Lf%s", &i, &x, name);
+  if (n != 3
+      || i != 25
+      || x != EXPECTED_LONG_DOUBLE_VALUE
+      || strcmp (name, "thompson"))
     return 1;
 
   return 0;
diff --git a/stdio-common/test-fscanf.input b/stdio-common/test-fscanf.input
index 69322cc51a..20859d314a 100644
--- a/stdio-common/test-fscanf.input
+++ b/stdio-common/test-fscanf.input
@@ -1 +1,4 @@ 
 25 24.5 thompson
+25 24.5 thompson
+25 24.5 thompson
+25 24.5 thompson