diff --git a/src/emitter.cpp b/src/emitter.cpp index ad21e22..c49fcc9 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -186,6 +186,7 @@ namespace YAML case ES_WRITING_FLOW_SEQ_ENTRY: return true; case ES_DONE_WITH_FLOW_SEQ_ENTRY: + EmitSeparationIfNecessary(); m_stream << ','; m_pState->RequireSoftSeparation(); m_pState->SwitchState(ES_WAITING_FOR_FLOW_SEQ_ENTRY); @@ -221,9 +222,9 @@ namespace YAML m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN); return true; case ES_WAITING_FOR_FLOW_MAP_KEY: + EmitSeparationIfNecessary(); m_pState->SwitchState(ES_WRITING_FLOW_MAP_KEY); if(m_pState->CurrentlyInLongKey()) { - EmitSeparationIfNecessary(); m_stream << '?'; m_pState->RequireSoftSeparation(); } @@ -234,6 +235,7 @@ namespace YAML m_pState->SetError(ErrorMsg::EXPECTED_VALUE_TOKEN); return true; case ES_WAITING_FOR_FLOW_MAP_VALUE: + EmitSeparationIfNecessary(); m_stream << ':'; m_pState->RequireSoftSeparation(); m_pState->SwitchState(ES_WRITING_FLOW_MAP_VALUE); @@ -496,6 +498,7 @@ namespace YAML } else if(flowType == FT_FLOW) { // Note: flow maps are allowed to be empty assert(curState == ES_DONE_WITH_FLOW_MAP_VALUE || curState == ES_WAITING_FOR_FLOW_MAP_ENTRY); + EmitSeparationIfNecessary(); m_stream << "}"; } else assert(false); @@ -526,6 +529,7 @@ namespace YAML m_pState->UnsetSeparation(); m_pState->SwitchState(ES_WAITING_FOR_BLOCK_MAP_KEY); } else if(flowType == FT_FLOW) { + EmitSeparationIfNecessary(); if(curState == ES_DONE_WITH_FLOW_MAP_VALUE) { m_stream << ','; m_pState->RequireSoftSeparation(); @@ -796,8 +800,12 @@ namespace YAML if(!good()) return *this; - m_stream << Indentation(m_pState->GetPreCommentIndent()); + if(m_stream.col() > 0) + m_stream << Indentation(m_pState->GetPreCommentIndent()); Utils::WriteComment(m_stream, comment.content, m_pState->GetPostCommentIndent()); + m_pState->RequireHardSeparation(); + m_pState->ForceHardSeparation(); + return *this; } diff --git a/src/emitterutils.cpp b/src/emitterutils.cpp index 38bd18f..5bc0ba9 100644 --- a/src/emitterutils.cpp +++ b/src/emitterutils.cpp @@ -267,7 +267,7 @@ namespace YAML bool WriteComment(ostream& out, const std::string& str, int postCommentIndent) { - unsigned curIndent = out.col(); + const unsigned curIndent = out.col(); out << "#" << Indentation(postCommentIndent); int codePoint; for(std::string::const_iterator i = str.begin(); diff --git a/test/emittertests.cpp b/test/emittertests.cpp index c3e0be7..246cd2d 100644 --- a/test/emittertests.cpp +++ b/test/emittertests.cpp @@ -503,6 +503,40 @@ namespace Test desiredOutput = "? long key # long key\n: value"; } + + void InitialComment(YAML::Emitter& out, std::string& desiredOutput) + { + out << YAML::Comment("A comment describing the purpose of the file."); + out << YAML::BeginMap << YAML::Key << "key" << YAML::Value << "value" << YAML::EndMap; + + desiredOutput = "# A comment describing the purpose of the file.\nkey: value"; + } + + void InitialCommentWithDocIndicator(YAML::Emitter& out, std::string& desiredOutput) + { + out << YAML::BeginDoc << YAML::Comment("A comment describing the purpose of the file."); + out << YAML::BeginMap << YAML::Key << "key" << YAML::Value << "value" << YAML::EndMap; + + desiredOutput = "---\n# A comment describing the purpose of the file.\nkey: value"; + } + + void CommentInFlowSeq(YAML::Emitter& out, std::string& desiredOutput) + { + out << YAML::Flow << YAML::BeginSeq << "foo" << YAML::Comment("foo!") << "bar" << YAML::EndSeq; + + desiredOutput = "[foo # foo!\n, bar]"; + } + + void CommentInFlowMap(YAML::Emitter& out, std::string& desiredOutput) + { + out << YAML::Flow << YAML::BeginMap; + out << YAML::Key << "foo" << YAML::Comment("foo!") << YAML::Value << "foo value"; + out << YAML::Key << "bar" << YAML::Value << "bar value" << YAML::Comment("bar!"); + out << YAML::Key << "baz" << YAML::Comment("baz!") << YAML::Value << "baz value" << YAML::Comment("baz!"); + out << YAML::EndMap; + + desiredOutput = "{foo # foo!\n: foo value, bar: bar value # bar!\n, baz # baz!\n: baz value # baz!\n}"; + } void Indentation(YAML::Emitter& out, std::string& desiredOutput) { @@ -980,6 +1014,10 @@ namespace Test RunEmitterTest(&Emitter::SimpleComment, "simple comment", passed, total); RunEmitterTest(&Emitter::MultiLineComment, "multi-line comment", passed, total); RunEmitterTest(&Emitter::ComplexComments, "complex comments", passed, total); + RunEmitterTest(&Emitter::InitialComment, "initial comment", passed, total); + RunEmitterTest(&Emitter::InitialCommentWithDocIndicator, "initial comment with doc indicator", passed, total); + RunEmitterTest(&Emitter::CommentInFlowSeq, "comment in flow seq", passed, total); + RunEmitterTest(&Emitter::CommentInFlowMap, "comment in flow map", passed, total); RunEmitterTest(&Emitter::Indentation, "indentation", passed, total); RunEmitterTest(&Emitter::SimpleGlobalSettings, "simple global settings", passed, total); RunEmitterTest(&Emitter::ComplexGlobalSettings, "complex global settings", passed, total);