diff --git a/include/yaml-cpp/emitter.h b/include/yaml-cpp/emitter.h index 5ea2b47..ae88751 100644 --- a/include/yaml-cpp/emitter.h +++ b/include/yaml-cpp/emitter.h @@ -81,8 +81,6 @@ namespace YAML void EmitEndSeq(); void EmitBeginMap(); void EmitEndMap(); - void EmitKey(); - void EmitValue(); void EmitNewline(); void EmitKindTag(); void EmitTag(bool verbatim, const _Tag& tag); diff --git a/src/emitter.cpp b/src/emitter.cpp index bb69988..d3cc8f0 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -131,10 +131,8 @@ namespace YAML EmitEndMap(); break; case Key: - EmitKey(); - break; case Value: - EmitValue(); + // deprecated (these can be deduced by the parity of nodes in a map) break; case TagByKind: EmitKindTag(); @@ -169,6 +167,20 @@ namespace YAML { if(!good()) return; + + if(m_pState->CurGroupType() != GroupType::None) { + m_pState->SetError("Unexpected begin document"); + return; + } + + if(m_pState->HasAnchor() || m_pState->HasTag()) { + m_pState->SetError("Unexpected begin document"); + return; + } + + if(m_stream.col() > 0) + m_stream << "\n"; + m_stream << "---\n"; } // EmitEndDoc @@ -176,6 +188,20 @@ namespace YAML { if(!good()) return; + + if(m_pState->CurGroupType() != GroupType::None) { + m_pState->SetError("Unexpected begin document"); + return; + } + + if(m_pState->HasAnchor() || m_pState->HasTag()) { + m_pState->SetError("Unexpected begin document"); + return; + } + + if(m_stream.col() > 0) + m_stream << "\n"; + m_stream << "...\n"; } // EmitBeginSeq @@ -183,6 +209,8 @@ namespace YAML { if(!good()) return; + + m_pState->BeginGroup(GroupType::Seq); } // EmitEndSeq @@ -190,6 +218,8 @@ namespace YAML { if(!good()) return; + + m_pState->EndGroup(GroupType::Seq); } // EmitBeginMap @@ -197,27 +227,18 @@ namespace YAML { if(!good()) return; + + m_pState->BeginGroup(GroupType::Map); } // EmitEndMap void Emitter::EmitEndMap() - { - if(!good()) - return; } - - // EmitKey - void Emitter::EmitKey() { if(!good()) return; - } - - // EmitValue - void Emitter::EmitValue() - { - if(!good()) - return; - } + + m_pState->EndGroup(GroupType::Map); + } // EmitNewline void Emitter::EmitNewline() @@ -238,6 +259,9 @@ namespace YAML { if(!good()) return *this; + + m_pState->BeginScalar(); + return *this; } @@ -291,6 +315,8 @@ namespace YAML if(!good()) return *this; + m_pState->BeginScalar(); + return *this; } @@ -299,6 +325,8 @@ namespace YAML if(!good()) return *this; + m_pState->BeginScalar(); + return *this; } @@ -307,6 +335,8 @@ namespace YAML if(!good()) return *this; + m_pState->BeginScalar(); + return *this; } @@ -315,6 +345,8 @@ namespace YAML if(!good()) return *this; + m_pState->BeginScalar(); + return *this; } @@ -323,6 +355,7 @@ namespace YAML if(!good()) return *this; + m_pState->BeginScalar(); return *this; } @@ -337,6 +370,8 @@ namespace YAML if(!good()) return *this; + m_pState->BeginScalar(); + return *this; } @@ -345,6 +380,8 @@ namespace YAML if(!good()) return *this; + m_pState->BeginScalar(); + return *this; } @@ -355,6 +392,8 @@ namespace YAML if(!good()) return *this; + m_pState->BeginScalar(); + return *this; } } diff --git a/src/emitterstate.cpp b/src/emitterstate.cpp index cc60ee6..f42e462 100644 --- a/src/emitterstate.cpp +++ b/src/emitterstate.cpp @@ -4,7 +4,7 @@ namespace YAML { - EmitterState::EmitterState(): m_isGood(true), m_curIndent(0) + EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_hasAnchor(false), m_hasTag(false) { // set default global manipulators m_charset.set(EmitNonAscii); @@ -43,8 +43,24 @@ namespace YAML SetMapKeyFormat(value, FmtScope::Local); } + void EmitterState::BeginNode() + { + if(!m_groups.empty()) + m_groups.top().childCount++; + + m_hasAnchor = false; + m_hasTag = false; + } + + void EmitterState::BeginScalar() + { + BeginNode(); + } + void EmitterState::BeginGroup(GroupType::value type) { + BeginNode(); + unsigned lastIndent = (m_groups.empty() ? 0 : m_groups.top().indent); m_curIndent += lastIndent; @@ -82,7 +98,7 @@ namespace YAML m_globalModifiedSettings.restore(); } - GroupType::value EmitterState::GetCurGroupType() const + GroupType::value EmitterState::CurGroupType() const { if(m_groups.empty()) return GroupType::None; @@ -90,7 +106,7 @@ namespace YAML return m_groups.top().type; } - FlowType::value EmitterState::GetCurGroupFlowType() const + FlowType::value EmitterState::CurGroupFlowType() const { if(m_groups.empty()) return FlowType::None; @@ -222,8 +238,7 @@ namespace YAML EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const { // force flow style if we're currently in a flow - FlowType::value flowType = GetCurGroupFlowType(); - if(flowType == FlowType::Flow) + if(CurGroupFlowType() == FlowType::Flow) return Flow; // otherwise, go with what's asked of us diff --git a/src/emitterstate.h b/src/emitterstate.h index 06aff62..92eabe8 100644 --- a/src/emitterstate.h +++ b/src/emitterstate.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace YAML { @@ -29,15 +30,18 @@ namespace YAML // basic state checking bool good() const { return m_isGood; } const std::string GetLastError() const { return m_lastError; } - void SetError(const std::string& error) { m_isGood = false; m_lastError = error; } + void SetError(const std::string& error) { throw std::runtime_error(error); m_isGood = false; m_lastError = error; } - // group handling + // node handling + void BeginScalar(); void BeginGroup(GroupType::value type); void EndGroup(GroupType::value type); - GroupType::value GetCurGroupType() const; - FlowType::value GetCurGroupFlowType() const; - int GetCurIndent() const { return m_curIndent; } + GroupType::value CurGroupType() const; + FlowType::value CurGroupFlowType() const; + int CurIndent() const { return m_curIndent; } + bool HasAnchor() const { return m_hasAnchor; } + bool HasTag() const { return m_hasTag; } void ClearModifiedSettings(); @@ -84,6 +88,8 @@ namespace YAML private: template void _Set(Setting& fmt, T value, FmtScope::value scope); + + void BeginNode(); private: // basic state ok? @@ -109,17 +115,20 @@ namespace YAML SettingChanges m_globalModifiedSettings; struct Group { - Group(GroupType::value type_): type(type_), indent(0) {} + explicit Group(GroupType::value type_): type(type_), indent(0), childCount(0) {} GroupType::value type; EMITTER_MANIP flow; int indent; + std::size_t childCount; SettingChanges modifiedSettings; }; ptr_stack m_groups; unsigned m_curIndent; + bool m_hasAnchor; + bool m_hasTag; }; template diff --git a/util/sandbox.cpp b/util/sandbox.cpp index e0979f2..3f1fa3e 100644 --- a/util/sandbox.cpp +++ b/util/sandbox.cpp @@ -4,14 +4,11 @@ int main() { YAML::Emitter out; + out << YAML::BeginDoc; out << YAML::BeginSeq; out << "foo"; - out << YAML::Comment("Skills"); - out << YAML::BeginMap; - out << YAML::Key << "attack" << YAML::Value << 23; - out << YAML::Key << "intelligence" << YAML::Value << 56; - out << YAML::EndMap; out << YAML::EndSeq; + out << YAML::EndDoc; std::cout << out.c_str() << "\n"; return 0;