From: Tomek Mrugalski Date: Wed, 9 Nov 2016 20:24:15 +0000 (+0100) Subject: [5014] Reading from file implemented X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b74aac9c5db03621f39a9fcfef3d1c0f8dd1cc48;p=thirdparty%2Fkea.git [5014] Reading from file implemented --- diff --git a/src/bin/dhcp6/dhcp6_lexer.ll b/src/bin/dhcp6/dhcp6_lexer.ll index 780ccc805e..e2504a402c 100644 --- a/src/bin/dhcp6/dhcp6_lexer.ll +++ b/src/bin/dhcp6/dhcp6_lexer.ll @@ -198,6 +198,25 @@ Parser6Context::scanStringEnd() yy_delete_buffer(YY_CURRENT_BUFFER); } +void +Parser6Context::scanFileBegin(FILE * f) { + loc.initialize(&file_); + yy_flex_debug = trace_scanning_; + YY_BUFFER_STATE buffer; + + // See dhcp6_lexer.cc header for available definitions + buffer = parser6__create_buffer(f, 65536 /*buffer size*/); + if (!buffer) { + fatal("cannot scan file " + file_); + } +} + +void +Parser6Context::scanFileEnd(FILE * f) { + fclose(f); + yy_delete_buffer(YY_CURRENT_BUFFER); +} + namespace { /// To avoid unused function error class Dummy { diff --git a/src/bin/dhcp6/parser_context.cc b/src/bin/dhcp6/parser_context.cc index b58dc955ae..e667a8e5e8 100644 --- a/src/bin/dhcp6/parser_context.cc +++ b/src/bin/dhcp6/parser_context.cc @@ -42,11 +42,74 @@ Parser6Context::parseString(const std::string& str) if (stack_.size() == 1) { return (stack_[0]); } else { - isc_throw(BadValue, "Expected exactly one terminal Element, found " + isc_throw(BadValue, "Expected exactly one terminal Element expected, found " << stack_.size()); } } +isc::data::ConstElementPtr +Parser6Context::parseFile(const std::string& filename) { + + ifstream f; + f.open(filename); + if (!f.is_open()) { + isc_throw(BadValue, "Can't open file " << filename); + } + + string_ = ""; + std::string line; + while (!f.eof()) { + std::getline(f, line); + string_ = string_ + line; + } + f.close(); + + file_ = filename; + + scanStringBegin(); + isc::dhcp::Dhcp6Parser parser(*this); + // Uncomment this to get detailed parser logs. + // trace_parsing_ = true; + parser.set_debug_level(trace_parsing_); + int res = parser.parse(); + if (res != 0) { + // @todo: handle exception here + } + scanStringEnd(); + if (stack_.size() == 1) { + return (stack_[0]); + } else { + isc_throw(BadValue, "Expected exactly one terminal Element expected, found " + << stack_.size()); + } + +#if 0 + FILE* f = fopen(filename.c_str(), "r"); + if (!f) { + isc_throw(BadValue, "Unable to open file " << filename); + } + file_ = filename; + scanFileBegin(f); + + isc::dhcp::Dhcp6Parser parser(*this); + // Uncomment this to get detailed parser logs. + // trace_parsing_ = true; + parser.set_debug_level(trace_parsing_); + int res = parser.parse(); + if (res != 0) { + // @todo: handle exception here + } + scanFileEnd(f); + if (stack_.size() == 1) { + return (stack_[0]); + } else { + isc_throw(BadValue, "Expected exactly one terminal Element expected, found " + << stack_.size()); + } +#endif +} + + void Parser6Context::error(const isc::dhcp::location& loc, const std::string& what) { diff --git a/src/bin/dhcp6/parser_context.h b/src/bin/dhcp6/parser_context.h index 5402e211ca..1bd2cb0b7b 100644 --- a/src/bin/dhcp6/parser_context.h +++ b/src/bin/dhcp6/parser_context.h @@ -53,12 +53,17 @@ public: /// @brief Method called after the last tokens are scanned from a string. void scanStringEnd(); + void scanFileBegin(FILE * f); + void scanFileEnd(FILE * f); + /// @brief Run the parser on the string specified. /// /// @param str string to be written /// @return true on success. isc::data::ConstElementPtr parseString(const std::string& str); + isc::data::ConstElementPtr parseFile(const std::string& filename); + /// @brief The name of the file being parsed. /// Used later to pass the file name to the location tracker. std::string file_; diff --git a/src/bin/dhcp6/tests/parser_unittest.cc b/src/bin/dhcp6/tests/parser_unittest.cc index 3490f8dd0d..188c906d43 100644 --- a/src/bin/dhcp6/tests/parser_unittest.cc +++ b/src/bin/dhcp6/tests/parser_unittest.cc @@ -164,4 +164,23 @@ TEST(ParserTest, multilineComments) { testParser2(txt); } +TEST(ParserTest, file) { + + ElementPtr reference_json; + ConstElementPtr test_json; + + std::string fname = "test.json"; + + EXPECT_NO_THROW(reference_json = Element::fromJSONFile(fname, true)); + EXPECT_NO_THROW({ + Parser6Context ctx; + test_json = ctx.parseFile(fname); + }); + + ASSERT_TRUE(reference_json); + ASSERT_TRUE(test_json); + + compareJSON(reference_json, test_json); +} + };