diff --git a/src/emitter.cpp b/src/emitter.cpp index 8dcc45c..d65fd0b 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -153,16 +153,19 @@ namespace YAML // document-level case ES_WAITING_FOR_DOC: m_stream << "---"; - m_pState->RequireSeparation(); + m_pState->RequireSoftSeparation(); m_pState->SwitchState(ES_WRITING_DOC); return true; case ES_WRITING_DOC: return true; + case ES_DONE_WITH_DOC: + m_pState->SetError("Write called on finished document"); + return true; // block sequence case ES_WAITING_FOR_BLOCK_SEQ_ENTRY: m_stream << IndentTo(curIndent) << "-"; - m_pState->RequireSeparation(); + m_pState->RequireSoftSeparation(); m_pState->SwitchState(ES_WRITING_BLOCK_SEQ_ENTRY); return true; case ES_WRITING_BLOCK_SEQ_ENTRY: @@ -180,7 +183,7 @@ namespace YAML return true; case ES_DONE_WITH_FLOW_SEQ_ENTRY: m_stream << ','; - m_pState->RequireSeparation(); + m_pState->RequireSoftSeparation(); m_pState->SwitchState(ES_WAITING_FOR_FLOW_SEQ_ENTRY); return false; @@ -191,7 +194,7 @@ namespace YAML case ES_WAITING_FOR_BLOCK_MAP_KEY: if(m_pState->CurrentlyInLongKey()) { m_stream << IndentTo(curIndent) << '?'; - m_pState->RequireSeparation(); + m_pState->RequireSoftSeparation(); } m_pState->SwitchState(ES_WRITING_BLOCK_MAP_KEY); return true; @@ -218,7 +221,7 @@ namespace YAML if(m_pState->CurrentlyInLongKey()) { EmitSeparationIfNecessary(); m_stream << '?'; - m_pState->RequireSeparation(); + m_pState->RequireSoftSeparation(); } return true; case ES_WRITING_FLOW_MAP_KEY: @@ -228,7 +231,7 @@ namespace YAML return true; case ES_WAITING_FOR_FLOW_MAP_VALUE: m_stream << ':'; - m_pState->RequireSeparation(); + m_pState->RequireSoftSeparation(); m_pState->SwitchState(ES_WRITING_FLOW_MAP_VALUE); return true; case ES_WRITING_FLOW_MAP_VALUE: @@ -284,7 +287,7 @@ namespace YAML case ES_WRITING_BLOCK_MAP_KEY: if(!m_pState->CurrentlyInLongKey()) { m_stream << ':'; - m_pState->RequireSeparation(); + m_pState->RequireSoftSeparation(); } m_pState->SwitchState(ES_DONE_WITH_BLOCK_MAP_KEY); break; @@ -312,8 +315,10 @@ namespace YAML if(!good()) return; - if(m_pState->RequiresSeparation()) + if(m_pState->RequiresSoftSeparation()) m_stream << ' '; + else if(m_pState->RequiresHardSeparation()) + m_stream << '\n'; m_pState->UnsetSeparation(); } @@ -403,8 +408,10 @@ namespace YAML curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE || curState == ES_WRITING_DOC ) { - m_stream << "\n"; - m_pState->UnsetSeparation(); + if(m_pState->RequiresHardSeparation() || curState != ES_WRITING_BLOCK_SEQ_ENTRY) { + m_stream << "\n"; + m_pState->UnsetSeparation(); + } } m_pState->PushState(ES_WAITING_FOR_BLOCK_MAP_ENTRY); } else if(flowType == Flow) { @@ -469,11 +476,12 @@ namespace YAML m_stream << '\n'; unsigned curIndent = m_pState->GetCurIndent(); m_stream << IndentTo(curIndent); + m_pState->UnsetSeparation(); m_pState->SwitchState(ES_WAITING_FOR_BLOCK_MAP_KEY); } else if(flowType == FT_FLOW) { if(curState == ES_DONE_WITH_FLOW_MAP_VALUE) { m_stream << ','; - m_pState->RequireSeparation(); + m_pState->RequireSoftSeparation(); } m_pState->SwitchState(ES_WAITING_FOR_FLOW_MAP_KEY); } else @@ -503,7 +511,7 @@ namespace YAML m_stream << '\n'; m_stream << IndentTo(m_pState->GetCurIndent()); m_stream << ':'; - m_pState->RequireSeparation(); + m_pState->RequireSoftSeparation(); } m_pState->SwitchState(ES_WAITING_FOR_BLOCK_MAP_VALUE); } else if(flowType == FT_FLOW) { @@ -518,8 +526,10 @@ namespace YAML if(!good()) return; - if(CanEmitNewline()) + if(CanEmitNewline()) { m_stream << '\n'; + m_pState->UnsetSeparation(); + } } bool Emitter::CanEmitNewline() const @@ -685,7 +695,7 @@ namespace YAML m_pState->SetError(ErrorMsg::INVALID_ANCHOR); return *this; } - m_pState->RequireSeparation(); + m_pState->RequireHardSeparation(); // Note: no PostAtomicWrite() because we need another value for this node return *this; } @@ -711,7 +721,7 @@ namespace YAML return *this; } - m_pState->RequireSeparation(); + m_pState->RequireHardSeparation(); // Note: no PostAtomicWrite() because we need another value for this node return *this; } diff --git a/src/emitterstate.cpp b/src/emitterstate.cpp index 1214ac5..6b8476f 100644 --- a/src/emitterstate.cpp +++ b/src/emitterstate.cpp @@ -3,7 +3,7 @@ namespace YAML { - EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_requiresSeparation(false) + EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_requiresSoftSeparation(false), m_requiresHardSeparation(false) { // start up m_stateStack.push(ES_WAITING_FOR_DOC); diff --git a/src/emitterstate.h b/src/emitterstate.h index 5df5008..697aafc 100644 --- a/src/emitterstate.h +++ b/src/emitterstate.h @@ -103,9 +103,12 @@ namespace YAML void StartLongKey(); void StartSimpleKey(); - bool RequiresSeparation() const { return m_requiresSeparation; } - void RequireSeparation() { m_requiresSeparation = true; } - void UnsetSeparation() { m_requiresSeparation = false; } + bool RequiresSoftSeparation() const { return m_requiresSoftSeparation; } + bool RequiresHardSeparation() const { return m_requiresHardSeparation; } + void RequireSoftSeparation() { m_requiresSoftSeparation = true; } + void RequireHardSeparation() { m_requiresSoftSeparation = true; m_requiresHardSeparation = true; } + void ForceHardSeparation() { m_requiresSoftSeparation = false; } + void UnsetSeparation() { m_requiresSoftSeparation = false; m_requiresHardSeparation = false; } void ClearModifiedSettings(); @@ -184,7 +187,8 @@ namespace YAML std::stack m_groups; unsigned m_curIndent; - bool m_requiresSeparation; + bool m_requiresSoftSeparation; + bool m_requiresHardSeparation; }; template diff --git a/test/emittertests.cpp b/test/emittertests.cpp index 16f8764..9f81e33 100644 --- a/test/emittertests.cpp +++ b/test/emittertests.cpp @@ -103,7 +103,7 @@ namespace Test out << "item 2"; out << YAML::EndSeq; - desiredOutput = "---\n- item 1\n-\n pens: 8\n pencils: 14\n- item 2"; + desiredOutput = "---\n- item 1\n- pens: 8\n pencils: 14\n- item 2"; } void NestedBlockMap(YAML::Emitter& out, std::string& desiredOutput) { @@ -451,7 +451,7 @@ namespace Test out << YAML::Value << YAML::Alias("id001"); out << YAML::EndMap; - desiredOutput = "---\nreceipt: Oz-Ware Purchase Invoice\ndate: 2007-08-06\ncustomer:\n given: Dorothy\n family: Gale\nitems:\n -\n part_no: A4786\n descrip: Water Bucket (Filled)\n price: 1.47\n quantity: 4\n -\n part_no: E1628\n descrip: High Heeled \"Ruby\" Slippers\n price: 100.27\n quantity: 1\nbill-to: &id001\n street: |\n 123 Tornado Alley\n Suite 16\n city: East Westville\n state: KS\nship-to: *id001"; + desiredOutput = "---\nreceipt: Oz-Ware Purchase Invoice\ndate: 2007-08-06\ncustomer:\n given: Dorothy\n family: Gale\nitems:\n - part_no: A4786\n descrip: Water Bucket (Filled)\n price: 1.47\n quantity: 4\n - part_no: E1628\n descrip: High Heeled \"Ruby\" Slippers\n price: 100.27\n quantity: 1\nbill-to: &id001\n street: |\n 123 Tornado Alley\n Suite 16\n city: East Westville\n state: KS\nship-to: *id001"; } void STLContainers(YAML::Emitter& out, std::string& desiredOutput) @@ -471,7 +471,7 @@ namespace Test out << ages; out << YAML::EndSeq; - desiredOutput = "---\n- [2, 3, 5, 7, 11, 13]\n-\n Daniel: 26\n Jesse: 24"; + desiredOutput = "---\n- [2, 3, 5, 7, 11, 13]\n- Daniel: 26\n Jesse: 24"; } void SimpleComment(YAML::Emitter& out, std::string& desiredOutput) @@ -514,7 +514,7 @@ namespace Test out << YAML::EndMap; out << YAML::EndSeq; - desiredOutput = "---\n-\n key 1: value 1\n key 2:\n - a\n - b\n - c"; + desiredOutput = "---\n- key 1: value 1\n key 2:\n - a\n - b\n - c"; } void SimpleGlobalSettings(YAML::Emitter& out, std::string& desiredOutput) @@ -529,7 +529,7 @@ namespace Test out << YAML::EndMap; out << YAML::EndSeq; - desiredOutput = "---\n-\n ? key 1\n : value 1\n ? key 2\n : [a, b, c]"; + desiredOutput = "---\n- ? key 1\n : value 1\n ? key 2\n : [a, b, c]"; } void ComplexGlobalSettings(YAML::Emitter& out, std::string& desiredOutput) @@ -548,7 +548,7 @@ namespace Test out << YAML::EndMap; out << YAML::EndSeq; - desiredOutput = "---\n-\n key 1: value 1\n key 2: [a, b, c]\n-\n ? [1, 2]\n :\n a: b"; + desiredOutput = "---\n- key 1: value 1\n key 2: [a, b, c]\n- ? [1, 2]\n :\n a: b"; } void Null(YAML::Emitter& out, std::string& desiredOutput) @@ -561,7 +561,7 @@ namespace Test out << YAML::EndMap; out << YAML::EndSeq; - desiredOutput = "---\n- ~\n-\n null value: ~\n ~: null key"; + desiredOutput = "---\n- ~\n- null value: ~\n ~: null key"; } void EscapedUnicode(YAML::Emitter& out, std::string& desiredOutput) @@ -606,7 +606,7 @@ namespace Test out << Foo(3, "goodbye"); out << YAML::EndSeq; - desiredOutput = "---\n-\n x: 5\n bar: hello\n-\n x: 3\n bar: goodbye"; + desiredOutput = "---\n- x: 5\n bar: hello\n- x: 3\n bar: goodbye"; } void UserTypeInContainer(YAML::Emitter& out, std::string& desiredOutput) @@ -616,7 +616,7 @@ namespace Test fv.push_back(Foo(3, "goodbye")); out << fv; - desiredOutput = "---\n-\n x: 5\n bar: hello\n-\n x: 3\n bar: goodbye"; + desiredOutput = "---\n- x: 5\n bar: hello\n- x: 3\n bar: goodbye"; } template @@ -649,7 +649,7 @@ namespace Test out << bar << baz; out << YAML::EndSeq; - desiredOutput = "---\n-\n x: 5\n bar: hello\n- ~"; + desiredOutput = "---\n- x: 5\n bar: hello\n- ~"; } void NewlineAtEnd(YAML::Emitter& out, std::string& desiredOutput) @@ -706,7 +706,7 @@ namespace Test out << YAML::LongKey << YAML::Key << "f" << YAML::Newline << YAML::Value << "foo"; out << YAML::EndMap; out << YAML::EndSeq; - desiredOutput = "---\n- a\n\n-\n - b\n - c\n\n\n-\n\n d: e\n ? f\n\n : foo"; + desiredOutput = "---\n- a\n\n-\n - b\n - c\n\n\n-\n d: e\n ? f\n\n : foo"; } void Binary(YAML::Emitter& out, std::string& desiredOutput)