Post by Gisle VanemSeems 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 */