Parcourir la source

[2373] implemented some simple case of string state handling.

JINMEI Tatuya il y a 12 ans
Parent
commit
587f975a2a
2 fichiers modifiés avec 32 ajouts et 3 suppressions
  1. 20 3
      src/lib/dns/master_lexer.cc
  2. 12 0
      src/lib/dns/tests/master_lexer_state_unittest.cc

+ 20 - 3
src/lib/dns/master_lexer.cc

@@ -56,6 +56,7 @@ struct MasterLexer::MasterLexerImpl {
     std::vector<InputSourcePtr> sources_;
     InputSource* source_;       // current source (NULL if sources_ is empty)
     Token token_;               // currently recognized token (set by a state)
+    std::vector<char> data_;    // placeholder for string data
 
     // These are used in states, and defined here only as a placeholder.
     // The main lexer class does not need these members.
@@ -197,9 +198,7 @@ class String : public State {
 public:
     String() {}
     virtual ~String() {}      // see the base class for the destructor
-    virtual const State* handle(MasterLexer& /*lexer*/) const {
-        return (NULL);
-    }
+    virtual const State* handle(MasterLexer& lexer) const;
 };
 
 // We use a common instance of a each state in a singleton-like way to save
@@ -275,12 +274,30 @@ State::start(MasterLexer& lexer, MasterLexer::Options options) {
         } else {
             // Note: in #2373 we should probably ungetChar().
             lexerimpl.last_was_eol_ = false;
+            lexerimpl.source_->ungetChar();
             return (&STRING_STATE);
         }
         // no code should be here; we just continue the loop.
     }
 }
 
+const State*
+String::handle(MasterLexer& lexer) const {
+    std::vector<char>& data = getLexerImpl(lexer)->data_;
+    MasterLexer::Token& token = getLexerImpl(lexer)->token_;
+    data.clear();
+
+    while (true) {
+        const int c = getLexerImpl(lexer)->source_->getChar(); // TODO comment
+        if (c == '\r' || c == EOF || c == '(' || c == ')') { // TODO special chars, etc.
+            getLexerImpl(lexer)->source_->ungetChar();
+            token = MasterLexer::Token(&data.at(0), data.size());
+            return (NULL);
+        }
+        data.push_back(c);
+    }
+}
+
 } // namespace master_lexer_internal
 
 } // end of namespace dns

+ 12 - 0
src/lib/dns/tests/master_lexer_state_unittest.cc

@@ -244,6 +244,7 @@ TEST_F(MasterLexerStateTest, crlf) {
     EXPECT_EQ(s_null, s_crlf.handle(lexer));
     EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
     EXPECT_EQ(&s_string, State::start(lexer, common_options));
+    EXPECT_EQ(s_null, s_string.handle(lexer)); // skip 'a'
 
     // 4. \r then EOF
     EXPECT_EQ(&s_crlf, State::start(lexer, common_options)); // recognize '\r'
@@ -253,4 +254,15 @@ TEST_F(MasterLexerStateTest, crlf) {
     EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType());
 }
 
+TEST_F(MasterLexerStateTest, string) {
+    ss << "a-string";
+    lexer.pushSource(ss);
+
+    EXPECT_EQ(&s_string, State::start(lexer, common_options));
+    EXPECT_EQ(s_null, s_string.handle(lexer));
+    EXPECT_FALSE(s_string.wasLastEOL(lexer));
+    EXPECT_EQ(Token::STRING, s_string.getToken(lexer).getType());
+    EXPECT_EQ("a-string", s_string.getToken(lexer).getString());
+}
+
 }