-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 ftell failed to compile on mingw due to missing EOVERFLOW (I hadn't noticed this, since M4 was using only ftello). In the process of fixing this, I also beefed up the ftell/o tests to check behavior after ungetc. Mingw ftell is weird when used on text mode files with plain LF endings (it subtracts 1 for each LF in the stripped readahead buffer, whether or not it was CRLF prior to copying into the readahead buffer, such that it can return negative results even though the file is seekable), so I also had to make the test force binary mode.
Hmm - should we provide a gnulib <errno.h> that guarantees all of the standard errors, rather than doing an ad-hoc definition of EOVERFLOW and others in every place where they are used? Or is it even possible, since errno.h is not required to do anything more than macros, such that include_next won't necessarily find the system <errno.h>? - -- Don't work too hard, make some time for fun as well! Eric Blake [EMAIL PROTECTED] -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.8 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAkfuy60ACgkQ84KuGfSFAYA7EgCfSrXMfD7rKjvt0BHqjRFGGcKl YeUAn0APLk0TKqHhso3sQjpK27g2yrWd =nUXF -----END PGP SIGNATURE-----
>From 857523660ddabbf1e4bba1c6f5f322451991fa08 Mon Sep 17 00:00:00 2001 From: Eric Blake <[EMAIL PROTECTED]> Date: Sat, 29 Mar 2008 16:55:56 -0600 Subject: [PATCH] Fix ftell on mingw. * lib/ftell.c (EOVERFLOW): Define if the system lacks it. * modules/ftell-tests (Depends-on): Add binary-io. * modules/ftello-tests (Depends-on): Likewise. * tests/test-ftell.c (main): Enhance test to cover behavior after ungetc. Enforce binary mode. * tests/test-ftello.c (main): Likewise. Signed-off-by: Eric Blake <[EMAIL PROTECTED]> --- ChangeLog | 8 ++++ lib/ftell.c | 7 +++- modules/ftell-tests | 1 + modules/ftello-tests | 1 + tests/test-ftell.c | 74 +++++++++++++++++++++++++++++++++++++++-- tests/test-ftello.c | 89 +++++++++++++++++++++++++++++++++++++++++++++---- 6 files changed, 168 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5b5933c..f6c7dc0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2008-03-29 Eric Blake <[EMAIL PROTECTED]> + Fix ftell on mingw. + * lib/ftell.c (EOVERFLOW): Define if the system lacks it. + * modules/ftell-tests (Depends-on): Add binary-io. + * modules/ftello-tests (Depends-on): Likewise. + * tests/test-ftell.c (main): Enhance test to cover behavior after + ungetc. Enforce binary mode. + * tests/test-ftello.c (main): Likewise. + Pass test-freadseek on cygwin. * modules/freadseek (Depends-on): Use freadptr, not freadseek. * lib/freadseek.c (freadseek): Don't increment beyond bounds of diff --git a/lib/ftell.c b/lib/ftell.c index 84622d7..e586fdb 100644 --- a/lib/ftell.c +++ b/lib/ftell.c @@ -1,5 +1,5 @@ /* An ftell() function that works around platform bugs. - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,6 +23,11 @@ /* Get off_t. */ #include <unistd.h> +/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */ +#ifndef EOVERFLOW +# define EOVERFLOW E2BIG +#endif + long ftell (FILE *fp) { diff --git a/modules/ftell-tests b/modules/ftell-tests index 03fbf27..ad82ded 100644 --- a/modules/ftell-tests +++ b/modules/ftell-tests @@ -3,6 +3,7 @@ tests/test-ftell.c tests/test-ftell.sh Depends-on: +binary-io configure.ac: diff --git a/modules/ftello-tests b/modules/ftello-tests index 9f0c6e2..48179bc 100644 --- a/modules/ftello-tests +++ b/modules/ftello-tests @@ -3,6 +3,7 @@ tests/test-ftello.c tests/test-ftello.sh Depends-on: +binary-io configure.ac: diff --git a/tests/test-ftell.c b/tests/test-ftell.c index 05e393d..e25bc02 100644 --- a/tests/test-ftell.c +++ b/tests/test-ftell.c @@ -1,5 +1,5 @@ /* Test of ftell() function. - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,11 +19,79 @@ #include <config.h> #include <stdio.h> +#include <stdlib.h> + +#include "binary-io.h" + +#define ASSERT(expr) \ + do \ + { \ + if (!(expr)) \ + { \ + fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ + abort (); \ + } \ + } \ + while (0) int main (int argc, char **argv) { + int ch; /* Assume stdin is seekable iff argc > 1. */ - int expected = argc > 1 ? 0 : -1; - return ftell (stdin) != expected; + if (argc == 1) + { + ASSERT (ftell (stdin) == -1); + return 0; + } + + /* mingw ftell is unreliable on text mode input. */ + SET_BINARY (0); + + /* Simple tests. */ + ASSERT (ftell (stdin) == 0); + + ch = fgetc (stdin); + ASSERT (ch == '#'); + ASSERT (ftell (stdin) == 1); + + /* Test ftell after ungetc of read input. */ + ch = ungetc ('#', stdin); + ASSERT (ch == '#'); + ASSERT (ftell (stdin) == 0); + + ch = fgetc (stdin); + ASSERT (ch == '#'); + ASSERT (ftell (stdin) == 1); + + /* Test ftell after fseek. */ + ASSERT (fseek (stdin, 2, SEEK_SET) == 0); + ASSERT (ftell (stdin) == 2); + + /* Test ftell after random ungetc. */ + ch = fgetc (stdin); + ASSERT (ch == '/'); + ch = ungetc ('@', stdin); + ASSERT (ch == '@'); + ASSERT (ftell (stdin) == 2); + + ch = fgetc (stdin); + ASSERT (ch == '@'); + ASSERT (ftell (stdin) == 3); + + /* Test ftell after ungetc without read. */ + ASSERT (fseek (stdin, 0, SEEK_CUR) == 0); + ASSERT (ftell (stdin) == 3); + + ch = ungetc ('~', stdin); + ASSERT (ch == '~'); + ASSERT (ftell (stdin) == 2); + + /* Test ftell beyond end of file. */ + ASSERT (fseek (stdin, 0, SEEK_END) == 0); + ch = ftell (stdin); + ASSERT (fseek (stdin, 10, SEEK_END) == 0); + ASSERT (ftell (stdin) == ch + 10); + + return 0; } diff --git a/tests/test-ftello.c b/tests/test-ftello.c index 0357282..73fd527 100644 --- a/tests/test-ftello.c +++ b/tests/test-ftello.c @@ -1,5 +1,5 @@ /* Test of ftello() function. - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007, 2008 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,17 +19,90 @@ #include <config.h> #include <stdio.h> +#include <stdlib.h> -/* Get off_t. */ -#include <sys/types.h> +#include "binary-io.h" + +#define ASSERT(expr) \ + do \ + { \ + if (!(expr)) \ + { \ + fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ + abort (); \ + } \ + } \ + while (0) int main (int argc, char **argv) { + int ch; /* Assume stdin is seekable iff argc > 1. */ - int expected = argc > 1 ? 0 : -1; - /* Exit with success only if ftell/ftello agree. */ - off_t pos1 = ftello (stdin); - long pos2 = ftell (stdin); - return ! (pos1 == pos2 && pos1 == expected); + if (argc == 1) + { + ASSERT (ftell (stdin) == -1); + ASSERT (ftello (stdin) == -1); + return 0; + } + + /* mingw ftell is unreliable on text mode input. */ + SET_BINARY (0); + + /* Simple tests. For each test, make sure ftell and ftello agree. */ + ASSERT (ftell (stdin) == 0); + ASSERT (ftello (stdin) == 0); + + ch = fgetc (stdin); + ASSERT (ch == '#'); + ASSERT (ftell (stdin) == 1); + ASSERT (ftello (stdin) == 1); + + /* Test ftell after ungetc of read input. */ + ch = ungetc ('#', stdin); + ASSERT (ch == '#'); + ASSERT (ftell (stdin) == 0); + ASSERT (ftello (stdin) == 0); + + ch = fgetc (stdin); + ASSERT (ch == '#'); + ASSERT (ftell (stdin) == 1); + ASSERT (ftello (stdin) == 1); + + /* Test ftell after fseek. */ + ASSERT (fseek (stdin, 2, SEEK_SET) == 0); + ASSERT (ftell (stdin) == 2); + ASSERT (ftello (stdin) == 2); + + /* Test ftell after random ungetc. */ + ch = fgetc (stdin); + ASSERT (ch == '/'); + ch = ungetc ('@', stdin); + ASSERT (ch == '@'); + ASSERT (ftell (stdin) == 2); + ASSERT (ftello (stdin) == 2); + + ch = fgetc (stdin); + ASSERT (ch == '@'); + ASSERT (ftell (stdin) == 3); + ASSERT (ftello (stdin) == 3); + + /* Test ftell after ungetc without read. */ + ASSERT (fseek (stdin, 0, SEEK_CUR) == 0); + ASSERT (ftell (stdin) == 3); + ASSERT (ftello (stdin) == 3); + + ch = ungetc ('~', stdin); + ASSERT (ch == '~'); + ASSERT (ftell (stdin) == 2); + ASSERT (ftello (stdin) == 2); + + /* Test ftell beyond end of file. */ + ASSERT (fseek (stdin, 0, SEEK_END) == 0); + ch = ftello (stdin); + ASSERT (fseek (stdin, 10, SEEK_END) == 0); + ASSERT (ftell (stdin) == ch + 10); + ASSERT (ftello (stdin) == ch + 10); + + return 0; } -- 1.5.4