Discussion:
MSVC and fseeko.c
Gisle Vanem
2016-12-12 10:01:19 UTC
Permalink
Seems this file supports every archaic target in existence, but
not MSVC. I've patched it like:

--- a/lib/fseeko.c 2016-01-30 20:42:16
+++ b/lib/fseeko.c 2016-01-31 10:25:06
@@ -100,7 +100,7 @@
#elif defined EPLAN9 /* Plan9 */
if (fp->rp == fp->buf
&& fp->wp == fp->buf)
-#elif FUNC_FFLUSH_STDIN < 0 && 200809 <= _POSIX_VERSION
+#elif FUNC_FFLUSH_STDIN < 0 && 200809 <= _POSIX_VERSION || _MSC_VER
/* Cross-compiling to some other system advertising conformance to
POSIX.1-2008 or later. Assume fseeko and fflush work as advertised.
If this assumption is incorrect, please report the bug to

but I've no idea if it's correct. Any pointers?
--
--gv
Bruno Haible
2016-12-13 00:45:24 UTC
Permalink
Post by Gisle Vanem
Seems this file supports every archaic target in existence, but
--- a/lib/fseeko.c 2016-01-30 20:42:16
+++ b/lib/fseeko.c 2016-01-31 10:25:06
@@ -100,7 +100,7 @@
#elif defined EPLAN9 /* Plan9 */
if (fp->rp == fp->buf
&& fp->wp == fp->buf)
-#elif FUNC_FFLUSH_STDIN < 0 && 200809 <= _POSIX_VERSION
+#elif FUNC_FFLUSH_STDIN < 0 && 200809 <= _POSIX_VERSION || _MSC_VER
/* Cross-compiling to some other system advertising conformance to
POSIX.1-2008 or later. Assume fseeko and fflush work as advertised.
If this assumption is incorrect, please report the bug to
but I've no idea if it's correct. Any pointers?
To determine whether the set of "stdioext" modules is correct, one can use a
testdir / tarball generated through

$ ./gnulib-tool --create-testdir --dir=/tmp/testdir-stdioext --with-tests \
--single-configure --avoid=havelib-tests \
fseterr freadable fwritable fbufmode freading fwriting \
freadptr freadseek freadahead fpurge fseeko ftello fpending \
fflush

With this patch, this testdir passes its testsuite on MSVC 14, both in 32-bit
and in 64-bit mode, except for the 'fpending' module.


2016-12-12 Bruno Haible <***@clisp.org>

stdioext: Port to native Windows with MSVC.
* lib/stdio-impl.h (WINDOWS_OPAQUE_FILE): New macro.
(struct _gl_real_FILE): New type.
(fp_, _IOREAD, _IOWRT, _IORW, _IOEOF, _IOERR): New macros, for native
Windows.
* lib/fbufmode.c (fbufmode): Add code for native Windows.
* lib/fflush.c (clear_ungetc_buffer): Treat native Windows like the
other SystemV derived implementations.
* lib/fpurge.c (fpurge): Likewise.
* lib/freadable.c (freadable): Likewise.
* lib/freadahead.c (freadahead): Likewise.
* lib/freading.c (freading): Likewise.
* lib/freadptr.c (freadptr): Likewise.
* lib/freadseek.c (freadptrinc): Likewise.
* lib/fseeko.c (fseeko): Likewise.
* lib/fseterr.c (fseterr): Likewise.
* lib/fwritable.c (fwritable): Likewise.
* lib/fwriting.c (fwriting): Likewise.
Reported by Gisle Vanem <***@yahoo.no>.

diff --git a/lib/stdio-impl.h b/lib/stdio-impl.h
index 987897a..7d389e9 100644
--- a/lib/stdio-impl.h
+++ b/lib/stdio-impl.h
@@ -110,4 +110,31 @@
# define _flag __flag
# endif

+#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ /* newer Windows with MSVC */
+
+/* <stdio.h> does not define the innards of FILE any more. */
+# define WINDOWS_OPAQUE_FILE
+
+struct _gl_real_FILE
+{
+ /* Note: Compared to older Windows and to mingw, it has the fields
+ _base and _cnt swapped. */
+ unsigned char *_ptr;
+ unsigned char *_base;
+ int _cnt;
+ int _flag;
+ int _file;
+ int _charbuf;
+ int _bufsiz;
+};
+# define fp_ ((struct _gl_real_FILE *) fp)
+
+/* These values were determined by a program similar to the one at
+ <http://lists.gnu.org/archive/html/bug-gnulib/2010-12/msg00165.html>. */
+# define _IOREAD 0x1
+# define _IOWRT 0x2
+# define _IORW 0x4
+# define _IOEOF 0x8
+# define _IOERR 0x10
+
#endif
diff --git a/lib/fbufmode.c b/lib/fbufmode.c
index 828eed7..483c8f0 100644
--- a/lib/fbufmode.c
+++ b/lib/fbufmode.c
@@ -53,17 +53,24 @@ fbufmode (FILE *fp)
return fp->_flags & (_IOLBF | _IONBF | _IOFBF);
#elif defined __minix /* Minix */
return fp->_flags & (_IOLBF | _IONBF | _IOFBF);
-#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
-# if HAVE___FLBF /* Solaris >= 7 */
+#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
+# if defined WINDOWS_OPAQUE_FILE
+ if (fp_->_flag & 0x100)
+ return _IOFBF; /* Impossible to distinguish _IOFBF and _IOLBF. */
+ else
+ return _IONBF;
+# else
+# if HAVE___FLBF /* Solaris >= 7 */
if (__flbf (fp))
return _IOLBF;
-# else
+# else
if (fp->_flag & _IOLBF)
return _IOLBF;
-# endif
+# endif
if (fp_->_flag & _IONBF)
return _IONBF;
return _IOFBF;
+# endif
#elif defined __UCLIBC__ /* uClibc */
if (fp->__modeflags & __FLAG_LBF)
return _IOLBF;
diff --git a/lib/fflush.c b/lib/fflush.c
index 2bd7cc9..ef2a7f1 100644
--- a/lib/fflush.c
+++ b/lib/fflush.c
@@ -63,7 +63,7 @@ clear_ungetc_buffer (FILE *fp)
fp->_ungetc_count = 0;
fp->_rcount = - fp->_rcount;
}
-# elif defined _IOERR /* Minix, AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
+# elif defined _IOERR /* Minix, AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
/* Nothing to do. */
# else /* other implementations */
fseeko (fp, 0, SEEK_CUR);
diff --git a/lib/fpurge.c b/lib/fpurge.c
index c85c409..53ee68c 100644
--- a/lib/fpurge.c
+++ b/lib/fpurge.c
@@ -98,10 +98,10 @@ fpurge (FILE *fp)
if (fp->_ptr != NULL)
fp->_count = 0;
return 0;
-# elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
- fp->_ptr = fp->_base;
- if (fp->_ptr != NULL)
- fp->_cnt = 0;
+# elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
+ fp_->_ptr = fp_->_base;
+ if (fp_->_ptr != NULL)
+ fp_->_cnt = 0;
return 0;
# elif defined __UCLIBC__ /* uClibc */
# ifdef __STDIO_BUFFERS
diff --git a/lib/freadable.c b/lib/freadable.c
index f6a0ff2..fc553ed 100644
--- a/lib/freadable.c
+++ b/lib/freadable.c
@@ -40,8 +40,8 @@ freadable (FILE *fp)
return (fp->_flags & (_IORW | _IOREAD)) != 0;
#elif defined __minix /* Minix */
return (fp->_flags & _IOREAD) != 0;
-#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
- return (fp->_flag & (_IORW | _IOREAD)) != 0;
+#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
+ return (fp_->_flag & (_IORW | _IOREAD)) != 0;
#elif defined __QNX__ /* QNX */
return (fp->_Mode & 0x1 /* _MOPENR */) != 0;
#elif defined __MINT__ /* Atari FreeMiNT */
diff --git a/lib/freadahead.c b/lib/freadahead.c
index 38f9dfb..cfc969b 100644
--- a/lib/freadahead.c
+++ b/lib/freadahead.c
@@ -53,7 +53,7 @@ freadahead (FILE *fp)
if ((fp_->_flags & _IOWRITING) != 0)
return 0;
return fp_->_count;
-#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
+#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
if ((fp_->_flag & _IOWRT) != 0)
return 0;
return fp_->_cnt;
diff --git a/lib/freading.c b/lib/freading.c
index 8a4247d..05cb0b8 100644
--- a/lib/freading.c
+++ b/lib/freading.c
@@ -42,11 +42,11 @@ freading (FILE *fp)
return (fp->_flags & _IOREAD) != 0;
# elif defined __minix /* Minix */
return (fp->_flags & _IOREADING) != 0;
-# elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
+# elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
# if defined __sun /* Solaris */
- return (fp->_flag & _IOREAD) != 0 && (fp->_flag & _IOWRT) == 0;
+ return (fp_->_flag & _IOREAD) != 0 && (fp_->_flag & _IOWRT) == 0;
# else
- return (fp->_flag & _IOREAD) != 0;
+ return (fp_->_flag & _IOREAD) != 0;
# endif
# elif defined __UCLIBC__ /* uClibc */
return (fp->__modeflags & (__FLAG_READONLY | __FLAG_READING)) != 0;
diff --git a/lib/freadptr.c b/lib/freadptr.c
index fbf9de2..bd92ac6 100644
--- a/lib/freadptr.c
+++ b/lib/freadptr.c
@@ -65,7 +65,7 @@ freadptr (FILE *fp, size_t *sizep)
return NULL;
*sizep = size;
return (const char *) fp_->_ptr;
-#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
+#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
if ((fp_->_flag & _IOWRT) != 0)
return NULL;
size = fp_->_cnt;
diff --git a/lib/freadseek.c b/lib/freadseek.c
index c613c6b..a6835e3 100644
--- a/lib/freadseek.c
+++ b/lib/freadseek.c
@@ -48,7 +48,7 @@ freadptrinc (FILE *fp, size_t increment)
#elif defined __minix /* Minix */
fp_->_ptr += increment;
fp_->_count -= increment;
-#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
+#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
fp_->_ptr += increment;
fp_->_cnt -= increment;
#elif defined __UCLIBC__ /* uClibc */
diff --git a/lib/fseeko.c b/lib/fseeko.c
index ba4d070..1c9ec37 100644
--- a/lib/fseeko.c
+++ b/lib/fseeko.c
@@ -80,7 +80,7 @@ fseeko (FILE *fp, off_t offset, int whence)
#elif defined __minix /* Minix */
if (fp_->_ptr == fp_->_buf
&& (fp_->_ptr == NULL || fp_->_count == 0))
-#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
+#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
if (fp_->_ptr == fp_->_base
&& (fp_->_ptr == NULL || fp_->_cnt == 0))
#elif defined __UCLIBC__ /* uClibc */
@@ -150,8 +150,8 @@ fseeko (FILE *fp, off_t offset, int whence)
fp_->_flags &= ~__SEOF;
#elif defined __EMX__ /* emx+gcc */
fp->_flags &= ~_IOEOF;
-#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
- fp->_flag &= ~_IOEOF;
+#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
+ fp_->_flag &= ~_IOEOF;
#elif defined __MINT__ /* Atari FreeMiNT */
fp->__offset = pos;
fp->__eof = 0;
diff --git a/lib/fseterr.c b/lib/fseterr.c
index 5aaa51f..025ec24 100644
--- a/lib/fseterr.c
+++ b/lib/fseterr.c
@@ -38,7 +38,7 @@ fseterr (FILE *fp)
fp->_flags |= _IOERR;
#elif defined __minix /* Minix */
fp->_flags |= _IOERR;
-#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
+#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
fp_->_flag |= _IOERR;
#elif defined __UCLIBC__ /* uClibc */
fp->__modeflags |= __FLAG_ERROR;
diff --git a/lib/fwritable.c b/lib/fwritable.c
index 7cba6e3..0233238 100644
--- a/lib/fwritable.c
+++ b/lib/fwritable.c
@@ -40,8 +40,8 @@ fwritable (FILE *fp)
return (fp->_flags & (_IORW | _IOWRT)) != 0;
#elif defined __minix /* Minix */
return (fp->_flags & _IOWRITE) != 0;
-#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
- return (fp->_flag & (_IORW | _IOWRT)) != 0;
+#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
+ return (fp_->_flag & (_IORW | _IOWRT)) != 0;
#elif defined __QNX__ /* QNX */
return (fp->_Mode & 0x2 /* _MOPENW */) != 0;
#elif defined __MINT__ /* Atari FreeMiNT */
diff --git a/lib/fwriting.c b/lib/fwriting.c
index 056d0c2..be9f3c3 100644
--- a/lib/fwriting.c
+++ b/lib/fwriting.c
@@ -36,8 +36,8 @@ fwriting (FILE *fp)
return (fp->_flags & _IOWRT) != 0;
#elif defined __minix /* Minix */
return (fp->_flags & _IOWRITING) != 0;
-#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, NonStop Kernel */
- return (fp->_flag & _IOWRT) != 0;
+#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
+ return (fp_->_flag & _IOWRT) != 0;
#elif defined __UCLIBC__ /* uClibc */
return (fp->__modeflags & __FLAG_WRITING) != 0;
#elif defined __QNX__ /* QNX */
Bruno Haible
2016-12-13 01:58:29 UTC
Permalink
Hi Jim,

On Windows with MSVC, the 'fpending' module does not pass its test,
because config.h defines

#define PENDING_OUTPUT_N_BYTES 1

In order to get this right, the expression should be

((struct { unsigned char *_ptr; unsigned char *_base; } *) fp)->_ptr - ((struct { unsigned char *_ptr; unsigned char *_base; } *) fp)->_base

But this is code duplication (with stdio-impl.h) and produces compiler warnings
("warning C4116: unnamed type definition in parentheses").

I would therefore propose to convert the 'fpending' module to the same
form as the other stdioext modules, with code that uses stdio-impl.h.
Yes, this replaces some autoconfiguration by #ifs. But porting to future
platforms is not that frequent, because hardly anyone creates freshly new stdio
implementations nowadays, and not that hard, because fseeko.c gives some hints.

Here's the proposed patch. It drops the 'old glibc iostream' case, which
I haven't encountered in 8 years. But it works on MSVC.


2016-12-12 Bruno Haible <***@clisp.org>

fpending: Port to native Windows with MSVC.
* lib/fpending.c: Include stdio-impl.h.
(__fpending): Include all known implementations. Err out if it's not
ported.
* m4/fpending.m4 (gl_PREREQ_FPENDING): Remove macro.
* modules/fpending (Files): Add lib/stdio-impl.h.
(configure.ac): Don't invoke gl_PREREQ_FPENDING.

diff --git a/lib/fpending.c b/lib/fpending.c
index a503b9f..14ef222 100644
--- a/lib/fpending.c
+++ b/lib/fpending.c
@@ -19,12 +19,42 @@

#include <config.h>

+/* Specification. */
#include "fpending.h"

+#include "stdio-impl.h"
+
/* Return the number of pending (aka buffered, unflushed)
bytes on the stream, FP, that is open for writing. */
size_t
__fpending (FILE *fp)
{
- return PENDING_OUTPUT_N_BYTES;
+ /* Most systems provide FILE as a struct and the necessary bitmask in
+ <stdio.h>, because they need it for implementing getc() and putc() as
+ fast macros. */
+#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
+ return fp->_IO_write_ptr - fp->_IO_write_base;
+#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
+ /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */
+ return fp->_p - fp->_bf._base;
+#elif defined __EMX__ /* emx+gcc */
+ return fp->_ptr - fp->_buffer;
+#elif defined __minix /* Minix */
+ return fp_->_ptr - fp_->_buf;
+#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel */
+ return (fp_->_ptr ? fp_->_ptr - fp_->_base : 0);
+#elif defined __UCLIBC__ /* uClibc */
+ return (fp->__modeflags & __FLAG_WRITING ? fp->__bufpos - fp->__bufstart : 0);
+#elif defined __QNX__ /* QNX */
+ return (fp->_Mode & 0x2000 /*_MWRITE*/ ? fp->_Next - fp->_Buf : 0);
+#elif defined __MINT__ /* Atari FreeMiNT */
+ return fp->__bufp - fp->__buffer;
+#elif defined EPLAN9 /* Plan9 */
+ return fp->wp - fp->buf;
+#elif defined __VMS /* VMS */
+ return (*fp)->_ptr - (*fp)->_base;
+#else
+# error "Please port gnulib fpending.c to your platform!"
+ return 1;
+#endif
}
diff --git a/m4/fpending.m4 b/m4/fpending.m4
index a446156..f6776a8 100644
--- a/m4/fpending.m4
+++ b/m4/fpending.m4
@@ -1,4 +1,4 @@
-# serial 21
+# serial 22

# Copyright (C) 2000-2001, 2004-2016 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
@@ -11,7 +11,7 @@ dnl and Ulrich Drepper.

dnl Find out how to determine the number of pending output bytes on a stream.
dnl glibc (2.1.93 and newer) and Solaris provide __fpending. On other systems,
-dnl we have to grub around in the FILE struct.
+dnl we have to grub around in the (possibly opaque) FILE struct.

AC_DEFUN([gl_FUNC_FPENDING],
[
@@ -34,66 +34,3 @@ AC_DEFUN([gl_FUNC_FPENDING],
AC_CHECK_DECLS([__fpending], [], [], [$fp_headers])
fi
])
-
-AC_DEFUN([gl_PREREQ_FPENDING],
-[
- AC_CACHE_CHECK(
- [how to determine the number of pending output bytes on a stream],
- ac_cv_sys_pending_output_n_bytes,
- [
- for ac_expr in \
- \
- '# glibc2' \
- 'fp->_IO_write_ptr - fp->_IO_write_base' \
- \
- '# traditional Unix' \
- 'fp->_ptr - fp->_base' \
- \
- '# BSD' \
- 'fp->_p - fp->_bf._base' \
- \
- '# SCO, Unixware' \
- '(fp->__ptr ? fp->__ptr - fp->__base : 0)' \
- \
- '# QNX' \
- '(fp->_Mode & 0x2000 /*_MWRITE*/ ? fp->_Next - fp->_Buf : 0)' \
- \
- '# old glibc?' \
- 'fp->__bufp - fp->__buffer' \
- \
- '# old glibc iostream?' \
- 'fp->_pptr - fp->_pbase' \
- \
- '# emx+gcc' \
- 'fp->_ptr - fp->_buffer' \
- \
- '# Minix' \
- 'fp->_ptr - fp->_buf' \
- \
- '# Plan9' \
- 'fp->wp - fp->buf' \
- \
- '# VMS' \
- '(*fp)->_ptr - (*fp)->_base' \
- \
- '# e.g., DGUX R4.11; the info is not available' \
- 1 \
- ; do
-
- # Skip each embedded comment.
- case "$ac_expr" in '#'*) continue;; esac
-
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]],
- [[FILE *fp = stdin; (void) ($ac_expr);]])],
- [fp_done=yes]
- )
- test "$fp_done" = yes && break
- done
-
- ac_cv_sys_pending_output_n_bytes=$ac_expr
- ]
- )
- AC_DEFINE_UNQUOTED([PENDING_OUTPUT_N_BYTES],
- $ac_cv_sys_pending_output_n_bytes,
- [the number of pending output bytes on stream 'fp'])
-])
diff --git a/modules/fpending b/modules/fpending
index 1375eb1..8dc4bee 100644
--- a/modules/fpending
+++ b/modules/fpending
@@ -4,6 +4,7 @@ Determine the number of bytes waiting in the output buffer of a stream.
Files:
lib/fpending.h
lib/fpending.c
+lib/stdio-impl.h
m4/fpending.m4

Depends-on:
@@ -12,7 +13,6 @@ configure.ac:
gl_FUNC_FPENDING
if test $gl_cv_func___fpending = no; then
AC_LIBOBJ([fpending])
- gl_PREREQ_FPENDING
fi

Makefile.am:
Jim Meyering
2016-12-13 02:10:04 UTC
Permalink
Post by Bruno Haible
Hi Jim,
On Windows with MSVC, the 'fpending' module does not pass its test,
because config.h defines
#define PENDING_OUTPUT_N_BYTES 1
In order to get this right, the expression should be
((struct { unsigned char *_ptr; unsigned char *_base; } *) fp)->_ptr - ((struct { unsigned char *_ptr; unsigned char *_base; } *) fp)->_base
But this is code duplication (with stdio-impl.h) and produces compiler warnings
("warning C4116: unnamed type definition in parentheses").
I would therefore propose to convert the 'fpending' module to the same
form as the other stdioext modules, with code that uses stdio-impl.h.
Yes, this replaces some autoconfiguration by #ifs. But porting to future
platforms is not that frequent, because hardly anyone creates freshly new stdio
implementations nowadays, and not that hard, because fseeko.c gives some hints.
Here's the proposed patch. It drops the 'old glibc iostream' case, which
I haven't encountered in 8 years. But it works on MSVC.
fpending: Port to native Windows with MSVC.
* lib/fpending.c: Include stdio-impl.h.
(__fpending): Include all known implementations. Err out if it's not
ported.
* m4/fpending.m4 (gl_PREREQ_FPENDING): Remove macro.
* modules/fpending (Files): Add lib/stdio-impl.h.
(configure.ac): Don't invoke gl_PREREQ_FPENDING.
Hi Bruno,
That sounds good, and your patch looks fine.
Thanks for taking that on.
Bruno Haible
2016-12-13 10:26:24 UTC
Permalink
Post by Jim Meyering
That sounds good, and your patch looks fine.
Thanks for taking that on.
OK. Pushed.

Bruno
--
In memoriam the victims of the Massacre of Margarita Belén <http://en.wikipedia.org/wiki/Massacre_of_Margarita_Belén>
Gisle Vanem
2016-12-13 13:20:14 UTC
Permalink
Post by Bruno Haible
$ ./gnulib-tool --create-testdir --dir=/tmp/testdir-stdioext --with-tests \
--single-configure --avoid=havelib-tests \
fseterr freadable fwritable fbufmode freading fwriting \
freadptr freadseek freadahead fpurge fseeko ftello fpending \
fflush
With this patch, this testdir passes its testsuite on MSVC 14, both in 32-bit
and in 64-bit mode, except for the 'fpending' module.
Thanks alot for your effort on this. It compiles fine, but I'm not sure
it works for all test-f*.exe tests. In test-fseeko.exe, I get this assert:
test-fseeko.c:45: assertion 'r1 == r2 && r1 == expected' failed

(r1 = -1, r2 = 0, expected = 0).

You tested this with MSVC 14? Does this use the "old" MSVCRT.dll?
BTW. I'm on Win-10 using MSVC 2015 and the WindowsKit (Universal CRT
ver. 10.0.10586.0).

I noticed you patched stdio-impl.h with the 'struct _gl_real_FILE' stuff.
Are you sure this is compatible with this newer Windows SDK?
--
--gv
Bruno Haible
2016-12-13 14:51:16 UTC
Permalink
Post by Gisle Vanem
Post by Bruno Haible
$ ./gnulib-tool --create-testdir --dir=/tmp/testdir-stdioext --with-tests \
--single-configure --avoid=havelib-tests \
fseterr freadable fwritable fbufmode freading fwriting \
freadptr freadseek freadahead fpurge fseeko ftello fpending \
fflush
With this patch, this testdir passes its testsuite on MSVC 14, both in 32-bit
and in 64-bit mode, except for the 'fpending' module.
Thanks alot for your effort on this. It compiles fine, but I'm not sure
test-fseeko.c:45: assertion 'r1 == r2 && r1 == expected' failed
(r1 = -1, r2 = 0, expected = 0).
And what about the other tests? When "make check" runs, which fail?
(This info should give a hint about where to start looking.)
Post by Gisle Vanem
You tested this with MSVC 14?
Yes.
Post by Gisle Vanem
Does this use the "old" MSVCRT.dll?
No, it uses vcruntime140.dll.
Post by Gisle Vanem
BTW. I'm on Win-10 using MSVC 2015 and the WindowsKit (Universal CRT
ver. 10.0.10586.0).
Mine is 10.0.10240.0.
Post by Gisle Vanem
I noticed you patched stdio-impl.h with the 'struct _gl_real_FILE' stuff.
Are you sure this is compatible with this newer Windows SDK?
No, Microsoft won't tell me when they make internal changes in their library.

Bruno

Loading...