2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 14:05:33 +00:00

[2572] added MasterLexer::getPosition().

This commit is contained in:
JINMEI Tatuya
2013-01-09 18:10:52 -08:00
parent e81f84bdab
commit 11b14c65cb
3 changed files with 55 additions and 3 deletions

View File

@@ -182,6 +182,15 @@ MasterLexer::getTotalSourceSize() const {
return (total_size);
}
size_t
MasterLexer::getPosition() const {
size_t position = 0;
BOOST_FOREACH(InputSourcePtr& src, impl_->sources_) {
position += src->getPosition();
}
return (position);
}
const MasterToken&
MasterLexer::getNextToken(Options options) {
if (impl_->source_ == NULL) {

View File

@@ -459,6 +459,34 @@ public:
/// \throw None
size_t getTotalSourceSize() const;
/// \brief Return the position of lexer in the currently pushed sources.
///
/// This method returns the position in terms of the number of recognized
/// characters from all sources. Roughly speaking, the position in a
/// single source is the offset from the beginning of the file or stream
/// to the current "read cursor" of the lexer, and the return value of
/// this method is the sum of the position in all the pushed sources.
///
/// If the lexer reaches the end for each of all the pushed sources,
/// the return value should be equal to that of \c getTotalSourceSize().
///
/// If there is no source pushed in the lexer, it returns 0.
///
/// The return values of this method and \c getTotalSourceSize() would
/// give the caller an idea of the progress of the lexer at the time of
/// the call. Note, however, that since it's not predictable whether
/// more sources will be pushed after the call, the progress determined
/// this way may not make much sense; it can only give an informational
/// hint of the progress.
///
/// Note also that if a source is pushed, this method will normally return
/// a smaller number by definition. Likewise, the conceptual "read
/// cursor" would move backward after a call to \c ungetToken(), in which
/// case this method will return a smaller value, too.
///
/// \throw None
size_t getPosition() const;
/// \brief Parse and return another token from the input.
///
/// It reads a bit of the last opened source and produces another token

View File

@@ -53,6 +53,7 @@ checkEmptySource(const MasterLexer& lexer) {
EXPECT_TRUE(lexer.getSourceName().empty());
EXPECT_EQ(0, lexer.getSourceLine());
EXPECT_EQ(0, lexer.getTotalSourceSize());
EXPECT_EQ(0, lexer.getPosition());
}
TEST_F(MasterLexerTest, preOpen) {
@@ -151,25 +152,31 @@ TEST_F(MasterLexerTest, noSource) {
EXPECT_THROW(lexer.getNextToken(), isc::InvalidOperation);
}
// Test getting some tokens
// Test getting some tokens. It also check basic behavior of getPosition().
TEST_F(MasterLexerTest, getNextToken) {
ss << "\n \n\"STRING\"\n";
lexer.pushSource(ss);
// First, the newline should get out.
EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType());
EXPECT_EQ(1, lexer.getPosition());
// Then the whitespace, if we specify the option.
EXPECT_EQ(MasterToken::INITIAL_WS,
lexer.getNextToken(MasterLexer::INITIAL_WS).getType());
EXPECT_EQ(2, lexer.getPosition());
// The newline
EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType());
EXPECT_EQ(5, lexer.getPosition()); // 1st \n + 3 spaces, then 2nd \n
// The (quoted) string
EXPECT_EQ(MasterToken::QSTRING,
lexer.getNextToken(MasterLexer::QSTRING).getType());
EXPECT_EQ(5 + 8, lexer.getPosition()); // 8 = len("STRING') + quotes
// And the end of line and file
EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType());
EXPECT_EQ(5 + 8 + 1, lexer.getPosition()); // previous + 3rd \n
EXPECT_EQ(MasterToken::END_OF_FILE, lexer.getNextToken().getType());
EXPECT_EQ(5 + 8 + 1, lexer.getPosition()); // position doesn't change
}
// Test we correctly find end of file.
@@ -214,20 +221,25 @@ TEST_F(MasterLexerTest, getUnbalancedString) {
EXPECT_EQ(MasterToken::END_OF_FILE, lexer.getNextToken().getType());
}
// Test ungetting tokens works
// Test ungetting tokens works. Also check getPosition() is adjusted
TEST_F(MasterLexerTest, ungetToken) {
ss << "\n (\"string\"\n) more";
lexer.pushSource(ss);
// Try getting the newline
EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType());
EXPECT_EQ(1, lexer.getPosition());
// Return it and get again
lexer.ungetToken();
EXPECT_EQ(0, lexer.getPosition());
EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType());
EXPECT_EQ(1, lexer.getPosition());
// Get the string and return it back
EXPECT_EQ(MasterToken::QSTRING,
lexer.getNextToken(MasterLexer::QSTRING).getType());
EXPECT_EQ(string("\n (\"string\"").size(), lexer.getPosition());
lexer.ungetToken();
EXPECT_EQ(1, lexer.getPosition()); // back to just after 1st \n
// But if we change the options, it honors them
EXPECT_EQ(MasterToken::INITIAL_WS,
lexer.getNextToken(MasterLexer::QSTRING |
@@ -263,7 +275,8 @@ TEST_F(MasterLexerTest, ungetRealOptions) {
}
// Check the initial whitespace is found even in the first line of included
// file
// file. It also confirms getPosition() works for multiple sources, each
// of which is partially parsed.
TEST_F(MasterLexerTest, includeAndInitialWS) {
ss << " \n";
lexer.pushSource(ss);
@@ -273,9 +286,11 @@ TEST_F(MasterLexerTest, includeAndInitialWS) {
EXPECT_EQ(MasterToken::INITIAL_WS,
lexer.getNextToken(MasterLexer::INITIAL_WS).getType());
EXPECT_EQ(1, lexer.getPosition());
lexer.pushSource(ss2);
EXPECT_EQ(MasterToken::INITIAL_WS,
lexer.getNextToken(MasterLexer::INITIAL_WS).getType());
EXPECT_EQ(2, lexer.getPosition()); // should be sum of position positions.
}
// Test only one token can be ungotten