mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 12:41:17 +00:00
Removed old emitter state machine
This commit is contained in:
@@ -70,21 +70,11 @@ namespace YAML
|
|||||||
Emitter& WriteStreamable(T value);
|
Emitter& WriteStreamable(T value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void PreWriteIntegralType(std::stringstream& str);
|
|
||||||
void PreWriteStreamable(std::stringstream& str);
|
|
||||||
void PostWriteIntegralType(const std::stringstream& str);
|
|
||||||
void PostWriteStreamable(const std::stringstream& str);
|
|
||||||
|
|
||||||
template<typename T> void SetStreamablePrecision(std::stringstream&) {}
|
template<typename T> void SetStreamablePrecision(std::stringstream&) {}
|
||||||
unsigned GetFloatPrecision() const;
|
unsigned GetFloatPrecision() const;
|
||||||
unsigned GetDoublePrecision() const;
|
unsigned GetDoublePrecision() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void PreAtomicWrite();
|
|
||||||
bool GotoNextPreAtomicState();
|
|
||||||
void PostAtomicWrite();
|
|
||||||
void EmitSeparationIfNecessary();
|
|
||||||
|
|
||||||
void EmitBeginDoc();
|
void EmitBeginDoc();
|
||||||
void EmitEndDoc();
|
void EmitEndDoc();
|
||||||
void EmitBeginSeq();
|
void EmitBeginSeq();
|
||||||
@@ -111,10 +101,6 @@ namespace YAML
|
|||||||
if(!good())
|
if(!good())
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
std::stringstream str;
|
|
||||||
PreWriteIntegralType(str);
|
|
||||||
str << value;
|
|
||||||
PostWriteIntegralType(str);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,11 +110,6 @@ namespace YAML
|
|||||||
if(!good())
|
if(!good())
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
std::stringstream str;
|
|
||||||
PreWriteStreamable(str);
|
|
||||||
SetStreamablePrecision<T>(str);
|
|
||||||
str << value;
|
|
||||||
PostWriteStreamable(str);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
539
src/emitter.cpp
539
src/emitter.cpp
@@ -164,207 +164,11 @@ namespace YAML
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GotoNextPreAtomicState
|
|
||||||
// . Runs the state machine, emitting if necessary, and returns 'true' if done (i.e., ready to emit an atom)
|
|
||||||
bool Emitter::GotoNextPreAtomicState()
|
|
||||||
{
|
|
||||||
if(!good())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
unsigned curIndent = m_pState->GetCurIndent();
|
|
||||||
|
|
||||||
EMITTER_STATE curState = m_pState->GetCurState();
|
|
||||||
switch(curState) {
|
|
||||||
// document-level
|
|
||||||
case ES_WAITING_FOR_DOC:
|
|
||||||
m_pState->SwitchState(ES_WRITING_DOC);
|
|
||||||
return true;
|
|
||||||
case ES_WRITING_DOC:
|
|
||||||
return true;
|
|
||||||
case ES_DONE_WITH_DOC:
|
|
||||||
EmitBeginDoc();
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// block sequence
|
|
||||||
case ES_WAITING_FOR_BLOCK_SEQ_ENTRY:
|
|
||||||
m_stream << IndentTo(curIndent) << "-";
|
|
||||||
m_pState->RequireSoftSeparation();
|
|
||||||
m_pState->SwitchState(ES_WRITING_BLOCK_SEQ_ENTRY);
|
|
||||||
return true;
|
|
||||||
case ES_WRITING_BLOCK_SEQ_ENTRY:
|
|
||||||
return true;
|
|
||||||
case ES_DONE_WITH_BLOCK_SEQ_ENTRY:
|
|
||||||
m_stream << '\n';
|
|
||||||
m_pState->SwitchState(ES_WAITING_FOR_BLOCK_SEQ_ENTRY);
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// flow sequence
|
|
||||||
case ES_WAITING_FOR_FLOW_SEQ_ENTRY:
|
|
||||||
m_pState->SwitchState(ES_WRITING_FLOW_SEQ_ENTRY);
|
|
||||||
return true;
|
|
||||||
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);
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// block map
|
|
||||||
case ES_WAITING_FOR_BLOCK_MAP_ENTRY:
|
|
||||||
m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN);
|
|
||||||
return true;
|
|
||||||
case ES_WAITING_FOR_BLOCK_MAP_KEY:
|
|
||||||
if(m_pState->CurrentlyInLongKey()) {
|
|
||||||
m_stream << IndentTo(curIndent) << '?';
|
|
||||||
m_pState->RequireSoftSeparation();
|
|
||||||
}
|
|
||||||
m_pState->SwitchState(ES_WRITING_BLOCK_MAP_KEY);
|
|
||||||
return true;
|
|
||||||
case ES_WRITING_BLOCK_MAP_KEY:
|
|
||||||
return true;
|
|
||||||
case ES_DONE_WITH_BLOCK_MAP_KEY:
|
|
||||||
m_pState->SetError(ErrorMsg::EXPECTED_VALUE_TOKEN);
|
|
||||||
return true;
|
|
||||||
case ES_WAITING_FOR_BLOCK_MAP_VALUE:
|
|
||||||
m_pState->SwitchState(ES_WRITING_BLOCK_MAP_VALUE);
|
|
||||||
return true;
|
|
||||||
case ES_WRITING_BLOCK_MAP_VALUE:
|
|
||||||
return true;
|
|
||||||
case ES_DONE_WITH_BLOCK_MAP_VALUE:
|
|
||||||
m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// flow map
|
|
||||||
case ES_WAITING_FOR_FLOW_MAP_ENTRY:
|
|
||||||
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()) {
|
|
||||||
m_stream << '?';
|
|
||||||
m_pState->RequireSoftSeparation();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
case ES_WRITING_FLOW_MAP_KEY:
|
|
||||||
return true;
|
|
||||||
case ES_DONE_WITH_FLOW_MAP_KEY:
|
|
||||||
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);
|
|
||||||
return true;
|
|
||||||
case ES_WRITING_FLOW_MAP_VALUE:
|
|
||||||
return true;
|
|
||||||
case ES_DONE_WITH_FLOW_MAP_VALUE:
|
|
||||||
m_pState->SetError(ErrorMsg::EXPECTED_KEY_TOKEN);
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(false);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PreAtomicWrite
|
|
||||||
// . Depending on the emitter state, write to the stream to get it
|
|
||||||
// in position to do an atomic write (e.g., scalar, sequence, or map)
|
|
||||||
void Emitter::PreAtomicWrite()
|
|
||||||
{
|
|
||||||
if(!good())
|
|
||||||
return;
|
|
||||||
|
|
||||||
while(!GotoNextPreAtomicState())
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PostAtomicWrite
|
|
||||||
// . Clean up
|
|
||||||
void Emitter::PostAtomicWrite()
|
|
||||||
{
|
|
||||||
if(!good())
|
|
||||||
return;
|
|
||||||
|
|
||||||
EMITTER_STATE curState = m_pState->GetCurState();
|
|
||||||
switch(curState) {
|
|
||||||
// document-level
|
|
||||||
case ES_WRITING_DOC:
|
|
||||||
m_pState->SwitchState(ES_DONE_WITH_DOC);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// block seq
|
|
||||||
case ES_WRITING_BLOCK_SEQ_ENTRY:
|
|
||||||
m_pState->SwitchState(ES_DONE_WITH_BLOCK_SEQ_ENTRY);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// flow seq
|
|
||||||
case ES_WRITING_FLOW_SEQ_ENTRY:
|
|
||||||
m_pState->SwitchState(ES_DONE_WITH_FLOW_SEQ_ENTRY);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// block map
|
|
||||||
case ES_WRITING_BLOCK_MAP_KEY:
|
|
||||||
if(!m_pState->CurrentlyInLongKey()) {
|
|
||||||
m_stream << ':';
|
|
||||||
m_pState->RequireSoftSeparation();
|
|
||||||
}
|
|
||||||
m_pState->SwitchState(ES_DONE_WITH_BLOCK_MAP_KEY);
|
|
||||||
break;
|
|
||||||
case ES_WRITING_BLOCK_MAP_VALUE:
|
|
||||||
m_pState->SwitchState(ES_DONE_WITH_BLOCK_MAP_VALUE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// flow map
|
|
||||||
case ES_WRITING_FLOW_MAP_KEY:
|
|
||||||
m_pState->SwitchState(ES_DONE_WITH_FLOW_MAP_KEY);
|
|
||||||
break;
|
|
||||||
case ES_WRITING_FLOW_MAP_VALUE:
|
|
||||||
m_pState->SwitchState(ES_DONE_WITH_FLOW_MAP_VALUE);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
m_pState->ClearModifiedSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
// EmitSeparationIfNecessary
|
|
||||||
void Emitter::EmitSeparationIfNecessary()
|
|
||||||
{
|
|
||||||
if(!good())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(m_pState->RequiresSoftSeparation())
|
|
||||||
m_stream << ' ';
|
|
||||||
else if(m_pState->RequiresHardSeparation())
|
|
||||||
m_stream << '\n';
|
|
||||||
m_pState->UnsetSeparation();
|
|
||||||
}
|
|
||||||
|
|
||||||
// EmitBeginDoc
|
// EmitBeginDoc
|
||||||
void Emitter::EmitBeginDoc()
|
void Emitter::EmitBeginDoc()
|
||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EMITTER_STATE curState = m_pState->GetCurState();
|
|
||||||
if(curState != ES_WAITING_FOR_DOC && curState != ES_WRITING_DOC && curState != ES_DONE_WITH_DOC) {
|
|
||||||
m_pState->SetError("Unexpected begin document");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(curState == ES_WRITING_DOC || curState == ES_DONE_WITH_DOC)
|
|
||||||
m_stream << '\n';
|
|
||||||
m_stream << "---\n";
|
|
||||||
|
|
||||||
m_pState->UnsetSeparation();
|
|
||||||
m_pState->SwitchState(ES_WAITING_FOR_DOC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmitEndDoc
|
// EmitEndDoc
|
||||||
@@ -372,20 +176,6 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
EMITTER_STATE curState = m_pState->GetCurState();
|
|
||||||
if(curState != ES_WAITING_FOR_DOC && curState != ES_WRITING_DOC && curState != ES_DONE_WITH_DOC) {
|
|
||||||
m_pState->SetError("Unexpected end document");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(curState == ES_WRITING_DOC || curState == ES_DONE_WITH_DOC)
|
|
||||||
m_stream << '\n';
|
|
||||||
m_stream << "...\n";
|
|
||||||
|
|
||||||
m_pState->UnsetSeparation();
|
|
||||||
m_pState->SwitchState(ES_WAITING_FOR_DOC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmitBeginSeq
|
// EmitBeginSeq
|
||||||
@@ -393,33 +183,6 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// must have a long key if we're emitting a sequence
|
|
||||||
m_pState->StartLongKey();
|
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
|
|
||||||
EMITTER_STATE curState = m_pState->GetCurState();
|
|
||||||
EMITTER_MANIP flowType = m_pState->GetFlowType(GroupType::Seq);
|
|
||||||
if(flowType == Block) {
|
|
||||||
if(curState == ES_WRITING_BLOCK_SEQ_ENTRY ||
|
|
||||||
curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE ||
|
|
||||||
curState == ES_WRITING_DOC
|
|
||||||
) {
|
|
||||||
if(m_pState->RequiresHardSeparation() || curState != ES_WRITING_DOC) {
|
|
||||||
m_stream << "\n";
|
|
||||||
m_pState->UnsetSeparation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_pState->PushState(ES_WAITING_FOR_BLOCK_SEQ_ENTRY);
|
|
||||||
} else if(flowType == Flow) {
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
m_stream << "[";
|
|
||||||
m_pState->PushState(ES_WAITING_FOR_FLOW_SEQ_ENTRY);
|
|
||||||
} else
|
|
||||||
assert(false);
|
|
||||||
|
|
||||||
m_pState->BeginGroup(GroupType::Seq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmitEndSeq
|
// EmitEndSeq
|
||||||
@@ -427,35 +190,6 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(m_pState->GetCurGroupType() != GroupType::Seq)
|
|
||||||
return m_pState->SetError(ErrorMsg::UNEXPECTED_END_SEQ);
|
|
||||||
|
|
||||||
EMITTER_STATE curState = m_pState->GetCurState();
|
|
||||||
FlowType::value flowType = m_pState->GetCurGroupFlowType();
|
|
||||||
if(flowType == FlowType::Block) {
|
|
||||||
// Note: block sequences are *not* allowed to be empty, but we convert it
|
|
||||||
// to a flow sequence if it is
|
|
||||||
assert(curState == ES_DONE_WITH_BLOCK_SEQ_ENTRY || curState == ES_WAITING_FOR_BLOCK_SEQ_ENTRY);
|
|
||||||
if(curState == ES_WAITING_FOR_BLOCK_SEQ_ENTRY) {
|
|
||||||
// Note: only one of these will actually output anything for a given situation
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
unsigned curIndent = m_pState->GetCurIndent();
|
|
||||||
m_stream << IndentTo(curIndent);
|
|
||||||
|
|
||||||
m_stream << "[]";
|
|
||||||
}
|
|
||||||
} else if(flowType == FlowType::Flow) {
|
|
||||||
// Note: flow sequences are allowed to be empty
|
|
||||||
assert(curState == ES_DONE_WITH_FLOW_SEQ_ENTRY || curState == ES_WAITING_FOR_FLOW_SEQ_ENTRY);
|
|
||||||
m_stream << "]";
|
|
||||||
} else
|
|
||||||
assert(false);
|
|
||||||
|
|
||||||
m_pState->PopState();
|
|
||||||
m_pState->EndGroup(GroupType::Seq);
|
|
||||||
|
|
||||||
PostAtomicWrite();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmitBeginMap
|
// EmitBeginMap
|
||||||
@@ -463,106 +197,19 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// must have a long key if we're emitting a map
|
|
||||||
m_pState->StartLongKey();
|
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
|
|
||||||
EMITTER_STATE curState = m_pState->GetCurState();
|
|
||||||
EMITTER_MANIP flowType = m_pState->GetFlowType(GroupType::Map);
|
|
||||||
if(flowType == Block) {
|
|
||||||
if(curState == ES_WRITING_BLOCK_SEQ_ENTRY ||
|
|
||||||
curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE ||
|
|
||||||
curState == ES_WRITING_DOC
|
|
||||||
) {
|
|
||||||
if(m_pState->RequiresHardSeparation() || (curState != ES_WRITING_DOC && 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) {
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
m_stream << "{";
|
|
||||||
m_pState->PushState(ES_WAITING_FOR_FLOW_MAP_ENTRY);
|
|
||||||
} else
|
|
||||||
assert(false);
|
|
||||||
|
|
||||||
m_pState->BeginGroup(GroupType::Map);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmitEndMap
|
// EmitEndMap
|
||||||
void Emitter::EmitEndMap()
|
void Emitter::EmitEndMap()
|
||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return;
|
return; }
|
||||||
|
|
||||||
if(m_pState->GetCurGroupType() != GroupType::Map)
|
|
||||||
return m_pState->SetError(ErrorMsg::UNEXPECTED_END_MAP);
|
|
||||||
|
|
||||||
EMITTER_STATE curState = m_pState->GetCurState();
|
|
||||||
FlowType::value flowType = m_pState->GetCurGroupFlowType();
|
|
||||||
if(flowType == FlowType::Block) {
|
|
||||||
// Note: block sequences are *not* allowed to be empty, but we convert it
|
|
||||||
// to a flow sequence if it is
|
|
||||||
assert(curState == ES_DONE_WITH_BLOCK_MAP_VALUE || curState == ES_WAITING_FOR_BLOCK_MAP_ENTRY);
|
|
||||||
if(curState == ES_WAITING_FOR_BLOCK_MAP_ENTRY) {
|
|
||||||
// Note: only one of these will actually output anything for a given situation
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
unsigned curIndent = m_pState->GetCurIndent();
|
|
||||||
m_stream << IndentTo(curIndent);
|
|
||||||
m_stream << "{}";
|
|
||||||
}
|
|
||||||
} else if(flowType == FlowType::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);
|
|
||||||
|
|
||||||
m_pState->PopState();
|
|
||||||
m_pState->EndGroup(GroupType::Map);
|
|
||||||
|
|
||||||
PostAtomicWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
// EmitKey
|
// EmitKey
|
||||||
void Emitter::EmitKey()
|
void Emitter::EmitKey()
|
||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EMITTER_STATE curState = m_pState->GetCurState();
|
|
||||||
FlowType::value flowType = m_pState->GetCurGroupFlowType();
|
|
||||||
if(curState != ES_WAITING_FOR_BLOCK_MAP_ENTRY && curState != ES_DONE_WITH_BLOCK_MAP_VALUE
|
|
||||||
&& curState != ES_WAITING_FOR_FLOW_MAP_ENTRY && curState != ES_DONE_WITH_FLOW_MAP_VALUE)
|
|
||||||
return m_pState->SetError(ErrorMsg::UNEXPECTED_KEY_TOKEN);
|
|
||||||
|
|
||||||
if(flowType == FlowType::Block) {
|
|
||||||
if(curState == ES_DONE_WITH_BLOCK_MAP_VALUE)
|
|
||||||
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 == FlowType::Flow) {
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
if(curState == ES_DONE_WITH_FLOW_MAP_VALUE) {
|
|
||||||
m_stream << ',';
|
|
||||||
m_pState->RequireSoftSeparation();
|
|
||||||
}
|
|
||||||
m_pState->SwitchState(ES_WAITING_FOR_FLOW_MAP_KEY);
|
|
||||||
} else
|
|
||||||
assert(false);
|
|
||||||
|
|
||||||
if(m_pState->GetMapKeyFormat() == LongKey)
|
|
||||||
m_pState->StartLongKey();
|
|
||||||
else if(m_pState->GetMapKeyFormat() == Auto)
|
|
||||||
m_pState->StartSimpleKey();
|
|
||||||
else
|
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmitValue
|
// EmitValue
|
||||||
@@ -570,24 +217,6 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EMITTER_STATE curState = m_pState->GetCurState();
|
|
||||||
FlowType::value flowType = m_pState->GetCurGroupFlowType();
|
|
||||||
if(curState != ES_DONE_WITH_BLOCK_MAP_KEY && curState != ES_DONE_WITH_FLOW_MAP_KEY)
|
|
||||||
return m_pState->SetError(ErrorMsg::UNEXPECTED_VALUE_TOKEN);
|
|
||||||
|
|
||||||
if(flowType == FlowType::Block) {
|
|
||||||
if(m_pState->CurrentlyInLongKey()) {
|
|
||||||
m_stream << '\n';
|
|
||||||
m_stream << IndentTo(m_pState->GetCurIndent());
|
|
||||||
m_stream << ':';
|
|
||||||
m_pState->RequireSoftSeparation();
|
|
||||||
}
|
|
||||||
m_pState->SwitchState(ES_WAITING_FOR_BLOCK_MAP_VALUE);
|
|
||||||
} else if(flowType == FlowType::Flow) {
|
|
||||||
m_pState->SwitchState(ES_WAITING_FOR_FLOW_MAP_VALUE);
|
|
||||||
} else
|
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EmitNewline
|
// EmitNewline
|
||||||
@@ -595,21 +224,11 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(CanEmitNewline()) {
|
|
||||||
m_stream << '\n';
|
|
||||||
m_pState->UnsetSeparation();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Emitter::CanEmitNewline() const
|
bool Emitter::CanEmitNewline() const
|
||||||
{
|
{
|
||||||
FlowType::value flowType = m_pState->GetCurGroupFlowType();
|
return false;
|
||||||
if(flowType == FlowType::Block && m_pState->CurrentlyInLongKey())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
EMITTER_STATE curState = m_pState->GetCurState();
|
|
||||||
return curState != ES_DONE_WITH_BLOCK_MAP_KEY && curState != ES_WAITING_FOR_BLOCK_MAP_VALUE && curState != ES_WRITING_BLOCK_MAP_VALUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// *******************************************************************************************
|
// *******************************************************************************************
|
||||||
@@ -619,75 +238,9 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
// literal scalars must use long keys
|
|
||||||
if(m_pState->GetStringFormat() == Literal && m_pState->GetCurGroupFlowType() != FlowType::Flow)
|
|
||||||
m_pState->StartLongKey();
|
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
|
|
||||||
bool escapeNonAscii = m_pState->GetOutputCharset() == EscapeNonAscii;
|
|
||||||
EMITTER_MANIP strFmt = m_pState->GetStringFormat();
|
|
||||||
FlowType::value flowType = m_pState->GetCurGroupFlowType();
|
|
||||||
unsigned curIndent = m_pState->GetCurIndent();
|
|
||||||
|
|
||||||
switch(strFmt) {
|
|
||||||
case Auto:
|
|
||||||
Utils::WriteString(m_stream, str, flowType == FlowType::Flow, escapeNonAscii);
|
|
||||||
break;
|
|
||||||
case SingleQuoted:
|
|
||||||
if(!Utils::WriteSingleQuotedString(m_stream, str)) {
|
|
||||||
m_pState->SetError(ErrorMsg::SINGLE_QUOTED_CHAR);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DoubleQuoted:
|
|
||||||
Utils::WriteDoubleQuotedString(m_stream, str, escapeNonAscii);
|
|
||||||
break;
|
|
||||||
case Literal:
|
|
||||||
if(flowType == FlowType::Flow)
|
|
||||||
Utils::WriteString(m_stream, str, flowType == FlowType::Flow, escapeNonAscii);
|
|
||||||
else
|
|
||||||
Utils::WriteLiteralString(m_stream, str, curIndent + m_pState->GetIndent());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
PostAtomicWrite();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Emitter::PreWriteIntegralType(std::stringstream& str)
|
|
||||||
{
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
|
|
||||||
EMITTER_MANIP intFmt = m_pState->GetIntFormat();
|
|
||||||
switch(intFmt) {
|
|
||||||
case Dec:
|
|
||||||
str << std::dec;
|
|
||||||
break;
|
|
||||||
case Hex:
|
|
||||||
str << "0x";
|
|
||||||
str << std::hex;
|
|
||||||
break;
|
|
||||||
case Oct:
|
|
||||||
str << "0";
|
|
||||||
str << std::oct;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Emitter::PreWriteStreamable(std::stringstream&)
|
|
||||||
{
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned Emitter::GetFloatPrecision() const
|
unsigned Emitter::GetFloatPrecision() const
|
||||||
{
|
{
|
||||||
return m_pState->GetFloatPrecision();
|
return m_pState->GetFloatPrecision();
|
||||||
@@ -698,18 +251,6 @@ namespace YAML
|
|||||||
return m_pState->GetDoublePrecision();
|
return m_pState->GetDoublePrecision();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Emitter::PostWriteIntegralType(const std::stringstream& str)
|
|
||||||
{
|
|
||||||
m_stream << str.str();
|
|
||||||
PostAtomicWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Emitter::PostWriteStreamable(const std::stringstream& str)
|
|
||||||
{
|
|
||||||
m_stream << str.str();
|
|
||||||
PostAtomicWrite();
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *Emitter::ComputeFullBoolName(bool b) const
|
const char *Emitter::ComputeFullBoolName(bool b) const
|
||||||
{
|
{
|
||||||
const EMITTER_MANIP mainFmt = (m_pState->GetBoolLengthFormat() == ShortBool ? YesNoBool : m_pState->GetBoolFormat());
|
const EMITTER_MANIP mainFmt = (m_pState->GetBoolLengthFormat() == ShortBool ? YesNoBool : m_pState->GetBoolFormat());
|
||||||
@@ -749,17 +290,7 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
|
|
||||||
const char *name = ComputeFullBoolName(b);
|
|
||||||
if(m_pState->GetBoolLengthFormat() == ShortBool)
|
|
||||||
m_stream << name[0];
|
|
||||||
else
|
|
||||||
m_stream << name;
|
|
||||||
|
|
||||||
PostAtomicWrite();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -767,13 +298,7 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
|
|
||||||
Utils::WriteChar(m_stream, ch);
|
|
||||||
|
|
||||||
PostAtomicWrite();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -781,14 +306,7 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
if(!Utils::WriteAlias(m_stream, alias.content)) {
|
|
||||||
m_pState->SetError(ErrorMsg::INVALID_ALIAS);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
PostAtomicWrite();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -796,15 +314,7 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
if(!Utils::WriteAnchor(m_stream, anchor.content)) {
|
|
||||||
m_pState->SetError(ErrorMsg::INVALID_ANCHOR);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
m_pState->RequireHardSeparation();
|
|
||||||
// Note: no PostAtomicWrite() because we need another value for this node
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -813,24 +323,7 @@ namespace YAML
|
|||||||
if(!good())
|
if(!good())
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
|
|
||||||
bool success = false;
|
|
||||||
if(tag.type == _Tag::Type::Verbatim)
|
|
||||||
success = Utils::WriteTag(m_stream, tag.content, true);
|
|
||||||
else if(tag.type == _Tag::Type::PrimaryHandle)
|
|
||||||
success = Utils::WriteTag(m_stream, tag.content, false);
|
|
||||||
else
|
|
||||||
success = Utils::WriteTagWithPrefix(m_stream, tag.prefix, tag.content);
|
|
||||||
|
|
||||||
if(!success) {
|
|
||||||
m_pState->SetError(ErrorMsg::INVALID_TAG);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pState->RequireHardSeparation();
|
|
||||||
// Note: no PostAtomicWrite() because we need another value for this node
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -843,13 +336,7 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -857,11 +344,7 @@ namespace YAML
|
|||||||
{
|
{
|
||||||
if(!good())
|
if(!good())
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
m_stream << "~";
|
|
||||||
PostAtomicWrite();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -871,11 +354,7 @@ namespace YAML
|
|||||||
|
|
||||||
if(!good())
|
if(!good())
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
PreAtomicWrite();
|
|
||||||
EmitSeparationIfNecessary();
|
|
||||||
Utils::WriteBinary(m_stream, binary);
|
|
||||||
PostAtomicWrite();
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,11 +4,8 @@
|
|||||||
|
|
||||||
namespace YAML
|
namespace YAML
|
||||||
{
|
{
|
||||||
EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_requiresSoftSeparation(false), m_requiresHardSeparation(false)
|
EmitterState::EmitterState(): m_isGood(true), m_curIndent(0)
|
||||||
{
|
{
|
||||||
// start up
|
|
||||||
m_stateStack.push(ES_WAITING_FOR_DOC);
|
|
||||||
|
|
||||||
// set default global manipulators
|
// set default global manipulators
|
||||||
m_charset.set(EmitNonAscii);
|
m_charset.set(EmitNonAscii);
|
||||||
m_strFmt.set(Auto);
|
m_strFmt.set(Auto);
|
||||||
@@ -59,7 +56,6 @@ namespace YAML
|
|||||||
// set up group
|
// set up group
|
||||||
pGroup->flow = GetFlowType(type);
|
pGroup->flow = GetFlowType(type);
|
||||||
pGroup->indent = GetIndent();
|
pGroup->indent = GetIndent();
|
||||||
pGroup->usingLongKey = (GetMapKeyFormat() == LongKey ? true : false);
|
|
||||||
|
|
||||||
m_groups.push(pGroup);
|
m_groups.push(pGroup);
|
||||||
}
|
}
|
||||||
@@ -101,25 +97,6 @@ namespace YAML
|
|||||||
|
|
||||||
return (m_groups.top().flow == Flow ? FlowType::Flow : FlowType::Block);
|
return (m_groups.top().flow == Flow ? FlowType::Flow : FlowType::Block);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmitterState::CurrentlyInLongKey()
|
|
||||||
{
|
|
||||||
if(m_groups.empty())
|
|
||||||
return false;
|
|
||||||
return m_groups.top().usingLongKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitterState::StartLongKey()
|
|
||||||
{
|
|
||||||
if(!m_groups.empty())
|
|
||||||
m_groups.top().usingLongKey = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitterState::StartSimpleKey()
|
|
||||||
{
|
|
||||||
if(!m_groups.empty())
|
|
||||||
m_groups.top().usingLongKey = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmitterState::ClearModifiedSettings()
|
void EmitterState::ClearModifiedSettings()
|
||||||
{
|
{
|
||||||
|
@@ -20,46 +20,6 @@ namespace YAML
|
|||||||
struct GroupType { enum value { None, Seq, Map }; };
|
struct GroupType { enum value { None, Seq, Map }; };
|
||||||
struct FlowType { enum value { None, Flow, Block }; };
|
struct FlowType { enum value { None, Flow, Block }; };
|
||||||
|
|
||||||
enum NODE_STATE {
|
|
||||||
NS_START,
|
|
||||||
NS_READY_FOR_ATOM,
|
|
||||||
NS_END
|
|
||||||
};
|
|
||||||
|
|
||||||
enum EMITTER_STATE {
|
|
||||||
ES_WAITING_FOR_DOC,
|
|
||||||
ES_WRITING_DOC,
|
|
||||||
ES_DONE_WITH_DOC,
|
|
||||||
|
|
||||||
// block seq
|
|
||||||
ES_WAITING_FOR_BLOCK_SEQ_ENTRY,
|
|
||||||
ES_WRITING_BLOCK_SEQ_ENTRY,
|
|
||||||
ES_DONE_WITH_BLOCK_SEQ_ENTRY,
|
|
||||||
|
|
||||||
// flow seq
|
|
||||||
ES_WAITING_FOR_FLOW_SEQ_ENTRY,
|
|
||||||
ES_WRITING_FLOW_SEQ_ENTRY,
|
|
||||||
ES_DONE_WITH_FLOW_SEQ_ENTRY,
|
|
||||||
|
|
||||||
// block map
|
|
||||||
ES_WAITING_FOR_BLOCK_MAP_ENTRY,
|
|
||||||
ES_WAITING_FOR_BLOCK_MAP_KEY,
|
|
||||||
ES_WRITING_BLOCK_MAP_KEY,
|
|
||||||
ES_DONE_WITH_BLOCK_MAP_KEY,
|
|
||||||
ES_WAITING_FOR_BLOCK_MAP_VALUE,
|
|
||||||
ES_WRITING_BLOCK_MAP_VALUE,
|
|
||||||
ES_DONE_WITH_BLOCK_MAP_VALUE,
|
|
||||||
|
|
||||||
// flow map
|
|
||||||
ES_WAITING_FOR_FLOW_MAP_ENTRY,
|
|
||||||
ES_WAITING_FOR_FLOW_MAP_KEY,
|
|
||||||
ES_WRITING_FLOW_MAP_KEY,
|
|
||||||
ES_DONE_WITH_FLOW_MAP_KEY,
|
|
||||||
ES_WAITING_FOR_FLOW_MAP_VALUE,
|
|
||||||
ES_WRITING_FLOW_MAP_VALUE,
|
|
||||||
ES_DONE_WITH_FLOW_MAP_VALUE
|
|
||||||
};
|
|
||||||
|
|
||||||
class EmitterState
|
class EmitterState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -71,14 +31,6 @@ namespace YAML
|
|||||||
const std::string GetLastError() const { return m_lastError; }
|
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) { m_isGood = false; m_lastError = error; }
|
||||||
|
|
||||||
// main state of the machine
|
|
||||||
EMITTER_STATE GetCurState() const { return m_stateStack.top(); }
|
|
||||||
void SwitchState(EMITTER_STATE state) { PopState(); PushState(state); }
|
|
||||||
void PushState(EMITTER_STATE state) { m_stateStack.push(state); }
|
|
||||||
void PopState() { m_stateStack.pop(); }
|
|
||||||
|
|
||||||
void SetLocalValue(EMITTER_MANIP value);
|
|
||||||
|
|
||||||
// group handling
|
// group handling
|
||||||
void BeginGroup(GroupType::value type);
|
void BeginGroup(GroupType::value type);
|
||||||
void EndGroup(GroupType::value type);
|
void EndGroup(GroupType::value type);
|
||||||
@@ -86,21 +38,12 @@ namespace YAML
|
|||||||
GroupType::value GetCurGroupType() const;
|
GroupType::value GetCurGroupType() const;
|
||||||
FlowType::value GetCurGroupFlowType() const;
|
FlowType::value GetCurGroupFlowType() const;
|
||||||
int GetCurIndent() const { return m_curIndent; }
|
int GetCurIndent() const { return m_curIndent; }
|
||||||
|
|
||||||
bool CurrentlyInLongKey();
|
|
||||||
void StartLongKey();
|
|
||||||
void StartSimpleKey();
|
|
||||||
|
|
||||||
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();
|
void ClearModifiedSettings();
|
||||||
|
|
||||||
// formatters
|
// formatters
|
||||||
|
void SetLocalValue(EMITTER_MANIP value);
|
||||||
|
|
||||||
bool SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope);
|
bool SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope);
|
||||||
EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); }
|
EMITTER_MANIP GetOutputCharset() const { return m_charset.get(); }
|
||||||
|
|
||||||
@@ -148,8 +91,6 @@ namespace YAML
|
|||||||
std::string m_lastError;
|
std::string m_lastError;
|
||||||
|
|
||||||
// other state
|
// other state
|
||||||
std::stack<EMITTER_STATE> m_stateStack;
|
|
||||||
|
|
||||||
Setting<EMITTER_MANIP> m_charset;
|
Setting<EMITTER_MANIP> m_charset;
|
||||||
Setting<EMITTER_MANIP> m_strFmt;
|
Setting<EMITTER_MANIP> m_strFmt;
|
||||||
Setting<EMITTER_MANIP> m_boolFmt;
|
Setting<EMITTER_MANIP> m_boolFmt;
|
||||||
@@ -168,11 +109,10 @@ namespace YAML
|
|||||||
SettingChanges m_globalModifiedSettings;
|
SettingChanges m_globalModifiedSettings;
|
||||||
|
|
||||||
struct Group {
|
struct Group {
|
||||||
Group(GroupType::value type_): type(type_), usingLongKey(false), indent(0) {}
|
Group(GroupType::value type_): type(type_), indent(0) {}
|
||||||
|
|
||||||
GroupType::value type;
|
GroupType::value type;
|
||||||
EMITTER_MANIP flow;
|
EMITTER_MANIP flow;
|
||||||
bool usingLongKey;
|
|
||||||
int indent;
|
int indent;
|
||||||
|
|
||||||
SettingChanges modifiedSettings;
|
SettingChanges modifiedSettings;
|
||||||
@@ -180,8 +120,6 @@ namespace YAML
|
|||||||
|
|
||||||
ptr_stack<Group> m_groups;
|
ptr_stack<Group> m_groups;
|
||||||
unsigned m_curIndent;
|
unsigned m_curIndent;
|
||||||
bool m_requiresSoftSeparation;
|
|
||||||
bool m_requiresHardSeparation;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
Reference in New Issue
Block a user