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