1/*=========================================================================
2
3  Program:   Visualization Toolkit
4  Module:    vtkTestStreamEOF.cxx.in
5
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10     This software is distributed WITHOUT ANY WARRANTY; without even
11     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12     PURPOSE.  See the above copyright notice for more information.
13
14=========================================================================*/
15
16// Many C++ streams libraries have buggy conditions when reading
17// reaches the end of a file.  When an ifstream attempts to read past
18// the end of the file, the "eof" and "fail" bits are set.  Clearing
19// the fail bit should be enough to allow seekg() to work and tellg()
20// to report the file position.  Some stream libraries have bugs in
21// this case.  This source file tests the severity of the eof
22// conditions for a compiler.
23//
24// Severity levels are reported in terms of the extent of the
25// work-around required:
26//
27//    0 - No bug exists.
28//    1 - User must clear eof bit.
29//    2 - User must clear eof bit and re-seek to end.
30//    3 - User must clear eof bit and call _M_seek_return on the filebuf.
31//  126 - Could not open sample input file.
32//  127 - Unknown severity level.
33//
34// Severity level 3 is only known to exist for -LANG:std streams on
35// the SGI MIPSpro 7.30 - 7.3.1.1 compiler versions.  The cause of the
36// bug is a code pattern like this:
37//
38//  _M_in_error_mode = true;
39//  while(!_M_in_error_mode) { _M_in_error_mode = false; }
40//
41// It requires directly calling a non-public member function in the
42// filebuf instance on the stream to escape the bad state.
43// Unfortunately there is no way to detect the patch level of the
44// compiler from the preprocessor, so we need to actually try the
45// call.
46
47#if defined(__sgi) && !defined(__GNUC__) && defined(_COMPILER_VERSION)
48# if _COMPILER_VERSION == 730
49#  define VTK_SGI_730
50# endif
51#endif
52
53#if defined(_MSC_VER)
54# pragma warning (push, 1)
55#endif
56
57// Include the streams library.  Hack access to SGI stream
58// implementation for MIPSpro 7.3 compiler.
59#if defined(VTK_SGI_730)
60# define protected public
61# define private public
62#endif
63#include <fstream>
64 using std::ifstream;
65 using std::ios;
66#if defined(VTK_SGI_730)
67# undef protected
68# undef private
69#endif
70
71#if defined(_MSC_VER)
72# pragma warning (pop)
73#endif
74
75int main()
76{
77  const char* fname = "@VTK_TEST_STREAM_EOF_CXX@";
78
79  // Open the file.
80#if defined(_WIN32)
81  ifstream fin(fname, ios::binary | ios::in);
82#else
83  ifstream fin(fname, ios::in);
84#endif
85
86  // Make sure we opened the file.
87  if(!fin)
88    {
89    return 126;
90    }
91
92  // Go to eof in a way that exposes the bug everywhere.
93  char c = 0;
94  fin.seekg(-1, ios::end);
95  while(fin.get(c));
96
97  // Clear the fail bit so tellg() is supposed to return something
98  // other than -1.
99  fin.clear(fin.rdstate() & ~ios::failbit);
100  if(fin.tellg() >= 0)
101    {
102    // Nothing is wrong with eof for this streams library.
103    return 0;
104    }
105
106  // Some streams return -1 from tellg() if eof is set.
107  fin.clear(fin.rdstate() & ~ios::failbit & ~ios::eofbit);
108  if(fin.tellg() >= 0)
109    {
110    return 1;
111    }
112
113  // Some streams still return -1 from tellg.  Try seeking to get it
114  // out of this strange state.
115  fin.clear(fin.rdstate() & ~ios::failbit & ~ios::eofbit);
116  fin.seekg(0, ios::end);
117  if(fin.tellg() >= 0)
118    {
119    return 2;
120    }
121
122  // Only SGI 7.30 to 7.3.1.1 is known to get this far.  Try to escape
123  // the bad state.
124#if defined(VTK_SGI_730)
125  fin.clear(fin.rdstate() & ~ios::failbit & ~ios::eofbit);
126  fin.rdbuf()->_M_seek_return(0, 0);
127  if(fin.tellg() >= 0)
128    {
129    return 3;
130    }
131#endif
132
133  return 127;
134}
135