123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583 |
- #include <dns/master_lexer.h>
- #include <dns/master_lexer_inputsource.h>
- #include <dns/master_lexer_state.h>
- #include <gtest/gtest.h>
- #include <sstream>
- using namespace isc::dns;
- using namespace master_lexer_internal;
- namespace {
- typedef MasterLexer::Token Token;
- class MasterLexerStateTest : public ::testing::Test {
- protected:
- MasterLexerStateTest() : common_options(MasterLexer::INITIAL_WS),
- s_null(NULL),
- s_crlf(State::getInstance(State::CRLF)),
- s_string(State::getInstance(State::String)),
- s_qstring(State::getInstance(State::QString)),
- s_number(State::getInstance(State::Number)),
- options(MasterLexer::NONE),
- orig_options(options)
- {}
-
- const MasterLexer::Options common_options;
- MasterLexer lexer;
- const State* const s_null;
- const State& s_crlf;
- const State& s_string;
- const State& s_qstring;
- const State& s_number;
- std::stringstream ss;
- MasterLexer::Options options, orig_options;
- };
- void
- eofCheck(const State& state, MasterLexer& lexer) {
- EXPECT_EQ(Token::END_OF_FILE, state.getToken(lexer).getType());
- EXPECT_FALSE(state.wasLastEOL(lexer));
- }
- TEST_F(MasterLexerStateTest, startAndEnd) {
-
-
- lexer.pushSource(ss);
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- eofCheck(s_crlf, lexer);
- }
- TEST_F(MasterLexerStateTest, startToEOL) {
- ss << "\n";
- lexer.pushSource(ss);
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_TRUE(s_crlf.wasLastEOL(lexer));
- EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
-
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- eofCheck(s_crlf, lexer);
- }
- TEST_F(MasterLexerStateTest, space) {
-
- ss << " \t\n\t\n ";
- lexer.pushSource(ss);
-
-
-
-
- for (size_t i = 0; i < 2; ++i) {
- EXPECT_EQ(s_null, State::start(lexer, MasterLexer::NONE));
- EXPECT_TRUE(s_crlf.wasLastEOL(lexer));
- EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
- }
-
-
- EXPECT_EQ(s_null, State::start(lexer, MasterLexer::INITIAL_WS));
- EXPECT_FALSE(s_crlf.wasLastEOL(lexer));
- EXPECT_EQ(Token::INITIAL_WS, s_crlf.getToken(lexer).getType());
- }
- TEST_F(MasterLexerStateTest, parentheses) {
- ss << "\n(\na\n )\n ";
- lexer.pushSource(ss);
- EXPECT_EQ(s_null, State::start(lexer, common_options));
-
- EXPECT_EQ(0, s_crlf.getParenCount(lexer));
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- EXPECT_EQ(1, s_crlf.getParenCount(lexer));
- EXPECT_FALSE(s_crlf.wasLastEOL(lexer));
-
- s_string.handle(lexer);
-
-
-
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_EQ(0, s_crlf.getParenCount(lexer));
-
-
- EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_EQ(Token::INITIAL_WS, s_crlf.getToken(lexer).getType());
- }
- TEST_F(MasterLexerStateTest, nestedParentheses) {
-
- ss << "(a(b)\n c)\n ";
- lexer.pushSource(ss);
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- EXPECT_EQ(2, s_crlf.getParenCount(lexer));
-
-
-
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- EXPECT_EQ(1, s_crlf.getParenCount(lexer));
-
-
- EXPECT_EQ(s_null, State::start(lexer, common_options));
-
-
- EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_EQ(Token::INITIAL_WS, s_crlf.getToken(lexer).getType());
- }
- TEST_F(MasterLexerStateTest, unbalancedParentheses) {
-
-
- ss << "\n)";
- ss << "(a";
- lexer.pushSource(ss);
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_TRUE(s_crlf.wasLastEOL(lexer));
-
-
- EXPECT_EQ(0, s_crlf.getParenCount(lexer));
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_EQ(0, s_crlf.getParenCount(lexer));
- ASSERT_EQ(Token::ERROR, s_crlf.getToken(lexer).getType());
- EXPECT_EQ(Token::UNBALANCED_PAREN, s_crlf.getToken(lexer).getErrorCode());
- EXPECT_FALSE(s_crlf.wasLastEOL(lexer));
-
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- EXPECT_EQ(1, s_crlf.getParenCount(lexer));
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- ASSERT_EQ(Token::ERROR, s_crlf.getToken(lexer).getType());
- EXPECT_EQ(Token::UNBALANCED_PAREN, s_crlf.getToken(lexer).getErrorCode());
- EXPECT_EQ(0, s_crlf.getParenCount(lexer));
- }
- TEST_F(MasterLexerStateTest, startToComment) {
-
-
-
- ss << " ;a;\n";
- ss << ";a;";
- lexer.pushSource(ss);
-
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
-
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType());
- }
- TEST_F(MasterLexerStateTest, commentAfterParen) {
-
-
-
- ss << "( ;this is a comment\na)\n";
- lexer.pushSource(ss);
-
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
- }
- TEST_F(MasterLexerStateTest, crlf) {
- ss << "\r\n";
- ss << "\r ";
- ss << "\r;comment\na";
- ss << "\r";
- lexer.pushSource(ss);
-
- EXPECT_EQ(&s_crlf, State::start(lexer, common_options));
- s_crlf.handle(lexer);
- EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
- EXPECT_TRUE(s_crlf.wasLastEOL(lexer));
-
-
- EXPECT_EQ(&s_crlf, State::start(lexer, common_options));
-
- s_crlf.handle(lexer);
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_EQ(Token::INITIAL_WS, s_crlf.getToken(lexer).getType());
-
- EXPECT_EQ(&s_crlf, State::start(lexer, common_options));
-
- s_crlf.handle(lexer);
- EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
-
- EXPECT_EQ(&s_crlf, State::start(lexer, common_options));
-
- s_crlf.handle(lexer);
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType());
- }
- void
- stringTokenCheck(const std::string& expected, const MasterLexer::Token& token,
- bool quoted = false)
- {
- EXPECT_EQ(quoted ? Token::QSTRING : Token::STRING, token.getType());
- EXPECT_EQ(expected, token.getString());
- const std::string actual(token.getStringRegion().beg,
- token.getStringRegion().beg +
- token.getStringRegion().len);
- EXPECT_EQ(expected, actual);
- }
- TEST_F(MasterLexerStateTest, string) {
-
- ss << "followed-by-EOL\n";
- ss << "followed-by-CR\r";
- ss << "followed-by-space ";
- ss << "followed-by-tab\t";
- ss << "followed-by-comment;this is comment and ignored\n";
- ss << "followed-by-paren(closing)";
- ss << "followed-by-EOF";
- lexer.pushSource(ss);
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- EXPECT_FALSE(s_string.wasLastEOL(lexer));
- stringTokenCheck("followed-by-EOL", s_string.getToken(lexer));
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("followed-by-CR", s_string.getToken(lexer));
- EXPECT_EQ(&s_crlf, State::start(lexer, common_options));
- s_crlf.handle(lexer);
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("followed-by-space", s_string.getToken(lexer));
-
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("followed-by-tab", s_string.getToken(lexer));
-
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("followed-by-comment", s_string.getToken(lexer));
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("followed-by-paren", s_string.getToken(lexer));
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("closing", s_string.getToken(lexer));
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("followed-by-EOF", s_string.getToken(lexer));
- }
- TEST_F(MasterLexerStateTest, stringEscape) {
-
-
- ss << "escaped\\ space ";
- ss << "escaped\\\ttab ";
- ss << "escaped\\(paren ";
- ss << "escaped\\)close ";
- ss << "escaped\\;comment ";
- ss << "escaped\\\\ backslash ";
- lexer.pushSource(ss);
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("escaped\\ space", s_string.getToken(lexer));
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("escaped\\\ttab", s_string.getToken(lexer));
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("escaped\\(paren", s_string.getToken(lexer));
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("escaped\\)close", s_string.getToken(lexer));
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("escaped\\;comment", s_string.getToken(lexer));
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("escaped\\\\", s_string.getToken(lexer));
-
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("backslash", s_string.getToken(lexer));
- }
- TEST_F(MasterLexerStateTest, quotedString) {
- ss << "\"ignore-quotes\"\n";
- ss << "\"quoted string\" ";
-
-
-
-
- ss << "\"quoted()\t\rstring\" ";
- ss << "\"escape\\ in quote\" ";
- ss << "\"escaped\\\"\" ";
- ss << "\"escaped backslash\\\\\" ";
- ss << "\"no;comment\"";
- lexer.pushSource(ss);
-
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("\"ignore-quotes\"", s_string.getToken(lexer));
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_TRUE(s_string.wasLastEOL(lexer));
-
-
- const MasterLexer::Options options = common_options | MasterLexer::QSTRING;
- EXPECT_EQ(&s_qstring, State::start(lexer, options));
- EXPECT_FALSE(s_string.wasLastEOL(lexer));
- s_qstring.handle(lexer);
- stringTokenCheck("quoted string", s_string.getToken(lexer), true);
-
- EXPECT_EQ(&s_qstring, State::start(lexer, options));
- s_qstring.handle(lexer);
- stringTokenCheck("quoted()\t\rstring", s_string.getToken(lexer), true);
-
-
- EXPECT_EQ(&s_qstring, State::start(lexer, options));
- s_qstring.handle(lexer);
- stringTokenCheck("escape\\ in quote", s_string.getToken(lexer), true);
-
-
- EXPECT_EQ(&s_qstring, State::start(lexer, options));
- s_qstring.handle(lexer);
- stringTokenCheck("escaped\"", s_string.getToken(lexer), true);
-
-
- EXPECT_EQ(&s_qstring, State::start(lexer, options));
- s_qstring.handle(lexer);
- stringTokenCheck("escaped backslash\\\\", s_string.getToken(lexer), true);
-
- EXPECT_EQ(&s_qstring, State::start(lexer, options));
- s_qstring.handle(lexer);
- stringTokenCheck("no;comment", s_string.getToken(lexer), true);
- }
- TEST_F(MasterLexerStateTest, brokenQuotedString) {
- ss << "\"unbalanced-quote\n";
- ss << "\"quoted\\\n\" ";
- ss << "\"unclosed quote and EOF";
- lexer.pushSource(ss);
-
- const MasterLexer::Options options = common_options | MasterLexer::QSTRING;
- EXPECT_EQ(&s_qstring, State::start(lexer, options));
- s_qstring.handle(lexer);
- ASSERT_EQ(Token::ERROR, s_qstring.getToken(lexer).getType());
- EXPECT_EQ(Token::UNBALANCED_QUOTES,
- s_qstring.getToken(lexer).getErrorCode());
-
- EXPECT_EQ(s_null, State::start(lexer, options));
- EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
-
- EXPECT_EQ(&s_qstring, State::start(lexer, options));
- s_qstring.handle(lexer);
- stringTokenCheck("quoted\\\n", s_string.getToken(lexer), true);
-
- EXPECT_EQ(&s_qstring, State::start(lexer, options));
- s_qstring.handle(lexer);
- ASSERT_EQ(Token::ERROR, s_qstring.getToken(lexer).getType());
- EXPECT_EQ(Token::UNEXPECTED_END, s_qstring.getToken(lexer).getErrorCode());
-
- EXPECT_EQ(s_null, State::start(lexer, options));
- EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType());
- }
- TEST_F(MasterLexerStateTest, basicNumbers) {
- ss << "0 ";
- ss << "1 ";
- ss << "12345 ";
- ss << "4294967295 ";
- ss << "4294967296 ";
- ss << "340282366920938463463374607431768211456 ";
-
- ss << "005 ";
- ss << "42;asdf\n";
- ss << "37";
-
-
- lexer.pushSource(ss);
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- EXPECT_EQ(0, s_number.getToken(lexer).getNumber());
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- EXPECT_EQ(1, s_number.getToken(lexer).getNumber());
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- EXPECT_EQ(12345, s_number.getToken(lexer).getNumber());
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- EXPECT_EQ(4294967295u, s_number.getToken(lexer).getNumber());
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- EXPECT_EQ(Token::NUMBER_RANGE,
- s_number.getToken(lexer).getErrorCode());
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- EXPECT_EQ(Token::NUMBER_RANGE,
- s_number.getToken(lexer).getErrorCode());
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- EXPECT_EQ(5, s_number.getToken(lexer).getNumber());
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- EXPECT_EQ(42, s_number.getToken(lexer).getNumber());
- EXPECT_EQ(s_null, State::start(lexer, common_options));
- EXPECT_TRUE(s_crlf.wasLastEOL(lexer));
- EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType());
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- EXPECT_EQ(37, s_number.getToken(lexer).getNumber());
-
- EXPECT_EQ(s_null, State::start(lexer, options));
- EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType());
- }
- TEST_F(MasterLexerStateTest, stringNumbers) {
- ss << "-1 ";
-
- ss << "123abc456 ";
-
- ss << "123\\456 ";
-
- ss << "3scaped\\ space ";
- ss << "3scaped\\\ttab ";
- ss << "3scaped\\(paren ";
- ss << "3scaped\\)close ";
- ss << "3scaped\\;comment ";
- ss << "3scaped\\\\ 8ackslash ";
- lexer.pushSource(ss);
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer);
- stringTokenCheck("-1", s_string.getToken(lexer), false);
-
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- stringTokenCheck("123abc456", s_number.getToken(lexer), false);
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- stringTokenCheck("123\\456", s_number.getToken(lexer), false);
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- stringTokenCheck("3scaped\\ space", s_number.getToken(lexer));
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- stringTokenCheck("3scaped\\\ttab", s_number.getToken(lexer));
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- stringTokenCheck("3scaped\\(paren", s_number.getToken(lexer));
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- stringTokenCheck("3scaped\\)close", s_number.getToken(lexer));
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- stringTokenCheck("3scaped\\;comment", s_number.getToken(lexer));
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- stringTokenCheck("3scaped\\\\", s_number.getToken(lexer));
-
- EXPECT_EQ(&s_number, State::start(lexer, common_options));
- s_number.handle(lexer);
- stringTokenCheck("8ackslash", s_number.getToken(lexer));
-
- EXPECT_EQ(s_null, State::start(lexer, options));
- EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType());
- }
- }
|