From 6e2acc5159d6f4ae6f1a7631d9149dd507444091 Mon Sep 17 00:00:00 2001 From: gereon Date: Sat, 29 Dec 2012 22:43:32 +0100 Subject: [PATCH] add checked_strtod and use it in all parsers --- .../DeterministicSparseTransitionParser.cpp | 13 ++++++------- .../NonDeterministicSparseTransitionParser.cpp | 9 ++++----- src/parser/Parser.cpp | 18 ++++++++++++++++++ src/parser/Parser.h | 5 +++++ src/parser/SparseStateRewardParser.cpp | 5 ++--- 5 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/parser/DeterministicSparseTransitionParser.cpp b/src/parser/DeterministicSparseTransitionParser.cpp index f3d3b9d00..d82e4e3d9 100644 --- a/src/parser/DeterministicSparseTransitionParser.cpp +++ b/src/parser/DeterministicSparseTransitionParser.cpp @@ -68,7 +68,6 @@ uint_fast64_t DeterministicSparseTransitionParser::firstPass(char* buf, uint_fas uint_fast64_t row, col; double val; maxnode = 0; - char* tmp; while (buf[0] != '\0') { /* * read row and column @@ -81,16 +80,16 @@ uint_fast64_t DeterministicSparseTransitionParser::firstPass(char* buf, uint_fas if (row > maxnode) maxnode = row; if (col > maxnode) maxnode = col; /* - * read value. if value is 0.0, either strtod could not read a number or we encountered a probability of zero. + * read value. * if row == col, we have a diagonal element which is treated separately and this non_zero must be decreased. */ - val = strtod(buf, &tmp); - if (val == 0.0) { - LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << std::string(buf, 0, 16) << "\"."); + val = checked_strtod(buf, &buf); + if ((val < 0.0) || (val > 1.0)) { + LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << val << "\"."); return 0; } if (row == col) non_zero--; - buf = trimWhitespaces(tmp); + buf = trimWhitespaces(buf); } return non_zero; @@ -176,7 +175,7 @@ DeterministicSparseTransitionParser::DeterministicSparseTransitionParser(std::st */ row = checked_strtol(buf, &buf); col = checked_strtol(buf, &buf); - val = strtod(buf, &buf); + val = checked_strtod(buf, &buf); this->matrix->addNextValue(row,col,val); buf = trimWhitespaces(buf); diff --git a/src/parser/NonDeterministicSparseTransitionParser.cpp b/src/parser/NonDeterministicSparseTransitionParser.cpp index 822235c11..eaf72bc7d 100644 --- a/src/parser/NonDeterministicSparseTransitionParser.cpp +++ b/src/parser/NonDeterministicSparseTransitionParser.cpp @@ -71,7 +71,6 @@ std::unique_ptr> NonDeterministicSparseTransitionPars double val; maxnode = 0; maxchoice = 0; - char* tmp; while (buf[0] != '\0') { /* * read row and column @@ -93,16 +92,16 @@ std::unique_ptr> NonDeterministicSparseTransitionPars while (non_zero->size() < maxchoice) non_zero->push_back(0); } /* - * read value. if value is 0.0, either strtod could not read a number or we encountered a probability of zero. + * read value. * if row == col, we have a diagonal element which is treated separately and this non_zero must be decreased. */ - val = strtod(buf, &tmp); - if (val == 0.0) { + val = checked_strtod(buf, &buf); + if ((val < 0.0) || (val > 1.0)) { LOG4CPLUS_ERROR(logger, "Expected a positive probability but got \"" << std::string(buf, 0, 16) << "\"."); return 0; } if (row != col) (*non_zero)[ndchoice-1]++; - buf = trimWhitespaces(tmp); + buf = trimWhitespaces(buf); } return non_zero; diff --git a/src/parser/Parser.cpp b/src/parser/Parser.cpp index 0c53f3ffa..df9071332 100644 --- a/src/parser/Parser.cpp +++ b/src/parser/Parser.cpp @@ -28,6 +28,24 @@ uint_fast64_t storm::parser::Parser::checked_strtol(const char* str, char** end) return res; } +/*! + * Calls strtod() internally and checks if the new pointer is different + * from the original one, i.e. if str != *end. If they are the same, a + * storm::exceptions::WrongFileFormatException will be thrown. + * @param str String to parse + * @param end New pointer will be written there + * @return Result of strtod() + */ +double storm::parser::Parser::checked_strtod(const char* str, char** end) { + double res = strtod(str, end); + if (str == *end) { + LOG4CPLUS_ERROR(logger, "Error while parsing floating point. Next input token is not a number."); + LOG4CPLUS_ERROR(logger, "\tUpcoming input is: \"" << std::string(str, 0, 16) << "\""); + throw storm::exceptions::WrongFileFormatException("Error while parsing floating point. Next input token is not a number."); + } + return res; +} + /*! * Skips spaces, tabs, newlines and carriage returns. Returns pointer * to first char that is not a whitespace. diff --git a/src/parser/Parser.h b/src/parser/Parser.h index 9aa8eef79..ef6c38c84 100644 --- a/src/parser/Parser.h +++ b/src/parser/Parser.h @@ -102,6 +102,11 @@ namespace parser { * @brief Parses integer and checks, if something has been parsed. */ uint_fast64_t checked_strtol(const char* str, char** end); + + /*! + * @brief Parses floating point and checks, if something has been parsed. + */ + double checked_strtod(const char* str, char** end); /*! * @brief Skips common whitespaces in a string. diff --git a/src/parser/SparseStateRewardParser.cpp b/src/parser/SparseStateRewardParser.cpp index bac83a2c0..24f4038bd 100644 --- a/src/parser/SparseStateRewardParser.cpp +++ b/src/parser/SparseStateRewardParser.cpp @@ -54,9 +54,9 @@ SparseStateRewardParser::SparseStateRewardParser(uint_fast64_t stateCount, std:: while (buf[0] != '\0') { // Parse state number and reward value. state = checked_strtol(buf, &buf); - reward = strtod(buf, &buf); + reward = checked_strtod(buf, &buf); if (reward < 0.0) { - LOG4CPLUS_ERROR(logger, "Expected positive probability but got \"" << std::string(buf, 0, 16) << "\"."); + LOG4CPLUS_ERROR(logger, "Expected positive reward value but got \"" << reward << "\"."); throw storm::exceptions::WrongFileFormatException() << "State reward file specifies illegal reward value."; } @@ -68,5 +68,4 @@ SparseStateRewardParser::SparseStateRewardParser(uint_fast64_t stateCount, std:: } } //namespace parser - } //namespace storm