diff --git a/include/yaml-cpp/emitter.h b/include/yaml-cpp/emitter.h index 2add9ee..675a2ae 100644 --- a/include/yaml-cpp/emitter.h +++ b/include/yaml-cpp/emitter.h @@ -50,6 +50,7 @@ class YAML_CPP_API Emitter { bool SetOutputCharset(EMITTER_MANIP value); bool SetStringFormat(EMITTER_MANIP value); bool SetBoolFormat(EMITTER_MANIP value); + bool SetNullFormat(EMITTER_MANIP value); bool SetIntBase(EMITTER_MANIP value); bool SetSeqFormat(EMITTER_MANIP value); bool SetMapFormat(EMITTER_MANIP value); @@ -123,6 +124,7 @@ class YAML_CPP_API Emitter { void SpaceOrIndentTo(bool requireSpace, std::size_t indent); const char* ComputeFullBoolName(bool b) const; + const char* ComputeNullName() const; bool CanEmitNewline() const; private: diff --git a/include/yaml-cpp/emittermanip.h b/include/yaml-cpp/emittermanip.h index 22691bc..010d860 100644 --- a/include/yaml-cpp/emittermanip.h +++ b/include/yaml-cpp/emittermanip.h @@ -26,6 +26,12 @@ enum EMITTER_MANIP { DoubleQuoted, Literal, + // null manipulators + LowerNull, + UpperNull, + CamelNull, + TildeNull, + // bool manipulators YesNoBool, // yes, no TrueFalseBool, // true, false diff --git a/src/.emitterstate.h.swp b/src/.emitterstate.h.swp new file mode 100644 index 0000000..c60f60a Binary files /dev/null and b/src/.emitterstate.h.swp differ diff --git a/src/emitter.cpp b/src/emitter.cpp index 56ef403..7defd43 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -49,6 +49,10 @@ bool Emitter::SetBoolFormat(EMITTER_MANIP value) { return ok; } +bool Emitter::SetNullFormat(EMITTER_MANIP value) { + return m_pState->SetNullFormat(value, FmtScope::Global); +} + bool Emitter::SetIntBase(EMITTER_MANIP value) { return m_pState->SetIntFormat(value, FmtScope::Global); } @@ -770,6 +774,21 @@ const char* Emitter::ComputeFullBoolName(bool b) const { // these answers } +const char* Emitter::ComputeNullName() const { + switch (m_pState->GetNullFormat()) { + case LowerNull: + return "null"; + case UpperNull: + return "NULL"; + case CamelNull: + return "Null"; + case TildeNull: + // fallthrough + default: + return "~"; + } +} + Emitter& Emitter::Write(bool b) { if (!good()) return *this; @@ -893,7 +912,7 @@ Emitter& Emitter::Write(const _Null& /*null*/) { PrepareNode(EmitterNodeType::Scalar); - m_stream << "~"; + m_stream << ComputeNullName(); StartedScalar(); diff --git a/src/emitterstate.cpp b/src/emitterstate.cpp index d50106c..59b3752 100644 --- a/src/emitterstate.cpp +++ b/src/emitterstate.cpp @@ -13,6 +13,7 @@ EmitterState::EmitterState() m_boolFmt(TrueFalseBool), m_boolLengthFmt(LongBool), m_boolCaseFmt(LowerCase), + m_nullFmt(TildeNull), m_intFmt(Dec), m_indent(2), m_preCommentIndent(2), @@ -43,6 +44,7 @@ void EmitterState::SetLocalValue(EMITTER_MANIP value) { SetBoolFormat(value, FmtScope::Local); SetBoolCaseFormat(value, FmtScope::Local); SetBoolLengthFormat(value, FmtScope::Local); + SetNullFormat(value, FmtScope::Local); SetIntFormat(value, FmtScope::Local); SetFlowType(GroupType::Seq, value, FmtScope::Local); SetFlowType(GroupType::Map, value, FmtScope::Local); @@ -279,6 +281,19 @@ bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, } } +bool EmitterState::SetNullFormat(EMITTER_MANIP value, FmtScope::value scope) { + switch (value) { + case LowerNull: + case UpperNull: + case CamelNull: + case TildeNull: + _Set(m_nullFmt, value, scope); + return true; + default: + return false; + } +} + bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope) { switch (value) { case Dec: diff --git a/src/emitterstate.h b/src/emitterstate.h index 75e2166..52c09ce 100644 --- a/src/emitterstate.h +++ b/src/emitterstate.h @@ -91,6 +91,9 @@ class EmitterState { bool SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope); EMITTER_MANIP GetBoolCaseFormat() const { return m_boolCaseFmt.get(); } + bool SetNullFormat(EMITTER_MANIP value, FmtScope::value scope); + EMITTER_MANIP GetNullFormat() const { return m_nullFmt.get(); } + bool SetIntFormat(EMITTER_MANIP value, FmtScope::value scope); EMITTER_MANIP GetIntFormat() const { return m_intFmt.get(); } @@ -131,6 +134,7 @@ class EmitterState { Setting m_boolFmt; Setting m_boolLengthFmt; Setting m_boolCaseFmt; + Setting m_nullFmt; Setting m_intFmt; Setting m_indent; Setting m_preCommentIndent, m_postCommentIndent; diff --git a/test/integration/emitter_test.cpp b/test/integration/emitter_test.cpp index 8e1ee29..04adadf 100644 --- a/test/integration/emitter_test.cpp +++ b/test/integration/emitter_test.cpp @@ -1047,6 +1047,45 @@ TEST_F(EmitterTest, BoolFormatting) { "- Y\n- Y\n- y\n- N\n- N\n- n"); } +TEST_F(EmitterTest, GlobalNullFormatting) { + out << Flow << BeginSeq; + out.SetNullFormat(LowerNull); + out << Null; + out.SetNullFormat(UpperNull); + out << Null; + out.SetNullFormat(CamelNull); + out << Null; + out.SetNullFormat(TildeNull); + out << Null; + out << EndSeq; + ExpectEmit("[null, NULL, Null, ~]"); +} + +TEST_F(EmitterTest, NullFormatting) { + out << Flow << BeginSeq; + out << LowerNull << Null; + out << UpperNull << Null; + out << CamelNull << Null; + out << TildeNull << Null; + out << EndSeq; + ExpectEmit("[null, NULL, Null, ~]"); +} + +TEST_F(EmitterTest, NullFormattingOnNode) { + Node n(Load("null")); + out << Flow << BeginSeq; + out.SetNullFormat(LowerNull); + out << n; + out.SetNullFormat(UpperNull); + out << n; + out.SetNullFormat(CamelNull); + out << n; + out.SetNullFormat(TildeNull); + out << n; + out << EndSeq; + ExpectEmit("[null, NULL, Null, ~]"); +} + // TODO: Fix this test. // TEST_F(EmitterTest, DocStartAndEnd) { // out << BeginDoc;