From 857523660ddabbf1e4bba1c6f5f322451991fa08 Mon Sep 17 00:00:00 2001 From: Eric Blake 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 --- 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 5b5933c0e..f6c7dc0d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2008-03-29 Eric Blake + 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 84622d713..e586fdb81 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 +/* 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 03fbf272a..ad82ded0a 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 9f0c6e249..48179bc12 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 05e393db5..e25bc029f 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 #include +#include + +#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 035728263..73fd52748 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 #include +#include -/* Get off_t. */ -#include +#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; } -- 2.11.0