Browse Source

[2372] handle comments in the start state

JINMEI Tatuya 12 years ago
parent
commit
c1799647fc

+ 18 - 6
src/lib/dns/master_lexer.cc

@@ -38,6 +38,18 @@ struct MasterLexer::MasterLexerImpl {
                         token_(Token::NOT_STARTED)
     {}
 
+    int skipComment(int c) {
+        if (c == ';') {
+            while (true) {
+                c = source_->getChar();
+                if (c == '\n' || c == InputSource::END_OF_STREAM) {
+                    return (c);
+                }
+            }
+        }
+        return (c);
+    }
+
     std::vector<InputSourcePtr> sources_;
     InputSource* source_;       // current source
     size_t paren_count_;
@@ -185,13 +197,12 @@ State::getInstance(ID state_id) {
         return (START_STATE);
     case CRLF:
         return (CRLF_STATE);
-    case EatLine:
-        return (CRLF_STATE);    // XXX
     case String:
-        return (STRING_STATE);    // XXX
+        return (STRING_STATE);
     }
 }
 
+namespace {
 inline void
 cancelOptions(MasterLexer::Options& options,
               MasterLexer::Options canceled_options)
@@ -199,13 +210,15 @@ cancelOptions(MasterLexer::Options& options,
     options = static_cast<MasterLexer::Options>(
         options & static_cast<MasterLexer::Options>(~canceled_options));
 }
+}
 
 const State*
 Start::handle(MasterLexer& lexer, MasterLexer::Options& options) const {
     size_t& paren_count = getLexerImpl(lexer)->paren_count_;
 
     while (true) {
-        const int c = getLexerImpl(lexer)->source_->getChar();
+        const int c = getLexerImpl(lexer)->skipComment(
+            getLexerImpl(lexer)->source_->getChar());
         if (c == InputSource::END_OF_STREAM) {
             if (paren_count != 0) {
                 getLexerImpl(lexer)->token_ = Token(Token::UNBALANCED_PAREN);
@@ -241,8 +254,7 @@ Start::handle(MasterLexer& lexer, MasterLexer::Options& options) const {
                 getLexerImpl(lexer)->token_ = Token(Token::UNBALANCED_PAREN);
                 return (NULL);
             }
-            --paren_count;
-            if (paren_count == 0) {
+            if (--paren_count == 0) {
                 options = getLexerImpl(lexer)->orig_options_;
             }
             continue;

+ 0 - 1
src/lib/dns/master_lexer_state.h

@@ -37,7 +37,6 @@ public:
     enum ID {
         Start,                  ///< TBD
         CRLF,
-        EatLine,
         String
     };
     static const State& getInstance(ID state_id);

+ 17 - 2
src/lib/dns/tests/master_lexer_state_unittest.cc

@@ -47,6 +47,7 @@ protected:
     const State* const s_null;
     const State& s_start;
     const State& s_crlf;
+
     const State& s_string;
     std::stringstream ss;
     MasterLexer::Options options, orig_options;
@@ -178,14 +179,28 @@ TEST_F(MasterLexerStateTest, unbalancedParentheses) {
     EXPECT_EQ(Token::UNBALANCED_PAREN, s_start.getToken(lexer).getErrorCode());
     EXPECT_FALSE(s_start.wasLastEOL(lexer));
 
-    // Reach EOF without a dangling open parenthesis.
+    // Reach EOF with a dangling open parenthesis.
     ss << "(a";
     EXPECT_EQ(&s_string, s_start.handle(lexer, options)); // consume '(a'
     EXPECT_EQ(1, s_start.getParenCount(lexer));
     EXPECT_EQ(s_null, s_start.handle(lexer, options));    // reach EOF
     ASSERT_EQ(Token::ERROR, s_start.getToken(lexer).getType());
     EXPECT_EQ(Token::UNBALANCED_PAREN, s_start.getToken(lexer).getErrorCode());
-    EXPECT_EQ(0, s_start.getParenCount(lexer));
+    EXPECT_EQ(0, s_start.getParenCount(lexer)); // should be reset to 0
+}
+
+TEST_F(MasterLexerStateTest, startToComment) {
+    // Begin with 'start', skip space, then encounter a comment.  Skip
+    // the rest of the line, and recognize the new line.  Note that the
+    // second ';' is simply ignored.
+    ss << "  ;a;\n";
+    EXPECT_EQ(s_null, s_start.handle(lexer, options));
+    EXPECT_EQ(Token::END_OF_LINE, s_start.getToken(lexer).getType());
+
+    // Likewise, but the comment ends with EOF.
+    ss << "  ;a;";
+    EXPECT_EQ(s_null, s_start.handle(lexer, options));
+    EXPECT_EQ(Token::END_OF_FILE, s_start.getToken(lexer).getType());
 }
 
 }