diff --git a/src/storm-dft/parser/DFTGalileoParser.cpp b/src/storm-dft/parser/DFTGalileoParser.cpp index e463bed37..b387a1a1a 100644 --- a/src/storm-dft/parser/DFTGalileoParser.cpp +++ b/src/storm-dft/parser/DFTGalileoParser.cpp @@ -48,7 +48,7 @@ namespace storm { std::string toplevelId = ""; bool comment = false; // Indicates whether the current line is part of a multiline comment try { - while (std::getline(file, line)) { + while (storm::utility::getline(file, line)) { ++lineNo; // First consider comments if (comment) { diff --git a/src/storm-gspn/api/storm-gspn.cpp b/src/storm-gspn/api/storm-gspn.cpp index d11ee28ba..ea4faf9e0 100644 --- a/src/storm-gspn/api/storm-gspn.cpp +++ b/src/storm-gspn/api/storm-gspn.cpp @@ -94,7 +94,7 @@ namespace storm { storm::utility::openFile(filename, stream); std::string line; - while ( std::getline(stream, line) ) { + while (storm::utility::getline(stream, line)) { std::vector strs; boost::split(strs, line, boost::is_any_of("\t ")); STORM_LOG_THROW(strs.size() == 2, storm::exceptions::WrongFormatException, "Expect key value pairs"); diff --git a/src/storm-parsers/parser/DirectEncodingParser.cpp b/src/storm-parsers/parser/DirectEncodingParser.cpp index 4814c77f5..35220498e 100644 --- a/src/storm-parsers/parser/DirectEncodingParser.cpp +++ b/src/storm-parsers/parser/DirectEncodingParser.cpp @@ -3,25 +3,21 @@ #include #include #include - - #include #include -#include "storm/models/sparse/MarkovAutomaton.h" -#include "storm/models/sparse/Ctmc.h" - +#include "storm/adapters/RationalFunctionAdapter.h" #include "storm/exceptions/FileIoException.h" -#include "storm/exceptions/WrongFormatException.h" #include "storm/exceptions/InvalidArgumentException.h" #include "storm/exceptions/NotSupportedException.h" +#include "storm/exceptions/WrongFormatException.h" +#include "storm/models/sparse/MarkovAutomaton.h" +#include "storm/models/sparse/Ctmc.h" #include "storm/settings/SettingsManager.h" - -#include "storm/adapters/RationalFunctionAdapter.h" -#include "storm/utility/constants.h" #include "storm/utility/builder.h" -#include "storm/utility/macros.h" +#include "storm/utility/constants.h" #include "storm/utility/file.h" +#include "storm/utility/macros.h" namespace storm { @@ -48,7 +44,7 @@ namespace storm { std::shared_ptr> modelComponents; // Parse header - while (std::getline(file, line)) { + while (storm::utility::getline(file, line)) { if (line.empty() || boost::starts_with(line, "//")) { continue; } @@ -65,7 +61,7 @@ namespace storm { } else if (line == "@parameters") { // Parse parameters STORM_LOG_THROW(!sawParameters, storm::exceptions::WrongFormatException, "Parameters declared twice"); - std::getline(file, line); + storm::utility::getline(file, line); if (line != "") { std::vector parameters; boost::split(parameters, line, boost::is_any_of(" ")); @@ -78,7 +74,7 @@ namespace storm { } else if (line == "@placeholders") { // Parse placeholders - while (std::getline(file, line)) { + while (storm::utility::getline(file, line)) { size_t posColon = line.find(':'); STORM_LOG_THROW(posColon != std::string::npos, storm::exceptions::WrongFormatException, "':' not found."); std::string placeName = line.substr(0, posColon - 1); @@ -96,16 +92,16 @@ namespace storm { } else if (line == "@reward_models") { // Parse reward models STORM_LOG_THROW(rewardModelNames.empty(), storm::exceptions::WrongFormatException, "Reward model names declared twice"); - std::getline(file, line); + storm::utility::getline(file, line); boost::split(rewardModelNames, line, boost::is_any_of("\t ")); } else if (line == "@nr_states") { // Parse no. of states STORM_LOG_THROW(nrStates == 0, storm::exceptions::WrongFormatException, "Number states declared twice"); - std::getline(file, line); + storm::utility::getline(file, line); nrStates = parseNumber(line); } else if (line == "@nr_choices") { STORM_LOG_THROW(nrChoices == 0, storm::exceptions::WrongFormatException, "Number of actions declared twice"); - std::getline(file, line); + storm::utility::getline(file, line); nrChoices = parseNumber(line); } else if (line == "@model") { // Parse rest of the model @@ -164,7 +160,7 @@ namespace storm { size_t state = 0; bool firstState = true; bool firstActionForState = true; - while (std::getline(file, line)) { + while (storm::utility::getline(file, line)) { STORM_LOG_TRACE("Parsing: " << line); if (boost::starts_with(line, "state ")) { // New state diff --git a/src/storm/settings/SettingsManager.cpp b/src/storm/settings/SettingsManager.cpp index 8e278fecb..8736c941e 100644 --- a/src/storm/settings/SettingsManager.cpp +++ b/src/storm/settings/SettingsManager.cpp @@ -539,7 +539,7 @@ namespace storm { bool globalScope = true; std::string activeModule = ""; uint_fast64_t lineNumber = 1; - for (std::string line; getline(input, line); ++lineNumber) { + for (std::string line; storm::utility::getline(input, line); ++lineNumber) { // If the first character of the line is a "[", we expect the settings of a new module to start and // the line to be of the shape []. if (line.at(0) == '[') { diff --git a/src/storm/utility/file.h b/src/storm/utility/file.h index f5ba06f4a..f4a1cbc96 100644 --- a/src/storm/utility/file.h +++ b/src/storm/utility/file.h @@ -70,5 +70,28 @@ namespace storm { return filestream.good(); } + /*! + * Overloaded getline function which handles different types of newline (\n and \r). + * @param input Input stream. + * @param str Output string. + * @return Remaining stream. + */ + template + inline std::basic_istream& getline(std::basic_istream& input, std::basic_string& str) { + auto& res = std::getline(input, str); + // Remove linebreaks + std::string::reverse_iterator rit = str.rbegin(); + while (rit != str.rend()) { + if (*rit == '\r' || *rit == '\n') { + ++rit; + str.pop_back(); + } else { + break; + } + } + return res; + } + + } } diff --git a/src/test/storm/utility/FileTest.cpp b/src/test/storm/utility/FileTest.cpp new file mode 100644 index 000000000..d804e653e --- /dev/null +++ b/src/test/storm/utility/FileTest.cpp @@ -0,0 +1,24 @@ +#include "test/storm_gtest.h" +#include "storm-config.h" + +#include "storm/utility/file.h" + +TEST(FileTest, GetLine) { + std::stringstream stream; + stream << "Hello world" << std::endl << "This is a test with n\nThis is a test with rn\r\n\nMore tests"; + + std::string str; + int i = 0; + std::string expected[] = {"Hello world", "This is a test with n", "This is a test with rn", "", "More tests"}; + while (storm::utility::getline(stream, str)) { + EXPECT_EQ(str, expected[i]); + ++i; + } +} + + +TEST(FileTest, GetLineEmpty) { + std::stringstream stream; + std::string str; + EXPECT_FALSE(storm::utility::getline(stream, str)); +}