diff --git a/apps/plasp-app/main.cpp b/apps/plasp-app/main.cpp index dc58301..51149e8 100644 --- a/apps/plasp-app/main.cpp +++ b/apps/plasp-app/main.cpp @@ -66,14 +66,6 @@ int main(int argc, char **argv) return EXIT_SUCCESS; } - const auto handleException = - [&](const auto &messagePrefix, const auto &exception) - { - std::cerr << messagePrefix << ": " << exception.what() << std::endl << std::endl; - printHelp(); - exit(EXIT_FAILURE); - }; - try { plasp::utils::Parser parser; @@ -108,7 +100,9 @@ int main(int argc, char **argv) if (language == plasp::Language::Type::Unknown) { - std::cerr << "Error: Unknown input language" << std::endl << std::endl; + plasp::utils::Logger logger; + logger.exception("error", "unknown input language"); + std::cout << std::endl; printHelp(); return EXIT_FAILURE; } @@ -137,19 +131,27 @@ int main(int argc, char **argv) } catch (const plasp::utils::ParserException &e) { - handleException("Parser error", e); + plasp::utils::Logger logger; + logger.parserException(e.coordinate(), e.message()); + return EXIT_FAILURE; } catch (const plasp::utils::ParserWarning &e) { - handleException("Parser warning", e); + plasp::utils::Logger logger; + logger.parserException(e.coordinate(), e.message()); + return EXIT_FAILURE; } catch (const plasp::utils::TranslatorException &e) { - handleException("Translation error", e); + plasp::utils::Logger logger; + logger.exception("translation error", e.what()); + return EXIT_FAILURE; } catch (const std::exception &e) { - handleException("Error", e); + plasp::utils::Logger logger; + logger.exception("unexpected error", e.what()); + return EXIT_FAILURE; } return EXIT_SUCCESS; diff --git a/include/plasp/pddl/expressions/NAry.h b/include/plasp/pddl/expressions/NAry.h index e778f17..9cbbb6c 100644 --- a/include/plasp/pddl/expressions/NAry.h +++ b/include/plasp/pddl/expressions/NAry.h @@ -71,7 +71,7 @@ std::unique_ptr NAry::parse(Context &context, } if (expression->m_arguments.empty()) - context.logger.parserWarning(context.parser, "\"" + Derived::Identifier + "\" expressions should not be empty"); + context.logger.parserWarning(context.parser, "“" + Derived::Identifier + "” expressions should not be empty"); parser.expect(")"); diff --git a/include/plasp/utils/Formatting.h b/include/plasp/utils/Formatting.h new file mode 100644 index 0000000..b0c1cf1 --- /dev/null +++ b/include/plasp/utils/Formatting.h @@ -0,0 +1,81 @@ +#ifndef __PLASP__UTILS__FORMATTING_H +#define __PLASP__UTILS__FORMATTING_H + +#include + +#include + +namespace plasp +{ +namespace utils +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Formatting +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +enum class Color +{ + Black = 0, + Red = 1, + Green = 2, + Yellow = 3, + Blue = 4, + Magenta = 5, + Cyan = 6, + White = 7 +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +enum class FontWeight +{ + Normal = 0, + Bold = 1 +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Format +{ + Format(Color color, FontWeight fontWeight = FontWeight::Normal) + : color{color}, + fontWeight{fontWeight} + { + } + + Color color; + FontWeight fontWeight; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::ostream &operator<<(std::ostream &ostream, const Format &format) +{ + const auto fontWeightCode = static_cast(format.fontWeight); + const auto colorCode = 30 + static_cast(format.color); + + return (ostream << "\033[" << fontWeightCode << ";" << colorCode << "m"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class ResetFormat +{ +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::ostream &operator<<(std::ostream &ostream, const ResetFormat &) +{ + return (ostream << "\033[0m"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/utils/Logger.h b/include/plasp/utils/Logger.h index 60b5503..cb51177 100644 --- a/include/plasp/utils/Logger.h +++ b/include/plasp/utils/Logger.h @@ -4,6 +4,7 @@ #include #include +#include namespace plasp { @@ -37,6 +38,8 @@ class Logger void setWarningLevel(WarningLevel warningLevel); + void exception(const std::string &errorType, const std::string &message); + void parserException(const Parser::Coordinate &coordinate, const std::string &message); void parserWarning(const Parser &parser, const std::string &message); private: diff --git a/include/plasp/utils/ParserException.h b/include/plasp/utils/ParserException.h index f2c56bb..e027a79 100644 --- a/include/plasp/utils/ParserException.h +++ b/include/plasp/utils/ParserException.h @@ -31,10 +31,11 @@ class ParserException: public std::exception } explicit ParserException(const utils::Parser &parser, const std::string &message) + : m_coordinate{parser.coordinate()}, + m_message{message}, + m_plainMessage{m_coordinate.sectionName + ":" + std::to_string(m_coordinate.row) + + ":" + std::to_string(m_coordinate.column) + " " + m_message} { - const auto coordinate = parser.coordinate(); - - m_message = coordinate.sectionName + ":" + std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) + " " + message; } ~ParserException() throw() @@ -43,14 +44,23 @@ class ParserException: public std::exception const char *what() const throw() { - if (m_message.empty()) - return "Unspecified parser error"; + return m_plainMessage.c_str(); + } - return m_message.c_str(); + const Parser::Coordinate &coordinate() const + { + return m_coordinate; + } + + const std::string &message() const + { + return m_message; } private: + Parser::Coordinate m_coordinate; std::string m_message; + std::string m_plainMessage; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/utils/ParserWarning.h b/include/plasp/utils/ParserWarning.h index 9cf9c20..c970d1e 100644 --- a/include/plasp/utils/ParserWarning.h +++ b/include/plasp/utils/ParserWarning.h @@ -31,10 +31,11 @@ class ParserWarning: public std::exception } explicit ParserWarning(const utils::Parser &parser, const std::string &message) + : m_coordinate{parser.coordinate()}, + m_message{message}, + m_plainMessage{m_coordinate.sectionName + ":" + std::to_string(m_coordinate.row) + + ":" + std::to_string(m_coordinate.column) + " " + m_message} { - const auto coordinate = parser.coordinate(); - - m_message = coordinate.sectionName + ":" + std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) + " " + message; } ~ParserWarning() throw() @@ -43,14 +44,23 @@ class ParserWarning: public std::exception const char *what() const throw() { - if (m_message.empty()) - return "Unspecified parser warning"; + return m_plainMessage.c_str(); + } - return m_message.c_str(); + const Parser::Coordinate &coordinate() const + { + return m_coordinate; + } + + const std::string &message() const + { + return m_message; } private: + Parser::Coordinate m_coordinate; std::string m_message; + std::string m_plainMessage; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/Description.cpp b/src/plasp/pddl/Description.cpp index 104b8af..5740e7d 100644 --- a/src/plasp/pddl/Description.cpp +++ b/src/plasp/pddl/Description.cpp @@ -188,7 +188,7 @@ void Description::findSections() else { const auto sectionIdentifier = parser.parse(); - throw utils::ParserException(parser, "Unknown PDDL section \"" + sectionIdentifier + "\""); + throw utils::ParserException(parser, "Unknown PDDL section “" + sectionIdentifier + "”"); } m_context.parser.skipWhiteSpace(); diff --git a/src/plasp/pddl/Domain.cpp b/src/plasp/pddl/Domain.cpp index 7bfa89c..3ac6ac3 100644 --- a/src/plasp/pddl/Domain.cpp +++ b/src/plasp/pddl/Domain.cpp @@ -54,7 +54,7 @@ void Domain::findSections() if (unique && sectionPosition != -1) { parser.seek(value); - throw utils::ParserException(parser, "Only one \":" + sectionName + "\" section allowed"); + throw utils::ParserException(parser, "Only one “:" + sectionName + "” section allowed"); } sectionPosition = value; @@ -95,7 +95,7 @@ void Domain::findSections() const auto sectionIdentifier = parser.parseIdentifier(isIdentifier); - m_context.logger.parserWarning(parser, "Section type \"" + sectionIdentifier + "\" currently unsupported"); + m_context.logger.parserWarning(parser, "Section type “" + sectionIdentifier + "” currently unsupported"); parser.seek(sectionIdentifierPosition); } @@ -104,7 +104,7 @@ void Domain::findSections() const auto sectionIdentifier = parser.parseIdentifier(isIdentifier); parser.seek(position); - throw utils::ParserException(m_context.parser, "Unknown domain section \"" + sectionIdentifier + "\""); + throw utils::ParserException(m_context.parser, "Unknown domain section “" + sectionIdentifier + "”"); } // Skip section for now and parse it later @@ -280,7 +280,7 @@ void Domain::checkRequirement(Requirement::Type requirementType) const if (hasRequirement(requirementType)) return; - throw ConsistencyException("Requirement \"" + Requirement(requirementType).toPDDL() + "\" used but never declared"); + throw ConsistencyException("Requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/Expression.cpp b/src/plasp/pddl/Expression.cpp index 0dfe022..bec5954 100644 --- a/src/plasp/pddl/Expression.cpp +++ b/src/plasp/pddl/Expression.cpp @@ -114,7 +114,7 @@ ExpressionPointer parseExpression(Context &context, ExpressionContext &expressio const auto expressionIdentifier = parser.parseIdentifier(isIdentifier); parser.seek(position); - throw utils::ParserException(context.parser, "Expression type \"" + expressionIdentifier + "\" unknown or not allowed in this context"); + throw utils::ParserException(context.parser, "Expression type “" + expressionIdentifier + "” unknown or not allowed in this context"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -186,7 +186,7 @@ ExpressionPointer parseEffectBodyExpression(Context &context, ExpressionContext const auto expressionIdentifier = parser.parseIdentifier(isIdentifier); parser.seek(position); - throw utils::ParserException(context.parser, "Expression type \"" + expressionIdentifier + "\" unknown or not allowed in this context"); + throw utils::ParserException(context.parser, "Expression type “" + expressionIdentifier + "” unknown or not allowed in this context"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/InitialState.cpp b/src/plasp/pddl/InitialState.cpp index 65ebd35..7290d3d 100644 --- a/src/plasp/pddl/InitialState.cpp +++ b/src/plasp/pddl/InitialState.cpp @@ -59,7 +59,7 @@ std::unique_ptr InitialState::parseDeclaration(Context &context, const auto expressionIdentifier = parser.parseIdentifier(isIdentifier); parser.seek(position); - throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" unknown or not allowed in this context"); + throw utils::ParserException(parser, "Expression type “" + expressionIdentifier + "” unknown or not allowed in this context"); }; parser.skipWhiteSpace(); diff --git a/src/plasp/pddl/Problem.cpp b/src/plasp/pddl/Problem.cpp index e521a3a..8976cb7 100644 --- a/src/plasp/pddl/Problem.cpp +++ b/src/plasp/pddl/Problem.cpp @@ -53,7 +53,7 @@ void Problem::findSections() if (unique && sectionPosition != -1) { parser.seek(value); - throw utils::ParserException(parser, "Only one \":" + sectionName + "\" section allowed"); + throw utils::ParserException(parser, "Only one “:" + sectionName + "” section allowed"); } sectionPosition = value; @@ -89,7 +89,7 @@ void Problem::findSections() const auto sectionIdentifier = parser.parseIdentifier(isIdentifier); - m_context.logger.parserWarning(parser, "Section type \"" + sectionIdentifier + "\" currently unsupported"); + m_context.logger.parserWarning(parser, "Section type “" + sectionIdentifier + "” currently unsupported"); parser.seek(sectionIdentifierPosition); } @@ -98,7 +98,7 @@ void Problem::findSections() const auto sectionIdentifier = parser.parseIdentifier(isIdentifier); parser.seek(position); - throw utils::ParserException(m_context.parser, "Unknown problem section \"" + sectionIdentifier + "\""); + throw utils::ParserException(m_context.parser, "Unknown problem section “" + sectionIdentifier + "”"); } // Skip section for now and parse it later @@ -204,7 +204,7 @@ void Problem::parseDomainSection() const auto domainName = parser.parseIdentifier(isIdentifier); if (m_domain.name() != domainName) - throw utils::ParserException(parser, "Domains do not match (\"" + m_domain.name() + "\" and \"" + domainName + "\")"); + throw utils::ParserException(parser, "Domains do not match (“" + m_domain.name() + "” and “" + domainName + "”)"); parser.expect(")"); } @@ -261,7 +261,7 @@ void Problem::checkRequirement(Requirement::Type requirementType) const if (hasRequirement(requirementType)) return; - throw ConsistencyException("Requirement \"" + Requirement(requirementType).toPDDL() + "\" used but never declared"); + throw ConsistencyException("Requirement “" + Requirement(requirementType).toPDDL() + "” used but never declared"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/Requirement.cpp b/src/plasp/pddl/Requirement.cpp index 72d87f7..ae00069 100644 --- a/src/plasp/pddl/Requirement.cpp +++ b/src/plasp/pddl/Requirement.cpp @@ -89,12 +89,12 @@ Requirement Requirement::parse(Context &context) const auto match = requirementTypesToPDDL.right.find(requirementName); if (match == requirementTypesToPDDL.right.end()) - throw utils::ParserException(context.parser, "Unknown PDDL requirement \"" + requirementName + "\""); + throw utils::ParserException(context.parser, "Unknown PDDL requirement “" + requirementName + "”"); const auto requirementType = match->second; if (requirementType == Requirement::Type::GoalUtilities) - context.logger.parserWarning(context.parser, "Requirement \"goal-utilities\" is not part of the PDDL 3.1 specification"); + context.logger.parserWarning(context.parser, "Requirement “goal-utilities” is not part of the PDDL 3.1 specification"); return Requirement(match->second); } diff --git a/src/plasp/pddl/TranslatorASP.cpp b/src/plasp/pddl/TranslatorASP.cpp index 49b7f4e..e8ac949 100644 --- a/src/plasp/pddl/TranslatorASP.cpp +++ b/src/plasp/pddl/TranslatorASP.cpp @@ -225,7 +225,7 @@ void TranslatorASP::translateActions() const else { if (precondition.expressionType() != Expression::Type::And) - throw utils::TranslatorException("Only \"and\" expressions and (negated) predicates supported as action preconditions currently"); + throw utils::TranslatorException("Only “and” expressions and (negated) predicates supported as action preconditions currently"); const auto &andExpression = dynamic_cast(precondition); @@ -251,7 +251,7 @@ void TranslatorASP::translateActions() const else { if (effect.expressionType() != Expression::Type::And) - throw utils::TranslatorException("Only \"and\" expressions and (negated) predicates supported as action effects currently"); + throw utils::TranslatorException("Only “and” expressions and (negated) predicates supported as action effects currently"); const auto &andExpression = dynamic_cast(effect); diff --git a/src/plasp/pddl/expressions/Constant.cpp b/src/plasp/pddl/expressions/Constant.cpp index 78b6fca..2b4a4e1 100644 --- a/src/plasp/pddl/expressions/Constant.cpp +++ b/src/plasp/pddl/expressions/Constant.cpp @@ -156,7 +156,7 @@ Constant *Constant::parseAndFind(Context &context, const Domain &domain) if (constant != nullptr) return constant; - throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared"); + throw utils::ParserException(context.parser, "Constant “" + constantName + "” used but never declared"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -177,7 +177,7 @@ Constant *Constant::parseAndFind(Context &context, const Problem &problem) if (constant) return constant; - throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared"); + throw utils::ParserException(context.parser, "Constant “" + constantName + "” used but never declared"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/expressions/PrimitiveType.cpp b/src/plasp/pddl/expressions/PrimitiveType.cpp index 525ac70..11e9cbf 100644 --- a/src/plasp/pddl/expressions/PrimitiveType.cpp +++ b/src/plasp/pddl/expressions/PrimitiveType.cpp @@ -122,11 +122,11 @@ PrimitiveType *PrimitiveType::parseAndFind(Context &context, Domain &domain) // Only "object" is allowed as an implicit type if (typeName == "object" || typeName == "objects") { - context.logger.parserWarning(context.parser, "Primitive type \"" + typeName + "\" should be declared"); + context.logger.parserWarning(context.parser, "Primitive type “" + typeName + "” should be declared"); types.emplace_back(std::make_unique(typeName)); } else - throw utils::ParserException(context.parser, "Type \"" + typeName + "\" used but never declared"); + throw utils::ParserException(context.parser, "Type “" + typeName + "” used but never declared"); return types.back().get(); } diff --git a/src/plasp/pddl/expressions/Unsupported.cpp b/src/plasp/pddl/expressions/Unsupported.cpp index cffed55..72d06c3 100644 --- a/src/plasp/pddl/expressions/Unsupported.cpp +++ b/src/plasp/pddl/expressions/Unsupported.cpp @@ -26,7 +26,7 @@ UnsupportedPointer Unsupported::parse(Context &context) expression->m_type = parser.parseIdentifier(isIdentifier); - context.logger.parserWarning(context.parser, "Expression type \"" + expression->m_type + "\" currently unsupported in this context"); + context.logger.parserWarning(context.parser, "Expression type “" + expression->m_type + "” currently unsupported in this context"); skipSection(parser); diff --git a/src/plasp/pddl/expressions/Variable.cpp b/src/plasp/pddl/expressions/Variable.cpp index 33bf631..571471e 100644 --- a/src/plasp/pddl/expressions/Variable.cpp +++ b/src/plasp/pddl/expressions/Variable.cpp @@ -52,7 +52,7 @@ void Variable::parseDeclaration(Context &context, Variables ¶meters) }); if (match != parameters.cend()) - throw utils::ParserException(context.parser, "Variable \"" + variable->m_name + "\" already declared in this scope"); + throw utils::ParserException(context.parser, "Variable “" + variable->m_name + "” already declared in this scope"); // Flag variable for potentially upcoming type declaration variable->setDirty(); @@ -154,7 +154,7 @@ const Variable *Variable::parseAndFind(Context &context, const ExpressionContext }); if (match == variables.cend()) - throw utils::ParserException(context.parser, "Parameter \"" + variableName + "\" used but never declared"); + throw utils::ParserException(context.parser, "Parameter “" + variableName + "” used but never declared"); return match->get(); } diff --git a/src/plasp/sas/Description.cpp b/src/plasp/sas/Description.cpp index 7bd67e8..ced16d6 100644 --- a/src/plasp/sas/Description.cpp +++ b/src/plasp/sas/Description.cpp @@ -56,7 +56,7 @@ Description Description::fromStream(std::istream &istream) Description Description::fromFile(const boost::filesystem::path &path) { if (!boost::filesystem::is_regular_file(path)) - throw std::runtime_error("File does not exist: \"" + path.string() + "\""); + throw std::runtime_error("File does not exist: “" + path.string() + "”"); utils::Parser parser; parser.readFile(path); diff --git a/src/plasp/sas/Value.cpp b/src/plasp/sas/Value.cpp index d399143..f3a29fe 100644 --- a/src/plasp/sas/Value.cpp +++ b/src/plasp/sas/Value.cpp @@ -74,7 +74,7 @@ Value Value::fromSAS(utils::Parser &parser) else if (sasSign == "NegatedAtom") value.m_sign = Value::Sign::Negative; else - throw utils::ParserException(parser, "Invalid value sign \"" + sasSign + "\""); + throw utils::ParserException(parser, "Invalid value sign “" + sasSign + "”"); try { diff --git a/src/plasp/utils/Logger.cpp b/src/plasp/utils/Logger.cpp index 96caf0b..0a67ada 100644 --- a/src/plasp/utils/Logger.cpp +++ b/src/plasp/utils/Logger.cpp @@ -1,5 +1,6 @@ #include +#include #include namespace plasp @@ -61,6 +62,56 @@ void Logger::setWarningLevel(WarningLevel warningLevel) //////////////////////////////////////////////////////////////////////////////////////////////////// +void Logger::exception(const std::string &errorType, const std::string &message) +{ + if (isatty(STDERR_FILENO)) + { + std::cerr + << Format(Color::Red, FontWeight::Bold) << "error:" + << ResetFormat() << " " + << Format(Color::White, FontWeight::Bold) << message + << ResetFormat() << std::endl; + } + else + { + std::cerr + << "error:" + << " " + << message + << std::endl; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Logger::parserException(const Parser::Coordinate &coordinate, const std::string &message) +{ + if (isatty(STDERR_FILENO)) + { + std::cerr + << Format(Color::White, FontWeight::Bold) << coordinate.sectionName << ":" + << std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":" + << ResetFormat() << " " + << Format(Color::Red, FontWeight::Bold) << "error:" + << ResetFormat() << " " + << Format(Color::White, FontWeight::Bold) << message + << ResetFormat() << std::endl; + } + else + { + std::cerr + << coordinate.sectionName << ":" + << std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":" + << " " + << "error:" + << " " + << message + << std::endl; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Logger::parserWarning(const Parser &parser, const std::string &message) { if (m_warningLevel == WarningLevel::Ignore) @@ -71,9 +122,28 @@ void Logger::parserWarning(const Parser &parser, const std::string &message) const auto coordinate = parser.coordinate(); - std::cerr << "Warning: " << coordinate.sectionName << ":" - << std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) - << " " << message << std::endl; + if (isatty(STDERR_FILENO)) + { + std::cerr + << Format(Color::White, FontWeight::Bold) << coordinate.sectionName << ":" + << std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":" + << ResetFormat() << " " + << Format(Color::Magenta, FontWeight::Bold) << "warning:" + << ResetFormat() << " " + << Format(Color::White, FontWeight::Bold) << message + << ResetFormat() << std::endl; + } + else + { + std::cerr + << coordinate.sectionName << ":" + << std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":" + << " " + << "warning:" + << " " + << message + << std::endl; + } } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/utils/Parser.cpp b/src/plasp/utils/Parser.cpp index bfb21c0..9a6ad85 100644 --- a/src/plasp/utils/Parser.cpp +++ b/src/plasp/utils/Parser.cpp @@ -79,7 +79,7 @@ void Parser::readStream(std::string streamName, std::istream &istream) void Parser::readFile(const boost::filesystem::path &path) { if (!boost::filesystem::is_regular_file(path)) - throw std::runtime_error("File does not exist: \"" + path.string() + "\""); + throw std::runtime_error("File does not exist: “" + path.string() + "”"); std::ifstream fileStream(path.string(), std::ios::in); @@ -310,7 +310,7 @@ template<> void Parser::expect(const std::string &expectedValue) { if (!probe(expectedValue)) - throw ParserException(*this, "Expected \"" + expectedValue + "\""); + throw ParserException(*this, "Expected “" + expectedValue + "”"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -344,7 +344,7 @@ template<> void Parser::expect(const char &expectedValue) { if (!probe(expectedValue)) - throw ParserException(*this, std::string("Expected \"") + expectedValue + "\""); + throw ParserException(*this, std::string("Expected “") + expectedValue + "”"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -439,7 +439,7 @@ template<> void Parser::expect(const int64_t &expectedValue) { if (!probe(expectedValue)) - throw ParserException(*this, "Expected \"" + std::to_string(expectedValue) + "\""); + throw ParserException(*this, "Expected “" + std::to_string(expectedValue) + "”"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -448,7 +448,7 @@ template<> void Parser::expect(const uint64_t &expectedValue) { if (!probe(expectedValue)) - throw ParserException(*this, "Expected \"" + std::to_string(expectedValue) + "\""); + throw ParserException(*this, "Expected “" + std::to_string(expectedValue) + "”"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -523,7 +523,7 @@ void Parser::expect(const bool &expectedValue) const auto value = parse(); if (value != expectedValue) - throw ParserException(*this, "Expected \"" + std::to_string(expectedValue) + "\""); + throw ParserException(*this, "Expected “" + std::to_string(expectedValue) + "”"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/tests/TestSASParser.cpp b/tests/TestSASParser.cpp index 0d8705c..4971b96 100644 --- a/tests/TestSASParser.cpp +++ b/tests/TestSASParser.cpp @@ -27,7 +27,7 @@ class SASParserTests : public ::testing::Test std::stringstream outputStream; if (!fileStream.is_open()) - throw std::runtime_error("Could not open file \"" + path + "\""); + throw std::runtime_error("Could not open file “" + path + "”"); outputStream << fileStream.rdbuf();