From 39c396ab0183d794b3de1a092581c6d1c99c3e03 Mon Sep 17 00:00:00 2001 From: Jesse Beder Date: Wed, 2 Mar 2011 20:55:05 +0000 Subject: [PATCH] Refactored bool emitting to make it 1) correct for the short bool form and 2) not barf on early versions of VS --- include/yaml-cpp/emitter.h | 1 + src/emitter.cpp | 68 +++++++++++++++++++++++--------------- test/emittertests.cpp | 36 ++++++++++++++++++++ 3 files changed, 79 insertions(+), 26 deletions(-) diff --git a/include/yaml-cpp/emitter.h b/include/yaml-cpp/emitter.h index ef362bb..f7ec3e1 100644 --- a/include/yaml-cpp/emitter.h +++ b/include/yaml-cpp/emitter.h @@ -85,6 +85,7 @@ namespace YAML void EmitKindTag(); void EmitTag(bool verbatim, const _Tag& tag); + const char *ComputeFullBoolName(bool b) const; bool CanEmitNewline() const; private: diff --git a/src/emitter.cpp b/src/emitter.cpp index 03555ea..eb9c339 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -606,12 +606,45 @@ namespace YAML PostAtomicWrite(); } - namespace { - struct BoolName { std::string trueName, falseName; }; - struct BoolFormatNames { BoolName upper, lower, camel; }; - struct BoolTypes { BoolFormatNames yesNo, trueFalse, onOff; }; + const char *Emitter::ComputeFullBoolName(bool b) const + { + const EMITTER_MANIP mainFmt = (m_pState->GetBoolLengthFormat() == ShortBool ? YesNoBool : m_pState->GetBoolFormat()); + const EMITTER_MANIP caseFmt = m_pState->GetBoolCaseFormat(); + switch(mainFmt) { + case YesNoBool: + switch(caseFmt) { + case UpperCase: + return b ? "YES" : "NO"; + case CamelCase: + return b ? "Yes" : "No"; + case LowerCase: // fall through to default + default: + return b ? "yes" : "no"; + } + case OnOffBool: + switch(caseFmt) { + case UpperCase: + return b ? "ON" : "OFF"; + case CamelCase: + return b ? "On" : "Off"; + case LowerCase: // fall through to default + default: + return b ? "on" : "off"; + } + case TrueFalseBool: // fall through to default + default: + switch(caseFmt) { + case UpperCase: + return b ? "TRUE" : "FALSE"; + case CamelCase: + return b ? "True" : "False"; + case LowerCase: // fall through to default + default: + return b ? "true" : "false"; + } + } } - + Emitter& Emitter::Write(bool b) { if(!good()) @@ -619,30 +652,13 @@ namespace YAML PreAtomicWrite(); EmitSeparationIfNecessary(); - - // set up all possible bools to write - static const BoolTypes boolTypes = { - { { "YES", "NO" }, { "yes", "no" }, { "Yes", "No" } }, - { { "TRUE", "FALSE" }, { "true", "false" }, { "True", "False" } }, - { { "ON", "OFF" }, { "on", "off" }, { "On", "Off" } } - }; - - // select the right one - EMITTER_MANIP boolFmt = m_pState->GetBoolFormat(); - EMITTER_MANIP boolLengthFmt = m_pState->GetBoolLengthFormat(); - EMITTER_MANIP boolCaseFmt = m_pState->GetBoolCaseFormat(); - - const BoolFormatNames& fmtNames = (boolFmt == YesNoBool ? boolTypes.yesNo : boolFmt == TrueFalseBool ? boolTypes.trueFalse : boolTypes.onOff); - const BoolName& boolName = (boolCaseFmt == UpperCase ? fmtNames.upper : boolCaseFmt == LowerCase ? fmtNames.lower : fmtNames.camel); - const std::string& name = (b ? boolName.trueName : boolName.falseName); - - // and say it! - // TODO: should we disallow writing OnOffBool with ShortBool? (it'll just print "o" for both, which is silly) - if(boolLengthFmt == ShortBool) + + const char *name = ComputeFullBoolName(b); + if(m_pState->GetBoolLengthFormat() == ShortBool) m_stream << name[0]; else m_stream << name; - + PostAtomicWrite(); return *this; } diff --git a/test/emittertests.cpp b/test/emittertests.cpp index b81ab68..16f8764 100644 --- a/test/emittertests.cpp +++ b/test/emittertests.cpp @@ -741,6 +741,41 @@ namespace Test out << YAML::EndMap; desiredOutput = "---\napple: \":\"\nbanana: \":\""; } + + void BoolFormatting(YAML::Emitter& out, std::string& desiredOutput) + { + out << YAML::BeginSeq; + out << YAML::TrueFalseBool << YAML::UpperCase << true; + out << YAML::TrueFalseBool << YAML::CamelCase << true; + out << YAML::TrueFalseBool << YAML::LowerCase << true; + out << YAML::TrueFalseBool << YAML::UpperCase << false; + out << YAML::TrueFalseBool << YAML::CamelCase << false; + out << YAML::TrueFalseBool << YAML::LowerCase << false; + out << YAML::YesNoBool << YAML::UpperCase << true; + out << YAML::YesNoBool << YAML::CamelCase << true; + out << YAML::YesNoBool << YAML::LowerCase << true; + out << YAML::YesNoBool << YAML::UpperCase << false; + out << YAML::YesNoBool << YAML::CamelCase << false; + out << YAML::YesNoBool << YAML::LowerCase << false; + out << YAML::OnOffBool << YAML::UpperCase << true; + out << YAML::OnOffBool << YAML::CamelCase << true; + out << YAML::OnOffBool << YAML::LowerCase << true; + out << YAML::OnOffBool << YAML::UpperCase << false; + out << YAML::OnOffBool << YAML::CamelCase << false; + out << YAML::OnOffBool << YAML::LowerCase << false; + out << YAML::ShortBool << YAML::UpperCase << true; + out << YAML::ShortBool << YAML::CamelCase << true; + out << YAML::ShortBool << YAML::LowerCase << true; + out << YAML::ShortBool << YAML::UpperCase << false; + out << YAML::ShortBool << YAML::CamelCase << false; + out << YAML::ShortBool << YAML::LowerCase << false; + out << YAML::EndSeq; + desiredOutput = + "---\n- TRUE\n- True\n- true\n- FALSE\n- False\n- false\n" + "- YES\n- Yes\n- yes\n- NO\n- No\n- no\n" + "- ON\n- On\n- on\n- OFF\n- Off\n- off\n" + "- Y\n- Y\n- y\n- N\n- N\n- n"; + } //////////////////////////////////////////////////////////////////////////////////////////////////////// // incorrect emitting @@ -933,6 +968,7 @@ namespace Test RunEmitterTest(&Emitter::EmptyBinary, "empty binary", passed, total); 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); RunEmitterErrorTest(&Emitter::ExtraEndSeq, "extra EndSeq", passed, total); RunEmitterErrorTest(&Emitter::ExtraEndMap, "extra EndMap", passed, total);