diff --git a/src/emitfromevents.cpp b/src/emitfromevents.cpp index 350bde648..fdd4d701f 100644 --- a/src/emitfromevents.cpp +++ b/src/emitfromevents.cpp @@ -116,12 +116,24 @@ void EmitFromEvents::BeginNode() { } void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) { - if (!tag.empty() && tag != "?" && tag != "!"){ - if (tag[0] == '!') { - m_emitter << LocalTag(std::string(tag.begin()+1, tag.end())); + if (!tag.empty() && tag != "?" && tag != "!" && tag != "!!") { + if (tag[0] == '!') { + auto prefix_end = tag.begin() + 1; + while (prefix_end != tag.end() && *prefix_end != '!') { + ++prefix_end; + } + if (prefix_end == tag.begin() + 1) { + m_emitter << SecondaryTag(std::string(tag.begin() + 2, tag.end())); + } else if (prefix_end == tag.end()) { + m_emitter << LocalTag(std::string(tag.begin() + 1, tag.end())); + } else if (prefix_end + 1 != tag.end()){ + m_emitter << LocalTag(std::string(tag.begin() + 1, prefix_end), std::string(prefix_end + 1, tag.end())); } else { m_emitter << VerbatimTag(tag); } + } else { + m_emitter << VerbatimTag(tag); + } } if (anchor) m_emitter << Anchor(ToString(anchor)); diff --git a/test/integration/emitter_test.cpp b/test/integration/emitter_test.cpp index f1472d6f3..9c94de33c 100644 --- a/test/integration/emitter_test.cpp +++ b/test/integration/emitter_test.cpp @@ -660,6 +660,52 @@ TEST_F(EmitterTest, LocalTagRetainedAfterLoadingNode) { EXPECT_EQ(expected, emitter.c_str()); } +TEST_F(EmitterTest, SecondaryTag) { + out << SecondaryTag("str") << "123"; + + ExpectEmit("!!str 123"); +} + +TEST_F(EmitterTest, SetVerbatimTag) { + Node node, root; + node = 42; + node.SetTag("hello"); + root["num"] = node; + out << root; + + ExpectEmit("num: ! 42"); +} + +TEST_F(EmitterTest, SetLocalTag) { + Node node, root; + node = 42; + node.SetTag("!foo"); + root["num"] = node; + out << root; + + ExpectEmit("num: !foo 42"); +} + +TEST_F(EmitterTest, SetLocalTagInNameHandle) { + Node node, root; + node = 42; + node.SetTag("!a!foo"); + root["num"] = node; + out << root; + + ExpectEmit("num: !a!foo 42"); +} + +TEST_F(EmitterTest, SetSecondaryTag) { + Node node, root; + node = 123; + node.SetTag("!!str"); + root["hello"] = node; + out << root; + + ExpectEmit("hello: !!str 123"); +} + TEST_F(EmitterTest, ComplexDoc) { out << BeginMap; out << Key << "receipt"; @@ -975,16 +1021,18 @@ TEST_F(EmitterTest, Unicode) { TEST_F(EmitterTest, DoubleQuotedUnicode) { out << DoubleQuoted << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2"; - ExpectEmit("\"\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2\""); + ExpectEmit("\"\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2\""); } TEST_F(EmitterTest, EscapedJsonString) { out.SetStringFormat(DoubleQuoted); out.SetOutputCharset(EscapeAsJson); out << "\" \\ " - "\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0A \x0B \x0C \x0D \x0E \x0F " - "\x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1A \x1B \x1C \x1D \x1E \x1F " - "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2"; + "\x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0A \x0B \x0C \x0D " + "\x0E \x0F " + "\x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1A \x1B \x1C " + "\x1D \x1E \x1F " + "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2"; ExpectEmit(R"("\" \\ \u0001 \u0002 \u0003 \u0004 \u0005 \u0006 \u0007 \b \t )" R"(\n \u000b \f \r \u000e \u000f \u0010 \u0011 \u0012 \u0013 )" @@ -994,22 +1042,14 @@ TEST_F(EmitterTest, EscapedJsonString) { } TEST_F(EmitterTest, EscapedCharacters) { - out << BeginSeq - << '\x00' - << '\x0C' - << '\x0D' - << EndSeq; + out << BeginSeq << '\x00' << '\x0C' << '\x0D' << EndSeq; ExpectEmit("- \"\\x00\"\n- \"\\f\"\n- \"\\r\""); } TEST_F(EmitterTest, CharactersEscapedAsJson) { out.SetOutputCharset(EscapeAsJson); - out << BeginSeq - << '\x00' - << '\x0C' - << '\x0D' - << EndSeq; + out << BeginSeq << '\x00' << '\x0C' << '\x0D' << EndSeq; ExpectEmit("- \"\\u0000\"\n- \"\\f\"\n- \"\\r\""); } @@ -1452,8 +1492,8 @@ TEST_F(EmitterTest, Infinity) { out << YAML::EndMap; ExpectEmit( - "foo: .inf\n" - "bar: .inf"); + "foo: .inf\n" + "bar: .inf"); } TEST_F(EmitterTest, NegInfinity) { @@ -1465,8 +1505,8 @@ TEST_F(EmitterTest, NegInfinity) { out << YAML::EndMap; ExpectEmit( - "foo: -.inf\n" - "bar: -.inf"); + "foo: -.inf\n" + "bar: -.inf"); } TEST_F(EmitterTest, NaN) { @@ -1478,11 +1518,11 @@ TEST_F(EmitterTest, NaN) { out << YAML::EndMap; ExpectEmit( - "foo: .nan\n" - "bar: .nan"); + "foo: .nan\n" + "bar: .nan"); } -TEST_F(EmitterTest, ComplexFlowSeqEmbeddingAMapWithNewLine) { +TEST_F(EmitterTest, ComplexFlowSeqEmbeddingAMapWithNewLine) { out << YAML::BeginMap; out << YAML::Key << "NodeA" << YAML::Value << YAML::BeginMap;