1 #include <algorithm>
2
3 #include "yaml-cpp/node/convert.h"
4
5 namespace {
6 // we're not gonna mess with the mess that is all the isupper/etc. functions
IsLower(char ch)7 bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; }
IsUpper(char ch)8 bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; }
ToLower(char ch)9 char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
10
tolower(const std::string & str)11 std::string tolower(const std::string& str) {
12 std::string s(str);
13 std::transform(s.begin(), s.end(), s.begin(), ToLower);
14 return s;
15 }
16
17 template <typename T>
IsEntirely(const std::string & str,T func)18 bool IsEntirely(const std::string& str, T func) {
19 for (std::size_t i = 0; i < str.size(); i++)
20 if (!func(str[i]))
21 return false;
22
23 return true;
24 }
25
26 // IsFlexibleCase
27 // . Returns true if 'str' is:
28 // . UPPERCASE
29 // . lowercase
30 // . Capitalized
IsFlexibleCase(const std::string & str)31 bool IsFlexibleCase(const std::string& str) {
32 if (str.empty())
33 return true;
34
35 if (IsEntirely(str, IsLower))
36 return true;
37
38 bool firstcaps = IsUpper(str[0]);
39 std::string rest = str.substr(1);
40 return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
41 }
42 }
43
44 namespace YAML {
decode(const Node & node,bool & rhs)45 bool convert<bool>::decode(const Node& node, bool& rhs) {
46 if (!node.IsScalar())
47 return false;
48
49 // we can't use iostream bool extraction operators as they don't
50 // recognize all possible values in the table below (taken from
51 // http://yaml.org/type/bool.html)
52 static const struct {
53 std::string truename, falsename;
54 } names[] = {
55 {"y", "n"}, {"yes", "no"}, {"true", "false"}, {"on", "off"},
56 };
57
58 if (!IsFlexibleCase(node.Scalar()))
59 return false;
60
61 for (unsigned i = 0; i < sizeof(names) / sizeof(names[0]); i++) {
62 if (names[i].truename == tolower(node.Scalar())) {
63 rhs = true;
64 return true;
65 }
66
67 if (names[i].falsename == tolower(node.Scalar())) {
68 rhs = false;
69 return true;
70 }
71 }
72
73 return false;
74 }
75 }
76