Commit 14cdec77 authored by Jesse Beder's avatar Jesse Beder
Browse files

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

(Thanks to Vadim Zeitlin)
parent 6e4317e3
...@@ -40,6 +40,7 @@ namespace YAML ...@@ -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>
......
...@@ -43,6 +43,7 @@ namespace YAML ...@@ -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; }
......
...@@ -293,6 +293,14 @@ namespace YAML ...@@ -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);
......
...@@ -5,6 +5,7 @@ ...@@ -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 ...@@ -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);
......
...@@ -24,6 +24,7 @@ namespace YAML ...@@ -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);
......
...@@ -58,6 +58,7 @@ ...@@ -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 @@ ...@@ -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"
......
...@@ -3,21 +3,19 @@ ...@@ -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";
} }
......
bad YAML: [ - true
\ No newline at end of file - n
- Off
- YES
- on
- FALSE
- FaLse
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment