mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 04:41:16 +00:00
Merged end of map/seq flow fix from core
This commit is contained in:
@@ -51,6 +51,13 @@ namespace YAML
|
|||||||
return m_tokens.front();
|
return m_tokens.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mark
|
||||||
|
// . Returns the current mark in the stream
|
||||||
|
Mark Scanner::mark() const
|
||||||
|
{
|
||||||
|
return INPUT.mark();
|
||||||
|
}
|
||||||
|
|
||||||
// EnsureTokensInQueue
|
// EnsureTokensInQueue
|
||||||
// . Scan until there's a valid token at the front of the queue,
|
// . Scan until there's a valid token at the front of the queue,
|
||||||
// or we're sure the queue is empty.
|
// or we're sure the queue is empty.
|
||||||
|
@@ -31,6 +31,7 @@ namespace YAML
|
|||||||
bool empty();
|
bool empty();
|
||||||
void pop();
|
void pop();
|
||||||
Token& peek();
|
Token& peek();
|
||||||
|
Mark mark() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct IndentMarker {
|
struct IndentMarker {
|
||||||
|
@@ -48,7 +48,7 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
// an empty node *is* a possibility
|
// an empty node *is* a possibility
|
||||||
if(m_scanner.empty()) {
|
if(m_scanner.empty()) {
|
||||||
eventHandler.OnNull(Mark::null(), NullAnchor);
|
eventHandler.OnNull(m_scanner.mark(), NullAnchor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ namespace YAML
|
|||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(m_scanner.empty())
|
if(m_scanner.empty())
|
||||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ);
|
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ);
|
||||||
|
|
||||||
Token token = m_scanner.peek();
|
Token token = m_scanner.peek();
|
||||||
if(token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
|
if(token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
|
||||||
@@ -169,7 +169,7 @@ namespace YAML
|
|||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(m_scanner.empty())
|
if(m_scanner.empty())
|
||||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ_FLOW);
|
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW);
|
||||||
|
|
||||||
// first check for end
|
// first check for end
|
||||||
if(m_scanner.peek().type == Token::FLOW_SEQ_END) {
|
if(m_scanner.peek().type == Token::FLOW_SEQ_END) {
|
||||||
@@ -179,6 +179,9 @@ namespace YAML
|
|||||||
|
|
||||||
// then read the node
|
// then read the node
|
||||||
HandleNode(eventHandler);
|
HandleNode(eventHandler);
|
||||||
|
|
||||||
|
if(m_scanner.empty())
|
||||||
|
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW);
|
||||||
|
|
||||||
// now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node)
|
// now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node)
|
||||||
Token& token = m_scanner.peek();
|
Token& token = m_scanner.peek();
|
||||||
@@ -211,7 +214,7 @@ namespace YAML
|
|||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(m_scanner.empty())
|
if(m_scanner.empty())
|
||||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP);
|
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP);
|
||||||
|
|
||||||
Token token = m_scanner.peek();
|
Token token = m_scanner.peek();
|
||||||
if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END)
|
if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END)
|
||||||
@@ -250,7 +253,7 @@ namespace YAML
|
|||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
if(m_scanner.empty())
|
if(m_scanner.empty())
|
||||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW);
|
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW);
|
||||||
|
|
||||||
Token& token = m_scanner.peek();
|
Token& token = m_scanner.peek();
|
||||||
// first check for end
|
// first check for end
|
||||||
@@ -274,6 +277,9 @@ namespace YAML
|
|||||||
} else {
|
} else {
|
||||||
eventHandler.OnNull(token.mark, NullAnchor);
|
eventHandler.OnNull(token.mark, NullAnchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(m_scanner.empty())
|
||||||
|
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW);
|
||||||
|
|
||||||
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
|
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
|
||||||
Token& nextToken = m_scanner.peek();
|
Token& nextToken = m_scanner.peek();
|
||||||
|
51
test/core/parsertests.cpp
Normal file
51
test/core/parsertests.cpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#include "parsertests.h"
|
||||||
|
#include "handlermacros.h"
|
||||||
|
#include "yaml-cpp/yaml.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace Test
|
||||||
|
{
|
||||||
|
namespace Parser {
|
||||||
|
TEST NoEndOfMapFlow()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
HANDLE("---{header: {id: 1");
|
||||||
|
} catch(const YAML::ParserException& e) {
|
||||||
|
YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::END_OF_MAP_FLOW));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return " no exception caught";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void RunParserTest(TEST (*test)(), const std::string& name, int& passed, int& total) {
|
||||||
|
TEST ret;
|
||||||
|
try {
|
||||||
|
ret = test();
|
||||||
|
} catch(const YAML::Exception& e) {
|
||||||
|
ret.ok = false;
|
||||||
|
ret.error = std::string(" Exception caught: ") + e.what();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ret.ok) {
|
||||||
|
std::cout << "Spec test " << index << " failed: " << name << "\n";
|
||||||
|
std::cout << ret.error << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ret.ok)
|
||||||
|
passed++;
|
||||||
|
total++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RunParserTests()
|
||||||
|
{
|
||||||
|
int passed = 0;
|
||||||
|
int total = 0;
|
||||||
|
RunParserTest(&Parser::NoEndOfMapFlow, "No end of map flow", passed, total);
|
||||||
|
|
||||||
|
std::cout << "Parser tests: " << passed << "/" << total << " passed\n";
|
||||||
|
return passed == total;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,12 +1,32 @@
|
|||||||
#include "yaml-cpp/yaml.h"
|
#include "yaml-cpp/yaml.h"
|
||||||
|
#include "yaml-cpp/eventhandler.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
class NullEventHandler: public YAML::EventHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef YAML::Mark Mark;
|
||||||
|
typedef YAML::anchor_t anchor_t;
|
||||||
|
|
||||||
|
NullEventHandler() {}
|
||||||
|
|
||||||
|
virtual void OnDocumentStart(const Mark&) {}
|
||||||
|
virtual void OnDocumentEnd() {}
|
||||||
|
virtual void OnNull(const Mark&, anchor_t) {}
|
||||||
|
virtual void OnAlias(const Mark&, anchor_t) {}
|
||||||
|
virtual void OnScalar(const Mark&, const std::string&, anchor_t, const std::string&) {}
|
||||||
|
virtual void OnSequenceStart(const Mark&, const std::string&, anchor_t) {}
|
||||||
|
virtual void OnSequenceEnd() {}
|
||||||
|
virtual void OnMapStart(const Mark&, const std::string&, anchor_t) {}
|
||||||
|
virtual void OnMapEnd() {}
|
||||||
|
};
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
YAML::Emitter out(std::cout);
|
std::stringstream stream("---{header: {id: 1");
|
||||||
out << YAML::BeginSeq;
|
YAML::Parser parser(stream);
|
||||||
out << "item 1";
|
// parser.PrintTokens(std::cout);
|
||||||
out << YAML::BeginSeq << "foo 1" << "bar 2" << YAML::EndSeq;
|
NullEventHandler handler;
|
||||||
out << YAML::EndSeq;
|
parser.HandleNextDocument(handler);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user