Browse Source

[2372] internal refactoring: pass original options at the time of start

this will make the overall interface simpler.
JINMEI Tatuya 12 years ago
parent
commit
a5767f8d4e

+ 13 - 10
src/lib/dns/master_lexer.cc

@@ -41,6 +41,7 @@ struct MasterLexer::MasterLexerImpl {
     std::vector<InputSourcePtr> sources_;
     std::vector<InputSourcePtr> sources_;
     InputSource* source_;       // current source
     InputSource* source_;       // current source
     size_t paren_count_;
     size_t paren_count_;
+    Options orig_options_;
     bool last_was_eol_;
     bool last_was_eol_;
     Token token_;
     Token token_;
 };
 };
@@ -148,16 +149,14 @@ class Start : public State {
 public:
 public:
     Start() {}
     Start() {}
     virtual const State* handle(MasterLexer& lexer,
     virtual const State* handle(MasterLexer& lexer,
-                                MasterLexer::Options& options,
-                                MasterLexer::Options orig_options) const;
+                                MasterLexer::Options& options) const;
 };
 };
 
 
 class CRLF : public State {
 class CRLF : public State {
 public:
 public:
     CRLF() {}
     CRLF() {}
     virtual const State* handle(MasterLexer& /*lexer*/,
     virtual const State* handle(MasterLexer& /*lexer*/,
-                                MasterLexer::Options& /*options*/,
-                                MasterLexer::Options /*orig_options*/) const
+                                MasterLexer::Options& /*options*/) const
     {
     {
         return (NULL);
         return (NULL);
     }
     }
@@ -167,8 +166,7 @@ class String : public State {
 public:
 public:
     String() {}
     String() {}
     virtual const State* handle(MasterLexer& /*lexer*/,
     virtual const State* handle(MasterLexer& /*lexer*/,
-                                MasterLexer::Options& /*options*/,
-                                MasterLexer::Options /*orig_options*/) const
+                                MasterLexer::Options& /*options*/) const
     {
     {
         return (NULL);
         return (NULL);
     }
     }
@@ -203,9 +201,7 @@ cancelOptions(MasterLexer::Options& options,
 }
 }
 
 
 const State*
 const State*
-Start::handle(MasterLexer& lexer, MasterLexer::Options& options,
-              MasterLexer::Options orig_options) const
-{
+Start::handle(MasterLexer& lexer, MasterLexer::Options& options) const {
     while (true) {
     while (true) {
         const int c = getLexerImpl(lexer)->source_->getChar();
         const int c = getLexerImpl(lexer)->source_->getChar();
         if (c == InputSource::END_OF_STREAM) {
         if (c == InputSource::END_OF_STREAM) {
@@ -237,7 +233,7 @@ Start::handle(MasterLexer& lexer, MasterLexer::Options& options,
             // TBD: unbalanced case
             // TBD: unbalanced case
             --getLexerImpl(lexer)->paren_count_;
             --getLexerImpl(lexer)->paren_count_;
             if (getLexerImpl(lexer)->paren_count_ == 0) {
             if (getLexerImpl(lexer)->paren_count_ == 0) {
-                options = orig_options;
+                options = getLexerImpl(lexer)->orig_options_;
             }
             }
             continue;
             continue;
         } else {
         } else {
@@ -247,6 +243,13 @@ Start::handle(MasterLexer& lexer, MasterLexer::Options& options,
     }
     }
 }
 }
 
 
+const State*
+State::getStartInstance(MasterLexer& lexer, MasterLexer::Options orig_options)
+{
+    lexer.impl_->orig_options_ = orig_options;
+    return (&START_STATE);
+}
+
 } // namespace master_lexer_internal
 } // namespace master_lexer_internal
 
 
 } // end of namespace dns
 } // end of namespace dns

+ 9 - 5
src/lib/dns/master_lexer_state.h

@@ -25,17 +25,21 @@ class InputSource;
 
 
 class State {
 class State {
 public:
 public:
+    virtual const State* handle(MasterLexer& lexer,
+                                MasterLexer::Options& options) const = 0;
+
+    static const State* getStartInstance(MasterLexer& lexer,
+                                         MasterLexer::Options orig_options);
+
+    /// Specific states are basically hidden within the implementation,
+    /// but we'd like to allow tests to examine them, so we provide
+    /// a way to get an instance of a specific state.
     enum ID {
     enum ID {
         Start,                  ///< TBD
         Start,                  ///< TBD
         CRLF,
         CRLF,
         EatLine,
         EatLine,
         String
         String
     };
     };
-    virtual const State* handle(MasterLexer& lexer,
-                                MasterLexer::Options& options,
-                                MasterLexer::Options orig_options =
-                                MasterLexer::NONE) const = 0;
-
     static const State& getInstance(ID state_id);
     static const State& getInstance(ID state_id);
 
 
     /// \name Read-only accessors for testing purposes.
     /// \name Read-only accessors for testing purposes.

+ 20 - 25
src/lib/dns/tests/master_lexer_state_unittest.cc

@@ -28,8 +28,11 @@ typedef MasterLexer::Token Token; // shortcut
 
 
 class MasterLexerStateTest : public ::testing::Test {
 class MasterLexerStateTest : public ::testing::Test {
 protected:
 protected:
-    MasterLexerStateTest() : s_null(NULL),
-                             s_start(State::getInstance(State::Start)),
+    MasterLexerStateTest() : common_options(MasterLexer::END_OF_LINE |
+                                            MasterLexer::INITIAL_WS),
+                             s_null(NULL),
+                             s_start(*State::getStartInstance(
+                                         lexer, common_options)),
                              s_crlf(State::getInstance(State::CRLF)),
                              s_crlf(State::getInstance(State::CRLF)),
                              s_string(State::getInstance(State::String)),
                              s_string(State::getInstance(State::String)),
                              options(MasterLexer::END_OF_LINE),
                              options(MasterLexer::END_OF_LINE),
@@ -37,11 +40,14 @@ protected:
     {
     {
         lexer.pushSource(ss);
         lexer.pushSource(ss);
     }
     }
+
+    // Specify END_OF_LINE and INITIAL_WS as common initial options.
+    const MasterLexer::Options common_options;
+    MasterLexer lexer;
     const State* const s_null;
     const State* const s_null;
     const State& s_start;
     const State& s_start;
     const State& s_crlf;
     const State& s_crlf;
     const State& s_string;
     const State& s_string;
-    MasterLexer lexer;
     std::stringstream ss;
     std::stringstream ss;
     MasterLexer::Options options, orig_options;
     MasterLexer::Options options, orig_options;
 };
 };
@@ -59,20 +65,18 @@ eofCheck(const State& state, MasterLexer& lexer) {
 TEST_F(MasterLexerStateTest, startAndEnd) {
 TEST_F(MasterLexerStateTest, startAndEnd) {
     // A simple case: the input is empty, so we begin with start and
     // A simple case: the input is empty, so we begin with start and
     // are immediately done.
     // are immediately done.
-    const State* s_next = s_start.handle(lexer, options);
-    EXPECT_EQ(s_null, s_next);
+    EXPECT_EQ(s_null, s_start.handle(lexer, options));
     eofCheck(s_start, lexer);
     eofCheck(s_start, lexer);
 }
 }
 
 
 TEST_F(MasterLexerStateTest, startToEOL) {
 TEST_F(MasterLexerStateTest, startToEOL) {
     ss << "\n";
     ss << "\n";
-    const State* s_next = s_start.handle(lexer, options);
-    EXPECT_EQ(s_null, s_next);
+    EXPECT_EQ(s_null, s_start.handle(lexer, options));
     EXPECT_TRUE(s_start.wasLastEOL(lexer));
     EXPECT_TRUE(s_start.wasLastEOL(lexer));
     EXPECT_EQ(Token::END_OF_LINE, s_start.getToken(lexer).getType());
     EXPECT_EQ(Token::END_OF_LINE, s_start.getToken(lexer).getType());
 
 
     // The next lexer session will reach EOF.  Same eof check should pass.
     // The next lexer session will reach EOF.  Same eof check should pass.
-    s_start.handle(lexer, options);
+    EXPECT_EQ(s_null, s_start.handle(lexer, options));
     eofCheck(s_start, lexer);
     eofCheck(s_start, lexer);
 
 
     // TBD: EOL after (
     // TBD: EOL after (
@@ -83,11 +87,9 @@ TEST_F(MasterLexerStateTest, space) {
     // twice; at the second iteration, it's a white space at the beginning
     // twice; at the second iteration, it's a white space at the beginning
     // of line, but since we don't specify INITIAL_WS option, it's treated as
     // of line, but since we don't specify INITIAL_WS option, it's treated as
     // normal space and ignored.
     // normal space and ignored.
-    const State* s_next;
     for (size_t i = 0; i < 2; ++i) {
     for (size_t i = 0; i < 2; ++i) {
         ss << " \t\n";
         ss << " \t\n";
-        s_next = s_start.handle(lexer, options);
-        EXPECT_EQ(s_null, s_next);
+        EXPECT_EQ(s_null, s_start.handle(lexer, options));
         EXPECT_TRUE(s_start.wasLastEOL(lexer));
         EXPECT_TRUE(s_start.wasLastEOL(lexer));
         EXPECT_EQ(Token::END_OF_LINE, s_start.getToken(lexer).getType());
         EXPECT_EQ(Token::END_OF_LINE, s_start.getToken(lexer).getType());
     }
     }
@@ -96,8 +98,7 @@ TEST_F(MasterLexerStateTest, space) {
     // corresponding token will be returned.
     // corresponding token will be returned.
     ss << " ";
     ss << " ";
     options = MasterLexer::INITIAL_WS;
     options = MasterLexer::INITIAL_WS;
-    s_next = s_start.handle(lexer, options);
-    EXPECT_EQ(s_null, s_next);
+    EXPECT_EQ(s_null, s_start.handle(lexer, options));
     EXPECT_FALSE(s_start.wasLastEOL(lexer));
     EXPECT_FALSE(s_start.wasLastEOL(lexer));
     EXPECT_EQ(Token::INITIAL_WS, s_start.getToken(lexer).getType());
     EXPECT_EQ(Token::INITIAL_WS, s_start.getToken(lexer).getType());
 }
 }
@@ -105,14 +106,13 @@ TEST_F(MasterLexerStateTest, space) {
 TEST_F(MasterLexerStateTest, parentheses) {
 TEST_F(MasterLexerStateTest, parentheses) {
     ss << "\n(\na)"; // 1st \n is to check if 'was EOL' is set to false
     ss << "\n(\na)"; // 1st \n is to check if 'was EOL' is set to false
 
 
-    const State* s_next = s_start.handle(lexer, options); // handle \n
-    EXPECT_EQ(s_null, s_next);
+    EXPECT_EQ(s_null, s_start.handle(lexer, options)); // handle \n
 
 
     // Now handle '('.  It skips \n and recognize 'a' as strin
     // Now handle '('.  It skips \n and recognize 'a' as strin
     EXPECT_EQ(0, s_start.getParenCount(lexer)); // check pre condition
     EXPECT_EQ(0, s_start.getParenCount(lexer)); // check pre condition
     options = MasterLexer::END_OF_LINE | MasterLexer::INITIAL_WS;
     options = MasterLexer::END_OF_LINE | MasterLexer::INITIAL_WS;
-    s_next = s_start.handle(lexer, options, options);
-    EXPECT_EQ(&s_string, s_next); // should recognize 'a' as string
+    // should recognize 'a' as string
+    EXPECT_EQ(&s_string, s_start.handle(lexer, options));
 
 
     // Check post '(' conditions.  paren_count should be incremented, and
     // Check post '(' conditions.  paren_count should be incremented, and
     // end-of-line and ws should be canceled at the first open paren
     // end-of-line and ws should be canceled at the first open paren
@@ -123,8 +123,7 @@ TEST_F(MasterLexerStateTest, parentheses) {
 
 
     // Then handle ')'.  eol and init_ws are currently cleared, which will be
     // Then handle ')'.  eol and init_ws are currently cleared, which will be
     // set again.
     // set again.
-    s_next = s_start.handle(lexer, options, (MasterLexer::END_OF_LINE |
-                                             MasterLexer::INITIAL_WS));
+    EXPECT_EQ(s_null, s_start.handle(lexer, options));
     EXPECT_EQ(0, s_start.getParenCount(lexer));
     EXPECT_EQ(0, s_start.getParenCount(lexer));
     EXPECT_TRUE((options & MasterLexer::END_OF_LINE) != 0);
     EXPECT_TRUE((options & MasterLexer::END_OF_LINE) != 0);
     EXPECT_TRUE((options & MasterLexer::INITIAL_WS) != 0);
     EXPECT_TRUE((options & MasterLexer::INITIAL_WS) != 0);
@@ -142,18 +141,14 @@ TEST_F(MasterLexerStateTest, nestedParentheses) {
 
 
     // Close the inner most parentheses.  count will be decreased, but option
     // Close the inner most parentheses.  count will be decreased, but option
     // shouldn't be restored yet.
     // shouldn't be restored yet.
-    EXPECT_EQ(&s_string,
-              s_start.handle(lexer, options, (MasterLexer::END_OF_LINE |
-                                              MasterLexer::INITIAL_WS)));
+    EXPECT_EQ(&s_string, s_start.handle(lexer, options));
     EXPECT_EQ(1, s_start.getParenCount(lexer));
     EXPECT_EQ(1, s_start.getParenCount(lexer));
     EXPECT_TRUE((options & MasterLexer::END_OF_LINE) == 0);
     EXPECT_TRUE((options & MasterLexer::END_OF_LINE) == 0);
     EXPECT_TRUE((options & MasterLexer::INITIAL_WS) == 0);
     EXPECT_TRUE((options & MasterLexer::INITIAL_WS) == 0);
 
 
     // Close the outermost parentheses.  count will be reset to 0, and original
     // Close the outermost parentheses.  count will be reset to 0, and original
     // options are restored.
     // options are restored.
-    EXPECT_EQ(s_null,
-              s_start.handle(lexer, options, (MasterLexer::END_OF_LINE |
-                                              MasterLexer::INITIAL_WS)));
+    EXPECT_EQ(s_null, s_start.handle(lexer, options));
     EXPECT_TRUE((options & MasterLexer::END_OF_LINE) != 0);
     EXPECT_TRUE((options & MasterLexer::END_OF_LINE) != 0);
     EXPECT_TRUE((options & MasterLexer::INITIAL_WS) != 0);
     EXPECT_TRUE((options & MasterLexer::INITIAL_WS) != 0);
 }
 }