Fix ftell on mingw.
authorEric Blake <ebb9@byu.net>
Sat, 29 Mar 2008 22:55:56 +0000 (16:55 -0600)
committerEric Blake <ebb9@byu.net>
Sat, 29 Mar 2008 22:55:56 +0000 (16:55 -0600)
* 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 <ebb9@byu.net>
ChangeLog
lib/ftell.c
modules/ftell-tests
modules/ftello-tests
tests/test-ftell.c
tests/test-ftello.c

index 5b5933c..f6c7dc0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2008-03-29  Eric Blake  <ebb9@byu.net>
 
+       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
index 84622d7..e586fdb 100644 (file)
@@ -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
 /* 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)
 {
index 03fbf27..ad82ded 100644 (file)
@@ -3,6 +3,7 @@ tests/test-ftell.c
 tests/test-ftell.sh
 
 Depends-on:
+binary-io
 
 configure.ac:
 
index 9f0c6e2..48179bc 100644 (file)
@@ -3,6 +3,7 @@ tests/test-ftello.c
 tests/test-ftello.sh
 
 Depends-on:
+binary-io
 
 configure.ac:
 
index 05e393d..e25bc02 100644 (file)
@@ -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
 #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;
 }
index 0357282..73fd527 100644 (file)
@@ -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
 #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;
 }