Added explicit doc start/end tokens for the emitter, and set it so that if you try to write after you've already written a full doc, it writes a doc start and continues

This commit is contained in:
Jesse Beder
2011-03-03 09:26:12 +00:00
parent b9d4ccd254
commit cb632b3968
4 changed files with 82 additions and 2 deletions

View File

@@ -75,6 +75,8 @@ namespace YAML
void PostAtomicWrite();
void EmitSeparationIfNecessary();
void EmitBeginDoc();
void EmitEndDoc();
void EmitBeginSeq();
void EmitEndSeq();
void EmitBeginMap();

View File

@@ -41,6 +41,10 @@ namespace YAML
Hex,
Oct,
// document manipulators
BeginDoc,
EndDoc,
// sequence manipulators
BeginSeq,
EndSeq,

View File

@@ -102,6 +102,12 @@ namespace YAML
return *this;
switch(value) {
case BeginDoc:
EmitBeginDoc();
break;
case EndDoc:
EmitEndDoc();
break;
case BeginSeq:
EmitBeginSeq();
break;
@@ -157,8 +163,8 @@ namespace YAML
case ES_WRITING_DOC:
return true;
case ES_DONE_WITH_DOC:
m_pState->SetError("Write called on finished document");
return true;
EmitBeginDoc();
return false;
// block sequence
case ES_WAITING_FOR_BLOCK_SEQ_ENTRY:
@@ -320,6 +326,47 @@ namespace YAML
m_pState->UnsetSeparation();
}
// EmitBeginDoc
void Emitter::EmitBeginDoc()
{
if(!good())
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
void Emitter::EmitEndDoc()
{
if(!good())
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
void Emitter::EmitBeginSeq()
{

View File

@@ -776,6 +776,28 @@ namespace Test
"- ON\n- On\n- on\n- OFF\n- Off\n- off\n"
"- Y\n- Y\n- y\n- N\n- N\n- n";
}
void DocStartAndEnd(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginDoc;
out << YAML::BeginSeq << 1 << 2 << 3 << YAML::EndSeq;
out << YAML::BeginDoc;
out << "Hi there!";
out << YAML::EndDoc;
out << YAML::EndDoc;
out << YAML::EndDoc;
out << YAML::BeginDoc;
out << YAML::VerbatimTag("foo") << "bar";
desiredOutput = "---\n- 1\n- 2\n- 3\n---\nHi there!\n...\n...\n...\n---\n!<foo> bar";
}
void ImplicitDocStart(YAML::Emitter& out, std::string& desiredOutput)
{
out << "Hi";
out << "Bye";
out << "Oops";
desiredOutput = "Hi\n---\nBye\n---\nOops";
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
// incorrect emitting
@@ -870,6 +892,7 @@ namespace Test
std::string desiredOutput;
test(out, desiredOutput);
std::string output = out.c_str();
std::string lastError = out.GetLastError();
if(output == desiredOutput) {
try {
@@ -888,6 +911,8 @@ namespace Test
std::cout << output << "<<<\n";
std::cout << "Desired output:\n";
std::cout << desiredOutput << "<<<\n";
if(!out.good())
std::cout << "Emitter error: " << lastError << "\n";
}
total++;
}
@@ -978,6 +1003,8 @@ namespace Test
RunEmitterTest(&Emitter::ColonAtEndOfScalar, "colon at end of scalar", passed, total);
RunEmitterTest(&Emitter::ColonAsScalar, "colon as scalar", passed, total);
RunEmitterTest(&Emitter::BoolFormatting, "bool formatting", passed, total);
RunEmitterTest(&Emitter::DocStartAndEnd, "doc start and end", passed, total);
RunEmitterTest(&Emitter::ImplicitDocStart, "implicit doc start", passed, total);
RunEmitterErrorTest(&Emitter::ExtraEndSeq, "extra EndSeq", passed, total);
RunEmitterErrorTest(&Emitter::ExtraEndMap, "extra EndMap", passed, total);