Browse Source

[5014] Reading from file implemented

Tomek Mrugalski 8 years ago
parent
commit
d774e03249

+ 19 - 0
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 {

+ 64 - 1
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)
 {

+ 5 - 0
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_;

+ 19 - 0
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);
+}
+
 };