From f09f3ea39ce3166d47ac56cfec19cf65680c5b1d Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Fri, 6 Nov 2015 07:29:41 +0100 Subject: [PATCH] [4088fd] Fixed most of C++ problems --- src/lib/eval/eval_context.cc | 41 +++++++++++--------------- src/lib/eval/eval_context.h | 32 +++++++++++++------- src/lib/eval/lexer.cc | 22 ++++++++++++-- src/lib/eval/lexer.ll | 22 ++++++++++++-- src/lib/eval/tests/context_unittest.cc | 17 +++++++---- 5 files changed, 90 insertions(+), 44 deletions(-) diff --git a/src/lib/eval/eval_context.cc b/src/lib/eval/eval_context.cc index a22e18c72d..9c6a9ddd72 100644 --- a/src/lib/eval/eval_context.cc +++ b/src/lib/eval/eval_context.cc @@ -26,46 +26,39 @@ EvalContext::~EvalContext() { } -int +bool EvalContext::parseFile(const std::string &filename) { file_ = filename; - scanBegin(); + scanFileBegin(); isc::eval::EvalParser parser(*this); parser.set_debug_level(trace_parsing_); int res = parser.parse(); - scanEnd(); - return res; + scanFileEnd(); + return (res == 0); } -int +bool EvalContext::parseString(const std::string& str) { - /// @todo: Is there any way for the parser to read from a stream, - /// rather than a file? It would be better to use stringstream, - /// but it seems that the lexer operates on FILE* interface. - - // Put the content into a file and then open that file for reading. - remove("/tmp/eval"); - std::fstream f("/tmp/eval", std::ios::out); - - if (!f.good()) { - isc_throw(isc::Unexpected, "Can't write /tmp/eval file"); - } - f << str; - f.close(); - - return (parseFile("/tmp/eval")); + file_ = ""; + string_ = str; + scanStringBegin(); + isc::eval::EvalParser parser(*this); + parser.set_debug_level(trace_parsing_); + int res = parser.parse(); + scanStringEnd(); + return (res == 0); } void -EvalContext::error(const isc::eval::location& l, const std::string& m) +EvalContext::error(const isc::eval::location& loc, const std::string& what) { - isc_throw(EvalError, l << ": " << m); + isc_throw(EvalParseError, loc << ": " << what); } void -EvalContext::error (const std::string& m) +EvalContext::error (const std::string& what) { - isc_throw(EvalError, m); + isc_throw(EvalParseError, what); } diff --git a/src/lib/eval/eval_context.h b/src/lib/eval/eval_context.h index 401c46b13b..3cb31eddcf 100644 --- a/src/lib/eval/eval_context.h +++ b/src/lib/eval/eval_context.h @@ -30,9 +30,9 @@ namespace isc { namespace eval { /// @brief Evaluation error exception raised when trying to parse an axceptions. -class EvalError : public isc::Exception { +class EvalParseError : public isc::Exception { public: - EvalError(const char* file, size_t line, const char* what) : + EvalParseError(const char* file, size_t line, const char* what) : isc::Exception(file, line, what) { }; }; @@ -50,32 +50,42 @@ public: /// @brief Parsed expression (output tokens are stored here) isc::dhcp::Expression expression; - /// @brief Method called before scanning starts. - void scanBegin(); + /// @brief Method called before scanning starts on a file. + void scanFileBegin(); - /// @brief Method called after the last tokens are scanned. - void scanEnd(); + /// @brief Method called after the last tokens are scanned from a file. + void scanFileEnd(); + + /// @brief Method called before scanning starts on a string. + void scanStringBegin(); + + /// @brief Method called after the last tokens are scanned from a string. + void scanStringEnd(); /// @brief Runs the parser on specified file. /// /// @param filename - /// Return 0 on success. - int parseFile(const std::string& filename); + /// @return true on success. + bool parseFile(const std::string& filename); /// @brief Run the parser on the string specified. /// /// @param str string to be written - int parseString(const std::string& str); + /// @return true on success. + bool parseString(const std::string& str); /// @brief The name of the file being parsed. /// Used later to pass the file name to the location tracker. std::string file_; + /// @brief The string being parsed. + std::string string_; + /// @brief Error handler /// - /// @param l location within the parsed file when experienced a problem. + /// @param loc location within the parsed file when experienced a problem. /// @param what string explaining the nature of the error. - void error(const isc::eval::location& l, const std::string& what); + void error(const isc::eval::location& loc, const std::string& what); /// @brief Error handler /// diff --git a/src/lib/eval/lexer.cc b/src/lib/eval/lexer.cc index 6d976b7011..953f05a313 100644 --- a/src/lib/eval/lexer.cc +++ b/src/lib/eval/lexer.cc @@ -2234,7 +2234,7 @@ void yyfree (void * ptr ) using namespace isc::eval; void -EvalContext::scanBegin() +EvalContext::scanFileBegin() { yy_flex_debug = trace_scanning_; if (file_.empty () || file_ == "-") { @@ -2247,8 +2247,26 @@ EvalContext::scanBegin() } void -EvalContext::scanEnd() +EvalContext::scanFileEnd() { fclose(yyin); } +void +EvalContext::scanStringBegin() +{ + YY_BUFFER_STATE buffer; + yy_flex_debug = trace_scanning_; + buffer = yy_scan_bytes(string_.c_str(),string_.size()); + if (!buffer) { + error("cannot scan string"); + exit(EXIT_FAILURE); + } +} + +void +EvalContext::scanStringEnd() +{ + yy_delete_buffer(YY_CURRENT_BUFFER); +} + diff --git a/src/lib/eval/lexer.ll b/src/lib/eval/lexer.ll index 1d86d9db90..b9455b2da6 100644 --- a/src/lib/eval/lexer.ll +++ b/src/lib/eval/lexer.ll @@ -146,7 +146,7 @@ str [a-zA-Z_0-9]* using namespace isc::eval; void -EvalContext::scanBegin() +EvalContext::scanFileBegin() { yy_flex_debug = trace_scanning_; if (file_.empty () || file_ == "-") { @@ -159,7 +159,25 @@ EvalContext::scanBegin() } void -EvalContext::scanEnd() +EvalContext::scanFileEnd() { fclose(yyin); } + +void +EvalContext::scanStringBegin() +{ + YY_BUFFER_STATE buffer; + yy_flex_debug = trace_scanning_; + buffer = yy_scan_bytes(string_.c_str(), string_.size()); + if (!buffer) { + error("cannot scan string"); + exit(EXIT_FAILURE); + } +} + +void +EvalContext::scanStringEnd() +{ + yy_delete_buffer(YY_CURRENT_BUFFER); +} diff --git a/src/lib/eval/tests/context_unittest.cc b/src/lib/eval/tests/context_unittest.cc index 38769740e2..077d74d40a 100644 --- a/src/lib/eval/tests/context_unittest.cc +++ b/src/lib/eval/tests/context_unittest.cc @@ -77,19 +77,23 @@ public: EXPECT_EQ(expected_option, opt->getCode()); } + + bool parsed_; ///< Parsing status }; TEST_F(EvalContextTest, basic) { EvalContext tmp; - EXPECT_NO_THROW(tmp.parseString("option[123] == 'MSFT'")); + EXPECT_NO_THROW(parsed_ = tmp.parseString("option[123] == 'MSFT'")); + EXPECT_TRUE(parsed_); } TEST_F(EvalContextTest, string) { EvalContext eval; - EXPECT_NO_THROW(eval.parseString("'foo'")); + EXPECT_NO_THROW(parsed_ = eval.parseString("'foo'")); + EXPECT_TRUE(parsed_); ASSERT_EQ(1, eval.expression.size()); @@ -101,7 +105,8 @@ TEST_F(EvalContextTest, string) { TEST_F(EvalContextTest, hexstring) { EvalContext eval; - EXPECT_NO_THROW(eval.parseString("0x666f6f")); + EXPECT_NO_THROW(parsed_ = eval.parseString("0x666f6f")); + EXPECT_TRUE(parsed_); ASSERT_EQ(1, eval.expression.size()); @@ -113,7 +118,8 @@ TEST_F(EvalContextTest, hexstring) { TEST_F(EvalContextTest, equal) { EvalContext eval; - EXPECT_NO_THROW(eval.parseString("'foo' == 'bar'")); + EXPECT_NO_THROW(parsed_ = eval.parseString("'foo' == 'bar'")); + EXPECT_TRUE(parsed_); ASSERT_EQ(3, eval.expression.size()); @@ -129,7 +135,8 @@ TEST_F(EvalContextTest, equal) { TEST_F(EvalContextTest, option) { EvalContext eval; - EXPECT_NO_THROW(eval.parseString("option[123]")); + EXPECT_NO_THROW(parsed_ = eval.parseString("option[123]")); + EXPECT_TRUE(parsed_); ASSERT_EQ(1, eval.expression.size()); checkTokenOption(eval.expression.at(0), 123); } -- 2.47.3