separators_.set('\t');
separators_.set('(');
separators_.set(')');
+ separators_.set('"');
esc_separators_.set('\r');
esc_separators_.set('\n');
}
"unbalanced quotes", // UNBALANCED_QUOTES
"no token produced", // NO_TOKEN_PRODUCED
"number out of range", // NUMBER_OUT_OF_RANGE
- "not a valid number" // BAD_NUMBER
+ "not a valid number", // BAD_NUMBER
+ "unexpected quotes" // UNEXPECTED_QUOTES
};
const size_t error_text_max_count = sizeof(error_text) / sizeof(error_text[0]);
} // end unnamed namespace
if (paren_count == 0) { // check if we are in () (see above)
return (&CRLF_STATE);
}
- } else if (c == '"' && (options & MasterLexer::QSTRING) != 0) {
- lexerimpl.last_was_eol_ = false;
- return (&QSTRING_STATE);
+ } else if (c == '"') {
+ if ((options & MasterLexer::QSTRING) != 0) {
+ lexerimpl.last_was_eol_ = false;
+ return (&QSTRING_STATE);
+ } else {
+ lexerimpl.token_ = MasterToken(MasterToken::UNEXPECTED_QUOTES);
+ return (NULL);
+ }
} else if (c == '(') {
lexerimpl.last_was_eol_ = false;
++paren_count;
/// error and should never get out of the lexer.
NUMBER_OUT_OF_RANGE, ///< Number was out of range
BAD_NUMBER, ///< Number is expected but not recognized
+ UNEXPECTED_QUOTES, ///< Unexpected quotes character detected
MAX_ERROR_CODE ///< Max integer corresponding to valid error codes.
/// (excluding this one). Mainly for internal use.
};
///
/// - If the expected type is MasterToken::QSTRING, both quoted and
/// unquoted strings are recognized and returned.
+ /// - A string with quotation marks is not recognized as a
+ /// - MasterToken::STRING. You have to get it as a
+ /// - MasterToken::QSTRING.
/// - If the optional \c eol_ok parameter is \c true (very rare case),
/// MasterToken::END_OF_LINE and MasterToken::END_OF_FILE are recognized
/// and returned if they are found instead of the expected type of
ss << "\"no;comment\"";
lexer.pushSource(ss);
- // by default, '"' doesn't have any special meaning and part of string
- EXPECT_EQ(&s_string, State::start(lexer, common_options));
- s_string.handle(lexer); // recognize str, see \n
- stringTokenCheck("\"ignore-quotes\"", s_string.getToken(lexer));
+ // by default, '"' is unexpected (when QSTRING is not specified),
+ // and it returns MasterToken::UNEXPECTED_QUOTES.
+ EXPECT_EQ(s_null, State::start(lexer, common_options));
+ EXPECT_EQ(Token::UNEXPECTED_QUOTES, s_string.getToken(lexer).getErrorCode());
+ // Read it as a QSTRING.
+ s_qstring.handle(lexer); // recognize quoted str, see \n
+ stringTokenCheck("ignore-quotes", s_qstring.getToken(lexer), true);
EXPECT_EQ(s_null, State::start(lexer, common_options)); // skip \n after it
EXPECT_TRUE(s_string.wasLastEOL(lexer));
getErrorText());
EXPECT_EQ("not a valid number",
MasterToken(MasterToken::BAD_NUMBER).getErrorText());
+ EXPECT_EQ("unexpected quotes",
+ MasterToken(MasterToken::UNEXPECTED_QUOTES).getErrorText());
// getErrorCode/Text() isn't allowed for non number types
EXPECT_THROW(token_num.getErrorCode(), isc::InvalidOperation);
EXPECT_THROW(token_num.getErrorText(), isc::InvalidOperation);
- // Only the pre-defined error code is accepted. Hardcoding '7' (max code
+ // Only the pre-defined error code is accepted. Hardcoding '8' (max code
// + 1) is intentional; it'd be actually better if we notice it when we
// update the enum list (which shouldn't happen too often).
- EXPECT_THROW(MasterToken(MasterToken::ErrorCode(7)),
+ //
+ // Note: if you fix this testcase, you probably want to update the
+ // getErrorText() tests above too.
+ EXPECT_THROW(MasterToken(MasterToken::ErrorCode(8)),
isc::InvalidParameter);
// Check the coexistence of "from number" and "from error-code"
// Check we properly return error when there's an opened parentheses and no
// closing one
TEST_F(MasterLexerTest, getUnbalancedParen) {
- ss << "(\"string\"";
+ ss << "(string";
lexer.pushSource(ss);
// The string gets out first
"$TTL with extra token" },
{ "$TTL", "unexpected end of input", "missing TTL" },
{ "$TTL No-ttl", "Unknown unit used: N in: No-ttl", "bad TTL" },
- { "$TTL \"100\"", "invalid TTL: \"100\"", "bad TTL, quoted" },
+ { "$TTL \"100\"", "unexpected quotes", "bad TTL, quoted" },
{ "$TT 100", "Unknown directive 'TT'", "bad directive, too short" },
{ "$TTLLIKE 100", "Unknown directive 'TTLLIKE'", "bad directive, extra" },
{ NULL, NULL, NULL }
checkFromTextSOA<EmptyLabel, EmptyLabel>(
". bad..example. 2010012601 1H 5M 1000H 20M");
- // Names shouldn't be quoted. (Note: on completion of #2534, the resulting
- // exception will be different).
- checkFromTextSOA<MissingNameOrigin, MissingNameOrigin>(
+ // Names shouldn't be quoted.
+ checkFromTextSOA<InvalidRdataText, MasterLexer::LexerError>(
"\".\" . 0 0 0 0 0");
- checkFromTextSOA<MissingNameOrigin, MissingNameOrigin>(
+ checkFromTextSOA<InvalidRdataText, MasterLexer::LexerError>(
". \".\" 0 0 0 0 0");
// Missing MAME or RNAME: for the string version, the serial would be
texts.push_back("\"Test-String\" Test-String"); // no '"' for one
texts.push_back("\"Test-String\"Test-String"); // and no space either
texts.push_back("Test-String \"Test-String\""); // no '"' for the other
- // This one currently doesn't work
- //texts.push_back("Test-String\"Test-String\""); // and no space either
+ texts.push_back("Test-String\"Test-String\""); // and no space either
std::stringstream ss;
for (std::vector<std::string >::const_iterator it = texts.begin();
// Check escape behavior
const TypeParam double_quotes("Test-String\"Test-String\"");
- EXPECT_EQ("\"Test-String\\\"Test-String\\\"\"", double_quotes.toText());
+ EXPECT_EQ("\"Test-String\" \"Test-String\"", double_quotes.toText());
const TypeParam semicolon("Test-String\\;Test-String");
EXPECT_EQ("\"Test-String\\;Test-String\"", semicolon.toText());
const TypeParam backslash("Test-String\\\\Test-String");