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 return std::all_of(str.begin(), str.end(), [=](char ch) { return func(ch); });
20 }
21
22 // IsFlexibleCase
23 // . Returns true if 'str' is:
24 // . UPPERCASE
25 // . lowercase
26 // . Capitalized
IsFlexibleCase(const std::string & str)27 bool IsFlexibleCase(const std::string& str) {
28 if (str.empty())
29 return true;
30
31 if (IsEntirely(str, IsLower))
32 return true;
33
34 bool firstcaps = IsUpper(str[0]);
35 std::string rest = str.substr(1);
36 return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
37 }
38 } // namespace
39
40 namespace YAML {
decode(const Node & node,bool & rhs)41 bool convert<bool>::decode(const Node& node, bool& rhs) {
42 if (!node.IsScalar())
43 return false;
44
45 // we can't use iostream bool extraction operators as they don't
46 // recognize all possible values in the table below (taken from
47 // http://yaml.org/type/bool.html)
48 static const struct {
49 std::string truename, falsename;
50 } names[] = {
51 {"y", "n"},
52 {"yes", "no"},
53 {"true", "false"},
54 {"on", "off"},
55 };
56
57 if (!IsFlexibleCase(node.Scalar()))
58 return false;
59
60 for (const auto& name : names) {
61 if (name.truename == tolower(node.Scalar())) {
62 rhs = true;
63 return true;
64 }
65
66 if (name.falsename == tolower(node.Scalar())) {
67 rhs = false;
68 return true;
69 }
70 }
71
72 return false;
73 }
74 } // namespace YAML
75