Commit ad712c4f authored by Jesse Beder's avatar Jesse Beder
Browse files

Add EmitterStyle, which will allow sequence or map style (i.e., flow or block)...

Add EmitterStyle, which will allow sequence or map style (i.e., flow or block) to be preserved between parsing and emitting
parent a397ad29
......@@ -10,6 +10,7 @@
#include <stack>
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h"
namespace YAML {
......@@ -32,11 +33,11 @@ class EmitFromEvents : public EventHandler {
anchor_t anchor, const std::string& value);
virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor);
anchor_t anchor, EmitterStyle::value style);
virtual void OnSequenceEnd();
virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor);
anchor_t anchor, EmitterStyle::value style);
virtual void OnMapEnd();
private:
......
#ifndef EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once
#endif
namespace YAML {
struct EmitterStyle {
enum value {
Default,
Block,
Flow,
};
};
}
#endif // EMITTERSTYLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
......@@ -7,9 +7,11 @@
#pragma once
#endif
#include "yaml-cpp/anchor.h"
#include <string>
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/emitterstyle.h"
namespace YAML {
struct Mark;
......@@ -26,11 +28,11 @@ class EventHandler {
anchor_t anchor, const std::string& value) = 0;
virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor) = 0;
anchor_t anchor, EmitterStyle::value style) = 0;
virtual void OnSequenceEnd() = 0;
virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor) = 0;
anchor_t anchor, EmitterStyle::value style) = 0;
virtual void OnMapEnd() = 0;
};
}
......
......@@ -9,6 +9,7 @@
#include "yaml-cpp/parser.h"
#include "yaml-cpp/emitter.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/stlemitter.h"
#include "yaml-cpp/exceptions.h"
......
......@@ -60,7 +60,8 @@ static const unsigned char decoding[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, };
255,
};
std::vector<unsigned char> DecodeBase64(const std::string &input) {
typedef std::vector<unsigned char> ret_type;
......
......@@ -30,7 +30,8 @@ void GraphBuilderAdapter::OnScalar(const Mark &mark, const std::string &tag,
void GraphBuilderAdapter::OnSequenceStart(const Mark &mark,
const std::string &tag,
anchor_t anchor) {
anchor_t anchor,
EmitterStyle::value style) {
void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent());
m_containers.push(ContainerFrame(pNode));
RegisterAnchor(anchor, pNode);
......@@ -44,7 +45,8 @@ void GraphBuilderAdapter::OnSequenceEnd() {
}
void GraphBuilderAdapter::OnMapStart(const Mark &mark, const std::string &tag,
anchor_t anchor) {
anchor_t anchor,
EmitterStyle::value style) {
void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent());
m_containers.push(ContainerFrame(pNode, m_pKeyNode));
m_pKeyNode = NULL;
......
......@@ -14,6 +14,7 @@
#include "yaml-cpp/anchor.h"
#include "yaml-cpp/contrib/anchordict.h"
#include "yaml-cpp/contrib/graphbuilder.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h"
namespace YAML {
......@@ -36,11 +37,11 @@ class GraphBuilderAdapter : public EventHandler {
anchor_t anchor, const std::string& value);
virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor);
anchor_t anchor, EmitterStyle::value style);
virtual void OnSequenceEnd();
virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor);
anchor_t anchor, EmitterStyle::value style);
virtual void OnMapEnd();
void* RootNode() const { return m_pRootNode; }
......
......@@ -44,9 +44,20 @@ void EmitFromEvents::OnScalar(const Mark&, const std::string& tag,
}
void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag,
anchor_t anchor) {
anchor_t anchor,
EmitterStyle::value style) {
BeginNode();
EmitProps(tag, anchor);
switch (style) {
case EmitterStyle::Block:
m_emitter << Block;
break;
case EmitterStyle::Flow:
m_emitter << Flow;
break;
default:
break;
}
m_emitter << BeginSeq;
m_stateStack.push(State::WaitingForSequenceEntry);
}
......@@ -58,9 +69,19 @@ void EmitFromEvents::OnSequenceEnd() {
}
void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag,
anchor_t anchor) {
anchor_t anchor, EmitterStyle::value style) {
BeginNode();
EmitProps(tag, anchor);
switch (style) {
case EmitterStyle::Block:
m_emitter << Block;
break;
case EmitterStyle::Flow:
m_emitter << Flow;
break;
default:
break;
}
m_emitter << BeginMap;
m_stateStack.push(State::WaitingForKey);
}
......
......@@ -16,7 +16,7 @@ RegEx::RegEx(const std::string& str, REGEX_OP op) : m_op(op) {
}
// combination constructors
RegEx operator!(const RegEx & ex) {
RegEx operator!(const RegEx& ex) {
RegEx ret(REGEX_NOT);
ret.m_params.push_back(ex);
return ret;
......
......@@ -34,7 +34,7 @@ class RegEx {
RegEx(const std::string& str, REGEX_OP op = REGEX_SEQ);
~RegEx() {}
friend RegEx operator!(const RegEx & ex);
friend RegEx operator!(const RegEx& ex);
friend RegEx operator||(const RegEx& ex1, const RegEx& ex2);
friend RegEx operator&&(const RegEx& ex1, const RegEx& ex2);
friend RegEx operator+(const RegEx& ex1, const RegEx& ex2);
......
......@@ -317,8 +317,9 @@ void Scanner::PopIndentToHere() {
const IndentMarker& indent = *m_indents.top();
if (indent.column < INPUT.column())
break;
if (indent.column == INPUT.column() && !(indent.type == IndentMarker::SEQ &&
!Exp::BlockEntry().Matches(INPUT)))
if (indent.column == INPUT.column() &&
!(indent.type == IndentMarker::SEQ &&
!Exp::BlockEntry().Matches(INPUT)))
break;
PopIndent();
......
......@@ -7,6 +7,7 @@
#include "singledocparser.h"
#include "tag.h"
#include "token.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/exceptions.h" // IWYU pragma: keep
#include "yaml-cpp/mark.h"
......@@ -55,7 +56,7 @@ void SingleDocParser::HandleNode(EventHandler& eventHandler) {
// special case: a value node by itself must be a map, with no header
if (m_scanner.peek().type == Token::VALUE) {
eventHandler.OnMapStart(mark, "?", NullAnchor);
eventHandler.OnMapStart(mark, "?", NullAnchor, EmitterStyle::Default);
HandleMap(eventHandler);
eventHandler.OnMapEnd();
return;
......@@ -92,14 +93,22 @@ void SingleDocParser::HandleNode(EventHandler& eventHandler) {
m_scanner.pop();
return;
case Token::FLOW_SEQ_START:
eventHandler.OnSequenceStart(mark, tag, anchor, EmitterStyle::Flow);
HandleSequence(eventHandler);
eventHandler.OnSequenceEnd();
return;
case Token::BLOCK_SEQ_START:
eventHandler.OnSequenceStart(mark, tag, anchor);
eventHandler.OnSequenceStart(mark, tag, anchor, EmitterStyle::Block);
HandleSequence(eventHandler);
eventHandler.OnSequenceEnd();
return;
case Token::FLOW_MAP_START:
eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Flow);
HandleMap(eventHandler);
eventHandler.OnMapEnd();
return;
case Token::BLOCK_MAP_START:
eventHandler.OnMapStart(mark, tag, anchor);
eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Block);
HandleMap(eventHandler);
eventHandler.OnMapEnd();
return;
......@@ -107,7 +116,7 @@ void SingleDocParser::HandleNode(EventHandler& eventHandler) {
// compact maps can only go in a flow sequence
if (m_pCollectionStack->GetCurCollectionType() ==
CollectionType::FlowSeq) {
eventHandler.OnMapStart(mark, tag, anchor);
eventHandler.OnMapStart(mark, tag, anchor, EmitterStyle::Flow);
HandleMap(eventHandler);
eventHandler.OnMapEnd();
return;
......
......@@ -7,7 +7,7 @@
#endif
#define S_ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A)))
#define S_ARRAY_END(A) ((A) + S_ARRAY_SIZE(A))
#define S_ARRAY_END(A) ((A)+S_ARRAY_SIZE(A))
#define CP_REPLACEMENT_CHARACTER (0xFFFD)
......@@ -46,25 +46,26 @@ enum UtfIntroCharType {
uictMax
};
static bool s_introFinalState[] = {false, // uis_start
false, // uis_utfbe_b1
false, // uis_utf32be_b2
false, // uis_utf32be_bom3
true, // uis_utf32be
true, // uis_utf16be
false, // uis_utf16be_bom1
false, // uis_utfle_bom1
false, // uis_utf16le_bom2
false, // uis_utf32le_bom3
true, // uis_utf16le
true, // uis_utf32le
false, // uis_utf8_imp
false, // uis_utf16le_imp
false, // uis_utf32le_imp3
false, // uis_utf8_bom1
false, // uis_utf8_bom2
true, // uis_utf8
true, // uis_error
static bool s_introFinalState[] = {
false, // uis_start
false, // uis_utfbe_b1
false, // uis_utf32be_b2
false, // uis_utf32be_bom3
true, // uis_utf32be
true, // uis_utf16be
false, // uis_utf16be_bom1
false, // uis_utfle_bom1
false, // uis_utf16le_bom2
false, // uis_utf32le_bom3
true, // uis_utf16le
true, // uis_utf32le
false, // uis_utf8_imp
false, // uis_utf16le_imp
false, // uis_utf32le_imp3
false, // uis_utf8_bom1
false, // uis_utf8_bom2
true, // uis_utf8
true, // uis_error
};
static UtfIntroState s_introTransitions[][uictMax] = {
......@@ -105,7 +106,8 @@ static UtfIntroState s_introTransitions[][uictMax] = {
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8,
uis_utf8},
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8,
uis_utf8}, };
uis_utf8},
};
static char s_introUngetCount[][uictMax] = {
// uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther
......@@ -126,7 +128,8 @@ static char s_introUngetCount[][uictMax] = {
{4, 4, 4, 4, 4, 4, 4, 4},
{2, 0, 2, 2, 2, 2, 2, 2},
{3, 3, 0, 3, 3, 3, 3, 3},
{1, 1, 1, 1, 1, 1, 1, 1}, };
{1, 1, 1, 1, 1, 1, 1, 1},
};
inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) {
if (std::istream::traits_type::eof() == ch) {
......
......@@ -52,7 +52,7 @@ def scalar(value, tag='', anchor='', anchor_id=0):
def comment(value):
return {'emit': 'Comment("%s")' % value, 'handle': ''}
def seq_start(tag='', anchor='', anchor_id=0):
def seq_start(tag='', anchor='', anchor_id=0, style='_'):
emit = []
if tag:
emit += ['VerbatimTag("%s")' % encode(tag)]
......@@ -63,12 +63,12 @@ def seq_start(tag='', anchor='', anchor_id=0):
else:
out_tag = '?'
emit += ['BeginSeq']
return {'emit': emit, 'handle': 'OnSequenceStart(_, "%s", %s)' % (out_tag, anchor_id)}
return {'emit': emit, 'handle': 'OnSequenceStart(_, "%s", %s, %s)' % (out_tag, anchor_id, style)}
def seq_end():
return {'emit': 'EndSeq', 'handle': 'OnSequenceEnd()'}
def map_start(tag='', anchor='', anchor_id=0):
def map_start(tag='', anchor='', anchor_id=0, style='_'):
emit = []
if tag:
emit += ['VerbatimTag("%s")' % encode(tag)]
......@@ -79,7 +79,7 @@ def map_start(tag='', anchor='', anchor_id=0):
else:
out_tag = '?'
emit += ['BeginMap']
return {'emit': emit, 'handle': 'OnMapStart(_, "%s", %s)' % (out_tag, anchor_id)}
return {'emit': emit, 'handle': 'OnMapStart(_, "%s", %s, %s)' % (out_tag, anchor_id, style)}
def map_end():
return {'emit': 'EndMap', 'handle': 'OnMapEnd()'}
......
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/yaml.h" // IWYU pragma: keep
#include "gtest/gtest.h"
......@@ -14,10 +15,12 @@ class NullEventHandler : public EventHandler {
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 OnSequenceStart(const Mark&, const std::string&, anchor_t,
EmitterStyle::value style) {}
virtual void OnSequenceEnd() {}
virtual void OnMapStart(const Mark&, const std::string&, anchor_t) {}
virtual void OnMapStart(const Mark&, const std::string&, anchor_t,
EmitterStyle::value style) {}
virtual void OnMapEnd() {}
};
......@@ -775,13 +778,13 @@ TEST_F(EmitterTest, Binary) {
TEST_F(EmitterTest, LongBinary) {
out << Binary(
reinterpret_cast<const unsigned char*>(
"Man is distinguished, not only by his reason, but by this "
"singular passion from other animals, which is a lust of the "
"mind, that by a perseverance of delight in the continued and "
"indefatigable generation of knowledge, exceeds the short "
"vehemence of any carnal pleasure.\n"),
270);
reinterpret_cast<const unsigned char*>(
"Man is distinguished, not only by his reason, but by this "
"singular passion from other animals, which is a lust of the "
"mind, that by a perseverance of delight in the continued and "
"indefatigable generation of knowledge, exceeds the short "
"vehemence of any carnal pleasure.\n"),
270);
ExpectEmit(
"!!binary "
"\"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieS"
......
......@@ -95,7 +95,7 @@ class EncodingTest : public HandlerTest {
void Run() {
InSequence sequence;
EXPECT_CALL(handler, OnDocumentStart(_));
EXPECT_CALL(handler, OnSequenceStart(_, "?", 0));
EXPECT_CALL(handler, OnSequenceStart(_, "?", 0, EmitterStyle::Block));
for (std::size_t i = 0; i < m_entries.size(); i++) {
EXPECT_CALL(handler, OnScalar(_, "!", 0, m_entries[i]));
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -11,8 +11,7 @@ using ::testing::_;
ASSERT_THROW(statement, ParserException); \
try { \
statement; \
} \
catch (const ParserException& e) { \
} catch (const ParserException& e) { \
EXPECT_EQ(e.msg, message); \
}
......@@ -26,7 +25,7 @@ TEST_F(HandlerTest, NoEndOfMapFlow) {
TEST_F(HandlerTest, PlainScalarStartingWithQuestionMark) {
EXPECT_CALL(handler, OnDocumentStart(_));
EXPECT_CALL(handler, OnMapStart(_, "?", 0));
EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "foo"));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "?bar"));
EXPECT_CALL(handler, OnMapEnd());
......@@ -36,7 +35,7 @@ TEST_F(HandlerTest, PlainScalarStartingWithQuestionMark) {
TEST_F(HandlerTest, NullStringScalar) {
EXPECT_CALL(handler, OnDocumentStart(_));
EXPECT_CALL(handler, OnMapStart(_, "?", 0));
EXPECT_CALL(handler, OnMapStart(_, "?", 0, EmitterStyle::Block));
EXPECT_CALL(handler, OnScalar(_, "?", 0, "foo"));
EXPECT_CALL(handler, OnNull(_, 0));
EXPECT_CALL(handler, OnMapEnd());
......
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/eventhandler.h"
#include "gmock/gmock.h"
......@@ -14,11 +15,12 @@ class MockEventHandler : public EventHandler {
MOCK_METHOD4(OnScalar, void(const Mark&, const std::string&, anchor_t,
const std::string&));
MOCK_METHOD3(OnSequenceStart,
void(const Mark&, const std::string&, anchor_t));
MOCK_METHOD4(OnSequenceStart, void(const Mark&, const std::string&, anchor_t,
EmitterStyle::value));
MOCK_METHOD0(OnSequenceEnd, void());
MOCK_METHOD3(OnMapStart, void(const Mark&, const std::string&, anchor_t));
MOCK_METHOD4(OnMapStart, void(const Mark&, const std::string&, anchor_t,
EmitterStyle::value));
MOCK_METHOD0(OnMapEnd, void());
};
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment