Few tests in the test suite failed and exposed problems due to text vs binary I/O issues.
First, location.c uses fseek and ftell to optimize access to source lines it reports with an error message. But fseek/ftell don't work reliably on MS-Windows when the file is open in text mode, because these functions try to "correct" the offsets on the assumption that the CR characters were stripped, which loses when the source has Unix-style EOLs. To make this work, we need to open the source in binary mode. Another related problem is that the pipe to m4 is set to binary I/O mode, so Bison receives the CR characters at the end of each line emitted by m4, and becomes confused. Here's the patch to fix these two problems: --- src/system.h~0 2013-08-02 18:35:13 +0300 +++ src/system.h 2014-10-06 18:12:00 +0300 @@ -39,6 +39,13 @@ # include <stdlib.h> # include <string.h> +# ifdef __MINGW32__ +/* This is needed to get O_TEXT for output.c */ +# include <fcntl.h> +/* This is needed for _mbschr in parse-gram.y */ +# include <mbstring.h> +# endif + # define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array)) # define STREQ(L, R) (strcmp(L, R) == 0) # define STRNEQ(L, R) (!STREQ(L, R)) --- src/location.c~0 2013-10-16 17:02:36 +0300 +++ src/location.c 2014-10-06 18:42:08 +0300 @@ -164,7 +164,7 @@ location_caret (location loc, FILE *out) /* FIXME: find a way to support multifile locations, and only open once each file. That would make the procedure future-proof. */ if (! (caret_info.source - || (caret_info.source = fopen (loc.start.file, "r"))) + || (caret_info.source = fopen (loc.start.file, "rb"))) || loc.start.column == -1 || loc.start.line == -1) return; @@ -193,9 +193,32 @@ location_caret (location loc, FILE *out) { /* Quote the file, indent by a single column. */ putc (' ', out); +#ifdef __MINGW32__ + { + int cr = 0; + + /* We are reading the file in binary mode, but writing it in + text mode, so don't write any CR characters before the + newline. */ + do { + if (cr) + { + putc (cr, out); + cr = 0; + } + if (c == '\r') + cr = c; + else + putc (c, out); + } while ((c = getc (caret_info.source)) != EOF && c != '\n'); + if (cr && c == EOF) + putc (cr, out); + } +#else /* !__MINGW32__ */ do putc (c, out); while ((c = getc (caret_info.source)) != EOF && c != '\n'); +#endif putc ('\n', out); { --- src/output.c~0 2013-12-04 17:53:01 +0200 +++ src/output.c 2014-10-06 18:49:31 +0300 @@ -620,6 +620,13 @@ output_skeleton (void) /* Read and process m4's output. */ timevar_push (TV_M4); +#ifdef __MINGW32__ + /* create_pipe_bidi opens the pipe in O_BINARY mode, which causes + failures in skel_lex, which doesn't expect to find a \r near the + end of a line. Switch pipe reading to text mode. (And no, + passing "rt" to fdopen doesn't work.) */ + setmode (filter_fd[0], O_TEXT); +#endif { FILE *in = xfdopen (filter_fd[0], "r"); scan_skel (in);