Provide workaround for GCC Bug 66145
This commit is contained in:
parent
79ce6e9aa6
commit
980794066b
|
@ -23,6 +23,7 @@ set(HEADER_FILES
|
|||
io/copy.h
|
||||
io/inifile.h
|
||||
io/path.h
|
||||
io/catchiofailure.h
|
||||
math/math.h
|
||||
misc/memory.h
|
||||
misc/random.h
|
||||
|
@ -45,6 +46,7 @@ set(SRC_FILES
|
|||
io/bitreader.cpp
|
||||
io/inifile.cpp
|
||||
io/path.cpp
|
||||
io/catchiofailure.cpp
|
||||
math/math.cpp
|
||||
misc/random.cpp
|
||||
tests/testutils.cpp
|
||||
|
|
|
@ -68,8 +68,8 @@ The repository [PKGBUILDs](https://github.com/Martchus/PKGBUILDs) contains files
|
|||
PKGBUILD files to build for Windows using the Mingw-w64 compiler are also included.
|
||||
|
||||
### Notes
|
||||
* Because of [GCC Bug 66145](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145) usage of the new libstdc++ ABI
|
||||
is currently disabled. Linking against cppunit built using new libstdc++ ABI isn't possible.
|
||||
* There is a workaround for [GCC Bug 66145](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145) provided
|
||||
in io/catchiofailure.h.
|
||||
|
||||
## TODO
|
||||
- remove unused features
|
||||
|
|
|
@ -43,8 +43,11 @@ configure_file(
|
|||
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
# disable new ABI (can't catch ios_base::failure with new ABI)
|
||||
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
|
||||
message(STATUS "Forcing usage of old CXX11 ABI to be able to catch std::ios_base::failure.")
|
||||
set(FORCE_OLD_ABI "no" CACHE STRING "specifies whether usage of old ABI should be forced")
|
||||
if(${FORCE_OLD_ABI} STREQUAL "yes")
|
||||
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
|
||||
message(STATUS "Forcing usage of old CXX11 ABI.")
|
||||
endif()
|
||||
|
||||
# enable debug-only code when doing a debug build
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
|
|
|
@ -137,7 +137,6 @@ string BinaryReader::readString(size_t length)
|
|||
string BinaryReader::readTerminatedString(byte termination)
|
||||
{
|
||||
stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
|
||||
// thrown ios_base::failure when badbit or failbit is set
|
||||
ss.exceptions(ios_base::badbit | ios_base::failbit);
|
||||
m_stream->get(*ss.rdbuf(), termination); // delim byte is not extracted from the stream
|
||||
m_stream->seekg(1, ios_base::cur); // "extract" delim byte manually
|
||||
|
@ -175,7 +174,6 @@ string BinaryReader::readTerminatedString(size_t maxBytesToRead, byte terminatio
|
|||
string BinaryReader::readMultibyteTerminatedStringBE(uint16 termination)
|
||||
{
|
||||
stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
|
||||
// thrown ios_base::failure when badbit or failbit is set
|
||||
ss.exceptions(ios_base::badbit | ios_base::failbit);
|
||||
char *delimChars = m_buffer, *buff = m_buffer + 2;
|
||||
ConversionUtilities::BE::getBytes(termination, delimChars);
|
||||
|
@ -196,7 +194,6 @@ string BinaryReader::readMultibyteTerminatedStringBE(uint16 termination)
|
|||
string BinaryReader::readMultibyteTerminatedStringLE(uint16 termination)
|
||||
{
|
||||
stringstream ss(ios_base::in | ios_base::out | ios_base::binary);
|
||||
// thrown ios_base::failure when badbit or failbit is set
|
||||
ss.exceptions(ios_base::badbit | ios_base::failbit);
|
||||
char *delimChars = m_buffer, *buff = m_buffer + 2;
|
||||
ConversionUtilities::LE::getBytes(termination, delimChars);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "./bitreader.h"
|
||||
#include "./catchiofailure.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -21,7 +22,7 @@ void BitReader::skipBits(std::size_t bitCount)
|
|||
m_bitsAvail -= bitCount;
|
||||
} else {
|
||||
if((m_buffer += 1 + (bitCount -= m_bitsAvail) / 8) >= m_end) {
|
||||
throw ios_base::failure("end of buffer exceeded");
|
||||
throwIoFailure("end of buffer exceeded");
|
||||
}
|
||||
m_bitsAvail = 8 - (bitCount % 8);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
// ensure the old ABI is used
|
||||
// TODO: add condition for GCC version if GCC Bug 66145 is fixed
|
||||
#define _GLIBCXX_USE_CXX11_ABI 0
|
||||
|
||||
#include "./catchiofailure.h"
|
||||
|
||||
#include <ios>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace IoUtilities {
|
||||
|
||||
/*!
|
||||
* \brief Provides a workaround for GCC Bug 66145.
|
||||
* \returns Returns the error message.
|
||||
* \throws Throws the current exception if it is not std::ios_base::failure.
|
||||
*/
|
||||
const char *catchIoFailure()
|
||||
{
|
||||
try {
|
||||
throw;
|
||||
} catch(const ios_base::failure &e) {
|
||||
return e.what();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Throws a std::ios_base::failure with the specified message.
|
||||
*/
|
||||
void throwIoFailure(const char *what)
|
||||
{
|
||||
throw ios_base::failure(what);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef IOUTILITIES_CATCHIOFAILURE_H
|
||||
#define IOUTILITIES_CATCHIOFAILURE_H
|
||||
|
||||
#include "../application/global.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace IoUtilities {
|
||||
|
||||
LIB_EXPORT const char *catchIoFailure();
|
||||
LIB_EXPORT void throwIoFailure(const char *what);
|
||||
|
||||
}
|
||||
|
||||
#endif // IOUTILITIES_CATCHIOFAILURE_H
|
|
@ -1,4 +1,5 @@
|
|||
#include "./inifile.h"
|
||||
#include "./catchiofailure.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
@ -135,13 +136,14 @@ void IniFile::parse(std::istream &inputStream)
|
|||
break;
|
||||
}
|
||||
}
|
||||
} catch (const ios_base::failure &) {
|
||||
} catch(...) {
|
||||
const char *what = catchIoFailure();
|
||||
if(inputStream.eof()) {
|
||||
// we just reached the end of the file
|
||||
// don't forget to save the last key/value pair
|
||||
finishKeyValue();
|
||||
} else {
|
||||
throw;
|
||||
throwIoFailure(what);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "../io/path.h"
|
||||
#include "../io/inifile.h"
|
||||
#include "../io/copy.h"
|
||||
#include "../io/catchiofailure.h"
|
||||
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include <cppunit/TestFixture.h>
|
||||
|
@ -57,17 +58,27 @@ void IoTests::tearDown()
|
|||
/*!
|
||||
* \brief Tests for GCC Bug 66145.
|
||||
* \sa https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145
|
||||
* \remarks Using workaround now; hence testing workaround instead.
|
||||
*/
|
||||
void IoTests::testFailure()
|
||||
{
|
||||
fstream stream;
|
||||
stream.exceptions(ios_base::failbit | ios_base::badbit);
|
||||
CPPUNIT_ASSERT_THROW(stream.open("path/to/file/which/does/not/exist", ios_base::in), ios_base::failure);
|
||||
//fstream stream;
|
||||
//stream.exceptions(ios_base::failbit | ios_base::badbit);
|
||||
//CPPUNIT_ASSERT_THROW(stream.open("path/to/file/which/does/not/exist", ios_base::in), ios_base::failure);
|
||||
// check other exceptions used by my applications, too
|
||||
vector<int> testVec;
|
||||
map<string, string> testMap;
|
||||
CPPUNIT_ASSERT_THROW(testVec.at(1), out_of_range);
|
||||
CPPUNIT_ASSERT_THROW(testMap.at("test"), out_of_range);
|
||||
|
||||
// check workaround
|
||||
try {
|
||||
fstream stream;
|
||||
stream.exceptions(ios_base::failbit | ios_base::badbit);
|
||||
stream.open("path/to/file/which/does/not/exist", ios_base::in);
|
||||
} catch(...) {
|
||||
catchIoFailure();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "../application/failure.h"
|
||||
#include "../conversion/stringconversion.h"
|
||||
#include "../io/catchiofailure.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
@ -13,6 +14,7 @@
|
|||
using namespace std;
|
||||
using namespace ApplicationUtilities;
|
||||
using namespace ConversionUtilities;
|
||||
using namespace IoUtilities;
|
||||
|
||||
/*!
|
||||
* \brief Contains classes and functions utilizing creating of test applications.
|
||||
|
@ -193,7 +195,8 @@ string TestApplication::workingCopyPath(const string &name) const
|
|||
workingCopy.open(path, ios_base::out | ios_base::binary | ios_base::trunc);
|
||||
workingCopy << origFile.rdbuf();
|
||||
return path;
|
||||
} catch(const ios_base::failure &) {
|
||||
} catch(...) {
|
||||
catchIoFailure();
|
||||
cerr << "Unable to create working copy for \"" << name << "\": an IO error occured." << endl;
|
||||
}
|
||||
return string();
|
||||
|
|
Loading…
Reference in New Issue