BIND 10 trac2427, updated. dc3f31bea1c264125464906dae050a995829e816 [2427] Separate initial token handling

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Dec 17 13:36:22 UTC 2012


The branch, trac2427 has been updated
       via  dc3f31bea1c264125464906dae050a995829e816 (commit)
      from  471c6f2d6c1ad9b71422f1d19b6223492c5b6023 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit dc3f31bea1c264125464906dae050a995829e816
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Mon Dec 17 14:34:09 2012 +0100

    [2427] Separate initial token handling
    
    As suggested by Jinmei, extracting to separate method. Adjusting to
    address changes added in between.

-----------------------------------------------------------------------

Summary of changes:
 src/lib/dns/master_loader.cc |  170 ++++++++++++++++++++++++------------------
 1 file changed, 97 insertions(+), 73 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/dns/master_loader.cc b/src/lib/dns/master_loader.cc
index 254adb0..d4aac36 100644
--- a/src/lib/dns/master_loader.cc
+++ b/src/lib/dns/master_loader.cc
@@ -136,6 +136,8 @@ public:
 
     bool loadIncremental(size_t count_limit);
 
+    MasterToken handleInitialToken();
+
     void doOrigin(bool is_optional) {
         // Parse and create the new origin. It is relative to the previous
         // one.
@@ -249,6 +251,92 @@ public:
                                 // load?
 };
 
+// A helper method of loadIncremental, parsing the first token of a new line.
+// If it looks like an RR, detect its owner name and return a string token for
+// the next field of the RR.
+// Otherwise, return either END_OF_LINE or END_OF_FILE token depending on
+// whether the loader continues to the next line or completes the load,
+// respectively.  Other corner cases including $-directive handling is done
+// here.
+// For unexpected errors, it throws an exception, which will be handled in
+// loadIncremental.
+MasterToken
+MasterLoader::MasterLoaderImpl::handleInitialToken() {
+    const MasterToken& initial_token =
+        lexer_.getNextToken(MasterLexer::QSTRING | MasterLexer::INITIAL_WS);
+
+    // The most likely case is INITIAL_WS, and then string/qstring.  We
+    // handle them first.
+    if (initial_token.getType() == MasterToken::INITIAL_WS) {
+        const MasterToken& next_token = lexer_.getNextToken();
+        if (next_token.getType() == MasterToken::END_OF_LINE) {
+            return (next_token); // blank line
+        } else if (next_token.getType() == MasterToken::END_OF_FILE) {
+            lexer_.ungetToken(); // handle it in the next iteration.
+            eatUntilEOL(true);  // effectively warn about the unexpected EOF.
+            return (MasterToken(MasterToken::END_OF_LINE));
+        }
+
+        // This means the same name as previous.
+        if (last_name_.get() == NULL) {
+            isc_throw(InternalException, "No previous name to use in "
+                      "place of initial whitespace");
+        } else if (!previous_name_) {
+            callbacks_.warning(lexer_.getSourceName(),
+                               lexer_.getSourceLine(),
+                               "Ambiguous previous name previous name for "
+                               "use in place of initial whitespace");
+        }
+        return (next_token);
+    } else if (initial_token.getType() == MasterToken::STRING ||
+               initial_token.getType() == MasterToken::QSTRING) {
+        // If it is name (or directive), handle it.
+        const MasterToken::StringRegion&
+            name_string(initial_token.getStringRegion());
+
+        if (name_string.len > 0 && name_string.beg[0] == '$') {
+            // This should have either thrown (and the error handler
+            // will read up until the end of line) or read until the
+            // end of line.
+
+            // Exclude the $ from the string on this point.
+            handleDirective(name_string.beg + 1, name_string.len - 1);
+            // So, get to the next line, there's nothing more interesting
+            // in this one.
+            return (MasterToken(MasterToken::END_OF_LINE));
+        }
+
+        // This should be an RR, starting with an owner name.  Construct the
+        // name, and some string token should follow.
+        last_name_.reset(new Name(name_string.beg, name_string.len,
+                                  &active_origin_));
+        previous_name_ = true;
+        return (lexer_.getNextToken(MasterToken::STRING));
+    }
+
+    switch (initial_token.getType()) { // handle less common cases
+    case MasterToken::END_OF_FILE:
+        if (!popSource()) {
+            return (initial_token);
+        } else {
+            // We try to read a token from the popped source
+            // So retry the loop, but first, make sure the source
+            // is at EOL
+            eatUntilEOL(true);
+            return (MasterToken(MasterToken::END_OF_LINE));
+        }
+    case MasterToken::END_OF_LINE:
+        return (initial_token); // empty line
+    case MasterToken::ERROR:
+        // Error token here.
+        isc_throw(InternalException, initial_token.getErrorText());
+    default:
+        // Some other token (what could that be?)
+        isc_throw(InternalException, "Parser got confused (unexpected "
+                  "token " << initial_token.getType() << ")");
+    }
+}
+
 bool
 MasterLoader::MasterLoaderImpl::loadIncremental(size_t count_limit) {
     if (count_limit == 0) {
@@ -264,85 +352,21 @@ MasterLoader::MasterLoaderImpl::loadIncremental(size_t count_limit) {
     size_t count = 0;
     while (ok_ && count < count_limit) {
         try {
-            MasterToken initial_token(MasterToken::NO_TOKEN_PRODUCED);
-            // Skip all EOLNs (empty lines) and finish on EOF
-            do {
-                initial_token = lexer_.getNextToken(MasterLexer::QSTRING |
-                                                    MasterLexer::INITIAL_WS);
-                if (initial_token.getType() == MasterToken::INITIAL_WS) {
-                    // The INITIAL_WS is interesting only if something is
-                    // after it. So peek there and if there's EOLN or EOF,
-                    // ignore it.
-                    const MasterToken& peek_token(lexer_.getNextToken());
-                    if (peek_token.getType() == MasterToken::END_OF_LINE ||
-                        peek_token.getType() == MasterToken::END_OF_FILE) {
-                        initial_token = peek_token;
-                    } else {
-                        // It is something interesting. Return it back and
-                        // keep the whitespace.
-                        lexer_.ungetToken();
-                    }
-                }
-                if (initial_token.getType() == MasterToken::END_OF_FILE) {
-                    if (!popSource()) {
-                        return (true);
-                    } else {
-                        // We try to read a token from the popped source
-                        // So retry the loop, but first, make sure the source
-                        // is at EOL
-                        eatUntilEOL(true);
-                        continue;
-                    }
-                }
-            } while (initial_token.getType() == MasterToken::END_OF_LINE ||
-                     initial_token.getType() == MasterToken::END_OF_FILE);
-
-            if (initial_token.getType() == MasterToken::QSTRING ||
-                initial_token.getType() == MasterToken::STRING) {
-                // If it is name (or directive), handle it.
-                const MasterToken::StringRegion&
-                    name_string(initial_token.getStringRegion());
-
-                if (name_string.len > 0 && name_string.beg[0] == '$') {
-                    // This should have either thrown (and the error handler
-                    // will read up until the end of line) or read until the
-                    // end of line.
-
-                    // Exclude the $ from the string on this point.
-                    handleDirective(name_string.beg + 1, name_string.len - 1);
-                    // So, get to the next line, there's nothing more interesting
-                    // in this one.
-                    continue;
-                }
-
-                last_name_.reset(new Name(name_string.beg, name_string.len,
-                                          &active_origin_));
-                previous_name_ = true;
-            } else if (initial_token.getType() == MasterToken::INITIAL_WS) {
-                // This means the same name as previous.
-                if (last_name_.get() == NULL) {
-                    isc_throw(InternalException, "No previous name to use in "
-                              "place of initial whitespace");
-                } else if (!previous_name_) {
-                    callbacks_.warning(lexer_.getSourceName(),
-                                       lexer_.getSourceLine(),
-                                       "Ambiguous previous name previous name "
-                                       "for initial whitespace");
-                }
-            } else if (initial_token.getType() == MasterToken::ERROR) {
-                // Error token here.
-                isc_throw(InternalException, initial_token.getErrorText());
-            } else {
-                // Some other token (what could that be?)
-                isc_throw(InternalException, "Parser got confused (unexpected "
-                          "token " << initial_token.getType() << ")");
+            const MasterToken next_token = handleInitialToken();
+            if (next_token.getType() == MasterToken::END_OF_FILE) {
+                return (true);  // we are done
+            } else if (next_token.getType() == MasterToken::END_OF_LINE) {
+                continue;       // nothing more to do in this line
             }
+            // We are going to parse an RR, have known the owner name,
+            // and are now seeing the next string token in the rest of the RR.
+            assert(next_token.getType() == MasterToken::STRING);
 
             // TODO: Some more flexibility. We don't allow omitting
             // anything yet
 
             // The parameters
-            const RRTTL ttl(getString());
+            const RRTTL ttl(next_token.getString());
             const RRClass rrclass(getString());
             const RRType rrtype(getString());
 



More information about the bind10-changes mailing list