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

(Thanks to Vadim Zeitlin)
This commit is contained in:
Jesse Beder
2008-09-25 00:15:40 +00:00
parent 6e4317e37c
commit 14cdec770c
8 changed files with 103 additions and 10 deletions

View File

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

View File

@@ -293,6 +293,14 @@ namespace YAML
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)
{
node.Write(out, 0, false, false);

View File

@@ -5,6 +5,7 @@
#include "exceptions.h"
#include "node.h"
#include <sstream>
#include <algorithm>
namespace YAML
{
@@ -86,6 +87,81 @@ namespace YAML
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)
{
return -pContent->Compare(this);

View File

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