Added more natural ways to parse boolean values (based on the YAML spec).

(Thanks to Vadim Zeitlin)
This commit is contained in:
jbeder
2008-09-25 00:15:40 +00:00
parent bf01059c38
commit d1ef1e8ef1
8 changed files with 103 additions and 10 deletions

View File

@@ -40,6 +40,7 @@ namespace YAML
bool Read(float& f) const; bool Read(float& f) const;
bool Read(double& d) const; bool Read(double& d) const;
bool Read(char& c) const; bool Read(char& c) const;
bool Read(bool& b) const;
// so you can specialize for other values // so you can specialize for other values
template <typename T> template <typename T>

View File

@@ -43,6 +43,7 @@ namespace YAML
virtual bool Read(float& f) const { return false; } virtual bool Read(float& f) const { return false; }
virtual bool Read(double& d) const { return false; } virtual bool Read(double& d) const { return false; }
virtual bool Read(char& c) const { return false; } virtual bool Read(char& c) const { return false; }
virtual bool Read(bool& b) const { return false; }
// ordering // ordering
virtual int Compare(Content *pContent) { return 0; } virtual int Compare(Content *pContent) { return 0; }

View File

@@ -293,6 +293,14 @@ namespace YAML
return m_pContent->Read(c); return m_pContent->Read(c);
} }
bool Node::Read(bool& b) const
{
if(!m_pContent)
return false;
return m_pContent->Read(b);
}
std::ostream& operator << (std::ostream& out, const Node& node) std::ostream& operator << (std::ostream& out, const Node& node)
{ {
node.Write(out, 0, false, false); node.Write(out, 0, false, false);

View File

@@ -5,6 +5,7 @@
#include "exceptions.h" #include "exceptions.h"
#include "node.h" #include "node.h"
#include <sstream> #include <sstream>
#include <algorithm>
namespace YAML namespace YAML
{ {
@@ -86,6 +87,81 @@ namespace YAML
return !data.fail(); return !data.fail();
} }
namespace
{
// we're not gonna mess with the mess that is all the isupper/etc. functions
bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; }
bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; }
char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
std::string tolower(const std::string& str)
{
std::string s(str);
std::transform(s.begin(), s.end(), s.begin(), ToLower);
return s;
}
template <typename T>
bool IsEntirely(const std::string& str, T func)
{
for(unsigned i=0;i<str.size();i++)
if(!func(str[i]))
return false;
return true;
}
// IsFlexibleCase
// . Returns true if 'str' is:
// . UPPERCASE
// . lowercase
// . Capitalized
bool IsFlexibleCase(const std::string& str)
{
if(str.empty())
return true;
if(IsEntirely(str, IsLower))
return true;
bool firstcaps = IsUpper(str[0]);
std::string rest = str.substr(1);
return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
}
}
bool Scalar::Read(bool& b) const
{
// we can't use iostream bool extraction operators as they don't
// recognize all possible values in the table below (taken from
// http://yaml.org/type/bool.html)
static const struct {
std::string truename, falsename;
} names[] = {
{ "y", "n" },
{ "yes", "no" },
{ "true", "false" },
{ "on", "off" },
};
if(!IsFlexibleCase(m_data))
return false;
for(unsigned i=0;i<sizeof(names)/sizeof(names[0]);i++) {
if(names[i].truename == tolower(m_data)) {
b = true;
return true;
}
if(names[i].falsename == tolower(m_data)) {
b = false;
return true;
}
}
return false;
}
int Scalar::Compare(Content *pContent) int Scalar::Compare(Content *pContent)
{ {
return -pContent->Compare(this); return -pContent->Compare(this);

View File

@@ -24,6 +24,7 @@ namespace YAML
virtual bool Read(float& f) const; virtual bool Read(float& f) const;
virtual bool Read(double& d) const; virtual bool Read(double& d) const;
virtual bool Read(char& c) const; virtual bool Read(char& c) const;
virtual bool Read(bool& b) const;
// ordering // ordering
virtual int Compare(Content *pContent); virtual int Compare(Content *pContent);

View File

@@ -58,6 +58,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="yamlcppd.lib"
AdditionalLibraryDirectories="lib" AdditionalLibraryDirectories="lib"
GenerateDebugInformation="true" GenerateDebugInformation="true"
TargetMachine="1" TargetMachine="1"
@@ -128,6 +129,7 @@
/> />
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalDependencies="yamlcpp.lib"
AdditionalLibraryDirectories="lib" AdditionalLibraryDirectories="lib"
GenerateDebugInformation="true" GenerateDebugInformation="true"
OptimizeReferences="2" OptimizeReferences="2"

View File

@@ -3,21 +3,19 @@
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#ifdef _MSC_VER
#ifdef _DEBUG
#pragma comment(lib, "yamlcppd.lib")
#else
#pragma comment(lib, "yamlcpp.lib")
#endif // _DEBUG
#endif // _MSC_VER
void run() void run()
{ {
std::ifstream fin("tests/test.yaml"); std::ifstream fin("tests/test.yaml");
try { try {
YAML::Parser parser(fin); YAML::Parser parser(fin);
parser.PrintTokens(std::cout); YAML::Node doc;
parser.GetNextDocument(doc);
for(unsigned i=0;i<doc.size();i++) {
bool value;
doc[i] >> value;
std::cout << (value ? "true" : "false") << "\n";
}
} catch(YAML::Exception&) { } catch(YAML::Exception&) {
std::cout << "Error parsing the yaml!\n"; std::cout << "Error parsing the yaml!\n";
} }

View File

@@ -1 +1,7 @@
bad YAML: [ - true
- n
- Off
- YES
- on
- FALSE
- FaLse