Commit d63ec48c by Jesse Beder

Run clang-format

parent 3355bbb3
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
// #pragma message( "Defining YAML_CPP_API for DLL import" ) // #pragma message( "Defining YAML_CPP_API for DLL import" )
#define YAML_CPP_API __declspec(dllimport) #define YAML_CPP_API __declspec(dllimport)
#endif // yaml_cpp_EXPORTS #endif // yaml_cpp_EXPORTS
#else // YAML_CPP_DLL #else // YAML_CPP_DLL
#define YAML_CPP_API #define YAML_CPP_API
#endif // YAML_CPP_DLL #endif // YAML_CPP_DLL
......
#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include "yaml-cpp/traits.h" #include "yaml-cpp/traits.h"
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <sstream> #include <sstream>
namespace YAML namespace YAML {
{ // error messages
// error messages namespace ErrorMsg {
namespace ErrorMsg const char* const YAML_DIRECTIVE_ARGS =
{ "YAML directives must have exactly one argument";
const char * const YAML_DIRECTIVE_ARGS = "YAML directives must have exactly one argument"; const char* const YAML_VERSION = "bad YAML version: ";
const char * const YAML_VERSION = "bad YAML version: "; const char* const YAML_MAJOR_VERSION = "YAML major version too large";
const char * const YAML_MAJOR_VERSION = "YAML major version too large"; const char* const REPEATED_YAML_DIRECTIVE = "repeated YAML directive";
const char * const REPEATED_YAML_DIRECTIVE= "repeated YAML directive"; const char* const TAG_DIRECTIVE_ARGS =
const char * const TAG_DIRECTIVE_ARGS = "TAG directives must have exactly two arguments"; "TAG directives must have exactly two arguments";
const char * const REPEATED_TAG_DIRECTIVE = "repeated TAG directive"; const char* const REPEATED_TAG_DIRECTIVE = "repeated TAG directive";
const char * const CHAR_IN_TAG_HANDLE = "illegal character found while scanning tag handle"; const char* const CHAR_IN_TAG_HANDLE =
const char * const TAG_WITH_NO_SUFFIX = "tag handle with no suffix"; "illegal character found while scanning tag handle";
const char * const END_OF_VERBATIM_TAG = "end of verbatim tag not found"; const char* const TAG_WITH_NO_SUFFIX = "tag handle with no suffix";
const char * const END_OF_MAP = "end of map not found"; const char* const END_OF_VERBATIM_TAG = "end of verbatim tag not found";
const char * const END_OF_MAP_FLOW = "end of map flow not found"; const char* const END_OF_MAP = "end of map not found";
const char * const END_OF_SEQ = "end of sequence not found"; const char* const END_OF_MAP_FLOW = "end of map flow not found";
const char * const END_OF_SEQ_FLOW = "end of sequence flow not found"; const char* const END_OF_SEQ = "end of sequence not found";
const char * const MULTIPLE_TAGS = "cannot assign multiple tags to the same node"; const char* const END_OF_SEQ_FLOW = "end of sequence flow not found";
const char * const MULTIPLE_ANCHORS = "cannot assign multiple anchors to the same node"; const char* const MULTIPLE_TAGS =
const char * const MULTIPLE_ALIASES = "cannot assign multiple aliases to the same node"; "cannot assign multiple tags to the same node";
const char * const ALIAS_CONTENT = "aliases can't have any content, *including* tags"; const char* const MULTIPLE_ANCHORS =
const char * const INVALID_HEX = "bad character found while scanning hex number"; "cannot assign multiple anchors to the same node";
const char * const INVALID_UNICODE = "invalid unicode: "; const char* const MULTIPLE_ALIASES =
const char * const INVALID_ESCAPE = "unknown escape character: "; "cannot assign multiple aliases to the same node";
const char * const UNKNOWN_TOKEN = "unknown token"; const char* const ALIAS_CONTENT =
const char * const DOC_IN_SCALAR = "illegal document indicator in scalar"; "aliases can't have any content, *including* tags";
const char * const EOF_IN_SCALAR = "illegal EOF in scalar"; const char* const INVALID_HEX = "bad character found while scanning hex number";
const char * const CHAR_IN_SCALAR = "illegal character in scalar"; const char* const INVALID_UNICODE = "invalid unicode: ";
const char * const TAB_IN_INDENTATION = "illegal tab when looking for indentation"; const char* const INVALID_ESCAPE = "unknown escape character: ";
const char * const FLOW_END = "illegal flow end"; const char* const UNKNOWN_TOKEN = "unknown token";
const char * const BLOCK_ENTRY = "illegal block entry"; const char* const DOC_IN_SCALAR = "illegal document indicator in scalar";
const char * const MAP_KEY = "illegal map key"; const char* const EOF_IN_SCALAR = "illegal EOF in scalar";
const char * const MAP_VALUE = "illegal map value"; const char* const CHAR_IN_SCALAR = "illegal character in scalar";
const char * const ALIAS_NOT_FOUND = "alias not found after *"; const char* const TAB_IN_INDENTATION =
const char * const ANCHOR_NOT_FOUND = "anchor not found after &"; "illegal tab when looking for indentation";
const char * const CHAR_IN_ALIAS = "illegal character found while scanning alias"; const char* const FLOW_END = "illegal flow end";
const char * const CHAR_IN_ANCHOR = "illegal character found while scanning anchor"; const char* const BLOCK_ENTRY = "illegal block entry";
const char * const ZERO_INDENT_IN_BLOCK = "cannot set zero indentation for a block scalar"; const char* const MAP_KEY = "illegal map key";
const char * const CHAR_IN_BLOCK = "unexpected character in block scalar"; const char* const MAP_VALUE = "illegal map value";
const char * const AMBIGUOUS_ANCHOR = "cannot assign the same alias to multiple nodes"; const char* const ALIAS_NOT_FOUND = "alias not found after *";
const char * const UNKNOWN_ANCHOR = "the referenced anchor is not defined"; const char* const ANCHOR_NOT_FOUND = "anchor not found after &";
const char* const CHAR_IN_ALIAS =
const char * const INVALID_NODE = "invalid node; this may result from using a map iterator as a sequence iterator, or vice-versa"; "illegal character found while scanning alias";
const char * const INVALID_SCALAR = "invalid scalar"; const char* const CHAR_IN_ANCHOR =
const char * const KEY_NOT_FOUND = "key not found"; "illegal character found while scanning anchor";
const char * const BAD_CONVERSION = "bad conversion"; const char* const ZERO_INDENT_IN_BLOCK =
const char * const BAD_DEREFERENCE = "bad dereference"; "cannot set zero indentation for a block scalar";
const char * const BAD_SUBSCRIPT = "operator[] call on a scalar"; const char* const CHAR_IN_BLOCK = "unexpected character in block scalar";
const char * const BAD_PUSHBACK = "appending to a non-sequence"; const char* const AMBIGUOUS_ANCHOR =
const char * const BAD_INSERT = "inserting in a non-convertible-to-map"; "cannot assign the same alias to multiple nodes";
const char* const UNKNOWN_ANCHOR = "the referenced anchor is not defined";
const char * const UNMATCHED_GROUP_TAG = "unmatched group tag";
const char * const UNEXPECTED_END_SEQ = "unexpected end sequence token"; const char* const INVALID_NODE =
const char * const UNEXPECTED_END_MAP = "unexpected end map token"; "invalid node; this may result from using a map iterator as a sequence "
const char * const SINGLE_QUOTED_CHAR = "invalid character in single-quoted string"; "iterator, or vice-versa";
const char * const INVALID_ANCHOR = "invalid anchor"; const char* const INVALID_SCALAR = "invalid scalar";
const char * const INVALID_ALIAS = "invalid alias"; const char* const KEY_NOT_FOUND = "key not found";
const char * const INVALID_TAG = "invalid tag"; const char* const BAD_CONVERSION = "bad conversion";
const char * const BAD_FILE = "bad file"; const char* const BAD_DEREFERENCE = "bad dereference";
const char* const BAD_SUBSCRIPT = "operator[] call on a scalar";
template <typename T> const char* const BAD_PUSHBACK = "appending to a non-sequence";
inline const std::string KEY_NOT_FOUND_WITH_KEY(const T&, typename disable_if<is_numeric<T> >::type * = 0) { const char* const BAD_INSERT = "inserting in a non-convertible-to-map";
return KEY_NOT_FOUND;
} const char* const UNMATCHED_GROUP_TAG = "unmatched group tag";
const char* const UNEXPECTED_END_SEQ = "unexpected end sequence token";
inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) { const char* const UNEXPECTED_END_MAP = "unexpected end map token";
std::stringstream stream; const char* const SINGLE_QUOTED_CHAR =
stream << KEY_NOT_FOUND << ": " << key; "invalid character in single-quoted string";
return stream.str(); const char* const INVALID_ANCHOR = "invalid anchor";
} const char* const INVALID_ALIAS = "invalid alias";
const char* const INVALID_TAG = "invalid tag";
template <typename T> const char* const BAD_FILE = "bad file";
inline const std::string KEY_NOT_FOUND_WITH_KEY(const T& key, typename enable_if<is_numeric<T> >::type * = 0) {
std::stringstream stream; template <typename T>
stream << KEY_NOT_FOUND << ": " << key; inline const std::string KEY_NOT_FOUND_WITH_KEY(
return stream.str(); const T&, typename disable_if<is_numeric<T> >::type* = 0) {
} return KEY_NOT_FOUND;
} }
class Exception: public std::runtime_error { inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) {
public: std::stringstream stream;
Exception(const Mark& mark_, const std::string& msg_) stream << KEY_NOT_FOUND << ": " << key;
: std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {} return stream.str();
virtual ~Exception() throw() {} }
Mark mark; template <typename T>
std::string msg; inline const std::string KEY_NOT_FOUND_WITH_KEY(
const T& key, typename enable_if<is_numeric<T> >::type* = 0) {
private: std::stringstream stream;
static const std::string build_what(const Mark& mark, const std::string& msg) { stream << KEY_NOT_FOUND << ": " << key;
std::stringstream output; return stream.str();
output << "yaml-cpp: error at line " << mark.line+1 << ", column " << mark.column+1 << ": " << msg; }
return output.str(); }
}
}; class Exception : public std::runtime_error {
public:
class ParserException: public Exception { Exception(const Mark& mark_, const std::string& msg_)
public: : std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {}
ParserException(const Mark& mark_, const std::string& msg_) virtual ~Exception() throw() {}
: Exception(mark_, msg_) {}
}; Mark mark;
std::string msg;
class RepresentationException: public Exception {
public: private:
RepresentationException(const Mark& mark_, const std::string& msg_) static const std::string build_what(const Mark& mark,
: Exception(mark_, msg_) {} const std::string& msg) {
}; std::stringstream output;
output << "yaml-cpp: error at line " << mark.line + 1 << ", column "
// representation exceptions << mark.column + 1 << ": " << msg;
class InvalidScalar: public RepresentationException { return output.str();
public: }
InvalidScalar(const Mark& mark_) };
: RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
}; class ParserException : public Exception {
public:
class KeyNotFound: public RepresentationException { ParserException(const Mark& mark_, const std::string& msg_)
public: : Exception(mark_, msg_) {}
template <typename T> };
KeyNotFound(const Mark& mark_, const T& key_)
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {} class RepresentationException : public Exception {
}; public:
RepresentationException(const Mark& mark_, const std::string& msg_)
template <typename T> : Exception(mark_, msg_) {}
class TypedKeyNotFound: public KeyNotFound { };
public:
TypedKeyNotFound(const Mark& mark_, const T& key_) // representation exceptions
: KeyNotFound(mark_, key_), key(key_) {} class InvalidScalar : public RepresentationException {
virtual ~TypedKeyNotFound() throw() {} public:
InvalidScalar(const Mark& mark_)
T key; : RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
}; };
template <typename T> class KeyNotFound : public RepresentationException {
inline TypedKeyNotFound <T> MakeTypedKeyNotFound(const Mark& mark, const T& key) { public:
return TypedKeyNotFound <T> (mark, key); template <typename T>
} KeyNotFound(const Mark& mark_, const T& key_)
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {
class InvalidNode: public RepresentationException { }
public: };
InvalidNode()
: RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {} template <typename T>
}; class TypedKeyNotFound : public KeyNotFound {
public:
class BadConversion: public RepresentationException { TypedKeyNotFound(const Mark& mark_, const T& key_)
public: : KeyNotFound(mark_, key_), key(key_) {}
BadConversion() virtual ~TypedKeyNotFound() throw() {}
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_CONVERSION) {}
}; T key;
};
template<typename T>
class TypedBadConversion: public BadConversion { template <typename T>
public: inline TypedKeyNotFound<T> MakeTypedKeyNotFound(const Mark& mark,
TypedBadConversion() const T& key) {
: BadConversion() {} return TypedKeyNotFound<T>(mark, key);
}; }
class BadDereference: public RepresentationException { class InvalidNode : public RepresentationException {
public: public:
BadDereference() InvalidNode()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {} : RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {}
}; };
class BadSubscript: public RepresentationException { class BadConversion : public RepresentationException {
public: public:
BadSubscript() BadConversion()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {} : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_CONVERSION) {}
}; };
class BadPushback: public RepresentationException { template <typename T>
public: class TypedBadConversion : public BadConversion {
BadPushback() public:
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {} TypedBadConversion() : BadConversion() {}
}; };
class BadInsert: public RepresentationException { class BadDereference : public RepresentationException {
public: public:
BadInsert() BadDereference()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {} : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {}
}; };
class EmitterException: public Exception { class BadSubscript : public RepresentationException {
public: public:
EmitterException(const std::string& msg_) BadSubscript()
: Exception(Mark::null_mark(), msg_) {} : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {}
}; };
class BadFile: public Exception { class BadPushback : public RepresentationException {
public: public:
BadFile(): Exception(Mark::null_mark(), ErrorMsg::BAD_FILE) {} BadPushback()
}; : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {}
};
class BadInsert : public RepresentationException {
public:
BadInsert()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {}
};
class EmitterException : public Exception {
public:
EmitterException(const std::string& msg_)
: Exception(Mark::null_mark(), msg_) {}
};
class BadFile : public Exception {
public:
BadFile() : Exception(Mark::null_mark(), ErrorMsg::BAD_FILE) {}
};
} }
#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/binary.h" #include "yaml-cpp/binary.h"
#include "yaml-cpp/node/node.h" #include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/iterator.h" #include "yaml-cpp/node/iterator.h"
...@@ -16,265 +17,259 @@ ...@@ -16,265 +17,259 @@
#include <sstream> #include <sstream>
#include <vector> #include <vector>
namespace YAML namespace YAML {
{ namespace conversion {
namespace conversion { inline bool IsInfinity(const std::string& input) {
inline bool IsInfinity(const std::string& input) { return input == ".inf" || input == ".Inf" || input == ".INF" ||
return input == ".inf" || input == ".Inf" || input == ".INF" || input == "+.inf" || input == "+.Inf" || input == "+.INF"; input == "+.inf" || input == "+.Inf" || input == "+.INF";
} }
inline bool IsNegativeInfinity(const std::string& input) { inline bool IsNegativeInfinity(const std::string& input) {
return input == "-.inf" || input == "-.Inf" || input == "-.INF"; return input == "-.inf" || input == "-.Inf" || input == "-.INF";
} }
inline bool IsNaN(const std::string& input) { inline bool IsNaN(const std::string& input) {
return input == ".nan" || input == ".NaN" || input == ".NAN"; return input == ".nan" || input == ".NaN" || input == ".NAN";
} }
} }
// std::string // std::string
template<> template <>
struct convert<std::string> { struct convert<std::string> {
static Node encode(const std::string& rhs) { static Node encode(const std::string& rhs) { return Node(rhs); }
return Node(rhs);
} static bool decode(const Node& node, std::string& rhs) {
if (!node.IsScalar())
static bool decode(const Node& node, std::string& rhs) { return false;
if(!node.IsScalar()) rhs = node.Scalar();
return false; return true;
rhs = node.Scalar(); }
return true; };
}
}; // C-strings can only be encoded
template <>
// C-strings can only be encoded struct convert<const char*> {
template<> static Node encode(const char*& rhs) { return Node(rhs); }
struct convert<const char *> { };
static Node encode(const char *&rhs) {
return Node(rhs); template <std::size_t N>
} struct convert<const char[N]> {
}; static Node encode(const char (&rhs)[N]) { return Node(rhs); }
};
template<std::size_t N>
struct convert<const char[N]> { template <>
static Node encode(const char (&rhs)[N]) { struct convert<_Null> {
return Node(rhs); static Node encode(const _Null& /* rhs */) { return Node(); }
}
}; static bool decode(const Node& node, _Null& /* rhs */) {
return node.IsNull();
template<> }
struct convert<_Null> { };
static Node encode(const _Null& /* rhs */) {
return Node(); #define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \
} template <> \
struct convert<type> { \
static bool decode(const Node& node, _Null& /* rhs */) { static Node encode(const type& rhs) { \
return node.IsNull(); std::stringstream stream; \
} stream.precision(std::numeric_limits<type>::digits10 + 1); \
}; stream << rhs; \
return Node(stream.str()); \
#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op)\ } \
template<>\ \
struct convert<type> {\ static bool decode(const Node& node, type& rhs) { \
static Node encode(const type& rhs) {\ if (node.Type() != NodeType::Scalar) \
std::stringstream stream;\ return false; \
stream.precision(std::numeric_limits<type>::digits10 + 1);\ const std::string& input = node.Scalar(); \
stream << rhs;\ std::stringstream stream(input); \
return Node(stream.str());\ stream.unsetf(std::ios::dec); \
}\ if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) \
\ return true; \
static bool decode(const Node& node, type& rhs) {\ if (std::numeric_limits<type>::has_infinity) { \
if(node.Type() != NodeType::Scalar)\ if (conversion::IsInfinity(input)) { \
return false;\ rhs = std::numeric_limits<type>::infinity(); \
const std::string& input = node.Scalar();\ return true; \
std::stringstream stream(input);\ } else if (conversion::IsNegativeInfinity(input)) { \
stream.unsetf(std::ios::dec);\ rhs = negative_op std::numeric_limits<type>::infinity(); \
if((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof())\ return true; \
return true;\ } \
if(std::numeric_limits<type>::has_infinity) {\ } \
if(conversion::IsInfinity(input)) {\ \
rhs = std::numeric_limits<type>::infinity();\ if (std::numeric_limits<type>::has_quiet_NaN && \
return true;\ conversion::IsNaN(input)) { \
} else if(conversion::IsNegativeInfinity(input)) {\ rhs = std::numeric_limits<type>::quiet_NaN(); \
rhs = negative_op std::numeric_limits<type>::infinity();\ return true; \
return true;\ } \
}\ \
}\ return false; \
\ } \
if(std::numeric_limits<type>::has_quiet_NaN && conversion::IsNaN(input)) {\ }
rhs = std::numeric_limits<type>::quiet_NaN();\
return true;\ #define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \
}\ YAML_DEFINE_CONVERT_STREAMABLE(type, -)
\
return false;\ #define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type) \
}\ YAML_DEFINE_CONVERT_STREAMABLE(type, +)
}
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int);
#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type)\ YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short);
YAML_DEFINE_CONVERT_STREAMABLE(type, -) YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long);
#define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type)\ YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned);
YAML_DEFINE_CONVERT_STREAMABLE(type, +) YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int); YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long); YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long); YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(char);
YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned char);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(float);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(double);
YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long double);
#undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED #undef YAML_DEFINE_CONVERT_STREAMABLE_SIGNED
#undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED #undef YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED
#undef YAML_DEFINE_CONVERT_STREAMABLE #undef YAML_DEFINE_CONVERT_STREAMABLE
// bool // bool
template<> template <>
struct convert<bool> { struct convert<bool> {
static Node encode(bool rhs) { static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); }
return rhs ? Node("true") : Node("false");
} static bool decode(const Node& node, bool& rhs);
};
static bool decode(const Node& node, bool& rhs);
}; // std::map
template <typename K, typename V>
// std::map struct convert<std::map<K, V> > {
template<typename K, typename V> static Node encode(const std::map<K, V>& rhs) {
struct convert<std::map<K, V> > { Node node(NodeType::Map);
static Node encode(const std::map<K, V>& rhs) { for (typename std::map<K, V>::const_iterator it = rhs.begin();
Node node(NodeType::Map); it != rhs.end(); ++it)
for(typename std::map<K, V>::const_iterator it=rhs.begin();it!=rhs.end();++it) node.force_insert(it->first, it->second);
node.force_insert(it->first, it->second); return node;
return node; }
}
static bool decode(const Node& node, std::map<K, V>& rhs) {
static bool decode(const Node& node, std::map<K, V>& rhs) { if (!node.IsMap())
if(!node.IsMap()) return false;
return false;
rhs.clear();
rhs.clear(); for (const_iterator it = node.begin(); it != node.end(); ++it)
for(const_iterator it=node.begin();it!=node.end();++it)
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
//workaround for GCC 3: // workaround for GCC 3:
rhs[it->first.template as<K>()] = it->second.template as<V>(); rhs[it->first.template as<K>()] = it->second.template as<V>();
#else #else
rhs[it->first.as<K>()] = it->second.as<V>(); rhs[it->first.as<K>()] = it->second.as<V>();
#endif #endif
return true; return true;
} }
}; };
// std::vector // std::vector
template<typename T> template <typename T>
struct convert<std::vector<T> > { struct convert<std::vector<T> > {
static Node encode(const std::vector<T>& rhs) { static Node encode(const std::vector<T>& rhs) {
Node node(NodeType::Sequence); Node node(NodeType::Sequence);
for(typename std::vector<T>::const_iterator it=rhs.begin();it!=rhs.end();++it) for (typename std::vector<T>::const_iterator it = rhs.begin();
node.push_back(*it); it != rhs.end(); ++it)
return node; node.push_back(*it);
} return node;
}
static bool decode(const Node& node, std::vector<T>& rhs) {
if(!node.IsSequence()) static bool decode(const Node& node, std::vector<T>& rhs) {
return false; if (!node.IsSequence())
return false;
rhs.clear();
for(const_iterator it=node.begin();it!=node.end();++it) rhs.clear();
for (const_iterator it = node.begin(); it != node.end(); ++it)
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
//workaround for GCC 3: // workaround for GCC 3:
rhs.push_back(it->template as<T>()); rhs.push_back(it->template as<T>());
#else #else
rhs.push_back(it->as<T>()); rhs.push_back(it->as<T>());
#endif #endif
return true; return true;
} }
}; };
// std::list // std::list
template<typename T> template <typename T>
struct convert<std::list<T> > { struct convert<std::list<T> > {
static Node encode(const std::list<T>& rhs) { static Node encode(const std::list<T>& rhs) {
Node node(NodeType::Sequence); Node node(NodeType::Sequence);
for(typename std::list<T>::const_iterator it=rhs.begin();it!=rhs.end();++it) for (typename std::list<T>::const_iterator it = rhs.begin();
node.push_back(*it); it != rhs.end(); ++it)
return node; node.push_back(*it);
} return node;
}
static bool decode(const Node& node, std::list<T>& rhs) {
if(!node.IsSequence()) static bool decode(const Node& node, std::list<T>& rhs) {
return false; if (!node.IsSequence())
return false;
rhs.clear();
for(const_iterator it=node.begin();it!=node.end();++it) rhs.clear();
for (const_iterator it = node.begin(); it != node.end(); ++it)
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
//workaround for GCC 3: // workaround for GCC 3:
rhs.push_back(it->template as<T>()); rhs.push_back(it->template as<T>());
#else #else
rhs.push_back(it->as<T>()); rhs.push_back(it->as<T>());
#endif #endif
return true; return true;
} }
}; };
// std::pair // std::pair
template<typename T, typename U> template <typename T, typename U>
struct convert<std::pair<T, U> > { struct convert<std::pair<T, U> > {
static Node encode(const std::pair<T, U>& rhs) { static Node encode(const std::pair<T, U>& rhs) {
Node node(NodeType::Sequence); Node node(NodeType::Sequence);
node.push_back(rhs.first); node.push_back(rhs.first);
node.push_back(rhs.second); node.push_back(rhs.second);
return node; return node;
} }
static bool decode(const Node& node, std::pair<T, U>& rhs) { static bool decode(const Node& node, std::pair<T, U>& rhs) {
if(!node.IsSequence()) if (!node.IsSequence())
return false; return false;
if (node.size() != 2) if (node.size() != 2)
return false; return false;
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
//workaround for GCC 3: // workaround for GCC 3:
rhs.first = node[0].template as<T>(); rhs.first = node[0].template as<T>();
#else #else
rhs.first = node[0].as<T>(); rhs.first = node[0].as<T>();
#endif #endif
#if defined(__GNUC__) && __GNUC__ < 4 #if defined(__GNUC__) && __GNUC__ < 4
//workaround for GCC 3: // workaround for GCC 3:
rhs.second = node[1].template as<U>(); rhs.second = node[1].template as<U>();
#else #else
rhs.second = node[1].as<U>(); rhs.second = node[1].as<U>();
#endif #endif
return true; return true;
} }
}; };
// binary // binary
template<> template <>
struct convert<Binary> { struct convert<Binary> {
static Node encode(const Binary& rhs) { static Node encode(const Binary& rhs) {
return Node(EncodeBase64(rhs.data(), rhs.size())); return Node(EncodeBase64(rhs.data(), rhs.size()));
} }
static bool decode(const Node& node, Binary& rhs) { static bool decode(const Node& node, Binary& rhs) {
if(!node.IsScalar()) if (!node.IsScalar())
return false; return false;
std::vector<unsigned char> data = DecodeBase64(node.Scalar()); std::vector<unsigned char> data = DecodeBase64(node.Scalar());
if(data.empty() && !node.Scalar().empty()) if (data.empty() && !node.Scalar().empty())
return false; return false;
rhs.swap(data); rhs.swap(data);
return true; return true;
} }
}; };
} }
#endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
namespace YAML namespace YAML {
{ namespace detail {
namespace detail struct unspecified_bool {
{ struct NOT_ALLOWED;
struct unspecified_bool { static void true_value(NOT_ALLOWED*) {}
struct NOT_ALLOWED; };
static void true_value(NOT_ALLOWED*) {} typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*);
};
typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*);
}
} }
#define YAML_CPP_OPERATOR_BOOL()\
operator YAML::detail::unspecified_bool_type() const\
{\
return this->operator!() ? 0 : &YAML::detail::unspecified_bool::true_value;\
} }
#endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define YAML_CPP_OPERATOR_BOOL() \
operator YAML::detail::unspecified_bool_type() const { \
return this->operator!() ? 0 \
: &YAML::detail::unspecified_bool::true_value; \
}
#endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/node/detail/node.h" #include "yaml-cpp/node/detail/node.h"
#include "yaml-cpp/node/detail/node_data.h" #include "yaml-cpp/node/detail/node_data.h"
#include <boost/type_traits.hpp> #include <boost/type_traits.hpp>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail template <typename Key, typename Enable = void>
{ struct get_idx {
template<typename Key, typename Enable = void> static node* get(const std::vector<node*>& /* sequence */,
struct get_idx { const Key& /* key */, shared_memory_holder /* pMemory */) {
static node *get(const std::vector<node *>& /* sequence */, const Key& /* key */, shared_memory_holder /* pMemory */) { return 0;
return 0; }
} };
};
template <typename Key>
template<typename Key> struct get_idx<
struct get_idx<Key, typename boost::enable_if_c<boost::is_unsigned<Key>::value && !boost::is_same<Key, bool>::value>::type> { Key, typename boost::enable_if_c<boost::is_unsigned<Key>::value &&
static node *get(const std::vector<node *>& sequence, const Key& key, shared_memory_holder /* pMemory */) { !boost::is_same<Key, bool>::value>::type> {
return key < sequence.size() ? sequence[key] : 0; static node* get(const std::vector<node*>& sequence, const Key& key,
} shared_memory_holder /* pMemory */) {
return key < sequence.size() ? sequence[key] : 0;
static node *get(std::vector<node *>& sequence, const Key& key, shared_memory_holder pMemory) { }
if(key > sequence.size())
return 0; static node* get(std::vector<node*>& sequence, const Key& key,
if(key == sequence.size()) shared_memory_holder pMemory) {
sequence.push_back(&pMemory->create_node()); if (key > sequence.size())
return sequence[key]; return 0;
} if (key == sequence.size())
}; sequence.push_back(&pMemory->create_node());
return sequence[key];
template<typename Key> }
struct get_idx<Key, typename boost::enable_if<boost::is_signed<Key> >::type> { };
static node *get(const std::vector<node *>& sequence, const Key& key, shared_memory_holder pMemory) {
return key >= 0 ? get_idx<std::size_t>::get(sequence, static_cast<std::size_t>(key), pMemory) : 0; template <typename Key>
} struct get_idx<Key, typename boost::enable_if<boost::is_signed<Key> >::type> {
static node *get(std::vector<node *>& sequence, const Key& key, shared_memory_holder pMemory) { static node* get(const std::vector<node*>& sequence, const Key& key,
return key >= 0 ? get_idx<std::size_t>::get(sequence, static_cast<std::size_t>(key), pMemory) : 0; shared_memory_holder pMemory) {
} return key >= 0 ? get_idx<std::size_t>::get(
}; sequence, static_cast<std::size_t>(key), pMemory)
: 0;
// indexing }
template<typename Key> static node* get(std::vector<node*>& sequence, const Key& key,
inline node& node_data::get(const Key& key, shared_memory_holder pMemory) const shared_memory_holder pMemory) {
{ return key >= 0 ? get_idx<std::size_t>::get(
switch(m_type) { sequence, static_cast<std::size_t>(key), pMemory)
case NodeType::Map: : 0;
break; }
case NodeType::Undefined: };
case NodeType::Null:
return pMemory->create_node(); // indexing
case NodeType::Sequence: template <typename Key>
if(node *pNode = get_idx<Key>::get(m_sequence, key, pMemory)) inline node& node_data::get(const Key& key,
return *pNode; shared_memory_holder pMemory) const {
return pMemory->create_node(); switch (m_type) {
case NodeType::Scalar: case NodeType::Map:
throw BadSubscript(); break;
} case NodeType::Undefined:
case NodeType::Null:
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { return pMemory->create_node();
if(equals(*it->first, key, pMemory)) case NodeType::Sequence:
return *it->second; if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory))
} return *pNode;
return pMemory->create_node();
return pMemory->create_node(); case NodeType::Scalar:
} throw BadSubscript();
}
template<typename Key>
inline node& node_data::get(const Key& key, shared_memory_holder pMemory) for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
{ if (equals(*it->first, key, pMemory))
switch(m_type) { return *it->second;
case NodeType::Map: }
break;
case NodeType::Undefined: return pMemory->create_node();
case NodeType::Null: }
case NodeType::Sequence:
if(node *pNode = get_idx<Key>::get(m_sequence, key, pMemory)) { template <typename Key>
m_type = NodeType::Sequence; inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
return *pNode; switch (m_type) {
} case NodeType::Map:
break;
convert_to_map(pMemory); case NodeType::Undefined:
break; case NodeType::Null:
case NodeType::Scalar: case NodeType::Sequence:
throw BadSubscript(); if (node* pNode = get_idx<Key>::get(m_sequence, key, pMemory)) {
} m_type = NodeType::Sequence;
return *pNode;
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { }
if(equals(*it->first, key, pMemory))
return *it->second; convert_to_map(pMemory);
} break;
case NodeType::Scalar:
node& k = convert_to_node(key, pMemory); throw BadSubscript();
node& v = pMemory->create_node(); }
insert_map_pair(k, v);
return v; for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
} if (equals(*it->first, key, pMemory))
return *it->second;
template<typename Key> }
inline bool node_data::remove(const Key& key, shared_memory_holder pMemory)
{ node& k = convert_to_node(key, pMemory);
if(m_type != NodeType::Map) node& v = pMemory->create_node();
return false; insert_map_pair(k, v);
return v;
for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) { }
if(equals(*it->first, key, pMemory)) {
m_map.erase(it); template <typename Key>
return true; inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) {
} if (m_type != NodeType::Map)
} return false;
return false; for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
} if (equals(*it->first, key, pMemory)) {
m_map.erase(it);
// map return true;
template<typename Key, typename Value> }
inline void node_data::force_insert(const Key& key, const Value& value, shared_memory_holder pMemory) }
{
switch(m_type) { return false;
case NodeType::Map: }
break;
case NodeType::Undefined: // map
case NodeType::Null: template <typename Key, typename Value>
case NodeType::Sequence: inline void node_data::force_insert(const Key& key, const Value& value,
convert_to_map(pMemory); shared_memory_holder pMemory) {
break; switch (m_type) {
case NodeType::Scalar: case NodeType::Map:
throw BadInsert(); break;
} case NodeType::Undefined:
case NodeType::Null:
node& k = convert_to_node(key, pMemory); case NodeType::Sequence:
node& v = convert_to_node(value, pMemory); convert_to_map(pMemory);
insert_map_pair(k, v); break;
} case NodeType::Scalar:
throw BadInsert();
template<typename T> }
inline bool node_data::equals(node& node, const T& rhs, shared_memory_holder pMemory)
{ node& k = convert_to_node(key, pMemory);
T lhs; node& v = convert_to_node(value, pMemory);
if(convert<T>::decode(Node(node, pMemory), lhs)) insert_map_pair(k, v);
return lhs == rhs; }
return false;
} template <typename T>
inline bool node_data::equals(node& node, const T& rhs,
inline bool node_data::equals(node& node, const char *rhs, shared_memory_holder pMemory) shared_memory_holder pMemory) {
{ T lhs;
return equals<std::string>(node, rhs, pMemory); if (convert<T>::decode(Node(node, pMemory), lhs))
} return lhs == rhs;
return false;
template<typename T> }
inline node& node_data::convert_to_node(const T& rhs, shared_memory_holder pMemory)
{ inline bool node_data::equals(node& node, const char* rhs,
Node value = convert<T>::encode(rhs); shared_memory_holder pMemory) {
value.EnsureNodeExists(); return equals<std::string>(node, rhs, pMemory);
pMemory->merge(*value.m_pMemory); }
return *value.m_pNode;
} template <typename T>
} inline node& node_data::convert_to_node(const T& rhs,
shared_memory_holder pMemory) {
Node value = convert<T>::encode(rhs);
value.EnsureNodeExists();
pMemory->merge(*value.m_pMemory);
return *value.m_pNode;
}
}
} }
#endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/detail/node_iterator.h" #include "yaml-cpp/node/detail/node_iterator.h"
#include <boost/iterator/iterator_adaptor.hpp> #include <boost/iterator/iterator_adaptor.hpp>
#include <boost/utility.hpp> #include <boost/utility.hpp>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail struct iterator_value;
{
struct iterator_value; template <typename V>
class iterator_base
: public boost::iterator_adaptor<iterator_base<V>, node_iterator, V,
std::forward_iterator_tag, V> {
private:
template <typename>
friend class iterator_base;
struct enabler {};
typedef typename iterator_base::base_type base_type;
public:
typedef typename iterator_base::value_type value_type;
public:
iterator_base() {}
explicit iterator_base(base_type rhs, shared_memory_holder pMemory)
: iterator_base::iterator_adaptor_(rhs), m_pMemory(pMemory) {}
template<typename V> template <class W>
class iterator_base: public boost::iterator_adaptor< iterator_base(
iterator_base<V>, const iterator_base<W>& rhs,
node_iterator, typename boost::enable_if<boost::is_convertible<W*, V*>, enabler>::type =
V, enabler())
std::forward_iterator_tag, : iterator_base::iterator_adaptor_(rhs.base()),
V> m_pMemory(rhs.m_pMemory) {}
{
private:
template<typename> friend class iterator_base;
struct enabler {};
typedef typename iterator_base::base_type base_type;
public:
typedef typename iterator_base::value_type value_type;
public:
iterator_base() {}
explicit iterator_base(base_type rhs, shared_memory_holder pMemory): iterator_base::iterator_adaptor_(rhs), m_pMemory(pMemory) {}
template<class W>
iterator_base(const iterator_base<W>& rhs, typename boost::enable_if<boost::is_convertible<W*, V*>, enabler>::type = enabler()): iterator_base::iterator_adaptor_(rhs.base()), m_pMemory(rhs.m_pMemory) {}
private:
friend class boost::iterator_core_access;
void increment() { this->base_reference() = boost::next(this->base()); } private:
friend class boost::iterator_core_access;
value_type dereference() const {
const typename base_type::value_type& v = *this->base(); void increment() { this->base_reference() = boost::next(this->base()); }
if(v.pNode)
return value_type(Node(*v, m_pMemory)); value_type dereference() const {
if(v.first && v.second) const typename base_type::value_type& v = *this->base();
return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory)); if (v.pNode)
return value_type(); return value_type(Node(*v, m_pMemory));
} if (v.first && v.second)
return value_type(Node(*v.first, m_pMemory), Node(*v.second, m_pMemory));
private: return value_type();
shared_memory_holder m_pMemory; }
};
} private:
shared_memory_holder m_pMemory;
};
}
} }
#endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include <list> #include <list>
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace YAML namespace YAML {
{ class node;
class node;
namespace detail {
namespace detail { struct iterator_value;
struct iterator_value; template <typename V>
template<typename V> class iterator_base; class iterator_base;
} }
typedef detail::iterator_base<detail::iterator_value> iterator; typedef detail::iterator_base<detail::iterator_value> iterator;
typedef detail::iterator_base<const detail::iterator_value> const_iterator; typedef detail::iterator_base<const detail::iterator_value> const_iterator;
} }
#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
...@@ -9,31 +11,29 @@ ...@@ -9,31 +11,29 @@
#include <set> #include <set>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail class memory {
{ public:
class memory { node& create_node();
public: void merge(const memory& rhs);
node& create_node();
void merge(const memory& rhs); private:
typedef std::set<shared_node> Nodes;
private: Nodes m_nodes;
typedef std::set<shared_node> Nodes; };
Nodes m_nodes;
}; class memory_holder {
public:
class memory_holder { memory_holder() : m_pMemory(new memory) {}
public:
memory_holder(): m_pMemory(new memory) {} node& create_node() { return m_pMemory->create_node(); }
void merge(memory_holder& rhs);
node& create_node() { return m_pMemory->create_node(); }
void merge(memory_holder& rhs); private:
boost::shared_ptr<memory> m_pMemory;
private: };
boost::shared_ptr<memory> m_pMemory; }
};
}
} }
#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/type.h" #include "yaml-cpp/node/type.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
...@@ -13,118 +14,134 @@ ...@@ -13,118 +14,134 @@
#include <set> #include <set>
#include <boost/utility.hpp> #include <boost/utility.hpp>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail class node : private boost::noncopyable {
{ public:
class node: private boost::noncopyable node() : m_pRef(new node_ref) {}
{
public: bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; }
node(): m_pRef(new node_ref) {} const node_ref* ref() const { return m_pRef.get(); }
bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; } bool is_defined() const { return m_pRef->is_defined(); }
const node_ref *ref() const { return m_pRef.get(); } NodeType::value type() const { return m_pRef->type(); }
bool is_defined() const { return m_pRef->is_defined(); } const std::string& scalar() const { return m_pRef->scalar(); }
NodeType::value type() const { return m_pRef->type(); } const std::string& tag() const { return m_pRef->tag(); }
const std::string& scalar() const { return m_pRef->scalar(); } void mark_defined() {
const std::string& tag() const { return m_pRef->tag(); } if (is_defined())
return;
void mark_defined() {
if(is_defined()) m_pRef->mark_defined();
return; for (nodes::iterator it = m_dependencies.begin();
it != m_dependencies.end(); ++it)
m_pRef->mark_defined(); (*it)->mark_defined();
for(nodes::iterator it=m_dependencies.begin();it!=m_dependencies.end();++it) m_dependencies.clear();
(*it)->mark_defined(); }
m_dependencies.clear();
} void add_dependency(node& rhs) {
if (is_defined())
void add_dependency(node& rhs) { rhs.mark_defined();
if(is_defined()) else
rhs.mark_defined(); m_dependencies.insert(&rhs);
else }
m_dependencies.insert(&rhs);
} void set_ref(const node& rhs) {
if (rhs.is_defined())
void set_ref(const node& rhs) { mark_defined();
if(rhs.is_defined()) m_pRef = rhs.m_pRef;
mark_defined(); }
m_pRef = rhs.m_pRef; void set_data(const node& rhs) {
} if (rhs.is_defined())
void set_data(const node& rhs) { mark_defined();
if(rhs.is_defined()) m_pRef->set_data(*rhs.m_pRef);
mark_defined(); }
m_pRef->set_data(*rhs.m_pRef);
} void set_type(NodeType::value type) {
if (type != NodeType::Undefined)
void set_type(NodeType::value type) { mark_defined();
if(type != NodeType::Undefined) m_pRef->set_type(type);
mark_defined(); }
m_pRef->set_type(type); void set_null() {
} mark_defined();
void set_null() { m_pRef->set_null();
mark_defined(); }
m_pRef->set_null(); void set_scalar(const std::string& scalar) {
} mark_defined();
void set_scalar(const std::string& scalar) { m_pRef->set_scalar(scalar);
mark_defined(); }
m_pRef->set_scalar(scalar); void set_tag(const std::string& tag) {
} mark_defined();
void set_tag(const std::string& tag) { m_pRef->set_tag(tag);
mark_defined(); }
m_pRef->set_tag(tag);
} // size/iterator
std::size_t size() const { return m_pRef->size(); }
// size/iterator
std::size_t size() const { return m_pRef->size(); } const_node_iterator begin() const {
return static_cast<const node_ref&>(*m_pRef).begin();
const_node_iterator begin() const { return static_cast<const node_ref&>(*m_pRef).begin(); } }
node_iterator begin() { return m_pRef->begin(); } node_iterator begin() { return m_pRef->begin(); }
const_node_iterator end() const { return static_cast<const node_ref&>(*m_pRef).end(); } const_node_iterator end() const {
node_iterator end() { return m_pRef->end(); } return static_cast<const node_ref&>(*m_pRef).end();
}
// sequence node_iterator end() { return m_pRef->end(); }
void push_back(node& node, shared_memory_holder pMemory) {
m_pRef->push_back(node, pMemory); // sequence
node.add_dependency(*this); void push_back(node& node, shared_memory_holder pMemory) {
} m_pRef->push_back(node, pMemory);
void insert(node& key, node& value, shared_memory_holder pMemory) { node.add_dependency(*this);
m_pRef->insert(key, value, pMemory); }
key.add_dependency(*this); void insert(node& key, node& value, shared_memory_holder pMemory) {
value.add_dependency(*this); m_pRef->insert(key, value, pMemory);
} key.add_dependency(*this);
value.add_dependency(*this);
// indexing }
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); }
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) { // indexing
node& value = m_pRef->get(key, pMemory); template <typename Key>
value.add_dependency(*this); node& get(const Key& key, shared_memory_holder pMemory) const {
return value; return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
} }
template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); } template <typename Key>
node& get(const Key& key, shared_memory_holder pMemory) {
node& get(node& key, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); } node& value = m_pRef->get(key, pMemory);
node& get(node& key, shared_memory_holder pMemory) { value.add_dependency(*this);
node& value = m_pRef->get(key, pMemory); return value;
key.add_dependency(*this); }
value.add_dependency(*this); template <typename Key>
return value; bool remove(const Key& key, shared_memory_holder pMemory) {
} return m_pRef->remove(key, pMemory);
bool remove(node& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); } }
// map node& get(node& key, shared_memory_holder pMemory) const {
template<typename Key, typename Value> return static_cast<const node_ref&>(*m_pRef).get(key, pMemory);
void force_insert(const Key& key, const Value& value, shared_memory_holder pMemory){ m_pRef->force_insert(key, value, pMemory); } }
node& get(node& key, shared_memory_holder pMemory) {
private: node& value = m_pRef->get(key, pMemory);
shared_node_ref m_pRef; key.add_dependency(*this);
typedef std::set<node *> nodes; value.add_dependency(*this);
nodes m_dependencies; return value;
}; }
} bool remove(node& key, shared_memory_holder pMemory) {
return m_pRef->remove(key, pMemory);
}
// map
template <typename Key, typename Value>
void force_insert(const Key& key, const Value& value,
shared_memory_holder pMemory) {
m_pRef->force_insert(key, value, pMemory);
}
private:
shared_node_ref m_pRef;
typedef std::set<node*> nodes;
nodes m_dependencies;
};
}
} }
#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/iterator.h" #include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
...@@ -15,96 +16,99 @@ ...@@ -15,96 +16,99 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail class node_data : private boost::noncopyable {
{ public:
class node_data: private boost::noncopyable node_data();
{
public: void mark_defined();
node_data(); void set_type(NodeType::value type);
void set_tag(const std::string& tag);
void mark_defined(); void set_null();
void set_type(NodeType::value type); void set_scalar(const std::string& scalar);
void set_tag(const std::string& tag);
void set_null(); bool is_defined() const { return m_isDefined; }
void set_scalar(const std::string& scalar); NodeType::value type() const {
return m_isDefined ? m_type : NodeType::Undefined;
bool is_defined() const { return m_isDefined; } }
NodeType::value type() const { return m_isDefined ? m_type : NodeType::Undefined; } const std::string& scalar() const { return m_scalar; }
const std::string& scalar() const { return m_scalar; } const std::string& tag() const { return m_tag; }
const std::string& tag() const { return m_tag; }
// size/iterator
// size/iterator std::size_t size() const;
std::size_t size() const;
const_node_iterator begin() const;
const_node_iterator begin() const; node_iterator begin();
node_iterator begin();
const_node_iterator end() const;
const_node_iterator end() const; node_iterator end();
node_iterator end();
// sequence
// sequence void push_back(node& node, shared_memory_holder pMemory);
void push_back(node& node, shared_memory_holder pMemory); void insert(node& key, node& value, shared_memory_holder pMemory);
void insert(node& key, node& value, shared_memory_holder pMemory);
// indexing
// indexing template <typename Key>
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const; node& get(const Key& key, shared_memory_holder pMemory) const;
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory); template <typename Key>
template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory); node& get(const Key& key, shared_memory_holder pMemory);
template <typename Key>
node& get(node& key, shared_memory_holder pMemory) const; bool remove(const Key& key, shared_memory_holder pMemory);
node& get(node& key, shared_memory_holder pMemory);
bool remove(node& key, shared_memory_holder pMemory); node& get(node& key, shared_memory_holder pMemory) const;
node& get(node& key, shared_memory_holder pMemory);
// map bool remove(node& key, shared_memory_holder pMemory);
template<typename Key, typename Value>
void force_insert(const Key& key, const Value& value, shared_memory_holder pMemory); // map
template <typename Key, typename Value>
public: void force_insert(const Key& key, const Value& value,
static std::string empty_scalar; shared_memory_holder pMemory);
private: public:
void compute_seq_size() const; static std::string empty_scalar;
void compute_map_size() const;
private:
void reset_sequence(); void compute_seq_size() const;
void reset_map(); void compute_map_size() const;
void insert_map_pair(node& key, node& value); void reset_sequence();
void convert_to_map(shared_memory_holder pMemory); void reset_map();
void convert_sequence_to_map(shared_memory_holder pMemory);
void insert_map_pair(node& key, node& value);
template<typename T> void convert_to_map(shared_memory_holder pMemory);
static bool equals(node& node, const T& rhs, shared_memory_holder pMemory); void convert_sequence_to_map(shared_memory_holder pMemory);
static bool equals(node& node, const char *rhs, shared_memory_holder pMemory);
template <typename T>
template<typename T> static bool equals(node& node, const T& rhs, shared_memory_holder pMemory);
static node& convert_to_node(const T& rhs, shared_memory_holder pMemory); static bool equals(node& node, const char* rhs, shared_memory_holder pMemory);
private: template <typename T>
bool m_isDefined; static node& convert_to_node(const T& rhs, shared_memory_holder pMemory);
NodeType::value m_type;
std::string m_tag; private:
bool m_isDefined;
// scalar NodeType::value m_type;
std::string m_scalar; std::string m_tag;
// sequence // scalar
typedef std::vector<node *> node_seq; std::string m_scalar;
node_seq m_sequence;
// sequence
mutable std::size_t m_seqSize; typedef std::vector<node*> node_seq;
node_seq m_sequence;
// map
typedef std::map<node *, node *> node_map; mutable std::size_t m_seqSize;
node_map m_map;
// map
typedef std::pair<node *, node *> kv_pair; typedef std::map<node*, node*> node_map;
typedef std::list<kv_pair> kv_pairs; node_map m_map;
mutable kv_pairs m_undefinedPairs;
}; typedef std::pair<node*, node*> kv_pair;
} typedef std::list<kv_pair> kv_pairs;
mutable kv_pairs m_undefinedPairs;
};
}
} }
#endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_NODE_DATA_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/iterator_facade.hpp>
...@@ -14,126 +15,143 @@ ...@@ -14,126 +15,143 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail struct iterator_type {
{ enum value {
struct iterator_type { enum value { None, Sequence, Map }; }; None,
Sequence,
template<typename V> Map
struct node_iterator_value: public std::pair<V*, V*> { };
typedef std::pair<V*, V*> kv; };
node_iterator_value(): kv(), pNode(0) {} template <typename V>
explicit node_iterator_value(V& rhs): kv(), pNode(&rhs) {} struct node_iterator_value : public std::pair<V*, V*> {
explicit node_iterator_value(V& key, V& value): kv(&key, &value), pNode(0) {} typedef std::pair<V*, V*> kv;
V& operator *() const { return *pNode; } node_iterator_value() : kv(), pNode(0) {}
V& operator ->() const { return *pNode; } explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {}
explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(0) {}
V *pNode;
}; V& operator*() const { return *pNode; }
V& operator->() const { return *pNode; }
typedef std::vector<node *> node_seq;
typedef std::map<node *, node *> node_map; V* pNode;
};
template<typename V>
struct node_iterator_type { typedef std::vector<node*> node_seq;
typedef node_seq::iterator seq; typedef std::map<node*, node*> node_map;
typedef node_map::iterator map;
}; template <typename V>
struct node_iterator_type {
template<typename V> typedef node_seq::iterator seq;
struct node_iterator_type<const V> { typedef node_map::iterator map;
typedef node_seq::const_iterator seq; };
typedef node_map::const_iterator map;
}; template <typename V>
struct node_iterator_type<const V> {
typedef node_seq::const_iterator seq;
template<typename V> typedef node_map::const_iterator map;
class node_iterator_base: public boost::iterator_facade< };
node_iterator_base<V>,
node_iterator_value<V>, template <typename V>
std::forward_iterator_tag, class node_iterator_base
node_iterator_value<V> > : public boost::iterator_facade<
{ node_iterator_base<V>, node_iterator_value<V>,
private: std::forward_iterator_tag, node_iterator_value<V> > {
struct enabler {}; private:
struct enabler {};
public:
typedef typename node_iterator_type<V>::seq SeqIter; public:
typedef typename node_iterator_type<V>::map MapIter; typedef typename node_iterator_type<V>::seq SeqIter;
typedef node_iterator_value<V> value_type; typedef typename node_iterator_type<V>::map MapIter;
typedef node_iterator_value<V> value_type;
node_iterator_base(): m_type(iterator_type::None) {}
explicit node_iterator_base(SeqIter seqIt): m_type(iterator_type::Sequence), m_seqIt(seqIt) {} node_iterator_base() : m_type(iterator_type::None) {}
explicit node_iterator_base(MapIter mapIt, MapIter mapEnd): m_type(iterator_type::Map), m_mapIt(mapIt), m_mapEnd(mapEnd) { explicit node_iterator_base(SeqIter seqIt)
m_mapIt = increment_until_defined(m_mapIt); : m_type(iterator_type::Sequence), m_seqIt(seqIt) {}
} explicit node_iterator_base(MapIter mapIt, MapIter mapEnd)
: m_type(iterator_type::Map), m_mapIt(mapIt), m_mapEnd(mapEnd) {
template<typename W> m_mapIt = increment_until_defined(m_mapIt);
node_iterator_base(const node_iterator_base<W>& rhs, typename boost::enable_if<boost::is_convertible<W*, V*>, enabler>::type = enabler()) }
: m_type(rhs.m_type), m_seqIt(rhs.m_seqIt), m_mapIt(rhs.m_mapIt), m_mapEnd(rhs.m_mapEnd) {}
template <typename W>
private: node_iterator_base(
friend class boost::iterator_core_access; const node_iterator_base<W>& rhs,
template<typename> friend class node_iterator_base; typename boost::enable_if<boost::is_convertible<W*, V*>, enabler>::type =
enabler())
template<typename W> : m_type(rhs.m_type),
bool equal(const node_iterator_base<W>& rhs) const { m_seqIt(rhs.m_seqIt),
if(m_type != rhs.m_type) m_mapIt(rhs.m_mapIt),
return false; m_mapEnd(rhs.m_mapEnd) {}
switch(m_type) { private:
case iterator_type::None: return true; friend class boost::iterator_core_access;
case iterator_type::Sequence: return m_seqIt == rhs.m_seqIt; template <typename>
case iterator_type::Map: return m_mapIt == rhs.m_mapIt; friend class node_iterator_base;
}
return true; template <typename W>
} bool equal(const node_iterator_base<W>& rhs) const {
if (m_type != rhs.m_type)
void increment() { return false;
switch(m_type) {
case iterator_type::None: break; switch (m_type) {
case iterator_type::Sequence: case iterator_type::None:
++m_seqIt; return true;
break; case iterator_type::Sequence:
case iterator_type::Map: return m_seqIt == rhs.m_seqIt;
++m_mapIt; case iterator_type::Map:
m_mapIt = increment_until_defined(m_mapIt); return m_mapIt == rhs.m_mapIt;
break; }
} return true;
} }
value_type dereference() const { void increment() {
switch(m_type) { switch (m_type) {
case iterator_type::None: return value_type(); case iterator_type::None:
case iterator_type::Sequence: return value_type(**m_seqIt); break;
case iterator_type::Map: return value_type(*m_mapIt->first, *m_mapIt->second); case iterator_type::Sequence:
} ++m_seqIt;
return value_type(); break;
} case iterator_type::Map:
++m_mapIt;
MapIter increment_until_defined(MapIter it) { m_mapIt = increment_until_defined(m_mapIt);
while(it != m_mapEnd && !is_defined(it)) break;
++it; }
return it; }
}
value_type dereference() const {
bool is_defined(MapIter it) const { switch (m_type) {
return it->first->is_defined() && it->second->is_defined(); case iterator_type::None:
} return value_type();
case iterator_type::Sequence:
private: return value_type(**m_seqIt);
typename iterator_type::value m_type; case iterator_type::Map:
return value_type(*m_mapIt->first, *m_mapIt->second);
SeqIter m_seqIt; }
MapIter m_mapIt, m_mapEnd; return value_type();
}; }
typedef node_iterator_base<node> node_iterator; MapIter increment_until_defined(MapIter it) {
typedef node_iterator_base<const node> const_node_iterator; while (it != m_mapEnd && !is_defined(it))
} ++it;
return it;
}
bool is_defined(MapIter it) const {
return it->first->is_defined() && it->second->is_defined();
}
private:
typename iterator_type::value m_type;
SeqIter m_seqIt;
MapIter m_mapIt, m_mapEnd;
};
typedef node_iterator_base<node> node_iterator;
typedef node_iterator_base<const node> const_node_iterator;
}
} }
#endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_NODE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/type.h" #include "yaml-cpp/node/type.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/detail/node_data.h" #include "yaml-cpp/node/detail/node_data.h"
#include <boost/utility.hpp> #include <boost/utility.hpp>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail class node_ref : private boost::noncopyable {
{ public:
class node_ref: private boost::noncopyable node_ref() : m_pData(new node_data) {}
{
public: bool is_defined() const { return m_pData->is_defined(); }
node_ref(): m_pData(new node_data) {} NodeType::value type() const { return m_pData->type(); }
const std::string& scalar() const { return m_pData->scalar(); }
bool is_defined() const { return m_pData->is_defined(); } const std::string& tag() const { return m_pData->tag(); }
NodeType::value type() const { return m_pData->type(); }
const std::string& scalar() const { return m_pData->scalar(); } void mark_defined() { m_pData->mark_defined(); }
const std::string& tag() const { return m_pData->tag(); } void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; }
void mark_defined() { m_pData->mark_defined(); } void set_type(NodeType::value type) { m_pData->set_type(type); }
void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; } void set_tag(const std::string& tag) { m_pData->set_tag(tag); }
void set_null() { m_pData->set_null(); }
void set_type(NodeType::value type) { m_pData->set_type(type); } void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); }
void set_tag(const std::string& tag) { m_pData->set_tag(tag); }
void set_null() { m_pData->set_null(); } // size/iterator
void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); } std::size_t size() const { return m_pData->size(); }
// size/iterator const_node_iterator begin() const {
std::size_t size() const { return m_pData->size(); } return static_cast<const node_data&>(*m_pData).begin();
}
const_node_iterator begin() const { return static_cast<const node_data&>(*m_pData).begin(); } node_iterator begin() { return m_pData->begin(); }
node_iterator begin() {return m_pData->begin(); }
const_node_iterator end() const { return static_cast<const node_data&>(*m_pData).end(); }
node_iterator end() {return m_pData->end(); }
// sequence const_node_iterator end() const {
void push_back(node& node, shared_memory_holder pMemory) { m_pData->push_back(node, pMemory); } return static_cast<const node_data&>(*m_pData).end();
void insert(node& key, node& value, shared_memory_holder pMemory) { m_pData->insert(key, value, pMemory); } }
node_iterator end() { return m_pData->end(); }
// indexing
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast<const node_data&>(*m_pData).get(key, pMemory); }
template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); }
template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory) { return m_pData->remove(key, pMemory); }
node& get(node& key, shared_memory_holder pMemory) const { return static_cast<const node_data&>(*m_pData).get(key, pMemory); }
node& get(node& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); }
bool remove(node& key, shared_memory_holder pMemory) { return m_pData->remove(key, pMemory); }
// map
template<typename Key, typename Value>
void force_insert(const Key& key, const Value& value, shared_memory_holder pMemory) { m_pData->force_insert(key, value, pMemory); }
private: // sequence
shared_node_data m_pData; void push_back(node& node, shared_memory_holder pMemory) {
}; m_pData->push_back(node, pMemory);
} }
void insert(node& key, node& value, shared_memory_holder pMemory) {
m_pData->insert(key, value, pMemory);
}
// indexing
template <typename Key>
node& get(const Key& key, shared_memory_holder pMemory) const {
return static_cast<const node_data&>(*m_pData).get(key, pMemory);
}
template <typename Key>
node& get(const Key& key, shared_memory_holder pMemory) {
return m_pData->get(key, pMemory);
}
template <typename Key>
bool remove(const Key& key, shared_memory_holder pMemory) {
return m_pData->remove(key, pMemory);
}
node& get(node& key, shared_memory_holder pMemory) const {
return static_cast<const node_data&>(*m_pData).get(key, pMemory);
}
node& get(node& key, shared_memory_holder pMemory) {
return m_pData->get(key, pMemory);
}
bool remove(node& key, shared_memory_holder pMemory) {
return m_pData->remove(key, pMemory);
}
// map
template <typename Key, typename Value>
void force_insert(const Key& key, const Value& value,
shared_memory_holder pMemory) {
m_pData->force_insert(key, value, pMemory);
}
private:
shared_node_data m_pData;
};
}
} }
#endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_DETAIL_NODE_REF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include <iosfwd> #include <iosfwd>
namespace YAML namespace YAML {
{ class Emitter;
class Emitter; class Node;
class Node;
Emitter& operator<<(Emitter& out, const Node& node);
Emitter& operator << (Emitter& out, const Node& node); std::ostream& operator<<(std::ostream& out, const Node& node);
std::ostream& operator << (std::ostream& out, const Node& node);
std::string Dump(const Node& node);
}
#endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 std::string Dump(const Node& node);
}
#endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/node/node.h" #include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/iterator.h" #include "yaml-cpp/node/iterator.h"
#include "yaml-cpp/node/detail/memory.h" #include "yaml-cpp/node/detail/memory.h"
...@@ -13,439 +14,406 @@ ...@@ -13,439 +14,406 @@
#include "yaml-cpp/exceptions.h" #include "yaml-cpp/exceptions.h"
#include <string> #include <string>
namespace YAML namespace YAML {
{ inline Node::Node() : m_isValid(true), m_pNode(NULL) {}
inline Node::Node(): m_isValid(true), m_pNode(NULL)
{ inline Node::Node(NodeType::value type)
} : m_isValid(true),
m_pMemory(new detail::memory_holder),
inline Node::Node(NodeType::value type): m_isValid(true), m_pMemory(new detail::memory_holder), m_pNode(&m_pMemory->create_node()) m_pNode(&m_pMemory->create_node()) {
{ m_pNode->set_type(type);
m_pNode->set_type(type); }
}
template <typename T>
template<typename T> inline Node::Node(const T& rhs)
inline Node::Node(const T& rhs): m_isValid(true), m_pMemory(new detail::memory_holder), m_pNode(&m_pMemory->create_node()) : m_isValid(true),
{ m_pMemory(new detail::memory_holder),
Assign(rhs); m_pNode(&m_pMemory->create_node()) {
} Assign(rhs);
}
inline Node::Node(const detail::iterator_value& rhs): m_isValid(rhs.m_isValid), m_pMemory(rhs.m_pMemory), m_pNode(rhs.m_pNode)
{ inline Node::Node(const detail::iterator_value& rhs)
} : m_isValid(rhs.m_isValid),
m_pMemory(rhs.m_pMemory),
inline Node::Node(const Node& rhs): m_isValid(rhs.m_isValid), m_pMemory(rhs.m_pMemory), m_pNode(rhs.m_pNode) m_pNode(rhs.m_pNode) {}
{
} inline Node::Node(const Node& rhs)
: m_isValid(rhs.m_isValid),
inline Node::Node(Zombie): m_isValid(false), m_pNode(NULL) m_pMemory(rhs.m_pMemory),
{ m_pNode(rhs.m_pNode) {}
}
inline Node::Node(Zombie) : m_isValid(false), m_pNode(NULL) {}
inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory): m_isValid(true), m_pMemory(pMemory), m_pNode(&node)
{ inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory)
} : m_isValid(true), m_pMemory(pMemory), m_pNode(&node) {}
inline Node::~Node() inline Node::~Node() {}
{
} inline void Node::EnsureNodeExists() const {
if (!m_isValid)
inline void Node::EnsureNodeExists() const throw InvalidNode();
{ if (!m_pNode) {
if(!m_isValid) m_pMemory.reset(new detail::memory_holder);
throw InvalidNode(); m_pNode = &m_pMemory->create_node();
if(!m_pNode) { m_pNode->set_null();
m_pMemory.reset(new detail::memory_holder); }
m_pNode = &m_pMemory->create_node(); }
m_pNode->set_null();
} inline bool Node::IsDefined() const {
} if (!m_isValid)
throw InvalidNode();
inline bool Node::IsDefined() const return m_pNode ? m_pNode->is_defined() : true;
{ }
if(!m_isValid)
throw InvalidNode(); inline NodeType::value Node::Type() const {
return m_pNode ? m_pNode->is_defined() : true; if (!m_isValid)
} throw InvalidNode();
return m_pNode ? m_pNode->type() : NodeType::Null;
inline NodeType::value Node::Type() const }
{
if(!m_isValid) // access
throw InvalidNode();
return m_pNode ? m_pNode->type() : NodeType::Null; // template helpers
} template <typename T, typename S>
struct as_if {
// access explicit as_if(const Node& node_) : node(node_) {}
const Node& node;
// template helpers
template<typename T, typename S> const T operator()(const S& fallback) const {
struct as_if { if (!node.m_pNode)
explicit as_if(const Node& node_): node(node_) {} return fallback;
const Node& node;
T t;
const T operator()(const S& fallback) const { if (convert<T>::decode(node, t))
if(!node.m_pNode) return t;
return fallback; return fallback;
}
T t; };
if(convert<T>::decode(node, t))
return t; template <typename S>
return fallback; struct as_if<std::string, S> {
} explicit as_if(const Node& node_) : node(node_) {}
}; const Node& node;
template<typename S> const std::string operator()(const S& fallback) const {
struct as_if<std::string, S> { if (node.Type() != NodeType::Scalar)
explicit as_if(const Node& node_): node(node_) {} return fallback;
const Node& node; return node.Scalar();
}
const std::string operator()(const S& fallback) const { };
if(node.Type() != NodeType::Scalar)
return fallback; template <typename T>
return node.Scalar(); struct as_if<T, void> {
} explicit as_if(const Node& node_) : node(node_) {}
}; const Node& node;
template<typename T> const T operator()() const {
struct as_if<T, void> { if (!node.m_pNode)
explicit as_if(const Node& node_): node(node_) {} throw TypedBadConversion<T>();
const Node& node;
T t;
const T operator()() const { if (convert<T>::decode(node, t))
if(!node.m_pNode) return t;
throw TypedBadConversion<T>(); throw TypedBadConversion<T>();
}
T t; };
if(convert<T>::decode(node, t))
return t; template <>
throw TypedBadConversion<T>(); struct as_if<std::string, void> {
} explicit as_if(const Node& node_) : node(node_) {}
}; const Node& node;
template<> const std::string operator()() const {
struct as_if<std::string, void> { if (node.Type() != NodeType::Scalar)
explicit as_if(const Node& node_): node(node_) {} throw TypedBadConversion<std::string>();
const Node& node; return node.Scalar();
}
const std::string operator()() const { };
if(node.Type() != NodeType::Scalar)
throw TypedBadConversion<std::string>(); // access functions
return node.Scalar(); template <typename T>
} inline const T Node::as() const {
}; if (!m_isValid)
throw InvalidNode();
// access functions return as_if<T, void>(*this)();
template<typename T> }
inline const T Node::as() const
{ template <typename T, typename S>
if(!m_isValid) inline const T Node::as(const S& fallback) const {
throw InvalidNode(); if (!m_isValid)
return as_if<T, void>(*this)(); throw InvalidNode();
} return as_if<T, S>(*this)(fallback);
}
template<typename T, typename S>
inline const T Node::as(const S& fallback) const inline const std::string& Node::Scalar() const {
{ if (!m_isValid)
if(!m_isValid) throw InvalidNode();
throw InvalidNode(); return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar;
return as_if<T, S>(*this)(fallback); }
}
inline const std::string& Node::Tag() const {
inline const std::string& Node::Scalar() const if (!m_isValid)
{ throw InvalidNode();
if(!m_isValid) return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar;
throw InvalidNode(); }
return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar;
} inline void Node::SetTag(const std::string& tag) {
if (!m_isValid)
inline const std::string& Node::Tag() const throw InvalidNode();
{ EnsureNodeExists();
if(!m_isValid) m_pNode->set_tag(tag);
throw InvalidNode(); }
return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar;
} // assignment
inline bool Node::is(const Node& rhs) const {
inline void Node::SetTag(const std::string& tag) if (!m_isValid || !rhs.m_isValid)
{ throw InvalidNode();
if(!m_isValid) if (!m_pNode || !rhs.m_pNode)
throw InvalidNode(); return false;
EnsureNodeExists(); return m_pNode->is(*rhs.m_pNode);
m_pNode->set_tag(tag); }
}
template <typename T>
// assignment inline Node& Node::operator=(const T& rhs) {
inline bool Node::is(const Node& rhs) const if (!m_isValid)
{ throw InvalidNode();
if(!m_isValid || !rhs.m_isValid) Assign(rhs);
throw InvalidNode(); return *this;
if(!m_pNode || !rhs.m_pNode) }
return false;
return m_pNode->is(*rhs.m_pNode); inline void Node::reset(const YAML::Node& rhs) {
} if (!m_isValid || !rhs.m_isValid)
throw InvalidNode();
template<typename T> m_pMemory = rhs.m_pMemory;
inline Node& Node::operator=(const T& rhs) m_pNode = rhs.m_pNode;
{ }
if(!m_isValid)
throw InvalidNode(); template <typename T>
Assign(rhs); inline void Node::Assign(const T& rhs) {
return *this; if (!m_isValid)
} throw InvalidNode();
AssignData(convert<T>::encode(rhs));
inline void Node::reset(const YAML::Node& rhs) }
{
if(!m_isValid || !rhs.m_isValid) template <>
throw InvalidNode(); inline void Node::Assign(const std::string& rhs) {
m_pMemory = rhs.m_pMemory; if (!m_isValid)
m_pNode = rhs.m_pNode; throw InvalidNode();
} EnsureNodeExists();
m_pNode->set_scalar(rhs);
template<typename T> }
inline void Node::Assign(const T& rhs)
{ inline void Node::Assign(const char* rhs) {
if(!m_isValid) if (!m_isValid)
throw InvalidNode(); throw InvalidNode();
AssignData(convert<T>::encode(rhs)); EnsureNodeExists();
} m_pNode->set_scalar(rhs);
}
template<>
inline void Node::Assign(const std::string& rhs) inline void Node::Assign(char* rhs) {
{ if (!m_isValid)
if(!m_isValid) throw InvalidNode();
throw InvalidNode(); EnsureNodeExists();
EnsureNodeExists(); m_pNode->set_scalar(rhs);
m_pNode->set_scalar(rhs); }
}
inline Node& Node::operator=(const Node& rhs) {
inline void Node::Assign(const char *rhs) if (!m_isValid || !rhs.m_isValid)
{ throw InvalidNode();
if(!m_isValid) if (is(rhs))
throw InvalidNode(); return *this;
EnsureNodeExists(); AssignNode(rhs);
m_pNode->set_scalar(rhs); return *this;
} }
inline void Node::Assign(char *rhs) inline void Node::AssignData(const Node& rhs) {
{ if (!m_isValid || !rhs.m_isValid)
if(!m_isValid) throw InvalidNode();
throw InvalidNode(); EnsureNodeExists();
EnsureNodeExists(); rhs.EnsureNodeExists();
m_pNode->set_scalar(rhs);
} m_pNode->set_data(*rhs.m_pNode);
m_pMemory->merge(*rhs.m_pMemory);
inline Node& Node::operator=(const Node& rhs) }
{
if(!m_isValid || !rhs.m_isValid) inline void Node::AssignNode(const Node& rhs) {
throw InvalidNode(); if (!m_isValid || !rhs.m_isValid)
if(is(rhs)) throw InvalidNode();
return *this; rhs.EnsureNodeExists();
AssignNode(rhs);
return *this; if (!m_pNode) {
} m_pNode = rhs.m_pNode;
m_pMemory = rhs.m_pMemory;
inline void Node::AssignData(const Node& rhs) return;
{ }
if(!m_isValid || !rhs.m_isValid)
throw InvalidNode(); m_pNode->set_ref(*rhs.m_pNode);
EnsureNodeExists(); m_pMemory->merge(*rhs.m_pMemory);
rhs.EnsureNodeExists(); m_pNode = rhs.m_pNode;
}
m_pNode->set_data(*rhs.m_pNode);
m_pMemory->merge(*rhs.m_pMemory); // size/iterator
} inline std::size_t Node::size() const {
if (!m_isValid)
inline void Node::AssignNode(const Node& rhs) throw InvalidNode();
{ return m_pNode ? m_pNode->size() : 0;
if(!m_isValid || !rhs.m_isValid) }
throw InvalidNode();
rhs.EnsureNodeExists(); inline const_iterator Node::begin() const {
if (!m_isValid)
if(!m_pNode) { throw InvalidNode();
m_pNode = rhs.m_pNode; return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory)
m_pMemory = rhs.m_pMemory; : const_iterator();
return; }
}
inline iterator Node::begin() {
m_pNode->set_ref(*rhs.m_pNode); if (!m_isValid)
m_pMemory->merge(*rhs.m_pMemory); throw InvalidNode();
m_pNode = rhs.m_pNode; return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator();
} }
// size/iterator inline const_iterator Node::end() const {
inline std::size_t Node::size() const if (!m_isValid)
{ throw InvalidNode();
if(!m_isValid) return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator();
throw InvalidNode(); }
return m_pNode ? m_pNode->size() : 0;
} inline iterator Node::end() {
if (!m_isValid)
inline const_iterator Node::begin() const throw InvalidNode();
{ return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator();
if(!m_isValid) }
throw InvalidNode();
return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory) : const_iterator(); // sequence
} template <typename T>
inline void Node::push_back(const T& rhs) {
inline iterator Node::begin() if (!m_isValid)
{ throw InvalidNode();
if(!m_isValid) push_back(Node(rhs));
throw InvalidNode(); }
return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator();
} inline void Node::push_back(const Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
inline const_iterator Node::end() const throw InvalidNode();
{ EnsureNodeExists();
if(!m_isValid) rhs.EnsureNodeExists();
throw InvalidNode();
return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator(); m_pNode->push_back(*rhs.m_pNode, m_pMemory);
} m_pMemory->merge(*rhs.m_pMemory);
}
inline iterator Node::end()
{ // helpers for indexing
if(!m_isValid) namespace detail {
throw InvalidNode(); template <typename T>
return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator(); struct to_value_t {
} explicit to_value_t(const T& t_) : t(t_) {}
const T& t;
// sequence typedef const T& return_type;
template<typename T>
inline void Node::push_back(const T& rhs) const T& operator()() const { return t; }
{ };
if(!m_isValid)
throw InvalidNode(); template <>
push_back(Node(rhs)); struct to_value_t<const char*> {
} explicit to_value_t(const char* t_) : t(t_) {}
const char* t;
inline void Node::push_back(const Node& rhs) typedef std::string return_type;
{
if(!m_isValid || !rhs.m_isValid) const std::string operator()() const { return t; }
throw InvalidNode(); };
EnsureNodeExists();
rhs.EnsureNodeExists(); template <>
struct to_value_t<char*> {
m_pNode->push_back(*rhs.m_pNode, m_pMemory); explicit to_value_t(char* t_) : t(t_) {}
m_pMemory->merge(*rhs.m_pMemory); const char* t;
} typedef std::string return_type;
// helpers for indexing const std::string operator()() const { return t; }
namespace detail { };
template<typename T>
struct to_value_t { template <std::size_t N>
explicit to_value_t(const T& t_): t(t_) {} struct to_value_t<char[N]> {
const T& t; explicit to_value_t(const char* t_) : t(t_) {}
typedef const T& return_type; const char* t;
typedef std::string return_type;
const T& operator()() const { return t; }
}; const std::string operator()() const { return t; }
};
template<>
struct to_value_t<const char*> { // converts C-strings to std::strings so they can be copied
explicit to_value_t(const char *t_): t(t_) {} template <typename T>
const char *t; inline typename to_value_t<T>::return_type to_value(const T& t) {
typedef std::string return_type; return to_value_t<T>(t)();
}
const std::string operator()() const { return t; } }
};
// indexing
template<> template <typename Key>
struct to_value_t<char*> { inline const Node Node::operator[](const Key& key) const {
explicit to_value_t(char *t_): t(t_) {} if (!m_isValid)
const char *t; throw InvalidNode();
typedef std::string return_type; EnsureNodeExists();
detail::node& value = static_cast<const detail::node&>(*m_pNode)
const std::string operator()() const { return t; } .get(detail::to_value(key), m_pMemory);
}; return Node(value, m_pMemory);
}
template<std::size_t N>
struct to_value_t<char [N]> { template <typename Key>
explicit to_value_t(const char *t_): t(t_) {} inline Node Node::operator[](const Key& key) {
const char *t; if (!m_isValid)
typedef std::string return_type; throw InvalidNode();
EnsureNodeExists();
const std::string operator()() const { return t; } detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory);
}; return Node(value, m_pMemory);
}
// converts C-strings to std::strings so they can be copied
template<typename T> template <typename Key>
inline typename to_value_t<T>::return_type to_value(const T& t) { inline bool Node::remove(const Key& key) {
return to_value_t<T>(t)(); if (!m_isValid)
} throw InvalidNode();
} EnsureNodeExists();
return m_pNode->remove(detail::to_value(key), m_pMemory);
// indexing }
template<typename Key>
inline const Node Node::operator[](const Key& key) const inline const Node Node::operator[](const Node& key) const {
{ if (!m_isValid || !key.m_isValid)
if(!m_isValid) throw InvalidNode();
throw InvalidNode(); EnsureNodeExists();
EnsureNodeExists(); key.EnsureNodeExists();
detail::node& value = static_cast<const detail::node&>(*m_pNode).get(detail::to_value(key), m_pMemory); detail::node& value =
return Node(value, m_pMemory); static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory);
} return Node(value, m_pMemory);
}
template<typename Key>
inline Node Node::operator[](const Key& key) inline Node Node::operator[](const Node& key) {
{ if (!m_isValid || !key.m_isValid)
if(!m_isValid) throw InvalidNode();
throw InvalidNode(); EnsureNodeExists();
EnsureNodeExists(); key.EnsureNodeExists();
detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory); detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory);
return Node(value, m_pMemory); return Node(value, m_pMemory);
} }
template<typename Key> inline bool Node::remove(const Node& key) {
inline bool Node::remove(const Key& key) if (!m_isValid || !key.m_isValid)
{ throw InvalidNode();
if(!m_isValid) EnsureNodeExists();
throw InvalidNode(); key.EnsureNodeExists();
EnsureNodeExists(); return m_pNode->remove(*key.m_pNode, m_pMemory);
return m_pNode->remove(detail::to_value(key), m_pMemory); }
}
// map
inline const Node Node::operator[](const Node& key) const template <typename Key, typename Value>
{ inline void Node::force_insert(const Key& key, const Value& value) {
if(!m_isValid || !key.m_isValid) if (!m_isValid)
throw InvalidNode(); throw InvalidNode();
EnsureNodeExists(); EnsureNodeExists();
key.EnsureNodeExists(); m_pNode->force_insert(detail::to_value(key), detail::to_value(value),
detail::node& value = static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory); m_pMemory);
return Node(value, m_pMemory); }
}
// free functions
inline Node Node::operator[](const Node& key) inline bool operator==(const Node& lhs, const Node& rhs) { return lhs.is(rhs); }
{ }
if(!m_isValid || !key.m_isValid)
throw InvalidNode(); #endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
EnsureNodeExists();
key.EnsureNodeExists();
detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory);
return Node(value, m_pMemory);
}
inline bool Node::remove(const Node& key)
{
if(!m_isValid || !key.m_isValid)
throw InvalidNode();
EnsureNodeExists();
key.EnsureNodeExists();
return m_pNode->remove(*key.m_pNode, m_pMemory);
}
// map
template<typename Key, typename Value>
inline void Node::force_insert(const Key& key, const Value& value)
{
if(!m_isValid)
throw InvalidNode();
EnsureNodeExists();
m_pNode->force_insert(detail::to_value(key), detail::to_value(value), m_pMemory);
}
// free functions
inline bool operator==(const Node& lhs, const Node& rhs)
{
return lhs.is(rhs);
}
}
#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/node.h" #include "yaml-cpp/node/node.h"
#include "yaml-cpp/node/detail/iterator_fwd.h" #include "yaml-cpp/node/detail/iterator_fwd.h"
...@@ -14,15 +15,17 @@ ...@@ -14,15 +15,17 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail { struct iterator_value : public Node, std::pair<Node, Node> {
struct iterator_value: public Node, std::pair<Node, Node> { iterator_value() {}
iterator_value() {} explicit iterator_value(const Node& rhs)
explicit iterator_value(const Node& rhs): Node(rhs), std::pair<Node, Node>(Node(Node::ZombieNode), Node(Node::ZombieNode)) {} : Node(rhs),
explicit iterator_value(const Node& key, const Node& value): Node(Node::ZombieNode), std::pair<Node, Node>(key, value) {} std::pair<Node, Node>(Node(Node::ZombieNode), Node(Node::ZombieNode)) {}
}; explicit iterator_value(const Node& key, const Node& value)
} : Node(Node::ZombieNode), std::pair<Node, Node>(key, value) {}
};
}
} }
#endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include "yaml-cpp/node/type.h" #include "yaml-cpp/node/type.h"
...@@ -13,104 +14,115 @@ ...@@ -13,104 +14,115 @@
#include "yaml-cpp/node/detail/bool_type.h" #include "yaml-cpp/node/detail/bool_type.h"
#include <stdexcept> #include <stdexcept>
namespace YAML namespace YAML {
{ class Node {
class Node public:
{ friend class NodeBuilder;
public: friend class NodeEvents;
friend class NodeBuilder; friend struct detail::iterator_value;
friend class NodeEvents; friend class detail::node_data;
friend struct detail::iterator_value; template <typename>
friend class detail::node_data; friend class detail::iterator_base;
template<typename> friend class detail::iterator_base; template <typename T, typename S>
template<typename T, typename S> friend struct as_if; friend struct as_if;
typedef YAML::iterator iterator; typedef YAML::iterator iterator;
typedef YAML::const_iterator const_iterator; typedef YAML::const_iterator const_iterator;
Node(); Node();
explicit Node(NodeType::value type); explicit Node(NodeType::value type);
template<typename T> explicit Node(const T& rhs); template <typename T>
explicit Node(const detail::iterator_value& rhs); explicit Node(const T& rhs);
Node(const Node& rhs); explicit Node(const detail::iterator_value& rhs);
~Node(); Node(const Node& rhs);
~Node();
NodeType::value Type() const;
bool IsDefined() const; NodeType::value Type() const;
bool IsNull() const { return Type() == NodeType::Null; } bool IsDefined() const;
bool IsScalar() const { return Type() == NodeType::Scalar; } bool IsNull() const { return Type() == NodeType::Null; }
bool IsSequence() const { return Type() == NodeType::Sequence; } bool IsScalar() const { return Type() == NodeType::Scalar; }
bool IsMap() const { return Type() == NodeType::Map; } bool IsSequence() const { return Type() == NodeType::Sequence; }
bool IsMap() const { return Type() == NodeType::Map; }
// bool conversions
YAML_CPP_OPERATOR_BOOL(); // bool conversions
bool operator!() const { return !IsDefined(); } YAML_CPP_OPERATOR_BOOL();
bool operator!() const { return !IsDefined(); }
// access
template<typename T> const T as() const; // access
template<typename T, typename S> const T as(const S& fallback) const; template <typename T>
const std::string& Scalar() const; const T as() const;
const std::string& Tag() const; template <typename T, typename S>
void SetTag(const std::string& tag); const T as(const S& fallback) const;
const std::string& Scalar() const;
// assignment const std::string& Tag() const;
bool is(const Node& rhs) const; void SetTag(const std::string& tag);
template<typename T> Node& operator=(const T& rhs);
Node& operator=(const Node& rhs); // assignment
void reset(const Node& rhs = Node()); bool is(const Node& rhs) const;
template <typename T>
// size/iterator Node& operator=(const T& rhs);
std::size_t size() const; Node& operator=(const Node& rhs);
void reset(const Node& rhs = Node());
const_iterator begin() const;
iterator begin(); // size/iterator
std::size_t size() const;
const_iterator end() const;
iterator end(); const_iterator begin() const;
iterator begin();
// sequence
template<typename T> void push_back(const T& rhs); const_iterator end() const;
void push_back(const Node& rhs); iterator end();
// indexing // sequence
template<typename Key> const Node operator[](const Key& key) const; template <typename T>
template<typename Key> Node operator[](const Key& key); void push_back(const T& rhs);
template<typename Key> bool remove(const Key& key); void push_back(const Node& rhs);
const Node operator[](const Node& key) const; // indexing
Node operator[](const Node& key); template <typename Key>
bool remove(const Node& key); const Node operator[](const Key& key) const;
template <typename Key>
// map Node operator[](const Key& key);
template<typename Key, typename Value> template <typename Key>
void force_insert(const Key& key, const Value& value); bool remove(const Key& key);
private: const Node operator[](const Node& key) const;
enum Zombie { ZombieNode }; Node operator[](const Node& key);
explicit Node(Zombie); bool remove(const Node& key);
explicit Node(detail::node& node, detail::shared_memory_holder pMemory);
// map
void EnsureNodeExists() const; template <typename Key, typename Value>
void force_insert(const Key& key, const Value& value);
template<typename T> void Assign(const T& rhs);
void Assign(const char *rhs); private:
void Assign(char *rhs); enum Zombie {
ZombieNode
void AssignData(const Node& rhs); };
void AssignNode(const Node& rhs); explicit Node(Zombie);
explicit Node(detail::node& node, detail::shared_memory_holder pMemory);
private:
bool m_isValid; void EnsureNodeExists() const;
mutable detail::shared_memory_holder m_pMemory;
mutable detail::node *m_pNode; template <typename T>
}; void Assign(const T& rhs);
void Assign(const char* rhs);
bool operator==(const Node& lhs, const Node& rhs); void Assign(char* rhs);
Node Clone(const Node& node); void AssignData(const Node& rhs);
void AssignNode(const Node& rhs);
template<typename T>
struct convert; private:
bool m_isValid;
mutable detail::shared_memory_holder m_pMemory;
mutable detail::node* m_pNode;
};
bool operator==(const Node& lhs, const Node& rhs);
Node Clone(const Node& node);
template <typename T>
struct convert;
} }
#endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
...@@ -9,20 +11,18 @@ ...@@ -9,20 +11,18 @@
#include <string> #include <string>
#include <vector> #include <vector>
namespace YAML namespace YAML {
{ class Node;
class Node;
Node Load(const std::string& input);
Node Load(const char *input);
Node Load(std::istream& input);
Node LoadFile(const std::string& filename);
std::vector<Node> LoadAll(const std::string& input); Node Load(const std::string& input);
std::vector<Node> LoadAll(const char *input); Node Load(const char* input);
std::vector<Node> LoadAll(std::istream& input); Node Load(std::istream& input);
std::vector<Node> LoadAllFromFile(const std::string& filename); Node LoadFile(const std::string& filename);
}
#endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 std::vector<Node> LoadAll(const std::string& input);
std::vector<Node> LoadAll(const char* input);
std::vector<Node> LoadAll(std::istream& input);
std::vector<Node> LoadAllFromFile(const std::string& filename);
}
#endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail { class node;
class node; class node_ref;
class node_ref; class node_data;
class node_data; class memory;
class memory; class memory_holder;
class memory_holder;
typedef boost::shared_ptr<node> shared_node; typedef boost::shared_ptr<node> shared_node;
typedef boost::shared_ptr<node_ref> shared_node_ref; typedef boost::shared_ptr<node_ref> shared_node_ref;
typedef boost::shared_ptr<node_data> shared_node_data; typedef boost::shared_ptr<node_data> shared_node_data;
typedef boost::shared_ptr<memory_holder> shared_memory_holder; typedef boost::shared_ptr<memory_holder> shared_memory_holder;
typedef boost::shared_ptr<memory> shared_memory; typedef boost::shared_ptr<memory> shared_memory;
} }
} }
#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
namespace YAML {
namespace YAML struct NodeType {
{ enum value {
struct NodeType { enum value { Undefined, Null, Scalar, Sequence, Map }; }; Undefined,
Null,
Scalar,
Sequence,
Map
};
};
} }
#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/noncopyable.h" #include "yaml-cpp/noncopyable.h"
#include <ios> #include <ios>
#include <memory> #include <memory>
namespace YAML namespace YAML {
{ struct Directives;
struct Directives; struct Token;
struct Token; class EventHandler;
class EventHandler; class Scanner;
class Scanner;
class YAML_CPP_API Parser : private noncopyable {
class YAML_CPP_API Parser: private noncopyable public:
{ Parser();
public: Parser(std::istream& in);
Parser(); ~Parser();
Parser(std::istream& in);
~Parser(); operator bool() const;
operator bool() const; void Load(std::istream& in);
bool HandleNextDocument(EventHandler& eventHandler);
void Load(std::istream& in);
bool HandleNextDocument(EventHandler& eventHandler); void PrintTokens(std::ostream& out);
void PrintTokens(std::ostream& out); private:
void ParseDirectives();
private: void HandleDirective(const Token& token);
void ParseDirectives(); void HandleYamlDirective(const Token& token);
void HandleDirective(const Token& token); void HandleTagDirective(const Token& token);
void HandleYamlDirective(const Token& token);
void HandleTagDirective(const Token& token); private:
std::auto_ptr<Scanner> m_pScanner;
private: std::auto_ptr<Directives> m_pDirectives;
std::auto_ptr<Scanner> m_pScanner; };
std::auto_ptr<Directives> m_pDirectives;
};
} }
#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
...@@ -18,4 +20,4 @@ ...@@ -18,4 +20,4 @@
#include "yaml-cpp/node/parse.h" #include "yaml-cpp/node/parse.h"
#include "yaml-cpp/node/emit.h" #include "yaml-cpp/node/emit.h"
#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
...@@ -2,82 +2,72 @@ ...@@ -2,82 +2,72 @@
#include "yaml-cpp/node/impl.h" #include "yaml-cpp/node/impl.h"
#include <algorithm> #include <algorithm>
namespace namespace {
{ // we're not gonna mess with the mess that is all the isupper/etc. functions
// 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 IsLower(char ch) { return 'a' <= ch && ch <= 'z'; } bool IsUpper(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; }
char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; }
std::string tolower(const std::string& str) {
std::string tolower(const std::string& str) std::string s(str);
{ std::transform(s.begin(), s.end(), s.begin(), ToLower);
std::string s(str); return s;
std::transform(s.begin(), s.end(), s.begin(), ToLower); }
return s;
} template <typename T>
bool IsEntirely(const std::string& str, T func) {
template <typename T> for (std::size_t i = 0; i < str.size(); i++)
bool IsEntirely(const std::string& str, T func) if (!func(str[i]))
{ return false;
for(std::size_t i=0;i<str.size();i++)
if(!func(str[i])) return true;
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));
}
} }
namespace YAML // IsFlexibleCase
{ // . Returns true if 'str' is:
bool convert<bool>::decode(const Node& node, bool& rhs) { // . UPPERCASE
if(!node.IsScalar()) // . lowercase
return false; // . Capitalized
bool IsFlexibleCase(const std::string& str) {
// we can't use iostream bool extraction operators as they don't if (str.empty())
// recognize all possible values in the table below (taken from return true;
// http://yaml.org/type/bool.html)
static const struct { if (IsEntirely(str, IsLower))
std::string truename, falsename; return true;
} names[] = {
{ "y", "n" }, bool firstcaps = IsUpper(str[0]);
{ "yes", "no" }, std::string rest = str.substr(1);
{ "true", "false" }, return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper));
{ "on", "off" }, }
}; }
if(!IsFlexibleCase(node.Scalar())) namespace YAML {
return false; bool convert<bool>::decode(const Node& node, bool& rhs) {
if (!node.IsScalar())
for(unsigned i=0;i<sizeof(names)/sizeof(names[0]);i++) { return false;
if(names[i].truename == tolower(node.Scalar())) {
rhs = true; // we can't use iostream bool extraction operators as they don't
return true; // recognize all possible values in the table below (taken from
} // http://yaml.org/type/bool.html)
static const struct {
if(names[i].falsename == tolower(node.Scalar())) { std::string truename, falsename;
rhs = false; } names[] = {{"y", "n"}, {"yes", "no"}, {"true", "false"}, {"on", "off"}, };
return true;
} if (!IsFlexibleCase(node.Scalar()))
} return false;
return false; for (unsigned i = 0; i < sizeof(names) / sizeof(names[0]); i++) {
} if (names[i].truename == tolower(node.Scalar())) {
rhs = true;
return true;
}
if (names[i].falsename == tolower(node.Scalar())) {
rhs = false;
return true;
}
}
return false;
}
} }
...@@ -3,27 +3,23 @@ ...@@ -3,27 +3,23 @@
#include "yaml-cpp/emitter.h" #include "yaml-cpp/emitter.h"
#include "nodeevents.h" #include "nodeevents.h"
namespace YAML namespace YAML {
{ Emitter& operator<<(Emitter& out, const Node& node) {
Emitter& operator << (Emitter& out, const Node& node) EmitFromEvents emitFromEvents(out);
{ NodeEvents events(node);
EmitFromEvents emitFromEvents(out); events.Emit(emitFromEvents);
NodeEvents events(node); return out;
events.Emit(emitFromEvents); }
return out;
} std::ostream& operator<<(std::ostream& out, const Node& node) {
Emitter emitter(out);
std::ostream& operator << (std::ostream& out, const Node& node) emitter << node;
{ return out;
Emitter emitter(out); }
emitter << node;
return out;
}
std::string Dump(const Node& node) std::string Dump(const Node& node) {
{ Emitter emitter;
Emitter emitter; emitter << node;
emitter << node; return emitter.c_str();
return emitter.c_str(); }
}
} }
#include "yaml-cpp/node/detail/memory.h" #include "yaml-cpp/node/detail/memory.h"
#include "yaml-cpp/node/detail/node.h" #include "yaml-cpp/node/detail/node.h"
namespace YAML namespace YAML {
{ namespace detail {
namespace detail void memory_holder::merge(memory_holder& rhs) {
{ if (m_pMemory == rhs.m_pMemory)
void memory_holder::merge(memory_holder& rhs) return;
{
if(m_pMemory == rhs.m_pMemory) m_pMemory->merge(*rhs.m_pMemory);
return; rhs.m_pMemory = m_pMemory;
}
m_pMemory->merge(*rhs.m_pMemory);
rhs.m_pMemory = m_pMemory; node& memory::create_node() {
} shared_node pNode(new node);
m_nodes.insert(pNode);
node& memory::create_node() return *pNode;
{ }
shared_node pNode(new node);
m_nodes.insert(pNode); void memory::merge(const memory& rhs) {
return *pNode; m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end());
} }
}
void memory::merge(const memory& rhs)
{
m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end());
}
}
} }
...@@ -2,13 +2,11 @@ ...@@ -2,13 +2,11 @@
#include "nodebuilder.h" #include "nodebuilder.h"
#include "nodeevents.h" #include "nodeevents.h"
namespace YAML namespace YAML {
{ Node Clone(const Node& node) {
Node Clone(const Node& node) NodeEvents events(node);
{ NodeBuilder builder;
NodeEvents events(node); events.Emit(builder);
NodeBuilder builder; return builder.Root();
events.Emit(builder); }
return builder.Root();
}
} }
...@@ -4,292 +4,280 @@ ...@@ -4,292 +4,280 @@
#include "yaml-cpp/exceptions.h" #include "yaml-cpp/exceptions.h"
#include <sstream> #include <sstream>
namespace YAML namespace YAML {
{ namespace detail {
namespace detail std::string node_data::empty_scalar;
{
std::string node_data::empty_scalar; node_data::node_data()
: m_isDefined(false), m_type(NodeType::Null), m_seqSize(0) {}
node_data::node_data(): m_isDefined(false), m_type(NodeType::Null), m_seqSize(0)
{ void node_data::mark_defined() {
} if (m_type == NodeType::Undefined)
m_type = NodeType::Null;
void node_data::mark_defined() m_isDefined = true;
{ }
if(m_type == NodeType::Undefined)
m_type = NodeType::Null; void node_data::set_type(NodeType::value type) {
m_isDefined = true; if (type == NodeType::Undefined) {
} m_type = type;
m_isDefined = false;
void node_data::set_type(NodeType::value type) return;
{ }
if(type == NodeType::Undefined) {
m_type = type; m_isDefined = true;
m_isDefined = false; if (type == m_type)
return; return;
}
m_type = type;
m_isDefined = true; switch (m_type) {
if(type == m_type) case NodeType::Null:
return; break;
case NodeType::Scalar:
m_type = type; m_scalar.clear();
break;
switch(m_type) { case NodeType::Sequence:
case NodeType::Null: reset_sequence();
break; break;
case NodeType::Scalar: case NodeType::Map:
m_scalar.clear(); reset_map();
break; break;
case NodeType::Sequence: case NodeType::Undefined:
reset_sequence(); assert(false);
break; break;
case NodeType::Map: }
reset_map(); }
break;
case NodeType::Undefined: void node_data::set_tag(const std::string& tag) { m_tag = tag; }
assert(false);
break; void node_data::set_null() {
} m_isDefined = true;
} m_type = NodeType::Null;
}
void node_data::set_tag(const std::string& tag)
{ void node_data::set_scalar(const std::string& scalar) {
m_tag = tag; m_isDefined = true;
} m_type = NodeType::Scalar;
m_scalar = scalar;
void node_data::set_null() }
{
m_isDefined = true; // size/iterator
m_type = NodeType::Null; std::size_t node_data::size() const {
} if (!m_isDefined)
return 0;
void node_data::set_scalar(const std::string& scalar)
{ switch (m_type) {
m_isDefined = true; case NodeType::Sequence:
m_type = NodeType::Scalar; compute_seq_size();
m_scalar = scalar; return m_seqSize;
} case NodeType::Map:
compute_map_size();
// size/iterator return m_map.size() - m_undefinedPairs.size();
std::size_t node_data::size() const default:
{ return 0;
if(!m_isDefined) }
return 0; return 0;
}
switch(m_type) {
case NodeType::Sequence: compute_seq_size(); return m_seqSize; void node_data::compute_seq_size() const {
case NodeType::Map: compute_map_size(); return m_map.size() - m_undefinedPairs.size(); while (m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined())
default: m_seqSize++;
return 0; }
}
return 0; void node_data::compute_map_size() const {
} kv_pairs::iterator it = m_undefinedPairs.begin();
while (it != m_undefinedPairs.end()) {
void node_data::compute_seq_size() const kv_pairs::iterator jt = boost::next(it);
{ if (it->first->is_defined() && it->second->is_defined())
while(m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined()) m_undefinedPairs.erase(it);
m_seqSize++; it = jt;
} }
}
void node_data::compute_map_size() const
{ const_node_iterator node_data::begin() const {
kv_pairs::iterator it = m_undefinedPairs.begin(); if (!m_isDefined)
while(it != m_undefinedPairs.end()) { return const_node_iterator();
kv_pairs::iterator jt = boost::next(it);
if(it->first->is_defined() && it->second->is_defined()) switch (m_type) {
m_undefinedPairs.erase(it); case NodeType::Sequence:
it = jt; return const_node_iterator(m_sequence.begin());
} case NodeType::Map:
} return const_node_iterator(m_map.begin(), m_map.end());
default:
const_node_iterator node_data::begin() const return const_node_iterator();
{ }
if(!m_isDefined) }
return const_node_iterator();
node_iterator node_data::begin() {
switch(m_type) { if (!m_isDefined)
case NodeType::Sequence: return const_node_iterator(m_sequence.begin()); return node_iterator();
case NodeType::Map: return const_node_iterator(m_map.begin(), m_map.end());
default: return const_node_iterator(); switch (m_type) {
} case NodeType::Sequence:
} return node_iterator(m_sequence.begin());
case NodeType::Map:
node_iterator node_data::begin() return node_iterator(m_map.begin(), m_map.end());
{ default:
if(!m_isDefined) return node_iterator();
return node_iterator(); }
}
switch(m_type) {
case NodeType::Sequence: return node_iterator(m_sequence.begin()); const_node_iterator node_data::end() const {
case NodeType::Map: return node_iterator(m_map.begin(), m_map.end()); if (!m_isDefined)
default: return node_iterator(); return const_node_iterator();
}
} switch (m_type) {
case NodeType::Sequence:
const_node_iterator node_data::end() const return const_node_iterator(m_sequence.end());
{ case NodeType::Map:
if(!m_isDefined) return const_node_iterator(m_map.end(), m_map.end());
return const_node_iterator(); default:
return const_node_iterator();
switch(m_type) { }
case NodeType::Sequence: return const_node_iterator(m_sequence.end()); }
case NodeType::Map: return const_node_iterator(m_map.end(), m_map.end());
default: return const_node_iterator(); node_iterator node_data::end() {
} if (!m_isDefined)
} return node_iterator();
node_iterator node_data::end() switch (m_type) {
{ case NodeType::Sequence:
if(!m_isDefined) return node_iterator(m_sequence.end());
return node_iterator(); case NodeType::Map:
return node_iterator(m_map.end(), m_map.end());
switch(m_type) { default:
case NodeType::Sequence: return node_iterator(m_sequence.end()); return node_iterator();
case NodeType::Map: return node_iterator(m_map.end(), m_map.end()); }
default: return node_iterator(); }
}
} // sequence
void node_data::push_back(node& node, shared_memory_holder /* pMemory */) {
// sequence if (m_type == NodeType::Undefined || m_type == NodeType::Null) {
void node_data::push_back(node& node, shared_memory_holder /* pMemory */) m_type = NodeType::Sequence;
{ reset_sequence();
if(m_type == NodeType::Undefined || m_type == NodeType::Null) { }
m_type = NodeType::Sequence;
reset_sequence(); if (m_type != NodeType::Sequence)
} throw BadPushback();
if(m_type != NodeType::Sequence) m_sequence.push_back(&node);
throw BadPushback(); }
m_sequence.push_back(&node); void node_data::insert(node& key, node& value, shared_memory_holder pMemory) {
} switch (m_type) {
case NodeType::Map:
void node_data::insert(node& key, node& value, shared_memory_holder pMemory) break;
{ case NodeType::Undefined:
switch(m_type) { case NodeType::Null:
case NodeType::Map: case NodeType::Sequence:
break; convert_to_map(pMemory);
case NodeType::Undefined: break;
case NodeType::Null: case NodeType::Scalar:
case NodeType::Sequence: throw BadSubscript();
convert_to_map(pMemory); }
break;
case NodeType::Scalar: insert_map_pair(key, value);
throw BadSubscript(); }
}
// indexing
insert_map_pair(key, value); node& node_data::get(node& key, shared_memory_holder pMemory) const {
} if (m_type != NodeType::Map)
return pMemory->create_node();
// indexing
node& node_data::get(node& key, shared_memory_holder pMemory) const for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
{ if (it->first->is(key))
if(m_type != NodeType::Map) return *it->second;
return pMemory->create_node(); }
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { return pMemory->create_node();
if(it->first->is(key)) }
return *it->second;
} node& node_data::get(node& key, shared_memory_holder pMemory) {
switch (m_type) {
return pMemory->create_node(); case NodeType::Map:
} break;
case NodeType::Undefined:
node& node_data::get(node& key, shared_memory_holder pMemory) case NodeType::Null:
{ case NodeType::Sequence:
switch(m_type) { convert_to_map(pMemory);
case NodeType::Map: break;
break; case NodeType::Scalar:
case NodeType::Undefined: throw BadSubscript();
case NodeType::Null: }
case NodeType::Sequence:
convert_to_map(pMemory); for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
break; if (it->first->is(key))
case NodeType::Scalar: return *it->second;
throw BadSubscript(); }
}
node& value = pMemory->create_node();
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { insert_map_pair(key, value);
if(it->first->is(key)) return value;
return *it->second; }
}
bool node_data::remove(node& key, shared_memory_holder /* pMemory */) {
node& value = pMemory->create_node(); if (m_type != NodeType::Map)
insert_map_pair(key, value); return false;
return value;
} for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
if (it->first->is(key)) {
bool node_data::remove(node& key, shared_memory_holder /* pMemory */) m_map.erase(it);
{ return true;
if(m_type != NodeType::Map) }
return false; }
for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) { return false;
if(it->first->is(key)) { }
m_map.erase(it);
return true; void node_data::reset_sequence() {
} m_sequence.clear();
} m_seqSize = 0;
}
return false;
} void node_data::reset_map() {
m_map.clear();
void node_data::reset_sequence() m_undefinedPairs.clear();
{ }
m_sequence.clear();
m_seqSize = 0; void node_data::insert_map_pair(node& key, node& value) {
} m_map[&key] = &value;
if (!key.is_defined() || !value.is_defined())
void node_data::reset_map() m_undefinedPairs.push_back(kv_pair(&key, &value));
{ }
m_map.clear();
m_undefinedPairs.clear(); void node_data::convert_to_map(shared_memory_holder pMemory) {
} switch (m_type) {
case NodeType::Undefined:
void node_data::insert_map_pair(node& key, node& value) case NodeType::Null:
{ reset_map();
m_map[&key] = &value; m_type = NodeType::Map;
if(!key.is_defined() || !value.is_defined()) break;
m_undefinedPairs.push_back(kv_pair(&key, &value)); case NodeType::Sequence:
} convert_sequence_to_map(pMemory);
break;
void node_data::convert_to_map(shared_memory_holder pMemory) case NodeType::Map:
{ break;
switch(m_type) { case NodeType::Scalar:
case NodeType::Undefined: assert(false);
case NodeType::Null: break;
reset_map(); }
m_type = NodeType::Map; }
break;
case NodeType::Sequence: void node_data::convert_sequence_to_map(shared_memory_holder pMemory) {
convert_sequence_to_map(pMemory); assert(m_type == NodeType::Sequence);
break;
case NodeType::Map: reset_map();
break; for (std::size_t i = 0; i < m_sequence.size(); i++) {
case NodeType::Scalar: std::stringstream stream;
assert(false); stream << i;
break;
} node& key = pMemory->create_node();
} key.set_scalar(stream.str());
insert_map_pair(key, *m_sequence[i]);
void node_data::convert_sequence_to_map(shared_memory_holder pMemory) }
{
assert(m_type == NodeType::Sequence); reset_sequence();
m_type = NodeType::Map;
reset_map(); }
for(std::size_t i=0;i<m_sequence.size();i++) { }
std::stringstream stream;
stream << i;
node& key = pMemory->create_node();
key.set_scalar(stream.str());
insert_map_pair(key, *m_sequence[i]);
}
reset_sequence();
m_type = NodeType::Map;
}
}
} }
...@@ -4,135 +4,119 @@ ...@@ -4,135 +4,119 @@
#include "yaml-cpp/node/impl.h" #include "yaml-cpp/node/impl.h"
#include <cassert> #include <cassert>
namespace YAML namespace YAML {
{ NodeBuilder::NodeBuilder()
NodeBuilder::NodeBuilder(): m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0) : m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0) {
{ m_anchors.push_back(0); // since the anchors start at 1
m_anchors.push_back(0); // since the anchors start at 1 }
}
NodeBuilder::~NodeBuilder() {}
NodeBuilder::~NodeBuilder()
{ Node NodeBuilder::Root() {
} if (!m_pRoot)
return Node();
Node NodeBuilder::Root()
{ return Node(*m_pRoot, m_pMemory);
if(!m_pRoot) }
return Node();
void NodeBuilder::OnDocumentStart(const Mark&) {}
return Node(*m_pRoot, m_pMemory);
} void NodeBuilder::OnDocumentEnd() {}
void NodeBuilder::OnDocumentStart(const Mark&) void NodeBuilder::OnNull(const Mark& /* mark */, anchor_t anchor) {
{ detail::node& node = Push(anchor);
} node.set_null();
Pop();
void NodeBuilder::OnDocumentEnd() }
{
} void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) {
detail::node& node = *m_anchors[anchor];
void NodeBuilder::OnNull(const Mark& /* mark */, anchor_t anchor) Push(node);
{ Pop();
detail::node& node = Push(anchor); }
node.set_null();
Pop(); void NodeBuilder::OnScalar(const Mark& /* mark */, const std::string& tag,
} anchor_t anchor, const std::string& value) {
detail::node& node = Push(anchor);
void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) node.set_scalar(value);
{ node.set_tag(tag);
detail::node& node = *m_anchors[anchor]; Pop();
Push(node); }
Pop();
} void NodeBuilder::OnSequenceStart(const Mark& /* mark */,
const std::string& tag, anchor_t anchor) {
void NodeBuilder::OnScalar(const Mark& /* mark */, const std::string& tag, anchor_t anchor, const std::string& value) detail::node& node = Push(anchor);
{ node.set_tag(tag);
detail::node& node = Push(anchor); node.set_type(NodeType::Sequence);
node.set_scalar(value); }
node.set_tag(tag);
Pop(); void NodeBuilder::OnSequenceEnd() { Pop(); }
}
void NodeBuilder::OnMapStart(const Mark& /* mark */, const std::string& tag,
void NodeBuilder::OnSequenceStart(const Mark& /* mark */, const std::string& tag, anchor_t anchor) anchor_t anchor) {
{ detail::node& node = Push(anchor);
detail::node& node = Push(anchor); node.set_type(NodeType::Map);
node.set_tag(tag); node.set_tag(tag);
node.set_type(NodeType::Sequence); m_mapDepth++;
} }
void NodeBuilder::OnSequenceEnd() void NodeBuilder::OnMapEnd() {
{ assert(m_mapDepth > 0);
Pop(); m_mapDepth--;
} Pop();
}
void NodeBuilder::OnMapStart(const Mark& /* mark */, const std::string& tag, anchor_t anchor)
{ detail::node& NodeBuilder::Push(anchor_t anchor) {
detail::node& node = Push(anchor); detail::node& node = m_pMemory->create_node();
node.set_type(NodeType::Map); RegisterAnchor(anchor, node);
node.set_tag(tag); Push(node);
m_mapDepth++; return node;
} }
void NodeBuilder::OnMapEnd() void NodeBuilder::Push(detail::node& node) {
{ const bool needsKey =
assert(m_mapDepth > 0); (!m_stack.empty() && m_stack.back()->type() == NodeType::Map &&
m_mapDepth--; m_keys.size() < m_mapDepth);
Pop();
} m_stack.push_back(&node);
if (needsKey)
detail::node& NodeBuilder::Push(anchor_t anchor) m_keys.push_back(PushedKey(&node, false));
{ }
detail::node& node = m_pMemory->create_node();
RegisterAnchor(anchor, node); void NodeBuilder::Pop() {
Push(node); assert(!m_stack.empty());
return node; if (m_stack.size() == 1) {
} m_pRoot = m_stack[0];
m_stack.pop_back();
void NodeBuilder::Push(detail::node& node) return;
{ }
const bool needsKey = (!m_stack.empty() && m_stack.back()->type() == NodeType::Map && m_keys.size() < m_mapDepth);
detail::node& node = *m_stack.back();
m_stack.push_back(&node); m_stack.pop_back();
if(needsKey)
m_keys.push_back(PushedKey(&node, false)); detail::node& collection = *m_stack.back();
}
if (collection.type() == NodeType::Sequence) {
void NodeBuilder::Pop() collection.push_back(node, m_pMemory);
{ } else if (collection.type() == NodeType::Map) {
assert(!m_stack.empty()); assert(!m_keys.empty());
if(m_stack.size() == 1) { PushedKey& key = m_keys.back();
m_pRoot = m_stack[0]; if (key.second) {
m_stack.pop_back(); collection.insert(*key.first, node, m_pMemory);
return; m_keys.pop_back();
} } else {
key.second = true;
detail::node& node = *m_stack.back(); }
m_stack.pop_back(); } else {
assert(false);
detail::node& collection = *m_stack.back(); m_stack.clear();
}
if(collection.type() == NodeType::Sequence) { }
collection.push_back(node, m_pMemory);
} else if(collection.type() == NodeType::Map) { void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node) {
assert(!m_keys.empty()); if (anchor) {
PushedKey& key = m_keys.back(); assert(anchor == m_anchors.size());
if(key.second) { m_anchors.push_back(&node);
collection.insert(*key.first, node, m_pMemory); }
m_keys.pop_back(); }
} else {
key.second = true;
}
} else {
assert(false);
m_stack.clear();
}
}
void NodeBuilder::RegisterAnchor(anchor_t anchor, detail::node& node)
{
if(anchor) {
assert(anchor == m_anchors.size());
m_anchors.push_back(&node);
}
}
} }
#ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
...@@ -9,50 +11,50 @@ ...@@ -9,50 +11,50 @@
#include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/ptr.h"
#include <vector> #include <vector>
namespace YAML namespace YAML {
{ class Node;
class Node;
class NodeBuilder : public EventHandler {
class NodeBuilder: public EventHandler public:
{ NodeBuilder();
public: virtual ~NodeBuilder();
NodeBuilder();
virtual ~NodeBuilder(); Node Root();
Node Root(); virtual void OnDocumentStart(const Mark& mark);
virtual void OnDocumentEnd();
virtual void OnDocumentStart(const Mark& mark);
virtual void OnDocumentEnd(); virtual void OnNull(const Mark& mark, anchor_t anchor);
virtual void OnAlias(const Mark& mark, anchor_t anchor);
virtual void OnNull(const Mark& mark, anchor_t anchor); virtual void OnScalar(const Mark& mark, const std::string& tag,
virtual void OnAlias(const Mark& mark, anchor_t anchor); anchor_t anchor, const std::string& value);
virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value);
virtual void OnSequenceStart(const Mark& mark, const std::string& tag,
virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor); anchor_t anchor);
virtual void OnSequenceEnd(); virtual void OnSequenceEnd();
virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor);
virtual void OnMapEnd();
private:
detail::node& Push(anchor_t anchor);
void Push(detail::node& node);
void Pop();
void RegisterAnchor(anchor_t anchor, detail::node& node);
private:
detail::shared_memory_holder m_pMemory;
detail::node *m_pRoot;
typedef std::vector<detail::node *> Nodes;
Nodes m_stack;
Nodes m_anchors;
typedef std::pair<detail::node *, bool> PushedKey;
std::vector<PushedKey> m_keys;
std::size_t m_mapDepth;
};
}
#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor);
virtual void OnMapEnd();
private:
detail::node& Push(anchor_t anchor);
void Push(detail::node& node);
void Pop();
void RegisterAnchor(anchor_t anchor, detail::node& node);
private:
detail::shared_memory_holder m_pMemory;
detail::node* m_pRoot;
typedef std::vector<detail::node*> Nodes;
Nodes m_stack;
Nodes m_anchors;
typedef std::pair<detail::node*, bool> PushedKey;
std::vector<PushedKey> m_keys;
std::size_t m_mapDepth;
};
}
#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
...@@ -4,98 +4,96 @@ ...@@ -4,98 +4,96 @@
#include "yaml-cpp/eventhandler.h" #include "yaml-cpp/eventhandler.h"
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
namespace YAML namespace YAML {
{ void NodeEvents::AliasManager::RegisterReference(const detail::node& node) {
void NodeEvents::AliasManager::RegisterReference(const detail::node& node) m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor()));
{ }
m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor()));
} anchor_t NodeEvents::AliasManager::LookupAnchor(const detail::node& node)
const {
anchor_t NodeEvents::AliasManager::LookupAnchor(const detail::node& node) const AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref());
{ if (it == m_anchorByIdentity.end())
AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref()); return 0;
if(it == m_anchorByIdentity.end()) return it->second;
return 0; }
return it->second;
} NodeEvents::NodeEvents(const Node& node)
: m_pMemory(node.m_pMemory), m_root(node.m_pNode) {
if (m_root)
Setup(*m_root);
}
void NodeEvents::Setup(const detail::node& node) {
int& refCount = m_refCount[node.ref()];
refCount++;
if (refCount > 1)
return;
NodeEvents::NodeEvents(const Node& node): m_pMemory(node.m_pMemory), m_root(node.m_pNode) if (node.type() == NodeType::Sequence) {
{ for (detail::const_node_iterator it = node.begin(); it != node.end(); ++it)
if(m_root) Setup(**it);
Setup(*m_root); } else if (node.type() == NodeType::Map) {
} for (detail::const_node_iterator it = node.begin(); it != node.end();
++it) {
Setup(*it->first);
Setup(*it->second);
}
}
}
void NodeEvents::Emit(EventHandler& handler) {
AliasManager am;
handler.OnDocumentStart(Mark());
if (m_root)
Emit(*m_root, handler, am);
handler.OnDocumentEnd();
}
void NodeEvents::Setup(const detail::node& node) void NodeEvents::Emit(const detail::node& node, EventHandler& handler,
{ AliasManager& am) const {
int& refCount = m_refCount[node.ref()]; anchor_t anchor = NullAnchor;
refCount++; if (IsAliased(node)) {
if(refCount > 1) anchor = am.LookupAnchor(node);
return; if (anchor) {
handler.OnAlias(Mark(), anchor);
if(node.type() == NodeType::Sequence) { return;
for(detail::const_node_iterator it=node.begin();it!=node.end();++it) }
Setup(**it);
} else if(node.type() == NodeType::Map) {
for(detail::const_node_iterator it=node.begin();it!=node.end();++it) {
Setup(*it->first);
Setup(*it->second);
}
}
}
void NodeEvents::Emit(EventHandler& handler) am.RegisterReference(node);
{ anchor = am.LookupAnchor(node);
AliasManager am; }
handler.OnDocumentStart(Mark());
if(m_root)
Emit(*m_root, handler, am);
handler.OnDocumentEnd();
}
void NodeEvents::Emit(const detail::node& node, EventHandler& handler, AliasManager& am) const switch (node.type()) {
{ case NodeType::Undefined:
anchor_t anchor = NullAnchor; break;
if(IsAliased(node)) { case NodeType::Null:
anchor = am.LookupAnchor(node); handler.OnNull(Mark(), anchor);
if(anchor) { break;
handler.OnAlias(Mark(), anchor); case NodeType::Scalar:
return; handler.OnScalar(Mark(), node.tag(), anchor, node.scalar());
} break;
case NodeType::Sequence:
am.RegisterReference(node); handler.OnSequenceStart(Mark(), node.tag(), anchor);
anchor = am.LookupAnchor(node); for (detail::const_node_iterator it = node.begin(); it != node.end();
} ++it)
Emit(**it, handler, am);
switch(node.type()) { handler.OnSequenceEnd();
case NodeType::Undefined: break;
break; case NodeType::Map:
case NodeType::Null: handler.OnMapStart(Mark(), node.tag(), anchor);
handler.OnNull(Mark(), anchor); for (detail::const_node_iterator it = node.begin(); it != node.end();
break; ++it) {
case NodeType::Scalar: Emit(*it->first, handler, am);
handler.OnScalar(Mark(), node.tag(), anchor, node.scalar()); Emit(*it->second, handler, am);
break; }
case NodeType::Sequence: handler.OnMapEnd();
handler.OnSequenceStart(Mark(), node.tag(), anchor); break;
for(detail::const_node_iterator it=node.begin();it!=node.end();++it) }
Emit(**it, handler, am); }
handler.OnSequenceEnd();
break;
case NodeType::Map:
handler.OnMapStart(Mark(), node.tag(), anchor);
for(detail::const_node_iterator it=node.begin();it!=node.end();++it) {
Emit(*it->first, handler, am);
Emit(*it->second, handler, am);
}
handler.OnMapEnd();
break;
}
}
bool NodeEvents::IsAliased(const detail::node& node) const bool NodeEvents::IsAliased(const detail::node& node) const {
{ RefCount::const_iterator it = m_refCount.find(node.ref());
RefCount::const_iterator it = m_refCount.find(node.ref()); return it != m_refCount.end() && it->second > 1;
return it != m_refCount.end() && it->second > 1; }
}
} }
#ifndef NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
...@@ -10,48 +12,46 @@ ...@@ -10,48 +12,46 @@
#include <map> #include <map>
#include <vector> #include <vector>
namespace YAML namespace YAML {
{ class EventHandler;
class EventHandler; class Node;
class Node;
class NodeEvents {
class NodeEvents public:
{ explicit NodeEvents(const Node& node);
public:
explicit NodeEvents(const Node& node); void Emit(EventHandler& handler);
void Emit(EventHandler& handler); private:
class AliasManager {
private: public:
class AliasManager { AliasManager() : m_curAnchor(0) {}
public:
AliasManager(): m_curAnchor(0) {} void RegisterReference(const detail::node& node);
anchor_t LookupAnchor(const detail::node& node) const;
void RegisterReference(const detail::node& node);
anchor_t LookupAnchor(const detail::node& node) const; private:
anchor_t _CreateNewAnchor() { return ++m_curAnchor; }
private:
anchor_t _CreateNewAnchor() { return ++m_curAnchor; }
private:
typedef std::map<const detail::node_ref*, anchor_t> AnchorByIdentity;
AnchorByIdentity m_anchorByIdentity;
anchor_t m_curAnchor;
};
void Setup(const detail::node& node);
void Emit(const detail::node& node, EventHandler& handler, AliasManager& am) const;
bool IsAliased(const detail::node& node) const;
private:
detail::shared_memory_holder m_pMemory;
detail::node* m_root;
typedef std::map<const detail::node_ref *, int> RefCount;
RefCount m_refCount;
};
}
#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 private:
typedef std::map<const detail::node_ref*, anchor_t> AnchorByIdentity;
AnchorByIdentity m_anchorByIdentity;
anchor_t m_curAnchor;
};
void Setup(const detail::node& node);
void Emit(const detail::node& node, EventHandler& handler,
AliasManager& am) const;
bool IsAliased(const detail::node& node) const;
private:
detail::shared_memory_holder m_pMemory;
detail::node* m_root;
typedef std::map<const detail::node_ref*, int> RefCount;
RefCount m_refCount;
};
}
#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
...@@ -2,55 +2,52 @@ ...@@ -2,55 +2,52 @@
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
namespace YAML namespace YAML {
{ ostream_wrapper::ostream_wrapper()
ostream_wrapper::ostream_wrapper(): m_buffer(1), m_pStream(0), m_pos(0), m_row(0), m_col(0), m_comment(false) : m_buffer(1),
{ m_pStream(0),
} m_pos(0),
m_row(0),
ostream_wrapper::ostream_wrapper(std::ostream& stream): m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false) m_col(0),
{ m_comment(false) {}
}
ostream_wrapper::ostream_wrapper(std::ostream& stream)
ostream_wrapper::~ostream_wrapper() : m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false) {}
{
} ostream_wrapper::~ostream_wrapper() {}
void ostream_wrapper::write(const std::string& str) void ostream_wrapper::write(const std::string& str) {
{ if (m_pStream) {
if(m_pStream) { m_pStream->write(str.c_str(), str.size());
m_pStream->write(str.c_str(), str.size()); } else {
} else { m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1));
m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1)); std::copy(str.begin(), str.end(), &m_buffer[m_pos]);
std::copy(str.begin(), str.end(), &m_buffer[m_pos]); }
}
for (std::size_t i = 0; i < str.size(); i++)
for(std::size_t i=0;i<str.size();i++) update_pos(str[i]);
update_pos(str[i]); }
}
void ostream_wrapper::write(const char* str, std::size_t size) {
void ostream_wrapper::write(const char *str, std::size_t size) if (m_pStream) {
{ m_pStream->write(str, size);
if(m_pStream) { } else {
m_pStream->write(str, size); m_buffer.resize(std::max(m_buffer.size(), m_pos + size + 1));
} else { std::copy(str, str + size, &m_buffer[m_pos]);
m_buffer.resize(std::max(m_buffer.size(), m_pos + size + 1)); }
std::copy(str, str + size, &m_buffer[m_pos]);
} for (std::size_t i = 0; i < size; i++)
update_pos(str[i]);
for(std::size_t i=0;i<size;i++) }
update_pos(str[i]);
} void ostream_wrapper::update_pos(char ch) {
m_pos++;
void ostream_wrapper::update_pos(char ch) m_col++;
{
m_pos++; if (ch == '\n') {
m_col++; m_row++;
m_col = 0;
if(ch == '\n') { m_comment = false;
m_row++; }
m_col = 0; }
m_comment = false;
}
}
} }
...@@ -7,62 +7,61 @@ ...@@ -7,62 +7,61 @@
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
namespace YAML namespace YAML {
{ Node Load(const std::string& input) {
Node Load(const std::string& input) { std::stringstream stream(input);
std::stringstream stream(input); return Load(stream);
return Load(stream); }
}
Node Load(const char* input) {
Node Load(const char *input) { std::stringstream stream(input);
std::stringstream stream(input); return Load(stream);
return Load(stream); }
}
Node Load(std::istream& input) {
Node Load(std::istream& input) { Parser parser(input);
Parser parser(input); NodeBuilder builder;
NodeBuilder builder; if (!parser.HandleNextDocument(builder))
if(!parser.HandleNextDocument(builder)) return Node();
return Node();
return builder.Root();
}
Node LoadFile(const std::string& filename) { return builder.Root();
std::ifstream fin(filename.c_str()); }
if(!fin)
throw BadFile(); Node LoadFile(const std::string& filename) {
return Load(fin); std::ifstream fin(filename.c_str());
} if (!fin)
throw BadFile();
return Load(fin);
}
std::vector<Node> LoadAll(const std::string& input) { std::vector<Node> LoadAll(const std::string& input) {
std::stringstream stream(input); std::stringstream stream(input);
return LoadAll(stream); return LoadAll(stream);
} }
std::vector<Node> LoadAll(const char *input) {
std::stringstream stream(input);
return LoadAll(stream);
}
std::vector<Node> LoadAll(std::istream& input) {
std::vector<Node> docs;
Parser parser(input);
while(1) {
NodeBuilder builder;
if(!parser.HandleNextDocument(builder))
break;
docs.push_back(builder.Root());
}
return docs;
}
std::vector<Node> LoadAllFromFile(const std::string& filename) { std::vector<Node> LoadAll(const char* input) {
std::ifstream fin(filename.c_str()); std::stringstream stream(input);
if(!fin) return LoadAll(stream);
throw BadFile(); }
return LoadAll(fin);
} std::vector<Node> LoadAll(std::istream& input) {
std::vector<Node> docs;
Parser parser(input);
while (1) {
NodeBuilder builder;
if (!parser.HandleNextDocument(builder))
break;
docs.push_back(builder.Root());
}
return docs;
}
std::vector<Node> LoadAllFromFile(const std::string& filename) {
std::ifstream fin(filename.c_str());
if (!fin)
throw BadFile();
return LoadAll(fin);
}
} }
...@@ -50,21 +50,21 @@ static bool s_introFinalState[] = {false, // uis_start ...@@ -50,21 +50,21 @@ static bool s_introFinalState[] = {false, // uis_start
false, // uis_utfbe_b1 false, // uis_utfbe_b1
false, // uis_utf32be_b2 false, // uis_utf32be_b2
false, // uis_utf32be_bom3 false, // uis_utf32be_bom3
true, // uis_utf32be true, // uis_utf32be
true, // uis_utf16be true, // uis_utf16be
false, // uis_utf16be_bom1 false, // uis_utf16be_bom1
false, // uis_utfle_bom1 false, // uis_utfle_bom1
false, // uis_utf16le_bom2 false, // uis_utf16le_bom2
false, // uis_utf32le_bom3 false, // uis_utf32le_bom3
true, // uis_utf16le true, // uis_utf16le
true, // uis_utf32le true, // uis_utf32le
false, // uis_utf8_imp false, // uis_utf8_imp
false, // uis_utf16le_imp false, // uis_utf16le_imp
false, // uis_utf32le_imp3 false, // uis_utf32le_imp3
false, // uis_utf8_bom1 false, // uis_utf8_bom1
false, // uis_utf8_bom2 false, // uis_utf8_bom2
true, // uis_utf8 true, // uis_utf8
true, // uis_error true, // uis_error
}; };
static UtfIntroState s_introTransitions[][uictMax] = { static UtfIntroState s_introTransitions[][uictMax] = {
......
...@@ -3,1162 +3,1197 @@ ...@@ -3,1162 +3,1197 @@
#include "yaml-cpp/yaml.h" #include "yaml-cpp/yaml.h"
#include <iostream> #include <iostream>
namespace Test namespace Test {
{ namespace Emitter {
namespace Emitter { ////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////// // correct emitting
// correct emitting
void SimpleScalar(YAML::Emitter& out, std::string& desiredOutput) {
void SimpleScalar(YAML::Emitter& out, std::string& desiredOutput) { out << "Hello, World!";
out << "Hello, World!"; desiredOutput = "Hello, World!";
desiredOutput = "Hello, World!"; }
}
void SimpleSeq(YAML::Emitter& out, std::string& desiredOutput) {
void SimpleSeq(YAML::Emitter& out, std::string& desiredOutput) { out << YAML::BeginSeq;
out << YAML::BeginSeq; out << "eggs";
out << "eggs"; out << "bread";
out << "bread"; out << "milk";
out << "milk"; out << YAML::EndSeq;
out << YAML::EndSeq;
desiredOutput = "- eggs\n- bread\n- milk";
desiredOutput = "- eggs\n- bread\n- milk"; }
}
void SimpleFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
void SimpleFlowSeq(YAML::Emitter& out, std::string& desiredOutput) { out << YAML::Flow;
out << YAML::Flow; out << YAML::BeginSeq;
out << YAML::BeginSeq; out << "Larry";
out << "Larry"; out << "Curly";
out << "Curly"; out << "Moe";
out << "Moe"; out << YAML::EndSeq;
out << YAML::EndSeq;
desiredOutput = "[Larry, Curly, Moe]";
desiredOutput = "[Larry, Curly, Moe]"; }
}
void EmptyFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
void EmptyFlowSeq(YAML::Emitter& out, std::string& desiredOutput) { out << YAML::Flow;
out << YAML::Flow; out << YAML::BeginSeq;
out << YAML::BeginSeq; out << YAML::EndSeq;
out << YAML::EndSeq;
desiredOutput = "[]";
desiredOutput = "[]"; }
}
void NestedBlockSeq(YAML::Emitter& out, std::string& desiredOutput) {
void NestedBlockSeq(YAML::Emitter& out, std::string& desiredOutput) { out << YAML::BeginSeq;
out << YAML::BeginSeq; out << "item 1";
out << "item 1"; out << YAML::BeginSeq << "subitem 1"
out << YAML::BeginSeq << "subitem 1" << "subitem 2" << YAML::EndSeq; << "subitem 2" << YAML::EndSeq;
out << YAML::EndSeq; out << YAML::EndSeq;
desiredOutput = "- item 1\n-\n - subitem 1\n - subitem 2"; desiredOutput = "- item 1\n-\n - subitem 1\n - subitem 2";
} }
void NestedFlowSeq(YAML::Emitter& out, std::string& desiredOutput) { void NestedFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginSeq; out << YAML::BeginSeq;
out << "one"; out << "one";
out << YAML::Flow << YAML::BeginSeq << "two" << "three" << YAML::EndSeq; out << YAML::Flow << YAML::BeginSeq << "two"
out << YAML::EndSeq; << "three" << YAML::EndSeq;
out << YAML::EndSeq;
desiredOutput = "- one\n- [two, three]";
} desiredOutput = "- one\n- [two, three]";
}
void SimpleMap(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginMap; void SimpleMap(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Key << "name"; out << YAML::BeginMap;
out << YAML::Value << "Ryan Braun"; out << YAML::Key << "name";
out << YAML::Key << "position"; out << YAML::Value << "Ryan Braun";
out << YAML::Value << "3B"; out << YAML::Key << "position";
out << YAML::EndMap; out << YAML::Value << "3B";
out << YAML::EndMap;
desiredOutput = "name: Ryan Braun\nposition: 3B";
} desiredOutput = "name: Ryan Braun\nposition: 3B";
}
void SimpleFlowMap(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Flow; void SimpleFlowMap(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginMap; out << YAML::Flow;
out << YAML::Key << "shape"; out << YAML::BeginMap;
out << YAML::Value << "square"; out << YAML::Key << "shape";
out << YAML::Key << "color"; out << YAML::Value << "square";
out << YAML::Value << "blue"; out << YAML::Key << "color";
out << YAML::EndMap; out << YAML::Value << "blue";
out << YAML::EndMap;
desiredOutput = "{shape: square, color: blue}";
} desiredOutput = "{shape: square, color: blue}";
}
void MapAndList(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginMap; void MapAndList(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Key << "name"; out << YAML::BeginMap;
out << YAML::Value << "Barack Obama"; out << YAML::Key << "name";
out << YAML::Key << "children"; out << YAML::Value << "Barack Obama";
out << YAML::Value << YAML::BeginSeq << "Sasha" << "Malia" << YAML::EndSeq; out << YAML::Key << "children";
out << YAML::EndMap; out << YAML::Value << YAML::BeginSeq << "Sasha"
<< "Malia" << YAML::EndSeq;
desiredOutput = "name: Barack Obama\nchildren:\n - Sasha\n - Malia"; out << YAML::EndMap;
}
desiredOutput = "name: Barack Obama\nchildren:\n - Sasha\n - Malia";
void ListAndMap(YAML::Emitter& out, std::string& desiredOutput) { }
out << YAML::BeginSeq;
out << "item 1"; void ListAndMap(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginMap; out << YAML::BeginSeq;
out << YAML::Key << "pens" << YAML::Value << 8; out << "item 1";
out << YAML::Key << "pencils" << YAML::Value << 14; out << YAML::BeginMap;
out << YAML::EndMap; out << YAML::Key << "pens" << YAML::Value << 8;
out << "item 2"; out << YAML::Key << "pencils" << YAML::Value << 14;
out << YAML::EndSeq; out << YAML::EndMap;
out << "item 2";
desiredOutput = "- item 1\n- pens: 8\n pencils: 14\n- item 2"; out << YAML::EndSeq;
}
desiredOutput = "- item 1\n- pens: 8\n pencils: 14\n- item 2";
void NestedBlockMap(YAML::Emitter& out, std::string& desiredOutput) { }
out << YAML::BeginMap;
out << YAML::Key << "name"; void NestedBlockMap(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Value << "Fred"; out << YAML::BeginMap;
out << YAML::Key << "grades"; out << YAML::Key << "name";
out << YAML::Value; out << YAML::Value << "Fred";
out << YAML::BeginMap; out << YAML::Key << "grades";
out << YAML::Key << "algebra" << YAML::Value << "A"; out << YAML::Value;
out << YAML::Key << "physics" << YAML::Value << "C+"; out << YAML::BeginMap;
out << YAML::Key << "literature" << YAML::Value << "B"; out << YAML::Key << "algebra" << YAML::Value << "A";
out << YAML::EndMap; out << YAML::Key << "physics" << YAML::Value << "C+";
out << YAML::EndMap; out << YAML::Key << "literature" << YAML::Value << "B";
out << YAML::EndMap;
desiredOutput = "name: Fred\ngrades:\n algebra: A\n physics: C+\n literature: B"; out << YAML::EndMap;
}
desiredOutput =
void NestedFlowMap(YAML::Emitter& out, std::string& desiredOutput) { "name: Fred\ngrades:\n algebra: A\n physics: C+\n literature: B";
out << YAML::Flow; }
out << YAML::BeginMap;
out << YAML::Key << "name"; void NestedFlowMap(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Value << "Fred"; out << YAML::Flow;
out << YAML::Key << "grades"; out << YAML::BeginMap;
out << YAML::Value; out << YAML::Key << "name";
out << YAML::BeginMap; out << YAML::Value << "Fred";
out << YAML::Key << "algebra" << YAML::Value << "A"; out << YAML::Key << "grades";
out << YAML::Key << "physics" << YAML::Value << "C+"; out << YAML::Value;
out << YAML::Key << "literature" << YAML::Value << "B"; out << YAML::BeginMap;
out << YAML::EndMap; out << YAML::Key << "algebra" << YAML::Value << "A";
out << YAML::EndMap; out << YAML::Key << "physics" << YAML::Value << "C+";
out << YAML::Key << "literature" << YAML::Value << "B";
desiredOutput = "{name: Fred, grades: {algebra: A, physics: C+, literature: B}}"; out << YAML::EndMap;
} out << YAML::EndMap;
void MapListMix(YAML::Emitter& out, std::string& desiredOutput) { desiredOutput =
out << YAML::BeginMap; "{name: Fred, grades: {algebra: A, physics: C+, literature: B}}";
out << YAML::Key << "name"; }
out << YAML::Value << "Bob";
out << YAML::Key << "position"; void MapListMix(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Value; out << YAML::BeginMap;
out << YAML::Flow << YAML::BeginSeq << 2 << 4 << YAML::EndSeq; out << YAML::Key << "name";
out << YAML::Key << "invincible" << YAML::Value << YAML::OnOffBool << false; out << YAML::Value << "Bob";
out << YAML::EndMap; out << YAML::Key << "position";
out << YAML::Value;
desiredOutput = "name: Bob\nposition: [2, 4]\ninvincible: off"; out << YAML::Flow << YAML::BeginSeq << 2 << 4 << YAML::EndSeq;
} out << YAML::Key << "invincible" << YAML::Value << YAML::OnOffBool << false;
out << YAML::EndMap;
void SimpleLongKey(YAML::Emitter& out, std::string& desiredOutput)
{ desiredOutput = "name: Bob\nposition: [2, 4]\ninvincible: off";
out << YAML::LongKey; }
out << YAML::BeginMap;
out << YAML::Key << "height"; void SimpleLongKey(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Value << "5'9\""; out << YAML::LongKey;
out << YAML::Key << "weight"; out << YAML::BeginMap;
out << YAML::Value << 145; out << YAML::Key << "height";
out << YAML::EndMap; out << YAML::Value << "5'9\"";
out << YAML::Key << "weight";
desiredOutput = "? height\n: 5'9\"\n? weight\n: 145"; out << YAML::Value << 145;
} out << YAML::EndMap;
void SingleLongKey(YAML::Emitter& out, std::string& desiredOutput) desiredOutput = "? height\n: 5'9\"\n? weight\n: 145";
{ }
out << YAML::BeginMap;
out << YAML::Key << "age"; void SingleLongKey(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Value << "24"; out << YAML::BeginMap;
out << YAML::LongKey << YAML::Key << "height"; out << YAML::Key << "age";
out << YAML::Value << "5'9\""; out << YAML::Value << "24";
out << YAML::Key << "weight"; out << YAML::LongKey << YAML::Key << "height";
out << YAML::Value << 145; out << YAML::Value << "5'9\"";
out << YAML::EndMap; out << YAML::Key << "weight";
out << YAML::Value << 145;
desiredOutput = "age: 24\n? height\n: 5'9\"\nweight: 145"; out << YAML::EndMap;
}
desiredOutput = "age: 24\n? height\n: 5'9\"\nweight: 145";
void ComplexLongKey(YAML::Emitter& out, std::string& desiredOutput) }
{
out << YAML::LongKey; void ComplexLongKey(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginMap; out << YAML::LongKey;
out << YAML::Key << YAML::BeginSeq << 1 << 3 << YAML::EndSeq; out << YAML::BeginMap;
out << YAML::Value << "monster"; out << YAML::Key << YAML::BeginSeq << 1 << 3 << YAML::EndSeq;
out << YAML::Key << YAML::Flow << YAML::BeginSeq << 2 << 0 << YAML::EndSeq; out << YAML::Value << "monster";
out << YAML::Value << "demon"; out << YAML::Key << YAML::Flow << YAML::BeginSeq << 2 << 0 << YAML::EndSeq;
out << YAML::EndMap; out << YAML::Value << "demon";
out << YAML::EndMap;
desiredOutput = "? - 1\n - 3\n: monster\n? [2, 0]\n: demon";
} desiredOutput = "? - 1\n - 3\n: monster\n? [2, 0]\n: demon";
}
void AutoLongKey(YAML::Emitter& out, std::string& desiredOutput)
{ void AutoLongKey(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginMap; out << YAML::BeginMap;
out << YAML::Key << YAML::BeginSeq << 1 << 3 << YAML::EndSeq; out << YAML::Key << YAML::BeginSeq << 1 << 3 << YAML::EndSeq;
out << YAML::Value << "monster"; out << YAML::Value << "monster";
out << YAML::Key << YAML::Flow << YAML::BeginSeq << 2 << 0 << YAML::EndSeq; out << YAML::Key << YAML::Flow << YAML::BeginSeq << 2 << 0 << YAML::EndSeq;
out << YAML::Value << "demon"; out << YAML::Value << "demon";
out << YAML::Key << "the origin"; out << YAML::Key << "the origin";
out << YAML::Value << "angel"; out << YAML::Value << "angel";
out << YAML::EndMap; out << YAML::EndMap;
desiredOutput = "? - 1\n - 3\n: monster\n[2, 0]: demon\nthe origin: angel"; desiredOutput = "? - 1\n - 3\n: monster\n[2, 0]: demon\nthe origin: angel";
} }
void ScalarFormat(YAML::Emitter& out, std::string& desiredOutput) void ScalarFormat(YAML::Emitter& out, std::string& desiredOutput) {
{ out << YAML::BeginSeq;
out << YAML::BeginSeq; out << "simple scalar";
out << "simple scalar"; out << YAML::SingleQuoted << "explicit single-quoted scalar";
out << YAML::SingleQuoted << "explicit single-quoted scalar"; out << YAML::DoubleQuoted << "explicit double-quoted scalar";
out << YAML::DoubleQuoted << "explicit double-quoted scalar"; out << "auto-detected\ndouble-quoted scalar";
out << "auto-detected\ndouble-quoted scalar"; out << "a non-\"auto-detected\" double-quoted scalar";
out << "a non-\"auto-detected\" double-quoted scalar"; out << YAML::Literal << "literal scalar\nthat may span\nmany, many\nlines "
out << YAML::Literal << "literal scalar\nthat may span\nmany, many\nlines and have \"whatever\" crazy\tsymbols that we like"; "and have \"whatever\" crazy\tsymbols that we like";
out << YAML::EndSeq; out << YAML::EndSeq;
desiredOutput = "- simple scalar\n- 'explicit single-quoted scalar'\n- \"explicit double-quoted scalar\"\n- \"auto-detected\\ndouble-quoted scalar\"\n- a non-\"auto-detected\" double-quoted scalar\n- |\n literal scalar\n that may span\n many, many\n lines and have \"whatever\" crazy\tsymbols that we like"; desiredOutput =
} "- simple scalar\n- 'explicit single-quoted scalar'\n- \"explicit "
"double-quoted scalar\"\n- \"auto-detected\\ndouble-quoted scalar\"\n- a "
void AutoLongKeyScalar(YAML::Emitter& out, std::string& desiredOutput) "non-\"auto-detected\" double-quoted scalar\n- |\n literal scalar\n "
{ "that may span\n many, many\n lines and have \"whatever\" "
out << YAML::BeginMap; "crazy\tsymbols that we like";
out << YAML::Key << YAML::Literal << "multi-line\nscalar"; }
out << YAML::Value << "and its value";
out << YAML::EndMap; void AutoLongKeyScalar(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginMap;
desiredOutput = "? |\n multi-line\n scalar\n: and its value"; out << YAML::Key << YAML::Literal << "multi-line\nscalar";
} out << YAML::Value << "and its value";
out << YAML::EndMap;
void LongKeyFlowMap(YAML::Emitter& out, std::string& desiredOutput)
{ desiredOutput = "? |\n multi-line\n scalar\n: and its value";
out << YAML::Flow; }
out << YAML::BeginMap;
out << YAML::Key << "simple key"; void LongKeyFlowMap(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Value << "and value"; out << YAML::Flow;
out << YAML::LongKey << YAML::Key << "long key"; out << YAML::BeginMap;
out << YAML::Value << "and its value"; out << YAML::Key << "simple key";
out << YAML::EndMap; out << YAML::Value << "and value";
out << YAML::LongKey << YAML::Key << "long key";
desiredOutput = "{simple key: and value, ? long key: and its value}"; out << YAML::Value << "and its value";
} out << YAML::EndMap;
void BlockMapAsKey(YAML::Emitter& out, std::string& desiredOutput) desiredOutput = "{simple key: and value, ? long key: and its value}";
{ }
out << YAML::BeginMap;
out << YAML::Key; void BlockMapAsKey(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginMap; out << YAML::BeginMap;
out << YAML::Key << "key" << YAML::Value << "value"; out << YAML::Key;
out << YAML::Key << "next key" << YAML::Value << "next value"; out << YAML::BeginMap;
out << YAML::EndMap; out << YAML::Key << "key" << YAML::Value << "value";
out << YAML::Value; out << YAML::Key << "next key" << YAML::Value << "next value";
out << "total value"; out << YAML::EndMap;
out << YAML::EndMap; out << YAML::Value;
out << "total value";
desiredOutput = "? key: value\n next key: next value\n: total value"; out << YAML::EndMap;
}
desiredOutput = "? key: value\n next key: next value\n: total value";
void AliasAndAnchor(YAML::Emitter& out, std::string& desiredOutput) }
{
out << YAML::BeginSeq; void AliasAndAnchor(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Anchor("fred"); out << YAML::BeginSeq;
out << YAML::BeginMap; out << YAML::Anchor("fred");
out << YAML::Key << "name" << YAML::Value << "Fred"; out << YAML::BeginMap;
out << YAML::Key << "age" << YAML::Value << 42; out << YAML::Key << "name" << YAML::Value << "Fred";
out << YAML::EndMap; out << YAML::Key << "age" << YAML::Value << 42;
out << YAML::Alias("fred"); out << YAML::EndMap;
out << YAML::EndSeq; out << YAML::Alias("fred");
out << YAML::EndSeq;
desiredOutput = "- &fred\n name: Fred\n age: 42\n- *fred";
} desiredOutput = "- &fred\n name: Fred\n age: 42\n- *fred";
}
void AliasAndAnchorWithNull(YAML::Emitter& out, std::string& desiredOutput)
{ void AliasAndAnchorWithNull(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginSeq; out << YAML::BeginSeq;
out << YAML::Anchor("fred") << YAML::Null; out << YAML::Anchor("fred") << YAML::Null;
out << YAML::Alias("fred"); out << YAML::Alias("fred");
out << YAML::EndSeq; out << YAML::EndSeq;
desiredOutput = "- &fred ~\n- *fred"; desiredOutput = "- &fred ~\n- *fred";
} }
void AliasAndAnchorInFlow(YAML::Emitter& out, std::string& desiredOutput) void AliasAndAnchorInFlow(YAML::Emitter& out, std::string& desiredOutput) {
{ out << YAML::Flow << YAML::BeginSeq;
out << YAML::Flow << YAML::BeginSeq; out << YAML::Anchor("fred");
out << YAML::Anchor("fred"); out << YAML::BeginMap;
out << YAML::BeginMap; out << YAML::Key << "name" << YAML::Value << "Fred";
out << YAML::Key << "name" << YAML::Value << "Fred"; out << YAML::Key << "age" << YAML::Value << 42;
out << YAML::Key << "age" << YAML::Value << 42; out << YAML::EndMap;
out << YAML::EndMap; out << YAML::Alias("fred");
out << YAML::Alias("fred"); out << YAML::EndSeq;
out << YAML::EndSeq;
desiredOutput = "[&fred {name: Fred, age: 42}, *fred]";
desiredOutput = "[&fred {name: Fred, age: 42}, *fred]"; }
}
void SimpleVerbatimTag(YAML::Emitter& out, std::string& desiredOutput) {
void SimpleVerbatimTag(YAML::Emitter& out, std::string& desiredOutput) out << YAML::VerbatimTag("!foo") << "bar";
{
out << YAML::VerbatimTag("!foo") << "bar"; desiredOutput = "!<!foo> bar";
}
desiredOutput = "!<!foo> bar";
} void VerbatimTagInBlockSeq(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginSeq;
void VerbatimTagInBlockSeq(YAML::Emitter& out, std::string& desiredOutput) out << YAML::VerbatimTag("!foo") << "bar";
{ out << "baz";
out << YAML::BeginSeq; out << YAML::EndSeq;
out << YAML::VerbatimTag("!foo") << "bar";
out << "baz"; desiredOutput = "- !<!foo> bar\n- baz";
out << YAML::EndSeq; }
desiredOutput = "- !<!foo> bar\n- baz"; void VerbatimTagInFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
} out << YAML::Flow << YAML::BeginSeq;
out << YAML::VerbatimTag("!foo") << "bar";
void VerbatimTagInFlowSeq(YAML::Emitter& out, std::string& desiredOutput) out << "baz";
{ out << YAML::EndSeq;
out << YAML::Flow << YAML::BeginSeq;
out << YAML::VerbatimTag("!foo") << "bar"; desiredOutput = "[!<!foo> bar, baz]";
out << "baz"; }
out << YAML::EndSeq;
void VerbatimTagInFlowSeqWithNull(YAML::Emitter& out,
desiredOutput = "[!<!foo> bar, baz]"; std::string& desiredOutput) {
} out << YAML::Flow << YAML::BeginSeq;
out << YAML::VerbatimTag("!foo") << YAML::Null;
void VerbatimTagInFlowSeqWithNull(YAML::Emitter& out, std::string& desiredOutput) out << "baz";
{ out << YAML::EndSeq;
out << YAML::Flow << YAML::BeginSeq;
out << YAML::VerbatimTag("!foo") << YAML::Null; desiredOutput = "[!<!foo> ~, baz]";
out << "baz"; }
out << YAML::EndSeq;
void VerbatimTagInBlockMap(YAML::Emitter& out, std::string& desiredOutput) {
desiredOutput = "[!<!foo> ~, baz]"; out << YAML::BeginMap;
} out << YAML::Key << YAML::VerbatimTag("!foo") << "bar";
out << YAML::Value << YAML::VerbatimTag("!waz") << "baz";
void VerbatimTagInBlockMap(YAML::Emitter& out, std::string& desiredOutput) out << YAML::EndMap;
{
out << YAML::BeginMap; desiredOutput = "!<!foo> bar: !<!waz> baz";
out << YAML::Key << YAML::VerbatimTag("!foo") << "bar"; }
out << YAML::Value << YAML::VerbatimTag("!waz") << "baz";
out << YAML::EndMap; void VerbatimTagInFlowMap(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Flow << YAML::BeginMap;
desiredOutput = "!<!foo> bar: !<!waz> baz"; out << YAML::Key << YAML::VerbatimTag("!foo") << "bar";
} out << YAML::Value << "baz";
out << YAML::EndMap;
void VerbatimTagInFlowMap(YAML::Emitter& out, std::string& desiredOutput)
{ desiredOutput = "{!<!foo> bar: baz}";
out << YAML::Flow << YAML::BeginMap; }
out << YAML::Key << YAML::VerbatimTag("!foo") << "bar";
out << YAML::Value << "baz"; void VerbatimTagInFlowMapWithNull(YAML::Emitter& out,
out << YAML::EndMap; std::string& desiredOutput) {
out << YAML::Flow << YAML::BeginMap;
desiredOutput = "{!<!foo> bar: baz}"; out << YAML::Key << YAML::VerbatimTag("!foo") << YAML::Null;
} out << YAML::Value << "baz";
out << YAML::EndMap;
void VerbatimTagInFlowMapWithNull(YAML::Emitter& out, std::string& desiredOutput)
{ desiredOutput = "{!<!foo> ~: baz}";
out << YAML::Flow << YAML::BeginMap; }
out << YAML::Key << YAML::VerbatimTag("!foo") << YAML::Null;
out << YAML::Value << "baz"; void VerbatimTagWithEmptySeq(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::EndMap; out << YAML::VerbatimTag("!foo") << YAML::BeginSeq << YAML::EndSeq;
desiredOutput = "{!<!foo> ~: baz}"; desiredOutput = "!<!foo>\n[]";
} }
void VerbatimTagWithEmptySeq(YAML::Emitter& out, std::string& desiredOutput) void VerbatimTagWithEmptyMap(YAML::Emitter& out, std::string& desiredOutput) {
{ out << YAML::VerbatimTag("!bar") << YAML::BeginMap << YAML::EndMap;
out << YAML::VerbatimTag("!foo") << YAML::BeginSeq << YAML::EndSeq;
desiredOutput = "!<!bar>\n{}";
desiredOutput = "!<!foo>\n[]"; }
}
void VerbatimTagWithEmptySeqAndMap(YAML::Emitter& out,
void VerbatimTagWithEmptyMap(YAML::Emitter& out, std::string& desiredOutput) std::string& desiredOutput) {
{ out << YAML::BeginSeq;
out << YAML::VerbatimTag("!bar") << YAML::BeginMap << YAML::EndMap; out << YAML::VerbatimTag("!foo") << YAML::BeginSeq << YAML::EndSeq;
out << YAML::VerbatimTag("!bar") << YAML::BeginMap << YAML::EndMap;
desiredOutput = "!<!bar>\n{}"; out << YAML::EndSeq;
}
desiredOutput = "- !<!foo>\n []\n- !<!bar>\n {}";
void VerbatimTagWithEmptySeqAndMap(YAML::Emitter& out, std::string& desiredOutput) }
{
out << YAML::BeginSeq; void ByKindTagWithScalar(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::VerbatimTag("!foo") << YAML::BeginSeq << YAML::EndSeq; out << YAML::BeginSeq;
out << YAML::VerbatimTag("!bar") << YAML::BeginMap << YAML::EndMap; out << YAML::DoubleQuoted << "12";
out << YAML::EndSeq; out << "12";
out << YAML::TagByKind << "12";
desiredOutput = "- !<!foo>\n []\n- !<!bar>\n {}"; out << YAML::EndSeq;
}
desiredOutput = "- \"12\"\n- 12\n- ! 12";
void ByKindTagWithScalar(YAML::Emitter& out, std::string& desiredOutput) }
{
out << YAML::BeginSeq; void LocalTagWithScalar(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::DoubleQuoted << "12"; out << YAML::LocalTag("foo") << "bar";
out << "12";
out << YAML::TagByKind << "12"; desiredOutput = "!foo bar";
out << YAML::EndSeq; }
desiredOutput = "- \"12\"\n- 12\n- ! 12"; void BadLocalTag(YAML::Emitter& out, std::string& desiredError) {
} out << YAML::LocalTag("e!far") << "bar";
void LocalTagWithScalar(YAML::Emitter& out, std::string& desiredOutput) desiredError = "invalid tag";
{ }
out << YAML::LocalTag("foo") << "bar";
void ComplexDoc(YAML::Emitter& out, std::string& desiredOutput) {
desiredOutput = "!foo bar"; out << YAML::BeginMap;
} out << YAML::Key << "receipt";
out << YAML::Value << "Oz-Ware Purchase Invoice";
void BadLocalTag(YAML::Emitter& out, std::string& desiredError) out << YAML::Key << "date";
{ out << YAML::Value << "2007-08-06";
out << YAML::LocalTag("e!far") << "bar"; out << YAML::Key << "customer";
out << YAML::Value;
desiredError = "invalid tag"; out << YAML::BeginMap;
} out << YAML::Key << "given";
out << YAML::Value << "Dorothy";
void ComplexDoc(YAML::Emitter& out, std::string& desiredOutput) out << YAML::Key << "family";
{ out << YAML::Value << "Gale";
out << YAML::BeginMap; out << YAML::EndMap;
out << YAML::Key << "receipt"; out << YAML::Key << "items";
out << YAML::Value << "Oz-Ware Purchase Invoice"; out << YAML::Value;
out << YAML::Key << "date"; out << YAML::BeginSeq;
out << YAML::Value << "2007-08-06"; out << YAML::BeginMap;
out << YAML::Key << "customer"; out << YAML::Key << "part_no";
out << YAML::Value; out << YAML::Value << "A4786";
out << YAML::BeginMap; out << YAML::Key << "descrip";
out << YAML::Key << "given"; out << YAML::Value << "Water Bucket (Filled)";
out << YAML::Value << "Dorothy"; out << YAML::Key << "price";
out << YAML::Key << "family"; out << YAML::Value << 1.47;
out << YAML::Value << "Gale"; out << YAML::Key << "quantity";
out << YAML::EndMap; out << YAML::Value << 4;
out << YAML::Key << "items"; out << YAML::EndMap;
out << YAML::Value; out << YAML::BeginMap;
out << YAML::BeginSeq; out << YAML::Key << "part_no";
out << YAML::BeginMap; out << YAML::Value << "E1628";
out << YAML::Key << "part_no"; out << YAML::Key << "descrip";
out << YAML::Value << "A4786"; out << YAML::Value << "High Heeled \"Ruby\" Slippers";
out << YAML::Key << "descrip"; out << YAML::Key << "price";
out << YAML::Value << "Water Bucket (Filled)"; out << YAML::Value << 100.27;
out << YAML::Key << "price"; out << YAML::Key << "quantity";
out << YAML::Value << 1.47; out << YAML::Value << 1;
out << YAML::Key << "quantity"; out << YAML::EndMap;
out << YAML::Value << 4; out << YAML::EndSeq;
out << YAML::EndMap; out << YAML::Key << "bill-to";
out << YAML::BeginMap; out << YAML::Value << YAML::Anchor("id001");
out << YAML::Key << "part_no"; out << YAML::BeginMap;
out << YAML::Value << "E1628"; out << YAML::Key << "street";
out << YAML::Key << "descrip"; out << YAML::Value << YAML::Literal << "123 Tornado Alley\nSuite 16";
out << YAML::Value << "High Heeled \"Ruby\" Slippers"; out << YAML::Key << "city";
out << YAML::Key << "price"; out << YAML::Value << "East Westville";
out << YAML::Value << 100.27; out << YAML::Key << "state";
out << YAML::Key << "quantity"; out << YAML::Value << "KS";
out << YAML::Value << 1; out << YAML::EndMap;
out << YAML::EndMap; out << YAML::Key << "ship-to";
out << YAML::EndSeq; out << YAML::Value << YAML::Alias("id001");
out << YAML::Key << "bill-to"; out << YAML::EndMap;
out << YAML::Value << YAML::Anchor("id001");
out << YAML::BeginMap; desiredOutput =
out << YAML::Key << "street"; "receipt: Oz-Ware Purchase Invoice\ndate: 2007-08-06\ncustomer:\n "
out << YAML::Value << YAML::Literal << "123 Tornado Alley\nSuite 16"; "given: Dorothy\n family: Gale\nitems:\n - part_no: A4786\n "
out << YAML::Key << "city"; "descrip: Water Bucket (Filled)\n price: 1.47\n quantity: 4\n - "
out << YAML::Value << "East Westville"; "part_no: E1628\n descrip: High Heeled \"Ruby\" Slippers\n price: "
out << YAML::Key << "state"; "100.27\n quantity: 1\nbill-to: &id001\n street: |\n 123 Tornado "
out << YAML::Value << "KS"; "Alley\n Suite 16\n city: East Westville\n state: KS\nship-to: "
out << YAML::EndMap; "*id001";
out << YAML::Key << "ship-to"; }
out << YAML::Value << YAML::Alias("id001");
out << YAML::EndMap; void STLContainers(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginSeq;
desiredOutput = "receipt: Oz-Ware Purchase Invoice\ndate: 2007-08-06\ncustomer:\n given: Dorothy\n family: Gale\nitems:\n - part_no: A4786\n descrip: Water Bucket (Filled)\n price: 1.47\n quantity: 4\n - part_no: E1628\n descrip: High Heeled \"Ruby\" Slippers\n price: 100.27\n quantity: 1\nbill-to: &id001\n street: |\n 123 Tornado Alley\n Suite 16\n city: East Westville\n state: KS\nship-to: *id001"; std::vector<int> primes;
} primes.push_back(2);
primes.push_back(3);
void STLContainers(YAML::Emitter& out, std::string& desiredOutput) primes.push_back(5);
{ primes.push_back(7);
out << YAML::BeginSeq; primes.push_back(11);
std::vector <int> primes; primes.push_back(13);
primes.push_back(2); out << YAML::Flow << primes;
primes.push_back(3); std::map<std::string, int> ages;
primes.push_back(5); ages["Daniel"] = 26;
primes.push_back(7); ages["Jesse"] = 24;
primes.push_back(11); out << ages;
primes.push_back(13); out << YAML::EndSeq;
out << YAML::Flow << primes;
std::map <std::string, int> ages; desiredOutput = "- [2, 3, 5, 7, 11, 13]\n- Daniel: 26\n Jesse: 24";
ages["Daniel"] = 26; }
ages["Jesse"] = 24;
out << ages; void SimpleComment(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::EndSeq; out << YAML::BeginMap;
out << YAML::Key << "method";
desiredOutput = "- [2, 3, 5, 7, 11, 13]\n- Daniel: 26\n Jesse: 24"; out << YAML::Value << "least squares"
} << YAML::Comment("should we change this method?");
out << YAML::EndMap;
void SimpleComment(YAML::Emitter& out, std::string& desiredOutput)
{ desiredOutput = "method: least squares # should we change this method?";
out << YAML::BeginMap; }
out << YAML::Key << "method";
out << YAML::Value << "least squares" << YAML::Comment("should we change this method?"); void MultiLineComment(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::EndMap; out << YAML::BeginSeq;
out << "item 1" << YAML::Comment(
desiredOutput = "method: least squares # should we change this method?"; "really really long\ncomment that couldn't "
} "possibly\nfit on one line");
out << "item 2";
void MultiLineComment(YAML::Emitter& out, std::string& desiredOutput) out << YAML::EndSeq;
{
out << YAML::BeginSeq; desiredOutput =
out << "item 1" << YAML::Comment("really really long\ncomment that couldn't possibly\nfit on one line"); "- item 1 # really really long\n # comment that couldn't "
out << "item 2"; "possibly\n # fit on one line\n- item 2";
out << YAML::EndSeq; }
desiredOutput = "- item 1 # really really long\n # comment that couldn't possibly\n # fit on one line\n- item 2"; void ComplexComments(YAML::Emitter& out, std::string& desiredOutput) {
} out << YAML::BeginMap;
out << YAML::LongKey << YAML::Key << "long key" << YAML::Comment("long key");
void ComplexComments(YAML::Emitter& out, std::string& desiredOutput) out << YAML::Value << "value";
{ out << YAML::EndMap;
out << YAML::BeginMap;
out << YAML::LongKey << YAML::Key << "long key" << YAML::Comment("long key"); desiredOutput = "? long key # long key\n: value";
out << YAML::Value << "value"; }
out << YAML::EndMap;
void InitialComment(YAML::Emitter& out, std::string& desiredOutput) {
desiredOutput = "? long key # long key\n: value"; out << YAML::Comment("A comment describing the purpose of the file.");
} out << YAML::BeginMap << YAML::Key << "key" << YAML::Value << "value"
<< YAML::EndMap;
void InitialComment(YAML::Emitter& out, std::string& desiredOutput)
{ desiredOutput = "# A comment describing the purpose of the file.\nkey: value";
out << YAML::Comment("A comment describing the purpose of the file.");
out << YAML::BeginMap << YAML::Key << "key" << YAML::Value << "value" << YAML::EndMap;
desiredOutput = "# A comment describing the purpose of the file.\nkey: value";
}
void InitialCommentWithDocIndicator(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginDoc << YAML::Comment("A comment describing the purpose of the file.");
out << YAML::BeginMap << YAML::Key << "key" << YAML::Value << "value" << YAML::EndMap;
desiredOutput = "---\n# A comment describing the purpose of the file.\nkey: value";
}
void CommentInFlowSeq(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::Flow << YAML::BeginSeq << "foo" << YAML::Comment("foo!") << "bar" << YAML::EndSeq;
desiredOutput = "[foo, # foo!\nbar]";
}
void CommentInFlowMap(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::Flow << YAML::BeginMap;
out << YAML::Key << "foo" << YAML::Value << "foo value";
out << YAML::Key << "bar" << YAML::Value << "bar value" << YAML::Comment("bar!");
out << YAML::Key << "baz" << YAML::Value << "baz value" << YAML::Comment("baz!");
out << YAML::EndMap;
desiredOutput = "{foo: foo value, bar: bar value, # bar!\nbaz: baz value, # baz!\n}";
}
void Indentation(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::Indent(4);
out << YAML::BeginSeq;
out << YAML::BeginMap;
out << YAML::Key << "key 1" << YAML::Value << "value 1";
out << YAML::Key << "key 2" << YAML::Value << YAML::BeginSeq << "a" << "b" << "c" << YAML::EndSeq;
out << YAML::EndMap;
out << YAML::EndSeq;
desiredOutput = "- key 1: value 1\n key 2:\n - a\n - b\n - c";
}
void SimpleGlobalSettings(YAML::Emitter& out, std::string& desiredOutput)
{
out.SetIndent(4);
out.SetMapFormat(YAML::LongKey);
out << YAML::BeginSeq;
out << YAML::BeginMap;
out << YAML::Key << "key 1" << YAML::Value << "value 1";
out << YAML::Key << "key 2" << YAML::Value << YAML::Flow << YAML::BeginSeq << "a" << "b" << "c" << YAML::EndSeq;
out << YAML::EndMap;
out << YAML::EndSeq;
desiredOutput = "- ? key 1\n : value 1\n ? key 2\n : [a, b, c]";
}
void ComplexGlobalSettings(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginSeq;
out << YAML::Block;
out << YAML::BeginMap;
out << YAML::Key << "key 1" << YAML::Value << "value 1";
out << YAML::Key << "key 2" << YAML::Value;
out.SetSeqFormat(YAML::Flow);
out << YAML::BeginSeq << "a" << "b" << "c" << YAML::EndSeq;
out << YAML::EndMap;
out << YAML::BeginMap;
out << YAML::Key << YAML::BeginSeq << 1 << 2 << YAML::EndSeq;
out << YAML::Value << YAML::BeginMap << YAML::Key << "a" << YAML::Value << "b" << YAML::EndMap;
out << YAML::EndMap;
out << YAML::EndSeq;
desiredOutput = "- key 1: value 1\n key 2: [a, b, c]\n- [1, 2]:\n a: b";
}
void Null(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginSeq;
out << YAML::Null;
out << YAML::BeginMap;
out << YAML::Key << "null value" << YAML::Value << YAML::Null;
out << YAML::Key << YAML::Null << YAML::Value << "null key";
out << YAML::EndMap;
out << YAML::EndSeq;
desiredOutput = "- ~\n- null value: ~\n ~: null key";
}
void EscapedUnicode(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::EscapeNonAscii << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2";
desiredOutput = "\"$ \\xa2 \\u20ac \\U00024b62\"";
}
void Unicode(YAML::Emitter& out, std::string& desiredOutput)
{
out << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2";
desiredOutput = "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2";
}
void DoubleQuotedUnicode(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::DoubleQuoted << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2";
desiredOutput = "\"\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2\"";
}
struct Foo {
Foo(): x(0) {}
Foo(int x_, const std::string& bar_): x(x_), bar(bar_) {}
int x;
std::string bar;
};
YAML::Emitter& operator << (YAML::Emitter& out, const Foo& foo) {
out << YAML::BeginMap;
out << YAML::Key << "x" << YAML::Value << foo.x;
out << YAML::Key << "bar" << YAML::Value << foo.bar;
out << YAML::EndMap;
return out;
}
void UserType(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginSeq;
out << Foo(5, "hello");
out << Foo(3, "goodbye");
out << YAML::EndSeq;
desiredOutput = "- x: 5\n bar: hello\n- x: 3\n bar: goodbye";
}
void UserTypeInContainer(YAML::Emitter& out, std::string& desiredOutput)
{
std::vector<Foo> fv;
fv.push_back(Foo(5, "hello"));
fv.push_back(Foo(3, "goodbye"));
out << fv;
desiredOutput = "- x: 5\n bar: hello\n- x: 3\n bar: goodbye";
}
template <typename T>
YAML::Emitter& operator << (YAML::Emitter& out, const T *v) {
if(v)
out << *v;
else
out << YAML::Null;
return out;
}
void PointerToInt(YAML::Emitter& out, std::string& desiredOutput)
{
int foo = 5;
int *bar = &foo;
int *baz = 0;
out << YAML::BeginSeq;
out << bar << baz;
out << YAML::EndSeq;
desiredOutput = "- 5\n- ~";
}
void PointerToUserType(YAML::Emitter& out, std::string& desiredOutput)
{
Foo foo(5, "hello");
Foo *bar = &foo;
Foo *baz = 0;
out << YAML::BeginSeq;
out << bar << baz;
out << YAML::EndSeq;
desiredOutput = "- x: 5\n bar: hello\n- ~";
}
void NewlineAtEnd(YAML::Emitter& out, std::string& desiredOutput)
{
out << "Hello" << YAML::Newline << YAML::Newline;
desiredOutput = "Hello\n\n";
}
void NewlineInBlockSequence(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginSeq;
out << "a" << YAML::Newline << "b" << "c" << YAML::Newline << "d";
out << YAML::EndSeq;
desiredOutput = "- a\n\n- b\n- c\n\n- d";
}
void NewlineInFlowSequence(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::Flow << YAML::BeginSeq;
out << "a" << YAML::Newline << "b" << "c" << YAML::Newline << "d";
out << YAML::EndSeq;
desiredOutput = "[a,\nb, c,\nd]";
}
void NewlineInBlockMap(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginMap;
out << YAML::Key << "a" << YAML::Value << "foo" << YAML::Newline;
out << YAML::Key << "b" << YAML::Newline << YAML::Value << "bar";
out << YAML::LongKey << YAML::Key << "c" << YAML::Newline << YAML::Value << "car";
out << YAML::EndMap;
desiredOutput = "a: foo\nb:\n bar\n? c\n\n: car";
}
void NewlineInFlowMap(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::Flow << YAML::BeginMap;
out << YAML::Key << "a" << YAML::Value << "foo" << YAML::Newline;
out << YAML::Key << "b" << YAML::Value << "bar";
out << YAML::EndMap;
desiredOutput = "{a: foo,\nb: bar}";
}
void LotsOfNewlines(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginSeq;
out << "a" << YAML::Newline;
out << YAML::BeginSeq;
out << "b" << "c" << YAML::Newline;
out << YAML::EndSeq;
out << YAML::Newline;
out << YAML::BeginMap;
out << YAML::Newline << YAML::Key << "d" << YAML::Value << YAML::Newline << "e";
out << YAML::LongKey << YAML::Key << "f" << YAML::Newline << YAML::Value << "foo";
out << YAML::EndMap;
out << YAML::EndSeq;
desiredOutput = "- a\n\n-\n - b\n - c\n\n\n-\n d:\n e\n ? f\n\n : foo";
}
void Binary(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::Binary(reinterpret_cast<const unsigned char*>("Hello, World!"), 13);
desiredOutput = "!!binary \"SGVsbG8sIFdvcmxkIQ==\"";
}
void LongBinary(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::Binary(reinterpret_cast<const unsigned char*>("Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.\n"), 270);
desiredOutput = "!!binary \"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4K\"";
}
void EmptyBinary(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::Binary(reinterpret_cast<const unsigned char *>(""), 0);
desiredOutput = "!!binary \"\"";
}
void ColonAtEndOfScalar(YAML::Emitter& out, std::string& desiredOutput)
{
out << "a:";
desiredOutput = "\"a:\"";
}
void ColonAsScalar(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginMap;
out << YAML::Key << "apple" << YAML::Value << ":";
out << YAML::Key << "banana" << YAML::Value << ":";
out << YAML::EndMap;
desiredOutput = "apple: \":\"\nbanana: \":\"";
}
void ColonAtEndOfScalarInFlow(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::Flow << YAML::BeginMap << YAML::Key << "C:" << YAML::Value << "C:" << YAML::EndMap;
desiredOutput = "{\"C:\": \"C:\"}";
}
void BoolFormatting(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginSeq;
out << YAML::TrueFalseBool << YAML::UpperCase << true;
out << YAML::TrueFalseBool << YAML::CamelCase << true;
out << YAML::TrueFalseBool << YAML::LowerCase << true;
out << YAML::TrueFalseBool << YAML::UpperCase << false;
out << YAML::TrueFalseBool << YAML::CamelCase << false;
out << YAML::TrueFalseBool << YAML::LowerCase << false;
out << YAML::YesNoBool << YAML::UpperCase << true;
out << YAML::YesNoBool << YAML::CamelCase << true;
out << YAML::YesNoBool << YAML::LowerCase << true;
out << YAML::YesNoBool << YAML::UpperCase << false;
out << YAML::YesNoBool << YAML::CamelCase << false;
out << YAML::YesNoBool << YAML::LowerCase << false;
out << YAML::OnOffBool << YAML::UpperCase << true;
out << YAML::OnOffBool << YAML::CamelCase << true;
out << YAML::OnOffBool << YAML::LowerCase << true;
out << YAML::OnOffBool << YAML::UpperCase << false;
out << YAML::OnOffBool << YAML::CamelCase << false;
out << YAML::OnOffBool << YAML::LowerCase << false;
out << YAML::ShortBool << YAML::UpperCase << true;
out << YAML::ShortBool << YAML::CamelCase << true;
out << YAML::ShortBool << YAML::LowerCase << true;
out << YAML::ShortBool << YAML::UpperCase << false;
out << YAML::ShortBool << YAML::CamelCase << false;
out << YAML::ShortBool << YAML::LowerCase << false;
out << YAML::EndSeq;
desiredOutput =
"- TRUE\n- True\n- true\n- FALSE\n- False\n- false\n"
"- YES\n- Yes\n- yes\n- NO\n- No\n- no\n"
"- ON\n- On\n- on\n- OFF\n- Off\n- off\n"
"- Y\n- Y\n- y\n- N\n- N\n- n";
}
void DocStartAndEnd(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginDoc;
out << YAML::BeginSeq << 1 << 2 << 3 << YAML::EndSeq;
out << YAML::BeginDoc;
out << "Hi there!";
out << YAML::EndDoc;
out << YAML::EndDoc;
out << YAML::EndDoc;
out << YAML::BeginDoc;
out << YAML::VerbatimTag("foo") << "bar";
desiredOutput = "---\n- 1\n- 2\n- 3\n---\nHi there!\n...\n...\n...\n---\n!<foo> bar";
}
void ImplicitDocStart(YAML::Emitter& out, std::string& desiredOutput)
{
out << "Hi";
out << "Bye";
out << "Oops";
desiredOutput = "Hi\n---\nBye\n---\nOops";
}
void EmptyString(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginMap;
out << YAML::Key << "key" << YAML::Value << "";
out << YAML::EndMap;
desiredOutput = "key: \"\"";
}
void SingleChar(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginSeq;
out << 'a';
out << ':';
out << (char)0x10;
out << '\n';
out << ' ';
out << '\t';
out << YAML::EndSeq;
desiredOutput = "- a\n- \":\"\n- \"\\x10\"\n- \"\\n\"\n- \" \"\n- \"\\t\"";
}
void DefaultPrecision(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginSeq;
out << 1.234f;
out << 3.14159265358979;
out << YAML::EndSeq;
desiredOutput = "- 1.234\n- 3.14159265358979";
}
void SetPrecision(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginSeq;
out << YAML::FloatPrecision(3) << 1.234f;
out << YAML::DoublePrecision(6) << 3.14159265358979;
out << YAML::EndSeq;
desiredOutput = "- 1.23\n- 3.14159";
}
void DashInBlockContext(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::BeginMap;
out << YAML::Key << "key" << YAML::Value << "-";
out << YAML::EndMap;
desiredOutput = "key: \"-\"";
}
void HexAndOct(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::Flow << YAML::BeginSeq;
out << 31;
out << YAML::Hex << 31;
out << YAML::Oct << 31;
out << YAML::EndSeq;
desiredOutput = "[31, 0x1f, 037]";
}
void CompactMapWithNewline(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::Comment("Characteristics");
out << YAML::BeginSeq;
out << YAML::BeginMap;
out << YAML::Key << "color" << YAML::Value << "blue";
out << YAML::Key << "height" << YAML::Value << 120;
out << YAML::EndMap;
out << YAML::Newline << YAML::Newline;
out << YAML::Comment("Skills");
out << YAML::BeginMap;
out << YAML::Key << "attack" << YAML::Value << 23;
out << YAML::Key << "intelligence" << YAML::Value << 56;
out << YAML::EndMap;
out << YAML::EndSeq;
desiredOutput =
"# Characteristics\n"
"- color: blue\n"
" height: 120\n"
"\n"
"# Skills\n"
"- attack: 23\n"
" intelligence: 56";
}
void ForceSingleQuotedToDouble(YAML::Emitter& out, std::string& desiredOutput)
{
out << YAML::SingleQuoted << "Hello\nWorld";
desiredOutput = "\"Hello\\nWorld\"";
}
////////////////////////////////////////////////////////////////////////////////
// incorrect emitting
void ExtraEndSeq(YAML::Emitter& out, std::string& desiredError)
{
desiredError = YAML::ErrorMsg::UNEXPECTED_END_SEQ;
out << YAML::BeginSeq;
out << "Hello";
out << "World";
out << YAML::EndSeq;
out << YAML::EndSeq;
}
void ExtraEndMap(YAML::Emitter& out, std::string& desiredError)
{
desiredError = YAML::ErrorMsg::UNEXPECTED_END_MAP;
out << YAML::BeginMap;
out << YAML::Key << "Hello" << YAML::Value << "World";
out << YAML::EndMap;
out << YAML::EndMap;
}
void InvalidAnchor(YAML::Emitter& out, std::string& desiredError)
{
desiredError = YAML::ErrorMsg::INVALID_ANCHOR;
out << YAML::BeginSeq;
out << YAML::Anchor("new\nline") << "Test";
out << YAML::EndSeq;
}
void InvalidAlias(YAML::Emitter& out, std::string& desiredError)
{
desiredError = YAML::ErrorMsg::INVALID_ALIAS;
out << YAML::BeginSeq;
out << YAML::Alias("new\nline");
out << YAML::EndSeq;
}
}
namespace {
void RunEmitterTest(void (*test)(YAML::Emitter&, std::string&), const std::string& name, int& passed, int& total) {
YAML::Emitter out;
std::string desiredOutput;
test(out, desiredOutput);
std::string output = out.c_str();
std::string lastError = out.GetLastError();
if(output == desiredOutput) {
try {
YAML::Node node = YAML::Load(output);
passed++;
} catch(const YAML::Exception& e) {
std::cout << "Emitter test failed: " << name << "\n";
std::cout << "Parsing output error: " << e.what() << "\n";
}
} else {
std::cout << "Emitter test failed: " << name << "\n";
std::cout << "Output:\n";
std::cout << output << "<<<\n";
std::cout << "Desired output:\n";
std::cout << desiredOutput << "<<<\n";
if(!out.good())
std::cout << "Emitter error: " << lastError << "\n";
}
total++;
}
void RunEmitterErrorTest(void (*test)(YAML::Emitter&, std::string&), const std::string& name, int& passed, int& total) {
YAML::Emitter out;
std::string desiredError;
test(out, desiredError);
std::string lastError = out.GetLastError();
if(!out.good() && lastError == desiredError) {
passed++;
} else {
std::cout << "Emitter test failed: " << name << "\n";
if(out.good())
std::cout << "No error detected\n";
else
std::cout << "Detected error: " << lastError << "\n";
std::cout << "Expected error: " << desiredError << "\n";
}
total++;
}
void RunGenEmitterTest(TEST (*test)(YAML::Emitter&), const std::string& name, int& passed, int& total) {
YAML::Emitter out;
TEST ret;
try {
ret = test(out);
} catch(const YAML::Exception& e) {
ret.ok = false;
ret.error = std::string(" Exception caught: ") + e.what();
}
if(!out.good()) {
ret.ok = false;
ret.error = out.GetLastError();
}
if(!ret.ok) {
std::cout << "Generated emitter test failed: " << name << "\n";
std::cout << "Output:\n";
std::cout << out.c_str() << "<<<\n";
std::cout << ret.error << "\n";
}
if(ret.ok)
passed++;
total++;
}
}
#include "genemittertests.h"
bool RunEmitterTests()
{
int passed = 0;
int total = 0;
RunEmitterTest(&Emitter::SimpleScalar, "simple scalar", passed, total);
RunEmitterTest(&Emitter::SimpleSeq, "simple seq", passed, total);
RunEmitterTest(&Emitter::SimpleFlowSeq, "simple flow seq", passed, total);
RunEmitterTest(&Emitter::EmptyFlowSeq, "empty flow seq", passed, total);
RunEmitterTest(&Emitter::NestedBlockSeq, "nested block seq", passed, total);
RunEmitterTest(&Emitter::NestedFlowSeq, "nested flow seq", passed, total);
RunEmitterTest(&Emitter::SimpleMap, "simple map", passed, total);
RunEmitterTest(&Emitter::SimpleFlowMap, "simple flow map", passed, total);
RunEmitterTest(&Emitter::MapAndList, "map and list", passed, total);
RunEmitterTest(&Emitter::ListAndMap, "list and map", passed, total);
RunEmitterTest(&Emitter::NestedBlockMap, "nested block map", passed, total);
RunEmitterTest(&Emitter::NestedFlowMap, "nested flow map", passed, total);
RunEmitterTest(&Emitter::MapListMix, "map list mix", passed, total);
RunEmitterTest(&Emitter::SimpleLongKey, "simple long key", passed, total);
RunEmitterTest(&Emitter::SingleLongKey, "single long key", passed, total);
RunEmitterTest(&Emitter::ComplexLongKey, "complex long key", passed, total);
RunEmitterTest(&Emitter::AutoLongKey, "auto long key", passed, total);
RunEmitterTest(&Emitter::ScalarFormat, "scalar format", passed, total);
RunEmitterTest(&Emitter::AutoLongKeyScalar, "auto long key scalar", passed, total);
RunEmitterTest(&Emitter::LongKeyFlowMap, "long key flow map", passed, total);
RunEmitterTest(&Emitter::BlockMapAsKey, "block map as key", passed, total);
RunEmitterTest(&Emitter::AliasAndAnchor, "alias and anchor", passed, total);
RunEmitterTest(&Emitter::AliasAndAnchorWithNull, "alias and anchor with null", passed, total);
RunEmitterTest(&Emitter::AliasAndAnchorInFlow, "alias and anchor in flow", passed, total);
RunEmitterTest(&Emitter::SimpleVerbatimTag, "simple verbatim tag", passed, total);
RunEmitterTest(&Emitter::VerbatimTagInBlockSeq, "verbatim tag in block seq", passed, total);
RunEmitterTest(&Emitter::VerbatimTagInFlowSeq, "verbatim tag in flow seq", passed, total);
RunEmitterTest(&Emitter::VerbatimTagInFlowSeqWithNull, "verbatim tag in flow seq with null", passed, total);
RunEmitterTest(&Emitter::VerbatimTagInBlockMap, "verbatim tag in block map", passed, total);
RunEmitterTest(&Emitter::VerbatimTagInFlowMap, "verbatim tag in flow map", passed, total);
RunEmitterTest(&Emitter::VerbatimTagInFlowMapWithNull, "verbatim tag in flow map with null", passed, total);
RunEmitterTest(&Emitter::VerbatimTagWithEmptySeq, "verbatim tag with empty seq", passed, total);
RunEmitterTest(&Emitter::VerbatimTagWithEmptyMap, "verbatim tag with empty map", passed, total);
RunEmitterTest(&Emitter::VerbatimTagWithEmptySeqAndMap, "verbatim tag with empty seq and map", passed, total);
RunEmitterTest(&Emitter::ByKindTagWithScalar, "by-kind tag with scalar", passed, total);
RunEmitterTest(&Emitter::LocalTagWithScalar, "local tag with scalar", passed, total);
RunEmitterTest(&Emitter::ComplexDoc, "complex doc", passed, total);
RunEmitterTest(&Emitter::STLContainers, "STL containers", passed, total);
RunEmitterTest(&Emitter::SimpleComment, "simple comment", passed, total);
RunEmitterTest(&Emitter::MultiLineComment, "multi-line comment", passed, total);
RunEmitterTest(&Emitter::ComplexComments, "complex comments", passed, total);
RunEmitterTest(&Emitter::InitialComment, "initial comment", passed, total);
RunEmitterTest(&Emitter::InitialCommentWithDocIndicator, "initial comment with doc indicator", passed, total);
RunEmitterTest(&Emitter::CommentInFlowSeq, "comment in flow seq", passed, total);
RunEmitterTest(&Emitter::CommentInFlowMap, "comment in flow map", passed, total);
RunEmitterTest(&Emitter::Indentation, "indentation", passed, total);
RunEmitterTest(&Emitter::SimpleGlobalSettings, "simple global settings", passed, total);
RunEmitterTest(&Emitter::ComplexGlobalSettings, "complex global settings", passed, total);
RunEmitterTest(&Emitter::Null, "null", passed, total);
RunEmitterTest(&Emitter::EscapedUnicode, "escaped unicode", passed, total);
RunEmitterTest(&Emitter::Unicode, "unicode", passed, total);
RunEmitterTest(&Emitter::DoubleQuotedUnicode, "double quoted unicode", passed, total);
RunEmitterTest(&Emitter::UserType, "user type", passed, total);
RunEmitterTest(&Emitter::UserTypeInContainer, "user type in container", passed, total);
RunEmitterTest(&Emitter::PointerToInt, "pointer to int", passed, total);
RunEmitterTest(&Emitter::PointerToUserType, "pointer to user type", passed, total);
RunEmitterTest(&Emitter::NewlineAtEnd, "newline at end", passed, total);
RunEmitterTest(&Emitter::NewlineInBlockSequence, "newline in block sequence", passed, total);
RunEmitterTest(&Emitter::NewlineInFlowSequence, "newline in flow sequence", passed, total);
RunEmitterTest(&Emitter::NewlineInBlockMap, "newline in block map", passed, total);
RunEmitterTest(&Emitter::NewlineInFlowMap, "newline in flow map", passed, total);
RunEmitterTest(&Emitter::LotsOfNewlines, "lots of newlines", passed, total);
RunEmitterTest(&Emitter::Binary, "binary", passed, total);
RunEmitterTest(&Emitter::LongBinary, "long binary", passed, total);
RunEmitterTest(&Emitter::EmptyBinary, "empty binary", passed, total);
RunEmitterTest(&Emitter::ColonAtEndOfScalar, "colon at end of scalar", passed, total);
RunEmitterTest(&Emitter::ColonAsScalar, "colon as scalar", passed, total);
RunEmitterTest(&Emitter::ColonAtEndOfScalarInFlow, "colon at end of scalar in flow", passed, total);
RunEmitterTest(&Emitter::BoolFormatting, "bool formatting", passed, total);
RunEmitterTest(&Emitter::DocStartAndEnd, "doc start and end", passed, total);
RunEmitterTest(&Emitter::ImplicitDocStart, "implicit doc start", passed, total);
RunEmitterTest(&Emitter::EmptyString, "empty string", passed, total);
RunEmitterTest(&Emitter::SingleChar, "single char", passed, total);
RunEmitterTest(&Emitter::DefaultPrecision, "default precision", passed, total);
RunEmitterTest(&Emitter::SetPrecision, "set precision", passed, total);
RunEmitterTest(&Emitter::DashInBlockContext, "dash in block context", passed, total);
RunEmitterTest(&Emitter::HexAndOct, "hex and oct", passed, total);
RunEmitterTest(&Emitter::CompactMapWithNewline, "compact map with newline", passed, total);
RunEmitterTest(&Emitter::ForceSingleQuotedToDouble, "force single quoted to double", passed, total);
RunEmitterErrorTest(&Emitter::ExtraEndSeq, "extra EndSeq", passed, total);
RunEmitterErrorTest(&Emitter::ExtraEndMap, "extra EndMap", passed, total);
RunEmitterErrorTest(&Emitter::InvalidAnchor, "invalid anchor", passed, total);
RunEmitterErrorTest(&Emitter::InvalidAlias, "invalid alias", passed, total);
RunEmitterErrorTest(&Emitter::BadLocalTag, "bad local tag", passed, total);
RunGenEmitterTests(passed, total);
std::cout << "Emitter tests: " << passed << "/" << total << " passed\n";
return passed == total;
}
} }
void InitialCommentWithDocIndicator(YAML::Emitter& out,
std::string& desiredOutput) {
out << YAML::BeginDoc
<< YAML::Comment("A comment describing the purpose of the file.");
out << YAML::BeginMap << YAML::Key << "key" << YAML::Value << "value"
<< YAML::EndMap;
desiredOutput =
"---\n# A comment describing the purpose of the file.\nkey: value";
}
void CommentInFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Flow << YAML::BeginSeq << "foo" << YAML::Comment("foo!") << "bar"
<< YAML::EndSeq;
desiredOutput = "[foo, # foo!\nbar]";
}
void CommentInFlowMap(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Flow << YAML::BeginMap;
out << YAML::Key << "foo" << YAML::Value << "foo value";
out << YAML::Key << "bar" << YAML::Value << "bar value"
<< YAML::Comment("bar!");
out << YAML::Key << "baz" << YAML::Value << "baz value"
<< YAML::Comment("baz!");
out << YAML::EndMap;
desiredOutput =
"{foo: foo value, bar: bar value, # bar!\nbaz: baz value, # baz!\n}";
}
void Indentation(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Indent(4);
out << YAML::BeginSeq;
out << YAML::BeginMap;
out << YAML::Key << "key 1" << YAML::Value << "value 1";
out << YAML::Key << "key 2" << YAML::Value << YAML::BeginSeq << "a"
<< "b"
<< "c" << YAML::EndSeq;
out << YAML::EndMap;
out << YAML::EndSeq;
desiredOutput =
"- key 1: value 1\n key 2:\n - a\n - b\n - "
" c";
}
void SimpleGlobalSettings(YAML::Emitter& out, std::string& desiredOutput) {
out.SetIndent(4);
out.SetMapFormat(YAML::LongKey);
out << YAML::BeginSeq;
out << YAML::BeginMap;
out << YAML::Key << "key 1" << YAML::Value << "value 1";
out << YAML::Key << "key 2" << YAML::Value << YAML::Flow << YAML::BeginSeq
<< "a"
<< "b"
<< "c" << YAML::EndSeq;
out << YAML::EndMap;
out << YAML::EndSeq;
desiredOutput = "- ? key 1\n : value 1\n ? key 2\n : [a, b, c]";
}
void ComplexGlobalSettings(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginSeq;
out << YAML::Block;
out << YAML::BeginMap;
out << YAML::Key << "key 1" << YAML::Value << "value 1";
out << YAML::Key << "key 2" << YAML::Value;
out.SetSeqFormat(YAML::Flow);
out << YAML::BeginSeq << "a"
<< "b"
<< "c" << YAML::EndSeq;
out << YAML::EndMap;
out << YAML::BeginMap;
out << YAML::Key << YAML::BeginSeq << 1 << 2 << YAML::EndSeq;
out << YAML::Value << YAML::BeginMap << YAML::Key << "a" << YAML::Value << "b"
<< YAML::EndMap;
out << YAML::EndMap;
out << YAML::EndSeq;
desiredOutput = "- key 1: value 1\n key 2: [a, b, c]\n- [1, 2]:\n a: b";
}
void Null(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginSeq;
out << YAML::Null;
out << YAML::BeginMap;
out << YAML::Key << "null value" << YAML::Value << YAML::Null;
out << YAML::Key << YAML::Null << YAML::Value << "null key";
out << YAML::EndMap;
out << YAML::EndSeq;
desiredOutput = "- ~\n- null value: ~\n ~: null key";
}
void EscapedUnicode(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::EscapeNonAscii << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2";
desiredOutput = "\"$ \\xa2 \\u20ac \\U00024b62\"";
}
void Unicode(YAML::Emitter& out, std::string& desiredOutput) {
out << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2";
desiredOutput = "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2";
}
void DoubleQuotedUnicode(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::DoubleQuoted << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2";
desiredOutput = "\"\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2\"";
}
struct Foo {
Foo() : x(0) {}
Foo(int x_, const std::string& bar_) : x(x_), bar(bar_) {}
int x;
std::string bar;
};
YAML::Emitter& operator<<(YAML::Emitter& out, const Foo& foo) {
out << YAML::BeginMap;
out << YAML::Key << "x" << YAML::Value << foo.x;
out << YAML::Key << "bar" << YAML::Value << foo.bar;
out << YAML::EndMap;
return out;
}
void UserType(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginSeq;
out << Foo(5, "hello");
out << Foo(3, "goodbye");
out << YAML::EndSeq;
desiredOutput = "- x: 5\n bar: hello\n- x: 3\n bar: goodbye";
}
void UserTypeInContainer(YAML::Emitter& out, std::string& desiredOutput) {
std::vector<Foo> fv;
fv.push_back(Foo(5, "hello"));
fv.push_back(Foo(3, "goodbye"));
out << fv;
desiredOutput = "- x: 5\n bar: hello\n- x: 3\n bar: goodbye";
}
template <typename T>
YAML::Emitter& operator<<(YAML::Emitter& out, const T* v) {
if (v)
out << *v;
else
out << YAML::Null;
return out;
}
void PointerToInt(YAML::Emitter& out, std::string& desiredOutput) {
int foo = 5;
int* bar = &foo;
int* baz = 0;
out << YAML::BeginSeq;
out << bar << baz;
out << YAML::EndSeq;
desiredOutput = "- 5\n- ~";
}
void PointerToUserType(YAML::Emitter& out, std::string& desiredOutput) {
Foo foo(5, "hello");
Foo* bar = &foo;
Foo* baz = 0;
out << YAML::BeginSeq;
out << bar << baz;
out << YAML::EndSeq;
desiredOutput = "- x: 5\n bar: hello\n- ~";
}
void NewlineAtEnd(YAML::Emitter& out, std::string& desiredOutput) {
out << "Hello" << YAML::Newline << YAML::Newline;
desiredOutput = "Hello\n\n";
}
void NewlineInBlockSequence(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginSeq;
out << "a" << YAML::Newline << "b"
<< "c" << YAML::Newline << "d";
out << YAML::EndSeq;
desiredOutput = "- a\n\n- b\n- c\n\n- d";
}
void NewlineInFlowSequence(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Flow << YAML::BeginSeq;
out << "a" << YAML::Newline << "b"
<< "c" << YAML::Newline << "d";
out << YAML::EndSeq;
desiredOutput = "[a,\nb, c,\nd]";
}
void NewlineInBlockMap(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginMap;
out << YAML::Key << "a" << YAML::Value << "foo" << YAML::Newline;
out << YAML::Key << "b" << YAML::Newline << YAML::Value << "bar";
out << YAML::LongKey << YAML::Key << "c" << YAML::Newline << YAML::Value
<< "car";
out << YAML::EndMap;
desiredOutput = "a: foo\nb:\n bar\n? c\n\n: car";
}
void NewlineInFlowMap(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Flow << YAML::BeginMap;
out << YAML::Key << "a" << YAML::Value << "foo" << YAML::Newline;
out << YAML::Key << "b" << YAML::Value << "bar";
out << YAML::EndMap;
desiredOutput = "{a: foo,\nb: bar}";
}
void LotsOfNewlines(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginSeq;
out << "a" << YAML::Newline;
out << YAML::BeginSeq;
out << "b"
<< "c" << YAML::Newline;
out << YAML::EndSeq;
out << YAML::Newline;
out << YAML::BeginMap;
out << YAML::Newline << YAML::Key << "d" << YAML::Value << YAML::Newline
<< "e";
out << YAML::LongKey << YAML::Key << "f" << YAML::Newline << YAML::Value
<< "foo";
out << YAML::EndMap;
out << YAML::EndSeq;
desiredOutput =
"- a\n\n-\n - b\n - c\n\n\n-\n d:\n e\n ? f\n\n : foo";
}
void Binary(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Binary(reinterpret_cast<const unsigned char*>("Hello, World!"),
13);
desiredOutput = "!!binary \"SGVsbG8sIFdvcmxkIQ==\"";
}
void LongBinary(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Binary(
reinterpret_cast<const unsigned char*>(
"Man is distinguished, not only by his reason, but by this "
"singular passion from other animals, which is a lust of the "
"mind, that by a perseverance of delight in the continued and "
"indefatigable generation of knowledge, exceeds the short "
"vehemence of any carnal pleasure.\n"),
270);
desiredOutput =
"!!binary "
"\"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieS"
"B0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIG"
"x1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbi"
"B0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZG"
"dlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS"
"4K\"";
}
void EmptyBinary(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Binary(reinterpret_cast<const unsigned char*>(""), 0);
desiredOutput = "!!binary \"\"";
}
void ColonAtEndOfScalar(YAML::Emitter& out, std::string& desiredOutput) {
out << "a:";
desiredOutput = "\"a:\"";
}
void ColonAsScalar(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginMap;
out << YAML::Key << "apple" << YAML::Value << ":";
out << YAML::Key << "banana" << YAML::Value << ":";
out << YAML::EndMap;
desiredOutput = "apple: \":\"\nbanana: \":\"";
}
void ColonAtEndOfScalarInFlow(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Flow << YAML::BeginMap << YAML::Key << "C:" << YAML::Value
<< "C:" << YAML::EndMap;
desiredOutput = "{\"C:\": \"C:\"}";
}
void BoolFormatting(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginSeq;
out << YAML::TrueFalseBool << YAML::UpperCase << true;
out << YAML::TrueFalseBool << YAML::CamelCase << true;
out << YAML::TrueFalseBool << YAML::LowerCase << true;
out << YAML::TrueFalseBool << YAML::UpperCase << false;
out << YAML::TrueFalseBool << YAML::CamelCase << false;
out << YAML::TrueFalseBool << YAML::LowerCase << false;
out << YAML::YesNoBool << YAML::UpperCase << true;
out << YAML::YesNoBool << YAML::CamelCase << true;
out << YAML::YesNoBool << YAML::LowerCase << true;
out << YAML::YesNoBool << YAML::UpperCase << false;
out << YAML::YesNoBool << YAML::CamelCase << false;
out << YAML::YesNoBool << YAML::LowerCase << false;
out << YAML::OnOffBool << YAML::UpperCase << true;
out << YAML::OnOffBool << YAML::CamelCase << true;
out << YAML::OnOffBool << YAML::LowerCase << true;
out << YAML::OnOffBool << YAML::UpperCase << false;
out << YAML::OnOffBool << YAML::CamelCase << false;
out << YAML::OnOffBool << YAML::LowerCase << false;
out << YAML::ShortBool << YAML::UpperCase << true;
out << YAML::ShortBool << YAML::CamelCase << true;
out << YAML::ShortBool << YAML::LowerCase << true;
out << YAML::ShortBool << YAML::UpperCase << false;
out << YAML::ShortBool << YAML::CamelCase << false;
out << YAML::ShortBool << YAML::LowerCase << false;
out << YAML::EndSeq;
desiredOutput =
"- TRUE\n- True\n- true\n- FALSE\n- False\n- false\n"
"- YES\n- Yes\n- yes\n- NO\n- No\n- no\n"
"- ON\n- On\n- on\n- OFF\n- Off\n- off\n"
"- Y\n- Y\n- y\n- N\n- N\n- n";
}
void DocStartAndEnd(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginDoc;
out << YAML::BeginSeq << 1 << 2 << 3 << YAML::EndSeq;
out << YAML::BeginDoc;
out << "Hi there!";
out << YAML::EndDoc;
out << YAML::EndDoc;
out << YAML::EndDoc;
out << YAML::BeginDoc;
out << YAML::VerbatimTag("foo") << "bar";
desiredOutput =
"---\n- 1\n- 2\n- 3\n---\nHi there!\n...\n...\n...\n---\n!<foo> bar";
}
void ImplicitDocStart(YAML::Emitter& out, std::string& desiredOutput) {
out << "Hi";
out << "Bye";
out << "Oops";
desiredOutput = "Hi\n---\nBye\n---\nOops";
}
void EmptyString(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginMap;
out << YAML::Key << "key" << YAML::Value << "";
out << YAML::EndMap;
desiredOutput = "key: \"\"";
}
void SingleChar(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginSeq;
out << 'a';
out << ':';
out << (char)0x10;
out << '\n';
out << ' ';
out << '\t';
out << YAML::EndSeq;
desiredOutput = "- a\n- \":\"\n- \"\\x10\"\n- \"\\n\"\n- \" \"\n- \"\\t\"";
}
void DefaultPrecision(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginSeq;
out << 1.234f;
out << 3.14159265358979;
out << YAML::EndSeq;
desiredOutput = "- 1.234\n- 3.14159265358979";
}
void SetPrecision(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginSeq;
out << YAML::FloatPrecision(3) << 1.234f;
out << YAML::DoublePrecision(6) << 3.14159265358979;
out << YAML::EndSeq;
desiredOutput = "- 1.23\n- 3.14159";
}
void DashInBlockContext(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::BeginMap;
out << YAML::Key << "key" << YAML::Value << "-";
out << YAML::EndMap;
desiredOutput = "key: \"-\"";
}
void HexAndOct(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Flow << YAML::BeginSeq;
out << 31;
out << YAML::Hex << 31;
out << YAML::Oct << 31;
out << YAML::EndSeq;
desiredOutput = "[31, 0x1f, 037]";
}
void CompactMapWithNewline(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::Comment("Characteristics");
out << YAML::BeginSeq;
out << YAML::BeginMap;
out << YAML::Key << "color" << YAML::Value << "blue";
out << YAML::Key << "height" << YAML::Value << 120;
out << YAML::EndMap;
out << YAML::Newline << YAML::Newline;
out << YAML::Comment("Skills");
out << YAML::BeginMap;
out << YAML::Key << "attack" << YAML::Value << 23;
out << YAML::Key << "intelligence" << YAML::Value << 56;
out << YAML::EndMap;
out << YAML::EndSeq;
desiredOutput =
"# Characteristics\n"
"- color: blue\n"
" height: 120\n"
"\n"
"# Skills\n"
"- attack: 23\n"
" intelligence: 56";
}
void ForceSingleQuotedToDouble(YAML::Emitter& out, std::string& desiredOutput) {
out << YAML::SingleQuoted << "Hello\nWorld";
desiredOutput = "\"Hello\\nWorld\"";
}
////////////////////////////////////////////////////////////////////////////////
// incorrect emitting
void ExtraEndSeq(YAML::Emitter& out, std::string& desiredError) {
desiredError = YAML::ErrorMsg::UNEXPECTED_END_SEQ;
out << YAML::BeginSeq;
out << "Hello";
out << "World";
out << YAML::EndSeq;
out << YAML::EndSeq;
}
void ExtraEndMap(YAML::Emitter& out, std::string& desiredError) {
desiredError = YAML::ErrorMsg::UNEXPECTED_END_MAP;
out << YAML::BeginMap;
out << YAML::Key << "Hello" << YAML::Value << "World";
out << YAML::EndMap;
out << YAML::EndMap;
}
void InvalidAnchor(YAML::Emitter& out, std::string& desiredError) {
desiredError = YAML::ErrorMsg::INVALID_ANCHOR;
out << YAML::BeginSeq;
out << YAML::Anchor("new\nline") << "Test";
out << YAML::EndSeq;
}
void InvalidAlias(YAML::Emitter& out, std::string& desiredError) {
desiredError = YAML::ErrorMsg::INVALID_ALIAS;
out << YAML::BeginSeq;
out << YAML::Alias("new\nline");
out << YAML::EndSeq;
}
}
namespace {
void RunEmitterTest(void (*test)(YAML::Emitter&, std::string&),
const std::string& name, int& passed, int& total) {
YAML::Emitter out;
std::string desiredOutput;
test(out, desiredOutput);
std::string output = out.c_str();
std::string lastError = out.GetLastError();
if (output == desiredOutput) {
try {
YAML::Node node = YAML::Load(output);
passed++;
}
catch (const YAML::Exception& e) {
std::cout << "Emitter test failed: " << name << "\n";
std::cout << "Parsing output error: " << e.what() << "\n";
}
} else {
std::cout << "Emitter test failed: " << name << "\n";
std::cout << "Output:\n";
std::cout << output << "<<<\n";
std::cout << "Desired output:\n";
std::cout << desiredOutput << "<<<\n";
if (!out.good())
std::cout << "Emitter error: " << lastError << "\n";
}
total++;
}
void RunEmitterErrorTest(void (*test)(YAML::Emitter&, std::string&),
const std::string& name, int& passed, int& total) {
YAML::Emitter out;
std::string desiredError;
test(out, desiredError);
std::string lastError = out.GetLastError();
if (!out.good() && lastError == desiredError) {
passed++;
} else {
std::cout << "Emitter test failed: " << name << "\n";
if (out.good())
std::cout << "No error detected\n";
else
std::cout << "Detected error: " << lastError << "\n";
std::cout << "Expected error: " << desiredError << "\n";
}
total++;
}
void RunGenEmitterTest(TEST (*test)(YAML::Emitter&), const std::string& name,
int& passed, int& total) {
YAML::Emitter out;
TEST ret;
try {
ret = test(out);
}
catch (const YAML::Exception& e) {
ret.ok = false;
ret.error = std::string(" Exception caught: ") + e.what();
}
if (!out.good()) {
ret.ok = false;
ret.error = out.GetLastError();
}
if (!ret.ok) {
std::cout << "Generated emitter test failed: " << name << "\n";
std::cout << "Output:\n";
std::cout << out.c_str() << "<<<\n";
std::cout << ret.error << "\n";
}
if (ret.ok)
passed++;
total++;
}
}
#include "genemittertests.h"
bool RunEmitterTests() {
int passed = 0;
int total = 0;
RunEmitterTest(&Emitter::SimpleScalar, "simple scalar", passed, total);
RunEmitterTest(&Emitter::SimpleSeq, "simple seq", passed, total);
RunEmitterTest(&Emitter::SimpleFlowSeq, "simple flow seq", passed, total);
RunEmitterTest(&Emitter::EmptyFlowSeq, "empty flow seq", passed, total);
RunEmitterTest(&Emitter::NestedBlockSeq, "nested block seq", passed, total);
RunEmitterTest(&Emitter::NestedFlowSeq, "nested flow seq", passed, total);
RunEmitterTest(&Emitter::SimpleMap, "simple map", passed, total);
RunEmitterTest(&Emitter::SimpleFlowMap, "simple flow map", passed, total);
RunEmitterTest(&Emitter::MapAndList, "map and list", passed, total);
RunEmitterTest(&Emitter::ListAndMap, "list and map", passed, total);
RunEmitterTest(&Emitter::NestedBlockMap, "nested block map", passed, total);
RunEmitterTest(&Emitter::NestedFlowMap, "nested flow map", passed, total);
RunEmitterTest(&Emitter::MapListMix, "map list mix", passed, total);
RunEmitterTest(&Emitter::SimpleLongKey, "simple long key", passed, total);
RunEmitterTest(&Emitter::SingleLongKey, "single long key", passed, total);
RunEmitterTest(&Emitter::ComplexLongKey, "complex long key", passed, total);
RunEmitterTest(&Emitter::AutoLongKey, "auto long key", passed, total);
RunEmitterTest(&Emitter::ScalarFormat, "scalar format", passed, total);
RunEmitterTest(&Emitter::AutoLongKeyScalar, "auto long key scalar", passed,
total);
RunEmitterTest(&Emitter::LongKeyFlowMap, "long key flow map", passed, total);
RunEmitterTest(&Emitter::BlockMapAsKey, "block map as key", passed, total);
RunEmitterTest(&Emitter::AliasAndAnchor, "alias and anchor", passed, total);
RunEmitterTest(&Emitter::AliasAndAnchorWithNull, "alias and anchor with null",
passed, total);
RunEmitterTest(&Emitter::AliasAndAnchorInFlow, "alias and anchor in flow",
passed, total);
RunEmitterTest(&Emitter::SimpleVerbatimTag, "simple verbatim tag", passed,
total);
RunEmitterTest(&Emitter::VerbatimTagInBlockSeq, "verbatim tag in block seq",
passed, total);
RunEmitterTest(&Emitter::VerbatimTagInFlowSeq, "verbatim tag in flow seq",
passed, total);
RunEmitterTest(&Emitter::VerbatimTagInFlowSeqWithNull,
"verbatim tag in flow seq with null", passed, total);
RunEmitterTest(&Emitter::VerbatimTagInBlockMap, "verbatim tag in block map",
passed, total);
RunEmitterTest(&Emitter::VerbatimTagInFlowMap, "verbatim tag in flow map",
passed, total);
RunEmitterTest(&Emitter::VerbatimTagInFlowMapWithNull,
"verbatim tag in flow map with null", passed, total);
RunEmitterTest(&Emitter::VerbatimTagWithEmptySeq,
"verbatim tag with empty seq", passed, total);
RunEmitterTest(&Emitter::VerbatimTagWithEmptyMap,
"verbatim tag with empty map", passed, total);
RunEmitterTest(&Emitter::VerbatimTagWithEmptySeqAndMap,
"verbatim tag with empty seq and map", passed, total);
RunEmitterTest(&Emitter::ByKindTagWithScalar, "by-kind tag with scalar",
passed, total);
RunEmitterTest(&Emitter::LocalTagWithScalar, "local tag with scalar", passed,
total);
RunEmitterTest(&Emitter::ComplexDoc, "complex doc", passed, total);
RunEmitterTest(&Emitter::STLContainers, "STL containers", passed, total);
RunEmitterTest(&Emitter::SimpleComment, "simple comment", passed, total);
RunEmitterTest(&Emitter::MultiLineComment, "multi-line comment", passed,
total);
RunEmitterTest(&Emitter::ComplexComments, "complex comments", passed, total);
RunEmitterTest(&Emitter::InitialComment, "initial comment", passed, total);
RunEmitterTest(&Emitter::InitialCommentWithDocIndicator,
"initial comment with doc indicator", passed, total);
RunEmitterTest(&Emitter::CommentInFlowSeq, "comment in flow seq", passed,
total);
RunEmitterTest(&Emitter::CommentInFlowMap, "comment in flow map", passed,
total);
RunEmitterTest(&Emitter::Indentation, "indentation", passed, total);
RunEmitterTest(&Emitter::SimpleGlobalSettings, "simple global settings",
passed, total);
RunEmitterTest(&Emitter::ComplexGlobalSettings, "complex global settings",
passed, total);
RunEmitterTest(&Emitter::Null, "null", passed, total);
RunEmitterTest(&Emitter::EscapedUnicode, "escaped unicode", passed, total);
RunEmitterTest(&Emitter::Unicode, "unicode", passed, total);
RunEmitterTest(&Emitter::DoubleQuotedUnicode, "double quoted unicode", passed,
total);
RunEmitterTest(&Emitter::UserType, "user type", passed, total);
RunEmitterTest(&Emitter::UserTypeInContainer, "user type in container",
passed, total);
RunEmitterTest(&Emitter::PointerToInt, "pointer to int", passed, total);
RunEmitterTest(&Emitter::PointerToUserType, "pointer to user type", passed,
total);
RunEmitterTest(&Emitter::NewlineAtEnd, "newline at end", passed, total);
RunEmitterTest(&Emitter::NewlineInBlockSequence, "newline in block sequence",
passed, total);
RunEmitterTest(&Emitter::NewlineInFlowSequence, "newline in flow sequence",
passed, total);
RunEmitterTest(&Emitter::NewlineInBlockMap, "newline in block map", passed,
total);
RunEmitterTest(&Emitter::NewlineInFlowMap, "newline in flow map", passed,
total);
RunEmitterTest(&Emitter::LotsOfNewlines, "lots of newlines", passed, total);
RunEmitterTest(&Emitter::Binary, "binary", passed, total);
RunEmitterTest(&Emitter::LongBinary, "long binary", passed, total);
RunEmitterTest(&Emitter::EmptyBinary, "empty binary", passed, total);
RunEmitterTest(&Emitter::ColonAtEndOfScalar, "colon at end of scalar", passed,
total);
RunEmitterTest(&Emitter::ColonAsScalar, "colon as scalar", passed, total);
RunEmitterTest(&Emitter::ColonAtEndOfScalarInFlow,
"colon at end of scalar in flow", passed, total);
RunEmitterTest(&Emitter::BoolFormatting, "bool formatting", passed, total);
RunEmitterTest(&Emitter::DocStartAndEnd, "doc start and end", passed, total);
RunEmitterTest(&Emitter::ImplicitDocStart, "implicit doc start", passed,
total);
RunEmitterTest(&Emitter::EmptyString, "empty string", passed, total);
RunEmitterTest(&Emitter::SingleChar, "single char", passed, total);
RunEmitterTest(&Emitter::DefaultPrecision, "default precision", passed,
total);
RunEmitterTest(&Emitter::SetPrecision, "set precision", passed, total);
RunEmitterTest(&Emitter::DashInBlockContext, "dash in block context", passed,
total);
RunEmitterTest(&Emitter::HexAndOct, "hex and oct", passed, total);
RunEmitterTest(&Emitter::CompactMapWithNewline, "compact map with newline",
passed, total);
RunEmitterTest(&Emitter::ForceSingleQuotedToDouble,
"force single quoted to double", passed, total);
RunEmitterErrorTest(&Emitter::ExtraEndSeq, "extra EndSeq", passed, total);
RunEmitterErrorTest(&Emitter::ExtraEndMap, "extra EndMap", passed, total);
RunEmitterErrorTest(&Emitter::InvalidAnchor, "invalid anchor", passed, total);
RunEmitterErrorTest(&Emitter::InvalidAlias, "invalid alias", passed, total);
RunEmitterErrorTest(&Emitter::BadLocalTag, "bad local tag", passed, total);
RunGenEmitterTests(passed, total);
std::cout << "Emitter tests: " << passed << "/" << total << " passed\n";
return passed == total;
}
}
...@@ -9,595 +9,587 @@ ...@@ -9,595 +9,587 @@
#endif #endif
namespace { namespace {
struct TEST { struct TEST {
TEST(): ok(false) {} TEST() : ok(false) {}
TEST(bool ok_): ok(ok_) {} TEST(bool ok_) : ok(ok_) {}
TEST(const char *error_): ok(false), error(error_) {} TEST(const char* error_) : ok(false), error(error_) {}
TEST(const std::string& error_): ok(false), error(error_) {} TEST(const std::string& error_) : ok(false), error(error_) {}
bool ok; bool ok;
std::string error; std::string error;
}; };
} }
#define YAML_ASSERT(cond)\ #define YAML_ASSERT(cond) \
do {\ do { \
if(!(cond))\ if (!(cond)) \
return " Assert failed: " #cond;\ return " Assert failed: " #cond; \
} while(false) } while (false)
#define YAML_ASSERT_THROWS(cond, exc)\ #define YAML_ASSERT_THROWS(cond, exc) \
do {\ do { \
try {\ try { \
(cond);\ (cond); \
return " Expression did not throw: " #cond;\ return " Expression did not throw: " #cond; \
} catch(const exc&) {\ } \
} catch(const std::runtime_error& e) {\ catch (const exc&) { \
std::stringstream stream;\ } \
stream << " Expression threw runtime error ther than " #exc ":\n " #cond "\n " << e.what();\ catch (const std::runtime_error& e) { \
return stream.str();\ std::stringstream stream; \
} catch(...) {\ stream << " Expression threw runtime error ther than " #exc \
return " Expression threw unknown exception, other than " #exc ":\n " #cond;\ ":\n " #cond "\n " << e.what(); \
}\ return stream.str(); \
} while(false) } \
catch (...) { \
namespace Test return " Expression threw unknown exception, other than " #exc \
{ ":\n " #cond; \
namespace Node } \
{ } while (false)
TEST SimpleScalar()
{ namespace Test {
YAML::Node node = YAML::Node("Hello, World!"); namespace Node {
YAML_ASSERT(node.IsScalar()); TEST SimpleScalar() {
YAML_ASSERT(node.as<std::string>() == "Hello, World!"); YAML::Node node = YAML::Node("Hello, World!");
return true; YAML_ASSERT(node.IsScalar());
} YAML_ASSERT(node.as<std::string>() == "Hello, World!");
return true;
TEST IntScalar() }
{
YAML::Node node = YAML::Node(15); TEST IntScalar() {
YAML_ASSERT(node.IsScalar()); YAML::Node node = YAML::Node(15);
YAML_ASSERT(node.as<int>() == 15); YAML_ASSERT(node.IsScalar());
return true; YAML_ASSERT(node.as<int>() == 15);
} return true;
}
TEST SimpleAppendSequence()
{ TEST SimpleAppendSequence() {
YAML::Node node; YAML::Node node;
node.push_back(10); node.push_back(10);
node.push_back("foo"); node.push_back("foo");
node.push_back("monkey"); node.push_back("monkey");
YAML_ASSERT(node.IsSequence()); YAML_ASSERT(node.IsSequence());
YAML_ASSERT(node.size() == 3); YAML_ASSERT(node.size() == 3);
YAML_ASSERT(node[0].as<int>() == 10); YAML_ASSERT(node[0].as<int>() == 10);
YAML_ASSERT(node[1].as<std::string>() == "foo"); YAML_ASSERT(node[1].as<std::string>() == "foo");
YAML_ASSERT(node[2].as<std::string>() == "monkey"); YAML_ASSERT(node[2].as<std::string>() == "monkey");
YAML_ASSERT(node.IsSequence()); YAML_ASSERT(node.IsSequence());
return true; return true;
} }
TEST SimpleAssignSequence() TEST SimpleAssignSequence() {
{ YAML::Node node;
YAML::Node node; node[0] = 10;
node[0] = 10; node[1] = "foo";
node[1] = "foo"; node[2] = "monkey";
node[2] = "monkey"; YAML_ASSERT(node.IsSequence());
YAML_ASSERT(node.IsSequence()); YAML_ASSERT(node.size() == 3);
YAML_ASSERT(node.size() == 3); YAML_ASSERT(node[0].as<int>() == 10);
YAML_ASSERT(node[0].as<int>() == 10); YAML_ASSERT(node[1].as<std::string>() == "foo");
YAML_ASSERT(node[1].as<std::string>() == "foo"); YAML_ASSERT(node[2].as<std::string>() == "monkey");
YAML_ASSERT(node[2].as<std::string>() == "monkey"); YAML_ASSERT(node.IsSequence());
YAML_ASSERT(node.IsSequence()); return true;
return true; }
}
TEST SimpleMap() {
TEST SimpleMap() YAML::Node node;
{ node["key"] = "value";
YAML::Node node; YAML_ASSERT(node.IsMap());
node["key"] = "value"; YAML_ASSERT(node["key"].as<std::string>() == "value");
YAML_ASSERT(node.IsMap()); YAML_ASSERT(node.size() == 1);
YAML_ASSERT(node["key"].as<std::string>() == "value"); return true;
YAML_ASSERT(node.size() == 1); }
return true;
} TEST MapWithUndefinedValues() {
YAML::Node node;
TEST MapWithUndefinedValues() node["key"] = "value";
{ node["undefined"];
YAML::Node node; YAML_ASSERT(node.IsMap());
node["key"] = "value"; YAML_ASSERT(node["key"].as<std::string>() == "value");
node["undefined"]; YAML_ASSERT(node.size() == 1);
YAML_ASSERT(node.IsMap());
YAML_ASSERT(node["key"].as<std::string>() == "value"); node["undefined"] = "monkey";
YAML_ASSERT(node.size() == 1); YAML_ASSERT(node["undefined"].as<std::string>() == "monkey");
YAML_ASSERT(node.size() == 2);
node["undefined"] = "monkey";
YAML_ASSERT(node["undefined"].as<std::string>() == "monkey"); return true;
YAML_ASSERT(node.size() == 2); }
return true; TEST MapIteratorWithUndefinedValues() {
} YAML::Node node;
node["key"] = "value";
TEST MapIteratorWithUndefinedValues() node["undefined"];
{
YAML::Node node; std::size_t count = 0;
node["key"] = "value"; for (YAML::const_iterator it = node.begin(); it != node.end(); ++it)
node["undefined"]; count++;
YAML_ASSERT(count == 1);
std::size_t count = 0; return true;
for(YAML::const_iterator it=node.begin();it!=node.end();++it) }
count++;
YAML_ASSERT(count == 1); TEST SimpleSubkeys() {
return true; YAML::Node node;
} node["device"]["udid"] = "12345";
node["device"]["name"] = "iPhone";
TEST SimpleSubkeys() node["device"]["os"] = "4.0";
{ node["username"] = "monkey";
YAML::Node node; YAML_ASSERT(node["device"]["udid"].as<std::string>() == "12345");
node["device"]["udid"] = "12345"; YAML_ASSERT(node["device"]["name"].as<std::string>() == "iPhone");
node["device"]["name"] = "iPhone"; YAML_ASSERT(node["device"]["os"].as<std::string>() == "4.0");
node["device"]["os"] = "4.0"; YAML_ASSERT(node["username"].as<std::string>() == "monkey");
node["username"] = "monkey"; return true;
YAML_ASSERT(node["device"]["udid"].as<std::string>() == "12345"); }
YAML_ASSERT(node["device"]["name"].as<std::string>() == "iPhone");
YAML_ASSERT(node["device"]["os"].as<std::string>() == "4.0"); TEST StdVector() {
YAML_ASSERT(node["username"].as<std::string>() == "monkey"); std::vector<int> primes;
return true; primes.push_back(2);
} primes.push_back(3);
primes.push_back(5);
TEST StdVector() primes.push_back(7);
{ primes.push_back(11);
std::vector<int> primes; primes.push_back(13);
primes.push_back(2);
primes.push_back(3); YAML::Node node;
primes.push_back(5); node["primes"] = primes;
primes.push_back(7); YAML_ASSERT(node["primes"].as<std::vector<int> >() == primes);
primes.push_back(11); return true;
primes.push_back(13); }
YAML::Node node; TEST StdList() {
node["primes"] = primes; std::list<int> primes;
YAML_ASSERT(node["primes"].as<std::vector<int> >() == primes); primes.push_back(2);
return true; primes.push_back(3);
} primes.push_back(5);
primes.push_back(7);
TEST StdList() primes.push_back(11);
{ primes.push_back(13);
std::list<int> primes;
primes.push_back(2); YAML::Node node;
primes.push_back(3); node["primes"] = primes;
primes.push_back(5); YAML_ASSERT(node["primes"].as<std::list<int> >() == primes);
primes.push_back(7); return true;
primes.push_back(11); }
primes.push_back(13);
TEST StdMap() {
YAML::Node node; std::map<int, int> squares;
node["primes"] = primes; squares[0] = 0;
YAML_ASSERT(node["primes"].as<std::list<int> >() == primes); squares[1] = 1;
return true; squares[2] = 4;
} squares[3] = 9;
squares[4] = 16;
TEST StdMap()
{ YAML::Node node;
std::map<int, int> squares; node["squares"] = squares;
squares[0] = 0; YAML_ASSERT((node["squares"].as<std::map<int, int> >() == squares));
squares[1] = 1; return true;
squares[2] = 4; }
squares[3] = 9;
squares[4] = 16; TEST StdPair() {
std::pair<int, std::string> p;
YAML::Node node; p.first = 5;
node["squares"] = squares; p.second = "five";
YAML_ASSERT((node["squares"].as<std::map<int, int> >() == squares));
return true; YAML::Node node;
} node["pair"] = p;
YAML_ASSERT((node["pair"].as<std::pair<int, std::string> >() == p));
TEST StdPair() return true;
{ }
std::pair<int, std::string> p;
p.first = 5; TEST SimpleAlias() {
p.second = "five"; YAML::Node node;
node["foo"] = "value";
YAML::Node node; node["bar"] = node["foo"];
node["pair"] = p; YAML_ASSERT(node["foo"].as<std::string>() == "value");
YAML_ASSERT((node["pair"].as<std::pair<int, std::string> >() == p)); YAML_ASSERT(node["bar"].as<std::string>() == "value");
return true; YAML_ASSERT(node["foo"] == node["bar"]);
} YAML_ASSERT(node.size() == 2);
return true;
TEST SimpleAlias() }
{
YAML::Node node; TEST AliasAsKey() {
node["foo"] = "value"; YAML::Node node;
node["bar"] = node["foo"]; node["foo"] = "value";
YAML_ASSERT(node["foo"].as<std::string>() == "value"); YAML::Node value = node["foo"];
YAML_ASSERT(node["bar"].as<std::string>() == "value"); node[value] = "foo";
YAML_ASSERT(node["foo"] == node["bar"]); YAML_ASSERT(node["foo"].as<std::string>() == "value");
YAML_ASSERT(node.size() == 2); YAML_ASSERT(node[value].as<std::string>() == "foo");
return true; YAML_ASSERT(node["value"].as<std::string>() == "foo");
} YAML_ASSERT(node.size() == 2);
return true;
TEST AliasAsKey() }
{
YAML::Node node; TEST SelfReferenceSequence() {
node["foo"] = "value"; YAML::Node node;
YAML::Node value = node["foo"]; node[0] = node;
node[value] = "foo"; YAML_ASSERT(node.IsSequence());
YAML_ASSERT(node["foo"].as<std::string>() == "value"); YAML_ASSERT(node.size() == 1);
YAML_ASSERT(node[value].as<std::string>() == "foo"); YAML_ASSERT(node[0] == node);
YAML_ASSERT(node["value"].as<std::string>() == "foo"); YAML_ASSERT(node[0][0] == node);
YAML_ASSERT(node.size() == 2); YAML_ASSERT(node[0][0] == node[0]);
return true; return true;
} }
TEST SelfReferenceSequence() TEST ValueSelfReferenceMap() {
{ YAML::Node node;
YAML::Node node; node["key"] = node;
node[0] = node; YAML_ASSERT(node.IsMap());
YAML_ASSERT(node.IsSequence()); YAML_ASSERT(node.size() == 1);
YAML_ASSERT(node.size() == 1); YAML_ASSERT(node["key"] == node);
YAML_ASSERT(node[0] == node); YAML_ASSERT(node["key"]["key"] == node);
YAML_ASSERT(node[0][0] == node); YAML_ASSERT(node["key"]["key"] == node["key"]);
YAML_ASSERT(node[0][0] == node[0]); return true;
return true; }
}
TEST KeySelfReferenceMap() {
TEST ValueSelfReferenceMap() YAML::Node node;
{ node[node] = "value";
YAML::Node node; YAML_ASSERT(node.IsMap());
node["key"] = node; YAML_ASSERT(node.size() == 1);
YAML_ASSERT(node.IsMap()); YAML_ASSERT(node[node].as<std::string>() == "value");
YAML_ASSERT(node.size() == 1); return true;
YAML_ASSERT(node["key"] == node); }
YAML_ASSERT(node["key"]["key"] == node);
YAML_ASSERT(node["key"]["key"] == node["key"]); TEST SelfReferenceMap() {
return true; YAML::Node node;
} node[node] = node;
YAML_ASSERT(node.IsMap());
TEST KeySelfReferenceMap() YAML_ASSERT(node.size() == 1);
{ YAML_ASSERT(node[node] == node);
YAML::Node node; YAML_ASSERT(node[node][node] == node);
node[node] = "value"; YAML_ASSERT(node[node][node] == node[node]);
YAML_ASSERT(node.IsMap()); return true;
YAML_ASSERT(node.size() == 1); }
YAML_ASSERT(node[node].as<std::string>() == "value");
return true; TEST TempMapVariable() {
} YAML::Node node;
YAML::Node tmp = node["key"];
TEST SelfReferenceMap() tmp = "value";
{ YAML_ASSERT(node.IsMap());
YAML::Node node; YAML_ASSERT(node.size() == 1);
node[node] = node; YAML_ASSERT(node["key"].as<std::string>() == "value");
YAML_ASSERT(node.IsMap()); return true;
YAML_ASSERT(node.size() == 1); }
YAML_ASSERT(node[node] == node);
YAML_ASSERT(node[node][node] == node); TEST TempMapVariableAlias() {
YAML_ASSERT(node[node][node] == node[node]); YAML::Node node;
return true; YAML::Node tmp = node["key"];
} tmp = node["other"];
node["other"] = "value";
TEST TempMapVariable() YAML_ASSERT(node.IsMap());
{ YAML_ASSERT(node.size() == 2);
YAML::Node node; YAML_ASSERT(node["key"].as<std::string>() == "value");
YAML::Node tmp = node["key"]; YAML_ASSERT(node["other"].as<std::string>() == "value");
tmp = "value"; YAML_ASSERT(node["other"] == node["key"]);
YAML_ASSERT(node.IsMap()); return true;
YAML_ASSERT(node.size() == 1); }
YAML_ASSERT(node["key"].as<std::string>() == "value");
return true; TEST Bool() {
} YAML::Node node;
node[true] = false;
TEST TempMapVariableAlias() YAML_ASSERT(node.IsMap());
{ YAML_ASSERT(node[true].as<bool>() == false);
YAML::Node node; return true;
YAML::Node tmp = node["key"]; }
tmp = node["other"];
node["other"] = "value"; TEST AutoBoolConversion() {
YAML_ASSERT(node.IsMap()); YAML::Node node;
YAML_ASSERT(node.size() == 2); node["foo"] = "bar";
YAML_ASSERT(node["key"].as<std::string>() == "value"); YAML_ASSERT(static_cast<bool>(node["foo"]));
YAML_ASSERT(node["other"].as<std::string>() == "value"); YAML_ASSERT(!node["monkey"]);
YAML_ASSERT(node["other"] == node["key"]); YAML_ASSERT(!!node["foo"]);
return true; return true;
} }
TEST Bool() TEST Reassign() {
{ YAML::Node node = YAML::Load("foo");
YAML::Node node; node = YAML::Node();
node[true] = false; return true;
YAML_ASSERT(node.IsMap()); }
YAML_ASSERT(node[true].as<bool>() == false);
return true; TEST FallbackValues() {
} YAML::Node node = YAML::Load("foo: bar\nx: 2");
YAML_ASSERT(node["foo"].as<std::string>() == "bar");
TEST AutoBoolConversion() YAML_ASSERT(node["foo"].as<std::string>("hello") == "bar");
{ YAML_ASSERT(node["baz"].as<std::string>("hello") == "hello");
YAML::Node node; YAML_ASSERT(node["x"].as<int>() == 2);
node["foo"] = "bar"; YAML_ASSERT(node["x"].as<int>(5) == 2);
YAML_ASSERT(static_cast<bool>(node["foo"])); YAML_ASSERT(node["y"].as<int>(5) == 5);
YAML_ASSERT(!node["monkey"]); return true;
YAML_ASSERT(!!node["foo"]); }
return true;
} TEST NumericConversion() {
YAML::Node node = YAML::Load("[1.5, 1, .nan, .inf, -.inf, 0x15, 015]");
TEST Reassign() YAML_ASSERT(node[0].as<float>() == 1.5f);
{ YAML_ASSERT(node[0].as<double>() == 1.5);
YAML::Node node = YAML::Load("foo"); YAML_ASSERT_THROWS(node[0].as<int>(), YAML::TypedBadConversion<int>);
node = YAML::Node(); YAML_ASSERT(node[1].as<int>() == 1);
return true; YAML_ASSERT(node[1].as<float>() == 1.0f);
} YAML_ASSERT(node[2].as<float>() != node[2].as<float>());
YAML_ASSERT(node[3].as<float>() == std::numeric_limits<float>::infinity());
TEST FallbackValues() YAML_ASSERT(node[4].as<float>() == -std::numeric_limits<float>::infinity());
{ YAML_ASSERT(node[5].as<int>() == 21);
YAML::Node node = YAML::Load("foo: bar\nx: 2"); YAML_ASSERT(node[6].as<int>() == 13);
YAML_ASSERT(node["foo"].as<std::string>() == "bar"); return true;
YAML_ASSERT(node["foo"].as<std::string>("hello") == "bar"); }
YAML_ASSERT(node["baz"].as<std::string>("hello") == "hello");
YAML_ASSERT(node["x"].as<int>() == 2); TEST Binary() {
YAML_ASSERT(node["x"].as<int>(5) == 2); YAML::Node node = YAML::Load(
YAML_ASSERT(node["y"].as<int>(5) == 5); "[!!binary \"SGVsbG8sIFdvcmxkIQ==\", !!binary "
return true; "\"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieS"
} "B0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIG"
"x1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbi"
TEST NumericConversion() "B0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZG"
{ "dlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS"
YAML::Node node = YAML::Load("[1.5, 1, .nan, .inf, -.inf, 0x15, 015]"); "4K\"]");
YAML_ASSERT(node[0].as<float>() == 1.5f); YAML_ASSERT(node[0].as<YAML::Binary>() ==
YAML_ASSERT(node[0].as<double>() == 1.5); YAML::Binary(
YAML_ASSERT_THROWS(node[0].as<int>(), YAML::TypedBadConversion<int>); reinterpret_cast<const unsigned char*>("Hello, World!"), 13));
YAML_ASSERT(node[1].as<int>() == 1); YAML_ASSERT(node[1].as<YAML::Binary>() ==
YAML_ASSERT(node[1].as<float>() == 1.0f); YAML::Binary(reinterpret_cast<const unsigned char*>(
YAML_ASSERT(node[2].as<float>() != node[2].as<float>()); "Man is distinguished, not only by his reason, "
YAML_ASSERT(node[3].as<float>() == std::numeric_limits<float>::infinity()); "but by this singular passion from other "
YAML_ASSERT(node[4].as<float>() == -std::numeric_limits<float>::infinity()); "animals, which is a lust of the mind, that by "
YAML_ASSERT(node[5].as<int>() == 21); "a perseverance of delight in the continued and "
YAML_ASSERT(node[6].as<int>() == 13); "indefatigable generation of knowledge, exceeds "
return true; "the short vehemence of any carnal pleasure.\n"),
} 270));
return true;
TEST Binary() }
{
YAML::Node node = YAML::Load("[!!binary \"SGVsbG8sIFdvcmxkIQ==\", !!binary \"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4K\"]"); TEST IterateSequence() {
YAML_ASSERT(node[0].as<YAML::Binary>() == YAML::Binary(reinterpret_cast<const unsigned char*>("Hello, World!"), 13)); YAML::Node node = YAML::Load("[1, 3, 5, 7]");
YAML_ASSERT(node[1].as<YAML::Binary>() == YAML::Binary(reinterpret_cast<const unsigned char*>("Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.\n"), 270)); int seq[] = {1, 3, 5, 7};
return true; int i = 0;
} for (YAML::const_iterator it = node.begin(); it != node.end(); ++it) {
YAML_ASSERT(i < 4);
TEST IterateSequence() int x = seq[i++];
{ YAML_ASSERT(it->as<int>() == x);
YAML::Node node = YAML::Load("[1, 3, 5, 7]"); }
int seq[] = {1, 3, 5, 7}; YAML_ASSERT(i == 4);
int i=0; return true;
for(YAML::const_iterator it=node.begin();it!=node.end();++it) { }
YAML_ASSERT(i < 4);
int x = seq[i++]; TEST IterateMap() {
YAML_ASSERT(it->as<int>() == x); YAML::Node node = YAML::Load("{a: A, b: B, c: C}");
} int i = 0;
YAML_ASSERT(i == 4); for (YAML::const_iterator it = node.begin(); it != node.end(); ++it) {
return true; YAML_ASSERT(i < 3);
} i++;
YAML_ASSERT(it->first.as<char>() + 'A' - 'a' == it->second.as<char>());
TEST IterateMap() }
{ YAML_ASSERT(i == 3);
YAML::Node node = YAML::Load("{a: A, b: B, c: C}"); return true;
int i=0; }
for(YAML::const_iterator it=node.begin();it!=node.end();++it) {
YAML_ASSERT(i < 3);
i++;
YAML_ASSERT(it->first.as<char>() + 'A' - 'a' == it->second.as<char>());
}
YAML_ASSERT(i == 3);
return true;
}
#ifdef BOOST_FOREACH #ifdef BOOST_FOREACH
TEST ForEach() TEST ForEach() {
{ YAML::Node node = YAML::Load("[1, 3, 5, 7]");
YAML::Node node = YAML::Load("[1, 3, 5, 7]"); int seq[] = {1, 3, 5, 7};
int seq[] = {1, 3, 5, 7}; int i = 0;
int i = 0; BOOST_FOREACH(const YAML::Node & item, node) {
BOOST_FOREACH(const YAML::Node &item, node) { int x = seq[i++];
int x = seq[i++]; YAML_ASSERT(item.as<int>() == x);
YAML_ASSERT(item.as<int>() == x); }
} return true;
return true; }
}
TEST ForEachMap() {
TEST ForEachMap() YAML::Node node = YAML::Load("{a: A, b: B, c: C}");
{ BOOST_FOREACH(const YAML::const_iterator::value_type & p, node) {
YAML::Node node = YAML::Load("{a: A, b: B, c: C}"); YAML_ASSERT(p.first.as<char>() + 'A' - 'a' == p.second.as<char>());
BOOST_FOREACH(const YAML::const_iterator::value_type &p, node) { }
YAML_ASSERT(p.first.as<char>() + 'A' - 'a' == p.second.as<char>()); return true;
} }
return true;
}
#endif #endif
TEST CloneScalar() TEST CloneScalar() {
{ YAML::Node node = YAML::Load("!foo monkey");
YAML::Node node = YAML::Load("!foo monkey"); YAML::Node clone = Clone(node);
YAML::Node clone = Clone(node); YAML_ASSERT(!(node == clone));
YAML_ASSERT(!(node == clone)); YAML_ASSERT(node.as<std::string>() == clone.as<std::string>());
YAML_ASSERT(node.as<std::string>() == clone.as<std::string>()); YAML_ASSERT(node.Tag() == clone.Tag());
YAML_ASSERT(node.Tag() == clone.Tag()); return true;
return true; }
}
TEST CloneSeq() {
TEST CloneSeq() YAML::Node node = YAML::Load("[1, 3, 5, 7]");
{ YAML::Node clone = Clone(node);
YAML::Node node = YAML::Load("[1, 3, 5, 7]"); YAML_ASSERT(!(node == clone));
YAML::Node clone = Clone(node); YAML_ASSERT(clone.Type() == YAML::NodeType::Sequence);
YAML_ASSERT(!(node == clone)); YAML_ASSERT(node.size() == clone.size());
YAML_ASSERT(clone.Type() == YAML::NodeType::Sequence); for (std::size_t i = 0; i < node.size(); i++)
YAML_ASSERT(node.size() == clone.size()); YAML_ASSERT(node[i].as<int>() == clone[i].as<int>());
for(std::size_t i=0;i<node.size();i++) return true;
YAML_ASSERT(node[i].as<int>() == clone[i].as<int>()); }
return true;
} TEST CloneMap() {
YAML::Node node = YAML::Load("{foo: bar}");
TEST CloneMap() YAML::Node clone = Clone(node);
{ YAML_ASSERT(!(node == clone));
YAML::Node node = YAML::Load("{foo: bar}"); YAML_ASSERT(clone.Type() == YAML::NodeType::Map);
YAML::Node clone = Clone(node); YAML_ASSERT(node.size() == clone.size());
YAML_ASSERT(!(node == clone)); YAML_ASSERT(node["foo"].as<std::string>() == clone["foo"].as<std::string>());
YAML_ASSERT(clone.Type() == YAML::NodeType::Map); return true;
YAML_ASSERT(node.size() == clone.size()); }
YAML_ASSERT(node["foo"].as<std::string>() == clone["foo"].as<std::string>());
return true; TEST CloneAlias() {
} YAML::Node node = YAML::Load("&foo [*foo]");
YAML::Node clone = Clone(node);
TEST CloneAlias() YAML_ASSERT(!(node == clone));
{ YAML_ASSERT(clone.Type() == YAML::NodeType::Sequence);
YAML::Node node = YAML::Load("&foo [*foo]"); YAML_ASSERT(node.size() == clone.size());
YAML::Node clone = Clone(node); YAML_ASSERT(clone == clone[0]);
YAML_ASSERT(!(node == clone)); return true;
YAML_ASSERT(clone.Type() == YAML::NodeType::Sequence); }
YAML_ASSERT(node.size() == clone.size());
YAML_ASSERT(clone == clone[0]); TEST ForceInsertIntoMap() {
return true; YAML::Node node;
} node["a"] = "b";
node.force_insert("x", "y");
TEST ForceInsertIntoMap() node.force_insert("a", 5);
{ YAML_ASSERT(node.size() == 3);
YAML::Node node; YAML_ASSERT(node.Type() == YAML::NodeType::Map);
node["a"] = "b"; bool ab = false;
node.force_insert("x", "y"); bool a5 = false;
node.force_insert("a", 5); bool xy = false;
YAML_ASSERT(node.size() == 3); for (YAML::const_iterator it = node.begin(); it != node.end(); ++it) {
YAML_ASSERT(node.Type() == YAML::NodeType::Map); if (it->first.as<std::string>() == "a") {
bool ab = false; if (it->second.as<std::string>() == "b")
bool a5 = false; ab = true;
bool xy = false; else if (it->second.as<std::string>() == "5")
for(YAML::const_iterator it=node.begin();it!=node.end();++it) { a5 = true;
if(it->first.as<std::string>() == "a") { } else if (it->first.as<std::string>() == "x" &&
if(it->second.as<std::string>() == "b") it->second.as<std::string>() == "y")
ab = true; xy = true;
else if(it->second.as<std::string>() == "5") }
a5 = true; YAML_ASSERT(ab);
} else if(it->first.as<std::string>() == "x" && it->second.as<std::string>() == "y") YAML_ASSERT(a5);
xy = true; YAML_ASSERT(xy);
} return true;
YAML_ASSERT(ab); }
YAML_ASSERT(a5);
YAML_ASSERT(xy); TEST ResetNode() {
return true; YAML::Node node = YAML::Load("[1, 2, 3]");
} YAML_ASSERT(!node.IsNull());
YAML::Node other = node;
TEST ResetNode() node.reset();
{ YAML_ASSERT(node.IsNull());
YAML::Node node = YAML::Load("[1, 2, 3]"); YAML_ASSERT(!other.IsNull());
YAML_ASSERT(!node.IsNull()); node.reset(other);
YAML::Node other = node; YAML_ASSERT(!node.IsNull());
node.reset(); YAML_ASSERT(other == node);
YAML_ASSERT(node.IsNull()); return true;
YAML_ASSERT(!other.IsNull()); }
node.reset(other);
YAML_ASSERT(!node.IsNull()); TEST DereferenceIteratorError() {
YAML_ASSERT(other == node); YAML::Node node = YAML::Load("[{a: b}, 1, 2]");
return true; YAML_ASSERT_THROWS(node.begin()->first.as<int>(), YAML::InvalidNode);
} YAML_ASSERT((*node.begin()).IsMap() == true);
YAML_ASSERT(node.begin()->IsMap() == true);
TEST DereferenceIteratorError() YAML_ASSERT_THROWS((*node.begin()->begin()).IsDefined(), YAML::InvalidNode);
{ YAML_ASSERT_THROWS(node.begin()->begin()->IsDefined(), YAML::InvalidNode);
YAML::Node node = YAML::Load("[{a: b}, 1, 2]"); return true;
YAML_ASSERT_THROWS(node.begin()->first.as<int>(), YAML::InvalidNode); }
YAML_ASSERT((*node.begin()).IsMap() == true);
YAML_ASSERT(node.begin()->IsMap() == true); TEST FloatingPrecision() {
YAML_ASSERT_THROWS((*node.begin()->begin()).IsDefined(), YAML::InvalidNode); const double x = 0.123456789;
YAML_ASSERT_THROWS(node.begin()->begin()->IsDefined(), YAML::InvalidNode); YAML::Node node = YAML::Node(x);
return true; YAML_ASSERT(node.as<double>() == x);
} return true;
}
TEST FloatingPrecision()
{ TEST EmitEmptyNode() {
const double x = 0.123456789; YAML::Node node;
YAML::Node node = YAML::Node(x); YAML::Emitter emitter;
YAML_ASSERT(node.as<double>() == x); emitter << node;
return true; YAML_ASSERT(std::string(emitter.c_str()) == "");
} return true;
}
TEST EmitEmptyNode()
{ TEST SpaceChar() {
YAML::Node node; YAML::Node node = YAML::Node(' ');
YAML::Emitter emitter; YAML_ASSERT(node.as<char>() == ' ');
emitter << node; return true;
YAML_ASSERT(std::string(emitter.c_str()) == ""); }
return true; }
}
void RunNodeTest(TEST (*test)(), const std::string& name, int& passed,
TEST SpaceChar() int& total) {
{ TEST ret;
YAML::Node node = YAML::Node(' '); try {
YAML_ASSERT(node.as<char>() == ' '); ret = test();
return true; }
} catch (const std::exception& e) {
} ret.ok = false;
ret.error = e.what();
void RunNodeTest(TEST (*test)(), const std::string& name, int& passed, int& total) { }
TEST ret; if (ret.ok) {
try { passed++;
ret = test(); } else {
} catch(const std::exception& e) { std::cout << "Node test failed: " << name << "\n";
ret.ok = false; if (ret.error != "")
ret.error = e.what(); std::cout << ret.error << "\n";
} }
if(ret.ok) { total++;
passed++; }
} else {
std::cout << "Node test failed: " << name << "\n"; bool RunNodeTests() {
if(ret.error != "") int passed = 0;
std::cout << ret.error << "\n"; int total = 0;
}
total++; RunNodeTest(&Node::SimpleScalar, "simple scalar", passed, total);
} RunNodeTest(&Node::IntScalar, "int scalar", passed, total);
RunNodeTest(&Node::SimpleAppendSequence, "simple append sequence", passed,
bool RunNodeTests() total);
{ RunNodeTest(&Node::SimpleAssignSequence, "simple assign sequence", passed,
int passed = 0; total);
int total = 0; RunNodeTest(&Node::SimpleMap, "simple map", passed, total);
RunNodeTest(&Node::MapWithUndefinedValues, "map with undefined values",
RunNodeTest(&Node::SimpleScalar, "simple scalar", passed, total); passed, total);
RunNodeTest(&Node::IntScalar, "int scalar", passed, total); RunNodeTest(&Node::MapIteratorWithUndefinedValues,
RunNodeTest(&Node::SimpleAppendSequence, "simple append sequence", passed, total); "map iterator with undefined values", passed, total);
RunNodeTest(&Node::SimpleAssignSequence, "simple assign sequence", passed, total); RunNodeTest(&Node::SimpleSubkeys, "simple subkey", passed, total);
RunNodeTest(&Node::SimpleMap, "simple map", passed, total); RunNodeTest(&Node::StdVector, "std::vector", passed, total);
RunNodeTest(&Node::MapWithUndefinedValues, "map with undefined values", passed, total); RunNodeTest(&Node::StdList, "std::list", passed, total);
RunNodeTest(&Node::MapIteratorWithUndefinedValues, "map iterator with undefined values", passed, total); RunNodeTest(&Node::StdMap, "std::map", passed, total);
RunNodeTest(&Node::SimpleSubkeys, "simple subkey", passed, total); RunNodeTest(&Node::StdPair, "std::pair", passed, total);
RunNodeTest(&Node::StdVector, "std::vector", passed, total); RunNodeTest(&Node::SimpleAlias, "simple alias", passed, total);
RunNodeTest(&Node::StdList, "std::list", passed, total); RunNodeTest(&Node::AliasAsKey, "alias as key", passed, total);
RunNodeTest(&Node::StdMap, "std::map", passed, total); RunNodeTest(&Node::SelfReferenceSequence, "self reference sequence", passed,
RunNodeTest(&Node::StdPair, "std::pair", passed, total); total);
RunNodeTest(&Node::SimpleAlias, "simple alias", passed, total); RunNodeTest(&Node::ValueSelfReferenceMap, "value self reference map", passed,
RunNodeTest(&Node::AliasAsKey, "alias as key", passed, total); total);
RunNodeTest(&Node::SelfReferenceSequence, "self reference sequence", passed, total); RunNodeTest(&Node::KeySelfReferenceMap, "key self reference map", passed,
RunNodeTest(&Node::ValueSelfReferenceMap, "value self reference map", passed, total); total);
RunNodeTest(&Node::KeySelfReferenceMap, "key self reference map", passed, total); RunNodeTest(&Node::SelfReferenceMap, "self reference map", passed, total);
RunNodeTest(&Node::SelfReferenceMap, "self reference map", passed, total); RunNodeTest(&Node::TempMapVariable, "temp map variable", passed, total);
RunNodeTest(&Node::TempMapVariable, "temp map variable", passed, total); RunNodeTest(&Node::TempMapVariableAlias, "temp map variable alias", passed,
RunNodeTest(&Node::TempMapVariableAlias, "temp map variable alias", passed, total); total);
RunNodeTest(&Node::Bool, "bool", passed, total); RunNodeTest(&Node::Bool, "bool", passed, total);
RunNodeTest(&Node::AutoBoolConversion, "auto bool conversion", passed, total); RunNodeTest(&Node::AutoBoolConversion, "auto bool conversion", passed, total);
RunNodeTest(&Node::Reassign, "reassign", passed, total); RunNodeTest(&Node::Reassign, "reassign", passed, total);
RunNodeTest(&Node::FallbackValues, "fallback values", passed, total); RunNodeTest(&Node::FallbackValues, "fallback values", passed, total);
RunNodeTest(&Node::NumericConversion, "numeric conversion", passed, total); RunNodeTest(&Node::NumericConversion, "numeric conversion", passed, total);
RunNodeTest(&Node::Binary, "binary", passed, total); RunNodeTest(&Node::Binary, "binary", passed, total);
RunNodeTest(&Node::IterateSequence, "iterate sequence", passed, total); RunNodeTest(&Node::IterateSequence, "iterate sequence", passed, total);
RunNodeTest(&Node::IterateMap, "iterate map", passed, total); RunNodeTest(&Node::IterateMap, "iterate map", passed, total);
#ifdef BOOST_FOREACH #ifdef BOOST_FOREACH
RunNodeTest(&Node::ForEach, "for each", passed, total); RunNodeTest(&Node::ForEach, "for each", passed, total);
RunNodeTest(&Node::ForEachMap, "for each map", passed, total); RunNodeTest(&Node::ForEachMap, "for each map", passed, total);
#endif #endif
RunNodeTest(&Node::CloneScalar, "clone scalar", passed, total); RunNodeTest(&Node::CloneScalar, "clone scalar", passed, total);
RunNodeTest(&Node::CloneSeq, "clone seq", passed, total); RunNodeTest(&Node::CloneSeq, "clone seq", passed, total);
RunNodeTest(&Node::CloneMap, "clone map", passed, total); RunNodeTest(&Node::CloneMap, "clone map", passed, total);
RunNodeTest(&Node::CloneAlias, "clone alias", passed, total); RunNodeTest(&Node::CloneAlias, "clone alias", passed, total);
RunNodeTest(&Node::ForceInsertIntoMap, "force insert into map", passed, total); RunNodeTest(&Node::ForceInsertIntoMap, "force insert into map", passed,
RunNodeTest(&Node::ResetNode, "reset node", passed, total); total);
RunNodeTest(&Node::DereferenceIteratorError, "dereference iterator error", passed, total); RunNodeTest(&Node::ResetNode, "reset node", passed, total);
RunNodeTest(&Node::FloatingPrecision, "floating precision", passed, total); RunNodeTest(&Node::DereferenceIteratorError, "dereference iterator error",
RunNodeTest(&Node::EmitEmptyNode, "emit empty node", passed, total); passed, total);
RunNodeTest(&Node::SpaceChar, "space char", passed, total); RunNodeTest(&Node::FloatingPrecision, "floating precision", passed, total);
RunNodeTest(&Node::EmitEmptyNode, "emit empty node", passed, total);
std::cout << "Node tests: " << passed << "/" << total << " passed\n"; RunNodeTest(&Node::SpaceChar, "space char", passed, total);
return passed == total;
} std::cout << "Node tests: " << passed << "/" << total << " passed\n";
return passed == total;
}
} }
#include "parsertests.h" #include "parsertests.h"
namespace Test { namespace Test {
bool RunParserTests() bool RunParserTests() { return true; }
{
return true;
}
} }
...@@ -3,1363 +3,1423 @@ ...@@ -3,1363 +3,1423 @@
#include "yaml-cpp/yaml.h" #include "yaml-cpp/yaml.h"
#include <iostream> #include <iostream>
#define YAML_ASSERT(cond) do { if(!(cond)) return " Assert failed: " #cond; } while(false) #define YAML_ASSERT(cond) \
do { \
namespace Test if (!(cond)) \
{ return " Assert failed: " #cond; \
namespace Spec } while (false)
{
// 2.1 namespace Test {
TEST SeqScalars() { namespace Spec {
YAML::Node doc = YAML::Load(ex2_1); // 2.1
YAML_ASSERT(doc.IsSequence()); TEST SeqScalars() {
YAML_ASSERT(doc.size() == 3); YAML::Node doc = YAML::Load(ex2_1);
YAML_ASSERT(doc[0].as<std::string>() == "Mark McGwire"); YAML_ASSERT(doc.IsSequence());
YAML_ASSERT(doc[1].as<std::string>() == "Sammy Sosa"); YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[2].as<std::string>() == "Ken Griffey"); YAML_ASSERT(doc[0].as<std::string>() == "Mark McGwire");
return true; YAML_ASSERT(doc[1].as<std::string>() == "Sammy Sosa");
} YAML_ASSERT(doc[2].as<std::string>() == "Ken Griffey");
return true;
// 2.2 }
TEST MappingScalarsToScalars() {
YAML::Node doc = YAML::Load(ex2_2); // 2.2
YAML_ASSERT(doc.IsMap()); TEST MappingScalarsToScalars() {
YAML_ASSERT(doc.size() == 3); YAML::Node doc = YAML::Load(ex2_2);
YAML_ASSERT(doc["hr"].as<std::string>() == "65"); YAML_ASSERT(doc.IsMap());
YAML_ASSERT(doc["avg"].as<std::string>() == "0.278"); YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["rbi"].as<std::string>() == "147"); YAML_ASSERT(doc["hr"].as<std::string>() == "65");
return true; YAML_ASSERT(doc["avg"].as<std::string>() == "0.278");
} YAML_ASSERT(doc["rbi"].as<std::string>() == "147");
return true;
// 2.3 }
TEST MappingScalarsToSequences() {
YAML::Node doc = YAML::Load(ex2_3); // 2.3
YAML_ASSERT(doc.IsMap()); TEST MappingScalarsToSequences() {
YAML_ASSERT(doc.size() == 2); YAML::Node doc = YAML::Load(ex2_3);
YAML_ASSERT(doc["american"].size() == 3); YAML_ASSERT(doc.IsMap());
YAML_ASSERT(doc["american"][0].as<std::string>() == "Boston Red Sox"); YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["american"][1].as<std::string>() == "Detroit Tigers"); YAML_ASSERT(doc["american"].size() == 3);
YAML_ASSERT(doc["american"][2].as<std::string>() == "New York Yankees"); YAML_ASSERT(doc["american"][0].as<std::string>() == "Boston Red Sox");
YAML_ASSERT(doc["national"].size() == 3); YAML_ASSERT(doc["american"][1].as<std::string>() == "Detroit Tigers");
YAML_ASSERT(doc["national"][0].as<std::string>() == "New York Mets"); YAML_ASSERT(doc["american"][2].as<std::string>() == "New York Yankees");
YAML_ASSERT(doc["national"][1].as<std::string>() == "Chicago Cubs"); YAML_ASSERT(doc["national"].size() == 3);
YAML_ASSERT(doc["national"][2].as<std::string>() == "Atlanta Braves"); YAML_ASSERT(doc["national"][0].as<std::string>() == "New York Mets");
return true; YAML_ASSERT(doc["national"][1].as<std::string>() == "Chicago Cubs");
} YAML_ASSERT(doc["national"][2].as<std::string>() == "Atlanta Braves");
return true;
// 2.4 }
TEST SequenceOfMappings() {
YAML::Node doc = YAML::Load(ex2_4); // 2.4
YAML_ASSERT(doc.size() == 2); TEST SequenceOfMappings() {
YAML_ASSERT(doc[0].size() == 3); YAML::Node doc = YAML::Load(ex2_4);
YAML_ASSERT(doc[0]["name"].as<std::string>() == "Mark McGwire"); YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc[0]["hr"].as<std::string>() == "65"); YAML_ASSERT(doc[0].size() == 3);
YAML_ASSERT(doc[0]["avg"].as<std::string>() == "0.278"); YAML_ASSERT(doc[0]["name"].as<std::string>() == "Mark McGwire");
YAML_ASSERT(doc[1].size() == 3); YAML_ASSERT(doc[0]["hr"].as<std::string>() == "65");
YAML_ASSERT(doc[1]["name"].as<std::string>() == "Sammy Sosa"); YAML_ASSERT(doc[0]["avg"].as<std::string>() == "0.278");
YAML_ASSERT(doc[1]["hr"].as<std::string>() == "63"); YAML_ASSERT(doc[1].size() == 3);
YAML_ASSERT(doc[1]["avg"].as<std::string>() == "0.288"); YAML_ASSERT(doc[1]["name"].as<std::string>() == "Sammy Sosa");
return true; YAML_ASSERT(doc[1]["hr"].as<std::string>() == "63");
} YAML_ASSERT(doc[1]["avg"].as<std::string>() == "0.288");
return true;
// 2.5 }
TEST SequenceOfSequences() {
YAML::Node doc = YAML::Load(ex2_5); // 2.5
YAML_ASSERT(doc.size() == 3); TEST SequenceOfSequences() {
YAML_ASSERT(doc[0].size() == 3); YAML::Node doc = YAML::Load(ex2_5);
YAML_ASSERT(doc[0][0].as<std::string>() == "name"); YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[0][1].as<std::string>() == "hr"); YAML_ASSERT(doc[0].size() == 3);
YAML_ASSERT(doc[0][2].as<std::string>() == "avg"); YAML_ASSERT(doc[0][0].as<std::string>() == "name");
YAML_ASSERT(doc[1].size() == 3); YAML_ASSERT(doc[0][1].as<std::string>() == "hr");
YAML_ASSERT(doc[1][0].as<std::string>() == "Mark McGwire"); YAML_ASSERT(doc[0][2].as<std::string>() == "avg");
YAML_ASSERT(doc[1][1].as<std::string>() == "65"); YAML_ASSERT(doc[1].size() == 3);
YAML_ASSERT(doc[1][2].as<std::string>() == "0.278"); YAML_ASSERT(doc[1][0].as<std::string>() == "Mark McGwire");
YAML_ASSERT(doc[2].size() == 3); YAML_ASSERT(doc[1][1].as<std::string>() == "65");
YAML_ASSERT(doc[2][0].as<std::string>() == "Sammy Sosa"); YAML_ASSERT(doc[1][2].as<std::string>() == "0.278");
YAML_ASSERT(doc[2][1].as<std::string>() == "63"); YAML_ASSERT(doc[2].size() == 3);
YAML_ASSERT(doc[2][2].as<std::string>() == "0.288"); YAML_ASSERT(doc[2][0].as<std::string>() == "Sammy Sosa");
return true; YAML_ASSERT(doc[2][1].as<std::string>() == "63");
} YAML_ASSERT(doc[2][2].as<std::string>() == "0.288");
return true;
// 2.6 }
TEST MappingOfMappings() {
YAML::Node doc = YAML::Load(ex2_6); // 2.6
YAML_ASSERT(doc.size() == 2); TEST MappingOfMappings() {
YAML_ASSERT(doc["Mark McGwire"].size() == 2); YAML::Node doc = YAML::Load(ex2_6);
YAML_ASSERT(doc["Mark McGwire"]["hr"].as<std::string>() == "65"); YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["Mark McGwire"]["avg"].as<std::string>() == "0.278"); YAML_ASSERT(doc["Mark McGwire"].size() == 2);
YAML_ASSERT(doc["Sammy Sosa"].size() == 2); YAML_ASSERT(doc["Mark McGwire"]["hr"].as<std::string>() == "65");
YAML_ASSERT(doc["Sammy Sosa"]["hr"].as<std::string>() == "63"); YAML_ASSERT(doc["Mark McGwire"]["avg"].as<std::string>() == "0.278");
YAML_ASSERT(doc["Sammy Sosa"]["avg"].as<std::string>() == "0.288"); YAML_ASSERT(doc["Sammy Sosa"].size() == 2);
return true; YAML_ASSERT(doc["Sammy Sosa"]["hr"].as<std::string>() == "63");
} YAML_ASSERT(doc["Sammy Sosa"]["avg"].as<std::string>() == "0.288");
return true;
// 2.7 }
TEST TwoDocumentsInAStream() {
std::vector<YAML::Node> docs = YAML::LoadAll(ex2_7); // 2.7
YAML_ASSERT(docs.size() == 2); TEST TwoDocumentsInAStream() {
std::vector<YAML::Node> docs = YAML::LoadAll(ex2_7);
{ YAML_ASSERT(docs.size() == 2);
YAML::Node doc = docs[0];
YAML_ASSERT(doc.size() == 3); {
YAML_ASSERT(doc[0].as<std::string>() == "Mark McGwire"); YAML::Node doc = docs[0];
YAML_ASSERT(doc[1].as<std::string>() == "Sammy Sosa"); YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[2].as<std::string>() == "Ken Griffey"); YAML_ASSERT(doc[0].as<std::string>() == "Mark McGwire");
} YAML_ASSERT(doc[1].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc[2].as<std::string>() == "Ken Griffey");
{ }
YAML::Node doc = docs[1];
YAML_ASSERT(doc.size() == 2); {
YAML_ASSERT(doc[0].as<std::string>() == "Chicago Cubs"); YAML::Node doc = docs[1];
YAML_ASSERT(doc[1].as<std::string>() == "St Louis Cardinals"); YAML_ASSERT(doc.size() == 2);
} YAML_ASSERT(doc[0].as<std::string>() == "Chicago Cubs");
return true; YAML_ASSERT(doc[1].as<std::string>() == "St Louis Cardinals");
} }
return true;
// 2.8 }
TEST PlayByPlayFeed() {
std::vector<YAML::Node> docs = YAML::LoadAll(ex2_8); // 2.8
YAML_ASSERT(docs.size() == 2); TEST PlayByPlayFeed() {
std::vector<YAML::Node> docs = YAML::LoadAll(ex2_8);
{ YAML_ASSERT(docs.size() == 2);
YAML::Node doc = docs[0];
YAML_ASSERT(doc.size() == 3); {
YAML_ASSERT(doc["time"].as<std::string>() == "20:03:20"); YAML::Node doc = docs[0];
YAML_ASSERT(doc["player"].as<std::string>() == "Sammy Sosa"); YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["action"].as<std::string>() == "strike (miss)"); YAML_ASSERT(doc["time"].as<std::string>() == "20:03:20");
} YAML_ASSERT(doc["player"].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc["action"].as<std::string>() == "strike (miss)");
{ }
YAML::Node doc = docs[1];
YAML_ASSERT(doc.size() == 3); {
YAML_ASSERT(doc["time"].as<std::string>() == "20:03:47"); YAML::Node doc = docs[1];
YAML_ASSERT(doc["player"].as<std::string>() == "Sammy Sosa"); YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["action"].as<std::string>() == "grand slam"); YAML_ASSERT(doc["time"].as<std::string>() == "20:03:47");
} YAML_ASSERT(doc["player"].as<std::string>() == "Sammy Sosa");
return true; YAML_ASSERT(doc["action"].as<std::string>() == "grand slam");
} }
return true;
// 2.9 }
TEST SingleDocumentWithTwoComments() {
YAML::Node doc = YAML::Load(ex2_9); // 2.9
YAML_ASSERT(doc.size() == 2); TEST SingleDocumentWithTwoComments() {
YAML_ASSERT(doc["hr"].size() == 2); YAML::Node doc = YAML::Load(ex2_9);
YAML_ASSERT(doc["hr"][0].as<std::string>() == "Mark McGwire"); YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["hr"][1].as<std::string>() == "Sammy Sosa"); YAML_ASSERT(doc["hr"].size() == 2);
YAML_ASSERT(doc["rbi"].size() == 2); YAML_ASSERT(doc["hr"][0].as<std::string>() == "Mark McGwire");
YAML_ASSERT(doc["rbi"][0].as<std::string>() == "Sammy Sosa"); YAML_ASSERT(doc["hr"][1].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc["rbi"][1].as<std::string>() == "Ken Griffey"); YAML_ASSERT(doc["rbi"].size() == 2);
return true; YAML_ASSERT(doc["rbi"][0].as<std::string>() == "Sammy Sosa");
} YAML_ASSERT(doc["rbi"][1].as<std::string>() == "Ken Griffey");
return true;
// 2.10 }
TEST SimpleAnchor() {
YAML::Node doc = YAML::Load(ex2_10); // 2.10
YAML_ASSERT(doc.size() == 2); TEST SimpleAnchor() {
YAML_ASSERT(doc["hr"].size() == 2); YAML::Node doc = YAML::Load(ex2_10);
YAML_ASSERT(doc["hr"][0].as<std::string>() == "Mark McGwire"); YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["hr"][1].as<std::string>() == "Sammy Sosa"); YAML_ASSERT(doc["hr"].size() == 2);
YAML_ASSERT(doc["rbi"].size() == 2); YAML_ASSERT(doc["hr"][0].as<std::string>() == "Mark McGwire");
YAML_ASSERT(doc["rbi"][0].as<std::string>() == "Sammy Sosa"); YAML_ASSERT(doc["hr"][1].as<std::string>() == "Sammy Sosa");
YAML_ASSERT(doc["rbi"][1].as<std::string>() == "Ken Griffey"); YAML_ASSERT(doc["rbi"].size() == 2);
return true; YAML_ASSERT(doc["rbi"][0].as<std::string>() == "Sammy Sosa");
} YAML_ASSERT(doc["rbi"][1].as<std::string>() == "Ken Griffey");
return true;
// 2.11 }
TEST MappingBetweenSequences() {
YAML::Node doc = YAML::Load(ex2_11); // 2.11
TEST MappingBetweenSequences() {
std::vector<std::string> tigers_cubs; YAML::Node doc = YAML::Load(ex2_11);
tigers_cubs.push_back("Detroit Tigers");
tigers_cubs.push_back("Chicago cubs"); std::vector<std::string> tigers_cubs;
tigers_cubs.push_back("Detroit Tigers");
std::vector<std::string> yankees_braves; tigers_cubs.push_back("Chicago cubs");
yankees_braves.push_back("New York Yankees");
yankees_braves.push_back("Atlanta Braves"); std::vector<std::string> yankees_braves;
yankees_braves.push_back("New York Yankees");
yankees_braves.push_back("Atlanta Braves");
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc[tigers_cubs].size() == 1); YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc[tigers_cubs][0].as<std::string>() == "2001-07-23"); YAML_ASSERT(doc[tigers_cubs].size() == 1);
YAML_ASSERT(doc[yankees_braves].size() == 3); YAML_ASSERT(doc[tigers_cubs][0].as<std::string>() == "2001-07-23");
YAML_ASSERT(doc[yankees_braves][0].as<std::string>() == "2001-07-02"); YAML_ASSERT(doc[yankees_braves].size() == 3);
YAML_ASSERT(doc[yankees_braves][1].as<std::string>() == "2001-08-12"); YAML_ASSERT(doc[yankees_braves][0].as<std::string>() == "2001-07-02");
YAML_ASSERT(doc[yankees_braves][2].as<std::string>() == "2001-08-14"); YAML_ASSERT(doc[yankees_braves][1].as<std::string>() == "2001-08-12");
return true; YAML_ASSERT(doc[yankees_braves][2].as<std::string>() == "2001-08-14");
} return true;
}
// 2.12
TEST CompactNestedMapping() { // 2.12
YAML::Node doc = YAML::Load(ex2_12); TEST CompactNestedMapping() {
YAML_ASSERT(doc.size() == 3); YAML::Node doc = YAML::Load(ex2_12);
YAML_ASSERT(doc[0].size() == 2); YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[0]["item"].as<std::string>() == "Super Hoop"); YAML_ASSERT(doc[0].size() == 2);
YAML_ASSERT(doc[0]["quantity"].as<int>() == 1); YAML_ASSERT(doc[0]["item"].as<std::string>() == "Super Hoop");
YAML_ASSERT(doc[1].size() == 2); YAML_ASSERT(doc[0]["quantity"].as<int>() == 1);
YAML_ASSERT(doc[1]["item"].as<std::string>() == "Basketball"); YAML_ASSERT(doc[1].size() == 2);
YAML_ASSERT(doc[1]["quantity"].as<int>() == 4); YAML_ASSERT(doc[1]["item"].as<std::string>() == "Basketball");
YAML_ASSERT(doc[2].size() == 2); YAML_ASSERT(doc[1]["quantity"].as<int>() == 4);
YAML_ASSERT(doc[2]["item"].as<std::string>() == "Big Shoes"); YAML_ASSERT(doc[2].size() == 2);
YAML_ASSERT(doc[2]["quantity"].as<int>() == 1); YAML_ASSERT(doc[2]["item"].as<std::string>() == "Big Shoes");
return true; YAML_ASSERT(doc[2]["quantity"].as<int>() == 1);
} return true;
}
// 2.13
TEST InLiteralsNewlinesArePreserved() { // 2.13
YAML::Node doc = YAML::Load(ex2_13); TEST InLiteralsNewlinesArePreserved() {
YAML_ASSERT(doc.as<std::string>() == YAML::Node doc = YAML::Load(ex2_13);
"\\//||\\/||\n" YAML_ASSERT(doc.as<std::string>() ==
"// || ||__"); "\\//||\\/||\n"
return true; "// || ||__");
} return true;
}
// 2.14
TEST InFoldedScalarsNewlinesBecomeSpaces() { // 2.14
YAML::Node doc = YAML::Load(ex2_14); TEST InFoldedScalarsNewlinesBecomeSpaces() {
YAML_ASSERT(doc.as<std::string>() == "Mark McGwire's year was crippled by a knee injury."); YAML::Node doc = YAML::Load(ex2_14);
return true; YAML_ASSERT(doc.as<std::string>() ==
} "Mark McGwire's year was crippled by a knee injury.");
return true;
// 2.15 }
TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines() {
YAML::Node doc = YAML::Load(ex2_15); // 2.15
YAML_ASSERT(doc.as<std::string>() == TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines() {
"Sammy Sosa completed another fine season with great stats.\n\n" YAML::Node doc = YAML::Load(ex2_15);
" 63 Home Runs\n" YAML_ASSERT(doc.as<std::string>() ==
" 0.288 Batting Average\n\n" "Sammy Sosa completed another fine season with great stats.\n\n"
"What a year!"); " 63 Home Runs\n"
return true; " 0.288 Batting Average\n\n"
} "What a year!");
return true;
// 2.16 }
TEST IndentationDeterminesScope() {
YAML::Node doc = YAML::Load(ex2_16); // 2.16
YAML_ASSERT(doc.size() == 3); TEST IndentationDeterminesScope() {
YAML_ASSERT(doc["name"].as<std::string>() == "Mark McGwire"); YAML::Node doc = YAML::Load(ex2_16);
YAML_ASSERT(doc["accomplishment"].as<std::string>() == "Mark set a major league home run record in 1998.\n"); YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["stats"].as<std::string>() == "65 Home Runs\n0.278 Batting Average\n"); YAML_ASSERT(doc["name"].as<std::string>() == "Mark McGwire");
return true; YAML_ASSERT(doc["accomplishment"].as<std::string>() ==
} "Mark set a major league home run record in 1998.\n");
YAML_ASSERT(doc["stats"].as<std::string>() ==
// 2.17 "65 Home Runs\n0.278 Batting Average\n");
TEST QuotedScalars() { return true;
YAML::Node doc = YAML::Load(ex2_17); }
YAML_ASSERT(doc.size() == 6);
YAML_ASSERT(doc["unicode"].as<std::string>() == "Sosa did fine.\xe2\x98\xba"); // 2.17
YAML_ASSERT(doc["control"].as<std::string>() == "\b1998\t1999\t2000\n"); TEST QuotedScalars() {
YAML_ASSERT(doc["hex esc"].as<std::string>() == "\x0d\x0a is \r\n"); YAML::Node doc = YAML::Load(ex2_17);
YAML_ASSERT(doc["single"].as<std::string>() == "\"Howdy!\" he cried."); YAML_ASSERT(doc.size() == 6);
YAML_ASSERT(doc["quoted"].as<std::string>() == " # Not a 'comment'."); YAML_ASSERT(doc["unicode"].as<std::string>() == "Sosa did fine.\xe2\x98\xba");
YAML_ASSERT(doc["tie-fighter"].as<std::string>() == "|\\-*-/|"); YAML_ASSERT(doc["control"].as<std::string>() == "\b1998\t1999\t2000\n");
return true; YAML_ASSERT(doc["hex esc"].as<std::string>() == "\x0d\x0a is \r\n");
} YAML_ASSERT(doc["single"].as<std::string>() == "\"Howdy!\" he cried.");
YAML_ASSERT(doc["quoted"].as<std::string>() == " # Not a 'comment'.");
// 2.18 YAML_ASSERT(doc["tie-fighter"].as<std::string>() == "|\\-*-/|");
TEST MultiLineFlowScalars() { return true;
YAML::Node doc = YAML::Load(ex2_18); }
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["plain"].as<std::string>() == "This unquoted scalar spans many lines."); // 2.18
YAML_ASSERT(doc["quoted"].as<std::string>() == "So does this quoted scalar.\n"); TEST MultiLineFlowScalars() {
return true; YAML::Node doc = YAML::Load(ex2_18);
} YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["plain"].as<std::string>() ==
// TODO: 2.19 - 2.22 schema tags "This unquoted scalar spans many lines.");
YAML_ASSERT(doc["quoted"].as<std::string>() ==
// 2.23 "So does this quoted scalar.\n");
TEST VariousExplicitTags() { return true;
YAML::Node doc = YAML::Load(ex2_23); }
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["not-date"].Tag() == "tag:yaml.org,2002:str"); // TODO: 2.19 - 2.22 schema tags
YAML_ASSERT(doc["not-date"].as<std::string>() == "2002-04-28");
YAML_ASSERT(doc["picture"].Tag() == "tag:yaml.org,2002:binary"); // 2.23
YAML_ASSERT(doc["picture"].as<std::string>() == TEST VariousExplicitTags() {
"R0lGODlhDAAMAIQAAP//9/X\n" YAML::Node doc = YAML::Load(ex2_23);
"17unp5WZmZgAAAOfn515eXv\n" YAML_ASSERT(doc.size() == 3);
"Pz7Y6OjuDg4J+fn5OTk6enp\n" YAML_ASSERT(doc["not-date"].Tag() == "tag:yaml.org,2002:str");
"56enmleECcgggoBADs=\n" YAML_ASSERT(doc["not-date"].as<std::string>() == "2002-04-28");
); YAML_ASSERT(doc["picture"].Tag() == "tag:yaml.org,2002:binary");
YAML_ASSERT(doc["application specific tag"].Tag() == "!something"); YAML_ASSERT(doc["picture"].as<std::string>() ==
YAML_ASSERT(doc["application specific tag"].as<std::string>() == "R0lGODlhDAAMAIQAAP//9/X\n"
"The semantics of the tag\n" "17unp5WZmZgAAAOfn515eXv\n"
"above may be different for\n" "Pz7Y6OjuDg4J+fn5OTk6enp\n"
"different documents." "56enmleECcgggoBADs=\n");
); YAML_ASSERT(doc["application specific tag"].Tag() == "!something");
return true; YAML_ASSERT(doc["application specific tag"].as<std::string>() ==
} "The semantics of the tag\n"
"above may be different for\n"
// 2.24 "different documents.");
TEST GlobalTags() { return true;
YAML::Node doc = YAML::Load(ex2_24); }
YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:shape");
YAML_ASSERT(doc.size() == 3); // 2.24
YAML_ASSERT(doc[0].Tag() == "tag:clarkevans.com,2002:circle"); TEST GlobalTags() {
YAML_ASSERT(doc[0].size() == 2); YAML::Node doc = YAML::Load(ex2_24);
YAML_ASSERT(doc[0]["center"].size() == 2); YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:shape");
YAML_ASSERT(doc[0]["center"]["x"].as<int>() == 73); YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[0]["center"]["y"].as<int>() == 129); YAML_ASSERT(doc[0].Tag() == "tag:clarkevans.com,2002:circle");
YAML_ASSERT(doc[0]["radius"].as<int>() == 7); YAML_ASSERT(doc[0].size() == 2);
YAML_ASSERT(doc[1].Tag() == "tag:clarkevans.com,2002:line"); YAML_ASSERT(doc[0]["center"].size() == 2);
YAML_ASSERT(doc[1].size() == 2); YAML_ASSERT(doc[0]["center"]["x"].as<int>() == 73);
YAML_ASSERT(doc[1]["start"].size() == 2); YAML_ASSERT(doc[0]["center"]["y"].as<int>() == 129);
YAML_ASSERT(doc[1]["start"]["x"].as<int>() == 73); YAML_ASSERT(doc[0]["radius"].as<int>() == 7);
YAML_ASSERT(doc[1]["start"]["y"].as<int>() == 129); YAML_ASSERT(doc[1].Tag() == "tag:clarkevans.com,2002:line");
YAML_ASSERT(doc[1]["finish"].size() == 2); YAML_ASSERT(doc[1].size() == 2);
YAML_ASSERT(doc[1]["finish"]["x"].as<int>() == 89); YAML_ASSERT(doc[1]["start"].size() == 2);
YAML_ASSERT(doc[1]["finish"]["y"].as<int>() == 102); YAML_ASSERT(doc[1]["start"]["x"].as<int>() == 73);
YAML_ASSERT(doc[2].Tag() == "tag:clarkevans.com,2002:label"); YAML_ASSERT(doc[1]["start"]["y"].as<int>() == 129);
YAML_ASSERT(doc[2].size() == 3); YAML_ASSERT(doc[1]["finish"].size() == 2);
YAML_ASSERT(doc[2]["start"].size() == 2); YAML_ASSERT(doc[1]["finish"]["x"].as<int>() == 89);
YAML_ASSERT(doc[2]["start"]["x"].as<int>() == 73); YAML_ASSERT(doc[1]["finish"]["y"].as<int>() == 102);
YAML_ASSERT(doc[2]["start"]["y"].as<int>() == 129); YAML_ASSERT(doc[2].Tag() == "tag:clarkevans.com,2002:label");
YAML_ASSERT(doc[2]["color"].as<std::string>() == "0xFFEEBB"); YAML_ASSERT(doc[2].size() == 3);
YAML_ASSERT(doc[2]["text"].as<std::string>() == "Pretty vector drawing."); YAML_ASSERT(doc[2]["start"].size() == 2);
return true; YAML_ASSERT(doc[2]["start"]["x"].as<int>() == 73);
} YAML_ASSERT(doc[2]["start"]["y"].as<int>() == 129);
YAML_ASSERT(doc[2]["color"].as<std::string>() == "0xFFEEBB");
// 2.25 YAML_ASSERT(doc[2]["text"].as<std::string>() == "Pretty vector drawing.");
TEST UnorderedSets() { return true;
YAML::Node doc = YAML::Load(ex2_25); }
YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:set");
YAML_ASSERT(doc.size() == 3); // 2.25
YAML_ASSERT(doc["Mark McGwire"].IsNull()); TEST UnorderedSets() {
YAML_ASSERT(doc["Sammy Sosa"].IsNull()); YAML::Node doc = YAML::Load(ex2_25);
YAML_ASSERT(doc["Ken Griffey"].IsNull()); YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:set");
return true; YAML_ASSERT(doc.size() == 3);
} YAML_ASSERT(doc["Mark McGwire"].IsNull());
YAML_ASSERT(doc["Sammy Sosa"].IsNull());
// 2.26 YAML_ASSERT(doc["Ken Griffey"].IsNull());
TEST OrderedMappings() { return true;
YAML::Node doc = YAML::Load(ex2_26); }
YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:omap");
YAML_ASSERT(doc.size() == 3); // 2.26
YAML_ASSERT(doc[0].size() == 1); TEST OrderedMappings() {
YAML_ASSERT(doc[0]["Mark McGwire"].as<int>() == 65); YAML::Node doc = YAML::Load(ex2_26);
YAML_ASSERT(doc[1].size() == 1); YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:omap");
YAML_ASSERT(doc[1]["Sammy Sosa"].as<int>() == 63); YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[2].size() == 1); YAML_ASSERT(doc[0].size() == 1);
YAML_ASSERT(doc[2]["Ken Griffey"].as<int>() == 58); YAML_ASSERT(doc[0]["Mark McGwire"].as<int>() == 65);
return true; YAML_ASSERT(doc[1].size() == 1);
} YAML_ASSERT(doc[1]["Sammy Sosa"].as<int>() == 63);
YAML_ASSERT(doc[2].size() == 1);
// 2.27 YAML_ASSERT(doc[2]["Ken Griffey"].as<int>() == 58);
TEST Invoice() { return true;
YAML::Node doc = YAML::Load(ex2_27); }
YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:invoice");
YAML_ASSERT(doc.size() == 8); // 2.27
YAML_ASSERT(doc["invoice"].as<int>() == 34843); TEST Invoice() {
YAML_ASSERT(doc["date"].as<std::string>() == "2001-01-23"); YAML::Node doc = YAML::Load(ex2_27);
YAML_ASSERT(doc["bill-to"].size() == 3); YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:invoice");
YAML_ASSERT(doc["bill-to"]["given"].as<std::string>() == "Chris"); YAML_ASSERT(doc.size() == 8);
YAML_ASSERT(doc["bill-to"]["family"].as<std::string>() == "Dumars"); YAML_ASSERT(doc["invoice"].as<int>() == 34843);
YAML_ASSERT(doc["bill-to"]["address"].size() == 4); YAML_ASSERT(doc["date"].as<std::string>() == "2001-01-23");
YAML_ASSERT(doc["bill-to"]["address"]["lines"].as<std::string>() == "458 Walkman Dr.\nSuite #292\n"); YAML_ASSERT(doc["bill-to"].size() == 3);
YAML_ASSERT(doc["bill-to"]["address"]["city"].as<std::string>() == "Royal Oak"); YAML_ASSERT(doc["bill-to"]["given"].as<std::string>() == "Chris");
YAML_ASSERT(doc["bill-to"]["address"]["state"].as<std::string>() == "MI"); YAML_ASSERT(doc["bill-to"]["family"].as<std::string>() == "Dumars");
YAML_ASSERT(doc["bill-to"]["address"]["postal"].as<std::string>() == "48046"); YAML_ASSERT(doc["bill-to"]["address"].size() == 4);
YAML_ASSERT(doc["ship-to"].size() == 3); YAML_ASSERT(doc["bill-to"]["address"]["lines"].as<std::string>() ==
YAML_ASSERT(doc["ship-to"]["given"].as<std::string>() == "Chris"); "458 Walkman Dr.\nSuite #292\n");
YAML_ASSERT(doc["ship-to"]["family"].as<std::string>() == "Dumars"); YAML_ASSERT(doc["bill-to"]["address"]["city"].as<std::string>() ==
YAML_ASSERT(doc["ship-to"]["address"].size() == 4); "Royal Oak");
YAML_ASSERT(doc["ship-to"]["address"]["lines"].as<std::string>() == "458 Walkman Dr.\nSuite #292\n"); YAML_ASSERT(doc["bill-to"]["address"]["state"].as<std::string>() == "MI");
YAML_ASSERT(doc["ship-to"]["address"]["city"].as<std::string>() == "Royal Oak"); YAML_ASSERT(doc["bill-to"]["address"]["postal"].as<std::string>() == "48046");
YAML_ASSERT(doc["ship-to"]["address"]["state"].as<std::string>() == "MI"); YAML_ASSERT(doc["ship-to"].size() == 3);
YAML_ASSERT(doc["ship-to"]["address"]["postal"].as<std::string>() == "48046"); YAML_ASSERT(doc["ship-to"]["given"].as<std::string>() == "Chris");
YAML_ASSERT(doc["product"].size() == 2); YAML_ASSERT(doc["ship-to"]["family"].as<std::string>() == "Dumars");
YAML_ASSERT(doc["product"][0].size() == 4); YAML_ASSERT(doc["ship-to"]["address"].size() == 4);
YAML_ASSERT(doc["product"][0]["sku"].as<std::string>() == "BL394D"); YAML_ASSERT(doc["ship-to"]["address"]["lines"].as<std::string>() ==
YAML_ASSERT(doc["product"][0]["quantity"].as<int>() == 4); "458 Walkman Dr.\nSuite #292\n");
YAML_ASSERT(doc["product"][0]["description"].as<std::string>() == "Basketball"); YAML_ASSERT(doc["ship-to"]["address"]["city"].as<std::string>() ==
YAML_ASSERT(doc["product"][0]["price"].as<std::string>() == "450.00"); "Royal Oak");
YAML_ASSERT(doc["product"][1].size() == 4); YAML_ASSERT(doc["ship-to"]["address"]["state"].as<std::string>() == "MI");
YAML_ASSERT(doc["product"][1]["sku"].as<std::string>() == "BL4438H"); YAML_ASSERT(doc["ship-to"]["address"]["postal"].as<std::string>() == "48046");
YAML_ASSERT(doc["product"][1]["quantity"].as<int>() == 1); YAML_ASSERT(doc["product"].size() == 2);
YAML_ASSERT(doc["product"][1]["description"].as<std::string>() == "Super Hoop"); YAML_ASSERT(doc["product"][0].size() == 4);
YAML_ASSERT(doc["product"][1]["price"].as<std::string>() == "2392.00"); YAML_ASSERT(doc["product"][0]["sku"].as<std::string>() == "BL394D");
YAML_ASSERT(doc["tax"].as<std::string>() == "251.42"); YAML_ASSERT(doc["product"][0]["quantity"].as<int>() == 4);
YAML_ASSERT(doc["total"].as<std::string>() == "4443.52"); YAML_ASSERT(doc["product"][0]["description"].as<std::string>() ==
YAML_ASSERT(doc["comments"].as<std::string>() == "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338."); "Basketball");
return true; YAML_ASSERT(doc["product"][0]["price"].as<std::string>() == "450.00");
} YAML_ASSERT(doc["product"][1].size() == 4);
YAML_ASSERT(doc["product"][1]["sku"].as<std::string>() == "BL4438H");
// 2.28 YAML_ASSERT(doc["product"][1]["quantity"].as<int>() == 1);
TEST LogFile() { YAML_ASSERT(doc["product"][1]["description"].as<std::string>() ==
std::vector<YAML::Node> docs = YAML::LoadAll(ex2_28); "Super Hoop");
YAML_ASSERT(docs.size() == 3); YAML_ASSERT(doc["product"][1]["price"].as<std::string>() == "2392.00");
YAML_ASSERT(doc["tax"].as<std::string>() == "251.42");
{ YAML_ASSERT(doc["total"].as<std::string>() == "4443.52");
YAML::Node doc = docs[0]; YAML_ASSERT(
YAML_ASSERT(doc.size() == 3); doc["comments"].as<std::string>() ==
YAML_ASSERT(doc["Time"].as<std::string>() == "2001-11-23 15:01:42 -5"); "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338.");
YAML_ASSERT(doc["User"].as<std::string>() == "ed"); return true;
YAML_ASSERT(doc["Warning"].as<std::string>() == "This is an error message for the log file"); }
}
// 2.28
{ TEST LogFile() {
YAML::Node doc = docs[1]; std::vector<YAML::Node> docs = YAML::LoadAll(ex2_28);
YAML_ASSERT(doc.size() == 3); YAML_ASSERT(docs.size() == 3);
YAML_ASSERT(doc["Time"].as<std::string>() == "2001-11-23 15:02:31 -5");
YAML_ASSERT(doc["User"].as<std::string>() == "ed"); {
YAML_ASSERT(doc["Warning"].as<std::string>() == "A slightly different error message."); YAML::Node doc = docs[0];
} YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["Time"].as<std::string>() == "2001-11-23 15:01:42 -5");
{ YAML_ASSERT(doc["User"].as<std::string>() == "ed");
YAML::Node doc = docs[2]; YAML_ASSERT(doc["Warning"].as<std::string>() ==
YAML_ASSERT(doc.size() == 4); "This is an error message for the log file");
YAML_ASSERT(doc["Date"].as<std::string>() == "2001-11-23 15:03:17 -5"); }
YAML_ASSERT(doc["User"].as<std::string>() == "ed");
YAML_ASSERT(doc["Fatal"].as<std::string>() == "Unknown variable \"bar\""); {
YAML_ASSERT(doc["Stack"].size() == 2); YAML::Node doc = docs[1];
YAML_ASSERT(doc["Stack"][0].size() == 3); YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["Stack"][0]["file"].as<std::string>() == "TopClass.py"); YAML_ASSERT(doc["Time"].as<std::string>() == "2001-11-23 15:02:31 -5");
YAML_ASSERT(doc["Stack"][0]["line"].as<std::string>() == "23"); YAML_ASSERT(doc["User"].as<std::string>() == "ed");
YAML_ASSERT(doc["Stack"][0]["code"].as<std::string>() == "x = MoreObject(\"345\\n\")\n"); YAML_ASSERT(doc["Warning"].as<std::string>() ==
YAML_ASSERT(doc["Stack"][1].size() == 3); "A slightly different error message.");
YAML_ASSERT(doc["Stack"][1]["file"].as<std::string>() == "MoreClass.py"); }
YAML_ASSERT(doc["Stack"][1]["line"].as<std::string>() == "58");
YAML_ASSERT(doc["Stack"][1]["code"].as<std::string>() == "foo = bar"); {
} YAML::Node doc = docs[2];
return true; YAML_ASSERT(doc.size() == 4);
} YAML_ASSERT(doc["Date"].as<std::string>() == "2001-11-23 15:03:17 -5");
YAML_ASSERT(doc["User"].as<std::string>() == "ed");
// TODO: 5.1 - 5.2 BOM YAML_ASSERT(doc["Fatal"].as<std::string>() == "Unknown variable \"bar\"");
YAML_ASSERT(doc["Stack"].size() == 2);
// 5.3 YAML_ASSERT(doc["Stack"][0].size() == 3);
TEST BlockStructureIndicators() { YAML_ASSERT(doc["Stack"][0]["file"].as<std::string>() == "TopClass.py");
YAML::Node doc = YAML::Load(ex5_3); YAML_ASSERT(doc["Stack"][0]["line"].as<std::string>() == "23");
YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["Stack"][0]["code"].as<std::string>() ==
YAML_ASSERT(doc["sequence"].size() == 2); "x = MoreObject(\"345\\n\")\n");
YAML_ASSERT(doc["sequence"][0].as<std::string>() == "one"); YAML_ASSERT(doc["Stack"][1].size() == 3);
YAML_ASSERT(doc["sequence"][1].as<std::string>() == "two"); YAML_ASSERT(doc["Stack"][1]["file"].as<std::string>() == "MoreClass.py");
YAML_ASSERT(doc["mapping"].size() == 2); YAML_ASSERT(doc["Stack"][1]["line"].as<std::string>() == "58");
YAML_ASSERT(doc["mapping"]["sky"].as<std::string>() == "blue"); YAML_ASSERT(doc["Stack"][1]["code"].as<std::string>() == "foo = bar");
YAML_ASSERT(doc["mapping"]["sea"].as<std::string>() == "green"); }
return true; return true;
} }
// 5.4 // TODO: 5.1 - 5.2 BOM
TEST FlowStructureIndicators() {
YAML::Node doc = YAML::Load(ex5_4); // 5.3
YAML_ASSERT(doc.size() == 2); TEST BlockStructureIndicators() {
YAML_ASSERT(doc["sequence"].size() == 2); YAML::Node doc = YAML::Load(ex5_3);
YAML_ASSERT(doc["sequence"][0].as<std::string>() == "one"); YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["sequence"][1].as<std::string>() == "two"); YAML_ASSERT(doc["sequence"].size() == 2);
YAML_ASSERT(doc["mapping"].size() == 2); YAML_ASSERT(doc["sequence"][0].as<std::string>() == "one");
YAML_ASSERT(doc["mapping"]["sky"].as<std::string>() == "blue"); YAML_ASSERT(doc["sequence"][1].as<std::string>() == "two");
YAML_ASSERT(doc["mapping"]["sea"].as<std::string>() == "green"); YAML_ASSERT(doc["mapping"].size() == 2);
return true; YAML_ASSERT(doc["mapping"]["sky"].as<std::string>() == "blue");
} YAML_ASSERT(doc["mapping"]["sea"].as<std::string>() == "green");
return true;
// 5.5 }
TEST CommentIndicator() {
YAML::Node doc = YAML::Load(ex5_5); // 5.4
YAML_ASSERT(doc.IsNull()); TEST FlowStructureIndicators() {
return true; YAML::Node doc = YAML::Load(ex5_4);
} YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["sequence"].size() == 2);
// 5.6 YAML_ASSERT(doc["sequence"][0].as<std::string>() == "one");
TEST NodePropertyIndicators() { YAML_ASSERT(doc["sequence"][1].as<std::string>() == "two");
YAML::Node doc = YAML::Load(ex5_6); YAML_ASSERT(doc["mapping"].size() == 2);
YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["mapping"]["sky"].as<std::string>() == "blue");
YAML_ASSERT(doc["anchored"].as<std::string>() == "value"); // TODO: assert tag YAML_ASSERT(doc["mapping"]["sea"].as<std::string>() == "green");
YAML_ASSERT(doc["alias"].as<std::string>() == "value"); return true;
return true; }
}
// 5.5
// 5.7 TEST CommentIndicator() {
TEST BlockScalarIndicators() { YAML::Node doc = YAML::Load(ex5_5);
YAML::Node doc = YAML::Load(ex5_7); YAML_ASSERT(doc.IsNull());
YAML_ASSERT(doc.size() == 2); return true;
YAML_ASSERT(doc["literal"].as<std::string>() == "some\ntext\n"); }
YAML_ASSERT(doc["folded"].as<std::string>() == "some text\n");
return true; // 5.6
} TEST NodePropertyIndicators() {
YAML::Node doc = YAML::Load(ex5_6);
// 5.8 YAML_ASSERT(doc.size() == 2);
TEST QuotedScalarIndicators() { YAML_ASSERT(doc["anchored"].as<std::string>() ==
YAML::Node doc = YAML::Load(ex5_8); "value"); // TODO: assert tag
YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["alias"].as<std::string>() == "value");
YAML_ASSERT(doc["single"].as<std::string>() == "text"); return true;
YAML_ASSERT(doc["double"].as<std::string>() == "text"); }
return true;
} // 5.7
TEST BlockScalarIndicators() {
// TODO: 5.9 directive YAML::Node doc = YAML::Load(ex5_7);
// TODO: 5.10 reserved indicator YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["literal"].as<std::string>() == "some\ntext\n");
// 5.11 YAML_ASSERT(doc["folded"].as<std::string>() == "some text\n");
TEST LineBreakCharacters() { return true;
YAML::Node doc = YAML::Load(ex5_11); }
YAML_ASSERT(doc.as<std::string>() == "Line break (no glyph)\nLine break (glyphed)\n");
return true; // 5.8
} TEST QuotedScalarIndicators() {
YAML::Node doc = YAML::Load(ex5_8);
// 5.12 YAML_ASSERT(doc.size() == 2);
TEST TabsAndSpaces() { YAML_ASSERT(doc["single"].as<std::string>() == "text");
YAML::Node doc = YAML::Load(ex5_12); YAML_ASSERT(doc["double"].as<std::string>() == "text");
YAML_ASSERT(doc.size() == 2); return true;
YAML_ASSERT(doc["quoted"].as<std::string>() == "Quoted\t"); }
YAML_ASSERT(doc["block"].as<std::string>() ==
"void main() {\n" // TODO: 5.9 directive
"\tprintf(\"Hello, world!\\n\");\n" // TODO: 5.10 reserved indicator
"}");
return true; // 5.11
} TEST LineBreakCharacters() {
YAML::Node doc = YAML::Load(ex5_11);
// 5.13 YAML_ASSERT(doc.as<std::string>() ==
TEST EscapedCharacters() { "Line break (no glyph)\nLine break (glyphed)\n");
YAML::Node doc = YAML::Load(ex5_13); return true;
YAML_ASSERT(doc.as<std::string>() == "Fun with \x5C \x22 \x07 \x08 \x1B \x0C \x0A \x0D \x09 \x0B " + std::string("\x00", 1) + " \x20 \xA0 \x85 \xe2\x80\xa8 \xe2\x80\xa9 A A A"); }
return true;
} // 5.12
TEST TabsAndSpaces() {
// 5.14 YAML::Node doc = YAML::Load(ex5_12);
TEST InvalidEscapedCharacters() { YAML_ASSERT(doc.size() == 2);
try { YAML_ASSERT(doc["quoted"].as<std::string>() == "Quoted\t");
YAML::Load(ex5_14); YAML_ASSERT(doc["block"].as<std::string>() ==
} catch(const YAML::ParserException& e) { "void main() {\n"
YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::INVALID_ESCAPE) + "c"); "\tprintf(\"Hello, world!\\n\");\n"
return true; "}");
} return true;
}
return false;
} // 5.13
TEST EscapedCharacters() {
// 6.1 YAML::Node doc = YAML::Load(ex5_13);
TEST IndentationSpaces() { YAML_ASSERT(doc.as<std::string>() ==
YAML::Node doc = YAML::Load(ex6_1); "Fun with \x5C \x22 \x07 \x08 \x1B \x0C \x0A \x0D \x09 \x0B " +
YAML_ASSERT(doc.size() == 1); std::string("\x00", 1) +
YAML_ASSERT(doc["Not indented"].size() == 2); " \x20 \xA0 \x85 \xe2\x80\xa8 \xe2\x80\xa9 A A A");
YAML_ASSERT(doc["Not indented"]["By one space"].as<std::string>() == "By four\n spaces\n"); return true;
YAML_ASSERT(doc["Not indented"]["Flow style"].size() == 3); }
YAML_ASSERT(doc["Not indented"]["Flow style"][0].as<std::string>() == "By two");
YAML_ASSERT(doc["Not indented"]["Flow style"][1].as<std::string>() == "Also by two"); // 5.14
YAML_ASSERT(doc["Not indented"]["Flow style"][2].as<std::string>() == "Still by two"); TEST InvalidEscapedCharacters() {
return true; try {
} YAML::Load(ex5_14);
}
// 6.2 catch (const YAML::ParserException& e) {
TEST IndentationIndicators() { YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::INVALID_ESCAPE) + "c");
YAML::Node doc = YAML::Load(ex6_2); return true;
YAML_ASSERT(doc.size() == 1); }
YAML_ASSERT(doc["a"].size() == 2);
YAML_ASSERT(doc["a"][0].as<std::string>() == "b"); return false;
YAML_ASSERT(doc["a"][1].size() == 2); }
YAML_ASSERT(doc["a"][1][0].as<std::string>() == "c");
YAML_ASSERT(doc["a"][1][1].as<std::string>() == "d"); // 6.1
return true; TEST IndentationSpaces() {
} YAML::Node doc = YAML::Load(ex6_1);
YAML_ASSERT(doc.size() == 1);
// 6.3 YAML_ASSERT(doc["Not indented"].size() == 2);
TEST SeparationSpaces() { YAML_ASSERT(doc["Not indented"]["By one space"].as<std::string>() ==
YAML::Node doc = YAML::Load(ex6_3); "By four\n spaces\n");
YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["Not indented"]["Flow style"].size() == 3);
YAML_ASSERT(doc[0].size() == 1); YAML_ASSERT(doc["Not indented"]["Flow style"][0].as<std::string>() ==
YAML_ASSERT(doc[0]["foo"].as<std::string>() == "bar"); "By two");
YAML_ASSERT(doc[1].size() == 2); YAML_ASSERT(doc["Not indented"]["Flow style"][1].as<std::string>() ==
YAML_ASSERT(doc[1][0].as<std::string>() == "baz"); "Also by two");
YAML_ASSERT(doc[1][1].as<std::string>() == "baz"); YAML_ASSERT(doc["Not indented"]["Flow style"][2].as<std::string>() ==
return true; "Still by two");
} return true;
}
// 6.4
TEST LinePrefixes() { // 6.2
YAML::Node doc = YAML::Load(ex6_4); TEST IndentationIndicators() {
YAML_ASSERT(doc.size() == 3); YAML::Node doc = YAML::Load(ex6_2);
YAML_ASSERT(doc["plain"].as<std::string>() == "text lines"); YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc["quoted"].as<std::string>() == "text lines"); YAML_ASSERT(doc["a"].size() == 2);
YAML_ASSERT(doc["block"].as<std::string>() == "text\n \tlines\n"); YAML_ASSERT(doc["a"][0].as<std::string>() == "b");
return true; YAML_ASSERT(doc["a"][1].size() == 2);
} YAML_ASSERT(doc["a"][1][0].as<std::string>() == "c");
YAML_ASSERT(doc["a"][1][1].as<std::string>() == "d");
// 6.5 return true;
TEST EmptyLines() { }
YAML::Node doc = YAML::Load(ex6_5);
YAML_ASSERT(doc.size() == 2); // 6.3
YAML_ASSERT(doc["Folding"].as<std::string>() == "Empty line\nas a line feed"); TEST SeparationSpaces() {
YAML_ASSERT(doc["Chomping"].as<std::string>() == "Clipped empty lines\n"); YAML::Node doc = YAML::Load(ex6_3);
return true; YAML_ASSERT(doc.size() == 2);
} YAML_ASSERT(doc[0].size() == 1);
YAML_ASSERT(doc[0]["foo"].as<std::string>() == "bar");
// 6.6 YAML_ASSERT(doc[1].size() == 2);
TEST LineFolding() { YAML_ASSERT(doc[1][0].as<std::string>() == "baz");
YAML::Node doc = YAML::Load(ex6_6); YAML_ASSERT(doc[1][1].as<std::string>() == "baz");
YAML_ASSERT(doc.as<std::string>() == "trimmed\n\n\nas space"); return true;
return true; }
}
// 6.4
// 6.7 TEST LinePrefixes() {
TEST BlockFolding() { YAML::Node doc = YAML::Load(ex6_4);
YAML::Node doc = YAML::Load(ex6_7); YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc.as<std::string>() == "foo \n\n\t bar\n\nbaz\n"); YAML_ASSERT(doc["plain"].as<std::string>() == "text lines");
return true; YAML_ASSERT(doc["quoted"].as<std::string>() == "text lines");
} YAML_ASSERT(doc["block"].as<std::string>() == "text\n \tlines\n");
return true;
// 6.8 }
TEST FlowFolding() {
YAML::Node doc = YAML::Load(ex6_8); // 6.5
YAML_ASSERT(doc.as<std::string>() == " foo\nbar\nbaz "); TEST EmptyLines() {
return true; YAML::Node doc = YAML::Load(ex6_5);
} YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["Folding"].as<std::string>() == "Empty line\nas a line feed");
// 6.9 YAML_ASSERT(doc["Chomping"].as<std::string>() == "Clipped empty lines\n");
TEST SeparatedComment() { return true;
YAML::Node doc = YAML::Load(ex6_9); }
YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc["key"].as<std::string>() == "value"); // 6.6
return true; TEST LineFolding() {
} YAML::Node doc = YAML::Load(ex6_6);
YAML_ASSERT(doc.as<std::string>() == "trimmed\n\n\nas space");
// 6.10 return true;
TEST CommentLines() { }
YAML::Node doc = YAML::Load(ex6_10);
YAML_ASSERT(doc.IsNull()); // 6.7
return true; TEST BlockFolding() {
} YAML::Node doc = YAML::Load(ex6_7);
YAML_ASSERT(doc.as<std::string>() == "foo \n\n\t bar\n\nbaz\n");
// 6.11 return true;
TEST MultiLineComments() { }
YAML::Node doc = YAML::Load(ex6_11);
YAML_ASSERT(doc.size() == 1); // 6.8
YAML_ASSERT(doc["key"].as<std::string>() == "value"); TEST FlowFolding() {
return true; YAML::Node doc = YAML::Load(ex6_8);
} YAML_ASSERT(doc.as<std::string>() == " foo\nbar\nbaz ");
return true;
// 6.12 }
TEST SeparationSpacesII() {
YAML::Node doc = YAML::Load(ex6_12); // 6.9
TEST SeparatedComment() {
std::map<std::string, std::string> sammy; YAML::Node doc = YAML::Load(ex6_9);
sammy["first"] = "Sammy"; YAML_ASSERT(doc.size() == 1);
sammy["last"] = "Sosa"; YAML_ASSERT(doc["key"].as<std::string>() == "value");
return true;
YAML_ASSERT(doc.size() == 1); }
YAML_ASSERT(doc[sammy].size() == 2);
YAML_ASSERT(doc[sammy]["hr"].as<int>() == 65); // 6.10
YAML_ASSERT(doc[sammy]["avg"].as<std::string>() == "0.278"); TEST CommentLines() {
return true; YAML::Node doc = YAML::Load(ex6_10);
} YAML_ASSERT(doc.IsNull());
return true;
// 6.13 }
TEST ReservedDirectives() {
YAML::Node doc = YAML::Load(ex6_13); // 6.11
YAML_ASSERT(doc.as<std::string>() == "foo"); TEST MultiLineComments() {
return true; YAML::Node doc = YAML::Load(ex6_11);
} YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc["key"].as<std::string>() == "value");
// 6.14 return true;
TEST YAMLDirective() { }
YAML::Node doc = YAML::Load(ex6_14);
YAML_ASSERT(doc.as<std::string>() == "foo"); // 6.12
return true; TEST SeparationSpacesII() {
} YAML::Node doc = YAML::Load(ex6_12);
// 6.15 std::map<std::string, std::string> sammy;
TEST InvalidRepeatedYAMLDirective() { sammy["first"] = "Sammy";
try { sammy["last"] = "Sosa";
YAML::Load(ex6_15);
} catch(const YAML::ParserException& e) { YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(e.msg == YAML::ErrorMsg::REPEATED_YAML_DIRECTIVE); YAML_ASSERT(doc[sammy].size() == 2);
return true; YAML_ASSERT(doc[sammy]["hr"].as<int>() == 65);
} YAML_ASSERT(doc[sammy]["avg"].as<std::string>() == "0.278");
return true;
return " No exception was thrown"; }
}
// 6.13
// 6.16 TEST ReservedDirectives() {
TEST TagDirective() { YAML::Node doc = YAML::Load(ex6_13);
YAML::Node doc = YAML::Load(ex6_16); YAML_ASSERT(doc.as<std::string>() == "foo");
YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:str"); return true;
YAML_ASSERT(doc.as<std::string>() == "foo"); }
return true;
} // 6.14
TEST YAMLDirective() {
// 6.17 YAML::Node doc = YAML::Load(ex6_14);
TEST InvalidRepeatedTagDirective() { YAML_ASSERT(doc.as<std::string>() == "foo");
try { return true;
YAML::Load(ex6_17); }
} catch(const YAML::ParserException& e) {
if(e.msg == YAML::ErrorMsg::REPEATED_TAG_DIRECTIVE) // 6.15
return true; TEST InvalidRepeatedYAMLDirective() {
try {
throw; YAML::Load(ex6_15);
} }
catch (const YAML::ParserException& e) {
return " No exception was thrown"; YAML_ASSERT(e.msg == YAML::ErrorMsg::REPEATED_YAML_DIRECTIVE);
} return true;
}
// 6.18
TEST PrimaryTagHandle() { return " No exception was thrown";
std::vector<YAML::Node> docs = YAML::LoadAll(ex6_18); }
YAML_ASSERT(docs.size() == 2);
// 6.16
{ TEST TagDirective() {
YAML::Node doc = docs[0]; YAML::Node doc = YAML::Load(ex6_16);
YAML_ASSERT(doc.Tag() == "!foo"); YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:str");
YAML_ASSERT(doc.as<std::string>() == "bar"); YAML_ASSERT(doc.as<std::string>() == "foo");
} return true;
}
{
YAML::Node doc = docs[1]; // 6.17
YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo"); TEST InvalidRepeatedTagDirective() {
YAML_ASSERT(doc.as<std::string>() == "bar"); try {
} YAML::Load(ex6_17);
return true; }
} catch (const YAML::ParserException& e) {
if (e.msg == YAML::ErrorMsg::REPEATED_TAG_DIRECTIVE)
// 6.19 return true;
TEST SecondaryTagHandle() {
YAML::Node doc = YAML::Load(ex6_19); throw;
YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/int"); }
YAML_ASSERT(doc.as<std::string>() == "1 - 3");
return true; return " No exception was thrown";
} }
// 6.20 // 6.18
TEST TagHandles() { TEST PrimaryTagHandle() {
YAML::Node doc = YAML::Load(ex6_20); std::vector<YAML::Node> docs = YAML::LoadAll(ex6_18);
YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo"); YAML_ASSERT(docs.size() == 2);
YAML_ASSERT(doc.as<std::string>() == "bar");
return true; {
} YAML::Node doc = docs[0];
YAML_ASSERT(doc.Tag() == "!foo");
// 6.21 YAML_ASSERT(doc.as<std::string>() == "bar");
TEST LocalTagPrefix() { }
std::vector<YAML::Node> docs = YAML::LoadAll(ex6_21);
YAML_ASSERT(docs.size() == 2); {
YAML::Node doc = docs[1];
{ YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo");
YAML::Node doc = docs[0]; YAML_ASSERT(doc.as<std::string>() == "bar");
YAML_ASSERT(doc.Tag() == "!my-light"); }
YAML_ASSERT(doc.as<std::string>() == "fluorescent"); return true;
} }
{ // 6.19
YAML::Node doc = docs[1]; TEST SecondaryTagHandle() {
YAML_ASSERT(doc.Tag() == "!my-light"); YAML::Node doc = YAML::Load(ex6_19);
YAML_ASSERT(doc.as<std::string>() == "green"); YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/int");
} YAML_ASSERT(doc.as<std::string>() == "1 - 3");
return true; return true;
} }
// 6.22 // 6.20
TEST GlobalTagPrefix() { TEST TagHandles() {
YAML::Node doc = YAML::Load(ex6_22); YAML::Node doc = YAML::Load(ex6_20);
YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo");
YAML_ASSERT(doc[0].Tag() == "tag:example.com,2000:app/foo"); YAML_ASSERT(doc.as<std::string>() == "bar");
YAML_ASSERT(doc[0].as<std::string>() == "bar"); return true;
return true; }
}
// 6.21
// 6.23 TEST LocalTagPrefix() {
TEST NodeProperties() { std::vector<YAML::Node> docs = YAML::LoadAll(ex6_21);
YAML::Node doc = YAML::Load(ex6_23); YAML_ASSERT(docs.size() == 2);
YAML_ASSERT(doc.size() == 2);
for(YAML::const_iterator it=doc.begin();it!=doc.end();++it) { {
if(it->first.as<std::string>() == "foo") { YAML::Node doc = docs[0];
YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(doc.Tag() == "!my-light");
YAML_ASSERT(it->second.Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(doc.as<std::string>() == "fluorescent");
YAML_ASSERT(it->second.as<std::string>() == "bar"); }
} else if(it->first.as<std::string>() == "baz") {
YAML_ASSERT(it->second.as<std::string>() == "foo"); {
} else YAML::Node doc = docs[1];
return " unknown key"; YAML_ASSERT(doc.Tag() == "!my-light");
} YAML_ASSERT(doc.as<std::string>() == "green");
}
return true; return true;
} }
// 6.24 // 6.22
TEST VerbatimTags() { TEST GlobalTagPrefix() {
YAML::Node doc = YAML::Load(ex6_24); YAML::Node doc = YAML::Load(ex6_22);
YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc.size() == 1);
for(YAML::const_iterator it=doc.begin();it!=doc.end();++it) { YAML_ASSERT(doc[0].Tag() == "tag:example.com,2000:app/foo");
YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(doc[0].as<std::string>() == "bar");
YAML_ASSERT(it->first.as<std::string>() == "foo"); return true;
YAML_ASSERT(it->second.Tag() == "!bar"); }
YAML_ASSERT(it->second.as<std::string>() == "baz");
} // 6.23
return true; TEST NodeProperties() {
} YAML::Node doc = YAML::Load(ex6_23);
YAML_ASSERT(doc.size() == 2);
// 6.25 for (YAML::const_iterator it = doc.begin(); it != doc.end(); ++it) {
TEST InvalidVerbatimTags() { if (it->first.as<std::string>() == "foo") {
YAML::Node doc = YAML::Load(ex6_25); YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str");
return " not implemented yet"; // TODO: check tags (but we probably will say these are valid, I think) YAML_ASSERT(it->second.Tag() == "tag:yaml.org,2002:str");
} YAML_ASSERT(it->second.as<std::string>() == "bar");
} else if (it->first.as<std::string>() == "baz") {
// 6.26 YAML_ASSERT(it->second.as<std::string>() == "foo");
TEST TagShorthands() { } else
YAML::Node doc = YAML::Load(ex6_26); return " unknown key";
YAML_ASSERT(doc.size() == 3); }
YAML_ASSERT(doc[0].Tag() == "!local");
YAML_ASSERT(doc[0].as<std::string>() == "foo"); return true;
YAML_ASSERT(doc[1].Tag() == "tag:yaml.org,2002:str"); }
YAML_ASSERT(doc[1].as<std::string>() == "bar");
YAML_ASSERT(doc[2].Tag() == "tag:example.com,2000:app/tag%21"); // 6.24
YAML_ASSERT(doc[2].as<std::string>() == "baz"); TEST VerbatimTags() {
return true; YAML::Node doc = YAML::Load(ex6_24);
} YAML_ASSERT(doc.size() == 1);
for (YAML::const_iterator it = doc.begin(); it != doc.end(); ++it) {
// 6.27 YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str");
TEST InvalidTagShorthands() { YAML_ASSERT(it->first.as<std::string>() == "foo");
bool threw = false; YAML_ASSERT(it->second.Tag() == "!bar");
try { YAML_ASSERT(it->second.as<std::string>() == "baz");
YAML::Load(ex6_27a); }
} catch(const YAML::ParserException& e) { return true;
threw = true; }
if(e.msg != YAML::ErrorMsg::TAG_WITH_NO_SUFFIX)
throw; // 6.25
} TEST InvalidVerbatimTags() {
YAML::Node doc = YAML::Load(ex6_25);
if(!threw) return " not implemented yet"; // TODO: check tags (but we probably will say
return " No exception was thrown for a tag with no suffix"; // these are valid, I think)
}
YAML::Load(ex6_27b); // TODO: should we reject this one (since !h! is not declared)?
return " not implemented yet"; // 6.26
} TEST TagShorthands() {
YAML::Node doc = YAML::Load(ex6_26);
// 6.28 YAML_ASSERT(doc.size() == 3);
TEST NonSpecificTags() { YAML_ASSERT(doc[0].Tag() == "!local");
YAML::Node doc = YAML::Load(ex6_28); YAML_ASSERT(doc[0].as<std::string>() == "foo");
YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc[1].Tag() == "tag:yaml.org,2002:str");
YAML_ASSERT(doc[0].as<std::string>() == "12"); // TODO: check tags. How? YAML_ASSERT(doc[1].as<std::string>() == "bar");
YAML_ASSERT(doc[1].as<int>() == 12); YAML_ASSERT(doc[2].Tag() == "tag:example.com,2000:app/tag%21");
YAML_ASSERT(doc[2].as<std::string>() == "12"); YAML_ASSERT(doc[2].as<std::string>() == "baz");
return true; return true;
} }
// 6.29 // 6.27
TEST NodeAnchors() { TEST InvalidTagShorthands() {
YAML::Node doc = YAML::Load(ex6_29); bool threw = false;
YAML_ASSERT(doc.size() == 2); try {
YAML_ASSERT(doc["First occurrence"].as<std::string>() == "Value"); YAML::Load(ex6_27a);
YAML_ASSERT(doc["Second occurrence"].as<std::string>() == "Value"); }
return true; catch (const YAML::ParserException& e) {
} threw = true;
if (e.msg != YAML::ErrorMsg::TAG_WITH_NO_SUFFIX)
// 7.1 throw;
TEST AliasNodes() { }
YAML::Node doc = YAML::Load(ex7_1);
YAML_ASSERT(doc.size() == 4); if (!threw)
YAML_ASSERT(doc["First occurrence"].as<std::string>() == "Foo"); return " No exception was thrown for a tag with no suffix";
YAML_ASSERT(doc["Second occurrence"].as<std::string>() == "Foo");
YAML_ASSERT(doc["Override anchor"].as<std::string>() == "Bar"); YAML::Load(
YAML_ASSERT(doc["Reuse anchor"].as<std::string>() == "Bar"); ex6_27b); // TODO: should we reject this one (since !h! is not declared)?
return true; return " not implemented yet";
} }
// 7.2 // 6.28
TEST EmptyNodes() { TEST NonSpecificTags() {
YAML::Node doc = YAML::Load(ex7_2); YAML::Node doc = YAML::Load(ex6_28);
YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc.size() == 3);
for(YAML::const_iterator it=doc.begin();it!=doc.end();++it) { YAML_ASSERT(doc[0].as<std::string>() == "12"); // TODO: check tags. How?
if(it->first.as<std::string>() == "foo") { YAML_ASSERT(doc[1].as<int>() == 12);
YAML_ASSERT(it->second.Tag() == "tag:yaml.org,2002:str"); YAML_ASSERT(doc[2].as<std::string>() == "12");
YAML_ASSERT(it->second.as<std::string>() == ""); return true;
} else if(it->first.as<std::string>() == "") { }
YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str");
YAML_ASSERT(it->second.as<std::string>() == "bar"); // 6.29
} else TEST NodeAnchors() {
return " unexpected key"; YAML::Node doc = YAML::Load(ex6_29);
} YAML_ASSERT(doc.size() == 2);
return true; YAML_ASSERT(doc["First occurrence"].as<std::string>() == "Value");
} YAML_ASSERT(doc["Second occurrence"].as<std::string>() == "Value");
return true;
// 7.3 }
TEST CompletelyEmptyNodes() {
YAML::Node doc = YAML::Load(ex7_3); // 7.1
YAML_ASSERT(doc.size() == 2); TEST AliasNodes() {
YAML_ASSERT(doc["foo"].IsNull()); YAML::Node doc = YAML::Load(ex7_1);
YAML_ASSERT(doc[YAML::Null].as<std::string>() == "bar"); YAML_ASSERT(doc.size() == 4);
return true; YAML_ASSERT(doc["First occurrence"].as<std::string>() == "Foo");
} YAML_ASSERT(doc["Second occurrence"].as<std::string>() == "Foo");
YAML_ASSERT(doc["Override anchor"].as<std::string>() == "Bar");
// 7.4 YAML_ASSERT(doc["Reuse anchor"].as<std::string>() == "Bar");
TEST DoubleQuotedImplicitKeys() { return true;
YAML::Node doc = YAML::Load(ex7_4); }
YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc["implicit block key"].size() == 1); // 7.2
YAML_ASSERT(doc["implicit block key"][0].size() == 1); TEST EmptyNodes() {
YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].as<std::string>() == "value"); YAML::Node doc = YAML::Load(ex7_2);
return true; YAML_ASSERT(doc.size() == 2);
} for (YAML::const_iterator it = doc.begin(); it != doc.end(); ++it) {
if (it->first.as<std::string>() == "foo") {
// 7.5 YAML_ASSERT(it->second.Tag() == "tag:yaml.org,2002:str");
TEST DoubleQuotedLineBreaks() { YAML_ASSERT(it->second.as<std::string>() == "");
YAML::Node doc = YAML::Load(ex7_5); } else if (it->first.as<std::string>() == "") {
YAML_ASSERT(doc.as<std::string>() == "folded to a space,\nto a line feed, or \t \tnon-content"); YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str");
return true; YAML_ASSERT(it->second.as<std::string>() == "bar");
} } else
return " unexpected key";
// 7.6 }
TEST DoubleQuotedLines() { return true;
YAML::Node doc = YAML::Load(ex7_6); }
YAML_ASSERT(doc.as<std::string>() == " 1st non-empty\n2nd non-empty 3rd non-empty ");
return true; // 7.3
} TEST CompletelyEmptyNodes() {
YAML::Node doc = YAML::Load(ex7_3);
// 7.7 YAML_ASSERT(doc.size() == 2);
TEST SingleQuotedCharacters() { YAML_ASSERT(doc["foo"].IsNull());
YAML::Node doc = YAML::Load(ex7_7); YAML_ASSERT(doc[YAML::Null].as<std::string>() == "bar");
YAML_ASSERT(doc.as<std::string>() == "here's to \"quotes\""); return true;
return true; }
}
// 7.4
// 7.8 TEST DoubleQuotedImplicitKeys() {
TEST SingleQuotedImplicitKeys() { YAML::Node doc = YAML::Load(ex7_4);
YAML::Node doc = YAML::Load(ex7_8); YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc["implicit block key"].size() == 1);
YAML_ASSERT(doc["implicit block key"].size() == 1); YAML_ASSERT(doc["implicit block key"][0].size() == 1);
YAML_ASSERT(doc["implicit block key"][0].size() == 1); YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"]
YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].as<std::string>() == "value"); .as<std::string>() == "value");
return true; return true;
} }
// 7.9 // 7.5
TEST SingleQuotedLines() { TEST DoubleQuotedLineBreaks() {
YAML::Node doc = YAML::Load(ex7_9); YAML::Node doc = YAML::Load(ex7_5);
YAML_ASSERT(doc.as<std::string>() == " 1st non-empty\n2nd non-empty 3rd non-empty "); YAML_ASSERT(doc.as<std::string>() ==
return true; "folded to a space,\nto a line feed, or \t \tnon-content");
} return true;
}
// 7.10
TEST PlainCharacters() { // 7.6
YAML::Node doc = YAML::Load(ex7_10); TEST DoubleQuotedLines() {
YAML_ASSERT(doc.size() == 6); YAML::Node doc = YAML::Load(ex7_6);
YAML_ASSERT(doc[0].as<std::string>() == "::vector"); YAML_ASSERT(doc.as<std::string>() ==
YAML_ASSERT(doc[1].as<std::string>() == ": - ()"); " 1st non-empty\n2nd non-empty 3rd non-empty ");
YAML_ASSERT(doc[2].as<std::string>() == "Up, up, and away!"); return true;
YAML_ASSERT(doc[3].as<int>() == -123); }
YAML_ASSERT(doc[4].as<std::string>() == "http://example.com/foo#bar");
YAML_ASSERT(doc[5].size() == 5); // 7.7
YAML_ASSERT(doc[5][0].as<std::string>() == "::vector"); TEST SingleQuotedCharacters() {
YAML_ASSERT(doc[5][1].as<std::string>() == ": - ()"); YAML::Node doc = YAML::Load(ex7_7);
YAML_ASSERT(doc[5][2].as<std::string>() == "Up, up, and away!"); YAML_ASSERT(doc.as<std::string>() == "here's to \"quotes\"");
YAML_ASSERT(doc[5][3].as<int>() == -123); return true;
YAML_ASSERT(doc[5][4].as<std::string>() == "http://example.com/foo#bar"); }
return true;
} // 7.8
TEST SingleQuotedImplicitKeys() {
// 7.11 YAML::Node doc = YAML::Load(ex7_8);
TEST PlainImplicitKeys() { YAML_ASSERT(doc.size() == 1);
YAML::Node doc = YAML::Load(ex7_11); YAML_ASSERT(doc["implicit block key"].size() == 1);
YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc["implicit block key"][0].size() == 1);
YAML_ASSERT(doc["implicit block key"].size() == 1); YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"]
YAML_ASSERT(doc["implicit block key"][0].size() == 1); .as<std::string>() == "value");
YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"].as<std::string>() == "value"); return true;
return true; }
}
// 7.9
// 7.12 TEST SingleQuotedLines() {
TEST PlainLines() { YAML::Node doc = YAML::Load(ex7_9);
YAML::Node doc = YAML::Load(ex7_12); YAML_ASSERT(doc.as<std::string>() ==
YAML_ASSERT(doc.as<std::string>() == "1st non-empty\n2nd non-empty 3rd non-empty"); " 1st non-empty\n2nd non-empty 3rd non-empty ");
return true; return true;
} }
// 7.13 // 7.10
TEST FlowSequence() { TEST PlainCharacters() {
YAML::Node doc = YAML::Load(ex7_13); YAML::Node doc = YAML::Load(ex7_10);
YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc.size() == 6);
YAML_ASSERT(doc[0].size() == 2); YAML_ASSERT(doc[0].as<std::string>() == "::vector");
YAML_ASSERT(doc[0][0].as<std::string>() == "one"); YAML_ASSERT(doc[1].as<std::string>() == ": - ()");
YAML_ASSERT(doc[0][1].as<std::string>() == "two"); YAML_ASSERT(doc[2].as<std::string>() == "Up, up, and away!");
YAML_ASSERT(doc[1].size() == 2); YAML_ASSERT(doc[3].as<int>() == -123);
YAML_ASSERT(doc[1][0].as<std::string>() == "three"); YAML_ASSERT(doc[4].as<std::string>() == "http://example.com/foo#bar");
YAML_ASSERT(doc[1][1].as<std::string>() == "four"); YAML_ASSERT(doc[5].size() == 5);
return true; YAML_ASSERT(doc[5][0].as<std::string>() == "::vector");
} YAML_ASSERT(doc[5][1].as<std::string>() == ": - ()");
YAML_ASSERT(doc[5][2].as<std::string>() == "Up, up, and away!");
// 7.14 YAML_ASSERT(doc[5][3].as<int>() == -123);
TEST FlowSequenceEntries() { YAML_ASSERT(doc[5][4].as<std::string>() == "http://example.com/foo#bar");
YAML::Node doc = YAML::Load(ex7_14); return true;
YAML_ASSERT(doc.size() == 5); }
YAML_ASSERT(doc[0].as<std::string>() == "double quoted");
YAML_ASSERT(doc[1].as<std::string>() == "single quoted"); // 7.11
YAML_ASSERT(doc[2].as<std::string>() == "plain text"); TEST PlainImplicitKeys() {
YAML_ASSERT(doc[3].size() == 1); YAML::Node doc = YAML::Load(ex7_11);
YAML_ASSERT(doc[3][0].as<std::string>() == "nested"); YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc[4].size() == 1); YAML_ASSERT(doc["implicit block key"].size() == 1);
YAML_ASSERT(doc[4]["single"].as<std::string>() == "pair"); YAML_ASSERT(doc["implicit block key"][0].size() == 1);
return true; YAML_ASSERT(doc["implicit block key"][0]["implicit flow key"]
} .as<std::string>() == "value");
return true;
// 7.15 }
TEST FlowMappings() {
YAML::Node doc = YAML::Load(ex7_15); // 7.12
YAML_ASSERT(doc.size() == 2); TEST PlainLines() {
YAML_ASSERT(doc[0].size() == 2); YAML::Node doc = YAML::Load(ex7_12);
YAML_ASSERT(doc[0]["one"].as<std::string>() == "two"); YAML_ASSERT(doc.as<std::string>() ==
YAML_ASSERT(doc[0]["three"].as<std::string>() == "four"); "1st non-empty\n2nd non-empty 3rd non-empty");
YAML_ASSERT(doc[1].size() == 2); return true;
YAML_ASSERT(doc[1]["five"].as<std::string>() == "six"); }
YAML_ASSERT(doc[1]["seven"].as<std::string>() == "eight");
return true; // 7.13
} TEST FlowSequence() {
YAML::Node doc = YAML::Load(ex7_13);
// 7.16 YAML_ASSERT(doc.size() == 2);
TEST FlowMappingEntries() { YAML_ASSERT(doc[0].size() == 2);
YAML::Node doc = YAML::Load(ex7_16); YAML_ASSERT(doc[0][0].as<std::string>() == "one");
YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc[0][1].as<std::string>() == "two");
YAML_ASSERT(doc["explicit"].as<std::string>() == "entry"); YAML_ASSERT(doc[1].size() == 2);
YAML_ASSERT(doc["implicit"].as<std::string>() == "entry"); YAML_ASSERT(doc[1][0].as<std::string>() == "three");
YAML_ASSERT(doc[YAML::Null].IsNull()); YAML_ASSERT(doc[1][1].as<std::string>() == "four");
return true; return true;
} }
// 7.17 // 7.14
TEST FlowMappingSeparateValues() { TEST FlowSequenceEntries() {
YAML::Node doc = YAML::Load(ex7_17); YAML::Node doc = YAML::Load(ex7_14);
YAML_ASSERT(doc.size() == 4); YAML_ASSERT(doc.size() == 5);
YAML_ASSERT(doc["unquoted"].as<std::string>() == "separate"); YAML_ASSERT(doc[0].as<std::string>() == "double quoted");
YAML_ASSERT(doc["http://foo.com"].IsNull()); YAML_ASSERT(doc[1].as<std::string>() == "single quoted");
YAML_ASSERT(doc["omitted value"].IsNull()); YAML_ASSERT(doc[2].as<std::string>() == "plain text");
YAML_ASSERT(doc[YAML::Null].as<std::string>() == "omitted key"); YAML_ASSERT(doc[3].size() == 1);
return true; YAML_ASSERT(doc[3][0].as<std::string>() == "nested");
} YAML_ASSERT(doc[4].size() == 1);
YAML_ASSERT(doc[4]["single"].as<std::string>() == "pair");
// 7.18 return true;
TEST FlowMappingAdjacentValues() { }
YAML::Node doc = YAML::Load(ex7_18);
YAML_ASSERT(doc.size() == 3); // 7.15
YAML_ASSERT(doc["adjacent"].as<std::string>() == "value"); TEST FlowMappings() {
YAML_ASSERT(doc["readable"].as<std::string>() == "value"); YAML::Node doc = YAML::Load(ex7_15);
YAML_ASSERT(doc["empty"].IsNull()); YAML_ASSERT(doc.size() == 2);
return true; YAML_ASSERT(doc[0].size() == 2);
} YAML_ASSERT(doc[0]["one"].as<std::string>() == "two");
YAML_ASSERT(doc[0]["three"].as<std::string>() == "four");
// 7.19 YAML_ASSERT(doc[1].size() == 2);
TEST SinglePairFlowMappings() { YAML_ASSERT(doc[1]["five"].as<std::string>() == "six");
YAML::Node doc = YAML::Load(ex7_19); YAML_ASSERT(doc[1]["seven"].as<std::string>() == "eight");
YAML_ASSERT(doc.size() == 1); return true;
YAML_ASSERT(doc[0].size() == 1); }
YAML_ASSERT(doc[0]["foo"].as<std::string>() == "bar");
return true; // 7.16
} TEST FlowMappingEntries() {
YAML::Node doc = YAML::Load(ex7_16);
// 7.20 YAML_ASSERT(doc.size() == 3);
TEST SinglePairExplicitEntry() { YAML_ASSERT(doc["explicit"].as<std::string>() == "entry");
YAML::Node doc = YAML::Load(ex7_20); YAML_ASSERT(doc["implicit"].as<std::string>() == "entry");
YAML_ASSERT(doc.size() == 1); YAML_ASSERT(doc[YAML::Null].IsNull());
YAML_ASSERT(doc[0].size() == 1); return true;
YAML_ASSERT(doc[0]["foo bar"].as<std::string>() == "baz"); }
return true;
} // 7.17
TEST FlowMappingSeparateValues() {
// 7.21 YAML::Node doc = YAML::Load(ex7_17);
TEST SinglePairImplicitEntries() { YAML_ASSERT(doc.size() == 4);
YAML::Node doc = YAML::Load(ex7_21); YAML_ASSERT(doc["unquoted"].as<std::string>() == "separate");
YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc["http://foo.com"].IsNull());
YAML_ASSERT(doc[0].size() == 1); YAML_ASSERT(doc["omitted value"].IsNull());
YAML_ASSERT(doc[0][0].size() == 1); YAML_ASSERT(doc[YAML::Null].as<std::string>() == "omitted key");
YAML_ASSERT(doc[0][0]["YAML"].as<std::string>() == "separate"); return true;
YAML_ASSERT(doc[1].size() == 1); }
YAML_ASSERT(doc[1][0].size() == 1);
YAML_ASSERT(doc[1][0][YAML::Null].as<std::string>() == "empty key entry"); // 7.18
YAML_ASSERT(doc[2].size() == 1); TEST FlowMappingAdjacentValues() {
YAML_ASSERT(doc[2][0].size() == 1); YAML::Node doc = YAML::Load(ex7_18);
YAML_ASSERT(doc.size() == 3);
std::map<std::string, std::string> key; YAML_ASSERT(doc["adjacent"].as<std::string>() == "value");
key["JSON"] = "like"; YAML_ASSERT(doc["readable"].as<std::string>() == "value");
YAML_ASSERT(doc[2][0][key].as<std::string>() == "adjacent"); YAML_ASSERT(doc["empty"].IsNull());
return true; return true;
} }
// 7.22 // 7.19
TEST InvalidImplicitKeys() { TEST SinglePairFlowMappings() {
try { YAML::Node doc = YAML::Load(ex7_19);
YAML::Load(ex7_22); YAML_ASSERT(doc.size() == 1);
} catch(const YAML::Exception& e) { YAML_ASSERT(doc[0].size() == 1);
if(e.msg == YAML::ErrorMsg::END_OF_SEQ_FLOW) YAML_ASSERT(doc[0]["foo"].as<std::string>() == "bar");
return true; return true;
}
throw;
} // 7.20
return " no exception thrown"; TEST SinglePairExplicitEntry() {
} YAML::Node doc = YAML::Load(ex7_20);
YAML_ASSERT(doc.size() == 1);
// 7.23 YAML_ASSERT(doc[0].size() == 1);
TEST FlowContent() { YAML_ASSERT(doc[0]["foo bar"].as<std::string>() == "baz");
YAML::Node doc = YAML::Load(ex7_23); return true;
YAML_ASSERT(doc.size() == 5); }
YAML_ASSERT(doc[0].size() == 2);
YAML_ASSERT(doc[0][0].as<std::string>() == "a"); // 7.21
YAML_ASSERT(doc[0][1].as<std::string>() == "b"); TEST SinglePairImplicitEntries() {
YAML_ASSERT(doc[1].size() == 1); YAML::Node doc = YAML::Load(ex7_21);
YAML_ASSERT(doc[1]["a"].as<std::string>() == "b"); YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[2].as<std::string>() == "a"); YAML_ASSERT(doc[0].size() == 1);
YAML_ASSERT(doc[3].as<char>() == 'b'); YAML_ASSERT(doc[0][0].size() == 1);
YAML_ASSERT(doc[4].as<std::string>() == "c"); YAML_ASSERT(doc[0][0]["YAML"].as<std::string>() == "separate");
return true; YAML_ASSERT(doc[1].size() == 1);
} YAML_ASSERT(doc[1][0].size() == 1);
YAML_ASSERT(doc[1][0][YAML::Null].as<std::string>() == "empty key entry");
// 7.24 YAML_ASSERT(doc[2].size() == 1);
TEST FlowNodes() { YAML_ASSERT(doc[2][0].size() == 1);
YAML::Node doc = YAML::Load(ex7_24);
YAML_ASSERT(doc.size() == 5); std::map<std::string, std::string> key;
YAML_ASSERT(doc[0].Tag() == "tag:yaml.org,2002:str"); key["JSON"] = "like";
YAML_ASSERT(doc[0].as<std::string>() == "a"); YAML_ASSERT(doc[2][0][key].as<std::string>() == "adjacent");
YAML_ASSERT(doc[1].as<char>() == 'b'); return true;
YAML_ASSERT(doc[2].as<std::string>() == "c"); }
YAML_ASSERT(doc[3].as<std::string>() == "c");
YAML_ASSERT(doc[4].Tag() == "tag:yaml.org,2002:str"); // 7.22
YAML_ASSERT(doc[4].as<std::string>() == ""); TEST InvalidImplicitKeys() {
return true; try {
} YAML::Load(ex7_22);
}
// 8.1 catch (const YAML::Exception& e) {
TEST BlockScalarHeader() { if (e.msg == YAML::ErrorMsg::END_OF_SEQ_FLOW)
YAML::Node doc = YAML::Load(ex8_1); return true;
YAML_ASSERT(doc.size() == 4);
YAML_ASSERT(doc[0].as<std::string>() == "literal\n"); throw;
YAML_ASSERT(doc[1].as<std::string>() == " folded\n"); }
YAML_ASSERT(doc[2].as<std::string>() == "keep\n\n"); return " no exception thrown";
YAML_ASSERT(doc[3].as<std::string>() == " strip"); }
return true;
} // 7.23
TEST FlowContent() {
// 8.2 YAML::Node doc = YAML::Load(ex7_23);
TEST BlockIndentationHeader() { YAML_ASSERT(doc.size() == 5);
YAML::Node doc = YAML::Load(ex8_2); YAML_ASSERT(doc[0].size() == 2);
YAML_ASSERT(doc.size() == 4); YAML_ASSERT(doc[0][0].as<std::string>() == "a");
YAML_ASSERT(doc[0].as<std::string>() == "detected\n"); YAML_ASSERT(doc[0][1].as<std::string>() == "b");
YAML_ASSERT(doc[1].as<std::string>() == "\n\n# detected\n"); YAML_ASSERT(doc[1].size() == 1);
YAML_ASSERT(doc[2].as<std::string>() == " explicit\n"); YAML_ASSERT(doc[1]["a"].as<std::string>() == "b");
YAML_ASSERT(doc[3].as<std::string>() == "\t\ndetected\n"); YAML_ASSERT(doc[2].as<std::string>() == "a");
return true; YAML_ASSERT(doc[3].as<char>() == 'b');
} YAML_ASSERT(doc[4].as<std::string>() == "c");
return true;
// 8.3 }
TEST InvalidBlockScalarIndentationIndicators() {
{ // 7.24
bool threw = false; TEST FlowNodes() {
try { YAML::Node doc = YAML::Load(ex7_24);
YAML::Load(ex8_3a); YAML_ASSERT(doc.size() == 5);
} catch(const YAML::Exception& e) { YAML_ASSERT(doc[0].Tag() == "tag:yaml.org,2002:str");
if(e.msg != YAML::ErrorMsg::END_OF_SEQ) YAML_ASSERT(doc[0].as<std::string>() == "a");
throw; YAML_ASSERT(doc[1].as<char>() == 'b');
YAML_ASSERT(doc[2].as<std::string>() == "c");
threw = true; YAML_ASSERT(doc[3].as<std::string>() == "c");
} YAML_ASSERT(doc[4].Tag() == "tag:yaml.org,2002:str");
YAML_ASSERT(doc[4].as<std::string>() == "");
if(!threw) return true;
return " no exception thrown for less indented auto-detecting indentation for a literal block scalar"; }
}
// 8.1
{ TEST BlockScalarHeader() {
bool threw = false; YAML::Node doc = YAML::Load(ex8_1);
try { YAML_ASSERT(doc.size() == 4);
YAML::Load(ex8_3b); YAML_ASSERT(doc[0].as<std::string>() == "literal\n");
} catch(const YAML::Exception& e) { YAML_ASSERT(doc[1].as<std::string>() == " folded\n");
if(e.msg != YAML::ErrorMsg::END_OF_SEQ) YAML_ASSERT(doc[2].as<std::string>() == "keep\n\n");
throw; YAML_ASSERT(doc[3].as<std::string>() == " strip");
return true;
threw = true; }
}
// 8.2
if(!threw) TEST BlockIndentationHeader() {
return " no exception thrown for less indented auto-detecting indentation for a folded block scalar"; YAML::Node doc = YAML::Load(ex8_2);
} YAML_ASSERT(doc.size() == 4);
YAML_ASSERT(doc[0].as<std::string>() == "detected\n");
{ YAML_ASSERT(doc[1].as<std::string>() == "\n\n# detected\n");
bool threw = false; YAML_ASSERT(doc[2].as<std::string>() == " explicit\n");
try { YAML_ASSERT(doc[3].as<std::string>() == "\t\ndetected\n");
YAML::Load(ex8_3c); return true;
} catch(const YAML::Exception& e) { }
if(e.msg != YAML::ErrorMsg::END_OF_SEQ)
throw; // 8.3
TEST InvalidBlockScalarIndentationIndicators() {
threw = true; {
} bool threw = false;
try {
if(!threw) YAML::Load(ex8_3a);
return " no exception thrown for less indented explicit indentation for a literal block scalar"; }
} catch (const YAML::Exception& e) {
if (e.msg != YAML::ErrorMsg::END_OF_SEQ)
return true; throw;
}
threw = true;
// 8.4 }
TEST ChompingFinalLineBreak() {
YAML::Node doc = YAML::Load(ex8_4); if (!threw)
YAML_ASSERT(doc.size() == 3); return " no exception thrown for less indented auto-detecting "
YAML_ASSERT(doc["strip"].as<std::string>() == "text"); "indentation for a literal block scalar";
YAML_ASSERT(doc["clip"].as<std::string>() == "text\n"); }
YAML_ASSERT(doc["keep"].as<std::string>() == "text\n");
return true; {
} bool threw = false;
try {
// 8.5 YAML::Load(ex8_3b);
TEST ChompingTrailingLines() { }
YAML::Node doc = YAML::Load(ex8_5); catch (const YAML::Exception& e) {
YAML_ASSERT(doc.size() == 3); if (e.msg != YAML::ErrorMsg::END_OF_SEQ)
YAML_ASSERT(doc["strip"].as<std::string>() == "# text"); throw;
YAML_ASSERT(doc["clip"].as<std::string>() == "# text\n");
YAML_ASSERT(doc["keep"].as<std::string>() == "# text\n"); // Note: I believe this is a bug in the YAML spec - it should be "# text\n\n" threw = true;
return true; }
}
if (!threw)
// 8.6 return " no exception thrown for less indented auto-detecting "
TEST EmptyScalarChomping() { "indentation for a folded block scalar";
YAML::Node doc = YAML::Load(ex8_6); }
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["strip"].as<std::string>() == ""); {
YAML_ASSERT(doc["clip"].as<std::string>() == ""); bool threw = false;
YAML_ASSERT(doc["keep"].as<std::string>() == "\n"); try {
return true; YAML::Load(ex8_3c);
} }
catch (const YAML::Exception& e) {
// 8.7 if (e.msg != YAML::ErrorMsg::END_OF_SEQ)
TEST LiteralScalar() { throw;
YAML::Node doc = YAML::Load(ex8_7);
YAML_ASSERT(doc.as<std::string>() == "literal\n\ttext\n"); threw = true;
return true; }
}
if (!threw)
// 8.8 return " no exception thrown for less indented explicit indentation for "
TEST LiteralContent() { "a literal block scalar";
YAML::Node doc = YAML::Load(ex8_8); }
YAML_ASSERT(doc.as<std::string>() == "\n\nliteral\n \n\ntext\n");
return true; return true;
} }
// 8.9 // 8.4
TEST FoldedScalar() { TEST ChompingFinalLineBreak() {
YAML::Node doc = YAML::Load(ex8_9); YAML::Node doc = YAML::Load(ex8_4);
YAML_ASSERT(doc.as<std::string>() == "folded text\n"); YAML_ASSERT(doc.size() == 3);
return true; YAML_ASSERT(doc["strip"].as<std::string>() == "text");
} YAML_ASSERT(doc["clip"].as<std::string>() == "text\n");
YAML_ASSERT(doc["keep"].as<std::string>() == "text\n");
// 8.10 return true;
TEST FoldedLines() { }
YAML::Node doc = YAML::Load(ex8_10);
YAML_ASSERT(doc.as<std::string>() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n"); // 8.5
return true; TEST ChompingTrailingLines() {
} YAML::Node doc = YAML::Load(ex8_5);
YAML_ASSERT(doc.size() == 3);
// 8.11 YAML_ASSERT(doc["strip"].as<std::string>() == "# text");
TEST MoreIndentedLines() { YAML_ASSERT(doc["clip"].as<std::string>() == "# text\n");
YAML::Node doc = YAML::Load(ex8_11); YAML_ASSERT(doc["keep"].as<std::string>() == "# text\n"); // Note: I believe
YAML_ASSERT(doc.as<std::string>() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n"); // this is a bug in
return true; // the YAML spec -
} // it should be "#
// text\n\n"
// 8.12 return true;
TEST EmptySeparationLines() { }
YAML::Node doc = YAML::Load(ex8_12);
YAML_ASSERT(doc.as<std::string>() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n"); // 8.6
return true; TEST EmptyScalarChomping() {
} YAML::Node doc = YAML::Load(ex8_6);
YAML_ASSERT(doc.size() == 3);
// 8.13 YAML_ASSERT(doc["strip"].as<std::string>() == "");
TEST FinalEmptyLines() { YAML_ASSERT(doc["clip"].as<std::string>() == "");
YAML::Node doc = YAML::Load(ex8_13); YAML_ASSERT(doc["keep"].as<std::string>() == "\n");
YAML_ASSERT(doc.as<std::string>() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n"); return true;
return true; }
}
// 8.7
// 8.14 TEST LiteralScalar() {
TEST BlockSequence() { YAML::Node doc = YAML::Load(ex8_7);
YAML::Node doc = YAML::Load(ex8_14); YAML_ASSERT(doc.as<std::string>() == "literal\n\ttext\n");
YAML_ASSERT(doc.size() == 1); return true;
YAML_ASSERT(doc["block sequence"].size() == 2); }
YAML_ASSERT(doc["block sequence"][0].as<std::string>() == "one");
YAML_ASSERT(doc["block sequence"][1].size() == 1); // 8.8
YAML_ASSERT(doc["block sequence"][1]["two"].as<std::string>() == "three"); TEST LiteralContent() {
return true; YAML::Node doc = YAML::Load(ex8_8);
} YAML_ASSERT(doc.as<std::string>() == "\n\nliteral\n \n\ntext\n");
return true;
// 8.15 }
TEST BlockSequenceEntryTypes() {
YAML::Node doc = YAML::Load(ex8_15); // 8.9
YAML_ASSERT(doc.size() == 4); TEST FoldedScalar() {
YAML_ASSERT(doc[0].IsNull()); YAML::Node doc = YAML::Load(ex8_9);
YAML_ASSERT(doc[1].as<std::string>() == "block node\n"); YAML_ASSERT(doc.as<std::string>() == "folded text\n");
YAML_ASSERT(doc[2].size() == 2); return true;
YAML_ASSERT(doc[2][0].as<std::string>() == "one"); }
YAML_ASSERT(doc[2][1].as<std::string>() == "two");
YAML_ASSERT(doc[3].size() == 1); // 8.10
YAML_ASSERT(doc[3]["one"].as<std::string>() == "two"); TEST FoldedLines() {
return true; YAML::Node doc = YAML::Load(ex8_10);
} YAML_ASSERT(doc.as<std::string>() ==
"\nfolded line\nnext line\n * bullet\n\n * list\n * "
// 8.16 "lines\n\nlast line\n");
TEST BlockMappings() { return true;
YAML::Node doc = YAML::Load(ex8_16); }
YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc["block mapping"].size() == 1); // 8.11
YAML_ASSERT(doc["block mapping"]["key"].as<std::string>() == "value"); TEST MoreIndentedLines() {
return true; YAML::Node doc = YAML::Load(ex8_11);
} YAML_ASSERT(doc.as<std::string>() ==
"\nfolded line\nnext line\n * bullet\n\n * list\n * "
// 8.17 "lines\n\nlast line\n");
TEST ExplicitBlockMappingEntries() { return true;
YAML::Node doc = YAML::Load(ex8_17); }
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["explicit key"].IsNull()); // 8.12
YAML_ASSERT(doc["block key\n"].size() == 2); TEST EmptySeparationLines() {
YAML_ASSERT(doc["block key\n"][0].as<std::string>() == "one"); YAML::Node doc = YAML::Load(ex8_12);
YAML_ASSERT(doc["block key\n"][1].as<std::string>() == "two"); YAML_ASSERT(doc.as<std::string>() ==
return true; "\nfolded line\nnext line\n * bullet\n\n * list\n * "
} "lines\n\nlast line\n");
return true;
// 8.18 }
TEST ImplicitBlockMappingEntries() {
YAML::Node doc = YAML::Load(ex8_18); // 8.13
YAML_ASSERT(doc.size() == 3); TEST FinalEmptyLines() {
YAML_ASSERT(doc["plain key"].as<std::string>() == "in-line value"); YAML::Node doc = YAML::Load(ex8_13);
YAML_ASSERT(doc[YAML::Null].IsNull()); YAML_ASSERT(doc.as<std::string>() ==
YAML_ASSERT(doc["quoted key"].size() == 1); "\nfolded line\nnext line\n * bullet\n\n * list\n * "
YAML_ASSERT(doc["quoted key"][0].as<std::string>() == "entry"); "lines\n\nlast line\n");
return true; return true;
} }
// 8.19 // 8.14
TEST CompactBlockMappings() { TEST BlockSequence() {
YAML::Node doc = YAML::Load(ex8_19); YAML::Node doc = YAML::Load(ex8_14);
YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc[0].size() == 1); YAML_ASSERT(doc["block sequence"].size() == 2);
YAML_ASSERT(doc[0]["sun"].as<std::string>() == "yellow"); YAML_ASSERT(doc["block sequence"][0].as<std::string>() == "one");
YAML_ASSERT(doc[1].size() == 1); YAML_ASSERT(doc["block sequence"][1].size() == 1);
std::map<std::string, std::string> key; YAML_ASSERT(doc["block sequence"][1]["two"].as<std::string>() == "three");
key["earth"] = "blue"; return true;
YAML_ASSERT(doc[1][key].size() == 1); }
YAML_ASSERT(doc[1][key]["moon"].as<std::string>() == "white");
return true; // 8.15
} TEST BlockSequenceEntryTypes() {
YAML::Node doc = YAML::Load(ex8_15);
// 8.20 YAML_ASSERT(doc.size() == 4);
TEST BlockNodeTypes() { YAML_ASSERT(doc[0].IsNull());
YAML::Node doc = YAML::Load(ex8_20); YAML_ASSERT(doc[1].as<std::string>() == "block node\n");
YAML_ASSERT(doc.size() == 3); YAML_ASSERT(doc[2].size() == 2);
YAML_ASSERT(doc[0].as<std::string>() == "flow in block"); YAML_ASSERT(doc[2][0].as<std::string>() == "one");
YAML_ASSERT(doc[1].as<std::string>() == "Block scalar\n"); YAML_ASSERT(doc[2][1].as<std::string>() == "two");
YAML_ASSERT(doc[2].size() == 1); YAML_ASSERT(doc[3].size() == 1);
YAML_ASSERT(doc[2]["foo"].as<std::string>() == "bar"); YAML_ASSERT(doc[3]["one"].as<std::string>() == "two");
return true; return true;
} }
// 8.21 // 8.16
TEST BlockScalarNodes() { TEST BlockMappings() {
YAML::Node doc = YAML::Load(ex8_21); YAML::Node doc = YAML::Load(ex8_16);
YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc.size() == 1);
YAML_ASSERT(doc["literal"].as<std::string>() == "value"); // Note: I believe this is a bug in the YAML spec - it should be "value\n" YAML_ASSERT(doc["block mapping"].size() == 1);
YAML_ASSERT(doc["folded"].as<std::string>() == "value"); YAML_ASSERT(doc["block mapping"]["key"].as<std::string>() == "value");
YAML_ASSERT(doc["folded"].Tag() == "!foo"); return true;
return true; }
}
// 8.17
// 8.22 TEST ExplicitBlockMappingEntries() {
TEST BlockCollectionNodes() { YAML::Node doc = YAML::Load(ex8_17);
YAML::Node doc = YAML::Load(ex8_22); YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc.size() == 2); YAML_ASSERT(doc["explicit key"].IsNull());
YAML_ASSERT(doc["sequence"].size() == 2); YAML_ASSERT(doc["block key\n"].size() == 2);
YAML_ASSERT(doc["sequence"][0].as<std::string>() == "entry"); YAML_ASSERT(doc["block key\n"][0].as<std::string>() == "one");
YAML_ASSERT(doc["sequence"][1].size() == 1); YAML_ASSERT(doc["block key\n"][1].as<std::string>() == "two");
YAML_ASSERT(doc["sequence"][1][0].as<std::string>() == "nested"); return true;
YAML_ASSERT(doc["mapping"].size() == 1); }
YAML_ASSERT(doc["mapping"]["foo"].as<std::string>() == "bar");
return true; // 8.18
} TEST ImplicitBlockMappingEntries() {
} YAML::Node doc = YAML::Load(ex8_18);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc["plain key"].as<std::string>() == "in-line value");
YAML_ASSERT(doc[YAML::Null].IsNull());
YAML_ASSERT(doc["quoted key"].size() == 1);
YAML_ASSERT(doc["quoted key"][0].as<std::string>() == "entry");
return true;
}
// 8.19
TEST CompactBlockMappings() {
YAML::Node doc = YAML::Load(ex8_19);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc[0].size() == 1);
YAML_ASSERT(doc[0]["sun"].as<std::string>() == "yellow");
YAML_ASSERT(doc[1].size() == 1);
std::map<std::string, std::string> key;
key["earth"] = "blue";
YAML_ASSERT(doc[1][key].size() == 1);
YAML_ASSERT(doc[1][key]["moon"].as<std::string>() == "white");
return true;
}
// 8.20
TEST BlockNodeTypes() {
YAML::Node doc = YAML::Load(ex8_20);
YAML_ASSERT(doc.size() == 3);
YAML_ASSERT(doc[0].as<std::string>() == "flow in block");
YAML_ASSERT(doc[1].as<std::string>() == "Block scalar\n");
YAML_ASSERT(doc[2].size() == 1);
YAML_ASSERT(doc[2]["foo"].as<std::string>() == "bar");
return true;
}
// 8.21
TEST BlockScalarNodes() {
YAML::Node doc = YAML::Load(ex8_21);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["literal"].as<std::string>() == "value"); // Note: I believe
// this is a bug in
// the YAML spec -
// it should be
// "value\n"
YAML_ASSERT(doc["folded"].as<std::string>() == "value");
YAML_ASSERT(doc["folded"].Tag() == "!foo");
return true;
}
// 8.22
TEST BlockCollectionNodes() {
YAML::Node doc = YAML::Load(ex8_22);
YAML_ASSERT(doc.size() == 2);
YAML_ASSERT(doc["sequence"].size() == 2);
YAML_ASSERT(doc["sequence"][0].as<std::string>() == "entry");
YAML_ASSERT(doc["sequence"][1].size() == 1);
YAML_ASSERT(doc["sequence"][1][0].as<std::string>() == "nested");
YAML_ASSERT(doc["mapping"].size() == 1);
YAML_ASSERT(doc["mapping"]["foo"].as<std::string>() == "bar");
return true;
}
}
} }
#ifndef NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
namespace Test { namespace Test {
bool RunNodeTests(); bool RunNodeTests();
} }
#endif // NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A6666 #endif // NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A6666
...@@ -9,25 +9,22 @@ ...@@ -9,25 +9,22 @@
#include <vector> #include <vector>
#include <iostream> #include <iostream>
namespace Test namespace Test {
{ void RunAll() {
void RunAll() bool passed = true;
{ if (!RunParserTests())
bool passed = true; passed = false;
if(!RunParserTests())
passed = false;
if(!RunEmitterTests())
passed = false;
if(!RunSpecTests()) if (!RunEmitterTests())
passed = false; passed = false;
if(!RunNodeTests()) if (!RunSpecTests())
passed = false; passed = false;
if(passed) if (!RunNodeTests())
std::cout << "All tests passed!\n"; passed = false;
}
}
if (passed)
std::cout << "All tests passed!\n";
}
}
...@@ -5,56 +5,57 @@ ...@@ -5,56 +5,57 @@
#include <vector> #include <vector>
struct Params { struct Params {
bool hasFile; bool hasFile;
std::string fileName; std::string fileName;
}; };
Params ParseArgs(int argc, char **argv) { Params ParseArgs(int argc, char** argv) {
Params p; Params p;
std::vector<std::string> args(argv + 1, argv + argc); std::vector<std::string> args(argv + 1, argv + argc);
return p; return p;
} }
class NullEventHandler: public YAML::EventHandler class NullEventHandler : public YAML::EventHandler {
{ public:
public: virtual void OnDocumentStart(const YAML::Mark&) {}
virtual void OnDocumentStart(const YAML::Mark&) {} virtual void OnDocumentEnd() {}
virtual void OnDocumentEnd() {}
virtual void OnNull(const YAML::Mark&, YAML::anchor_t) {}
virtual void OnNull(const YAML::Mark&, YAML::anchor_t) {} virtual void OnAlias(const YAML::Mark&, YAML::anchor_t) {}
virtual void OnAlias(const YAML::Mark&, YAML::anchor_t) {} virtual void OnScalar(const YAML::Mark&, const std::string&, YAML::anchor_t,
virtual void OnScalar(const YAML::Mark&, const std::string&, YAML::anchor_t, const std::string&) {} const std::string&) {}
virtual void OnSequenceStart(const YAML::Mark&, const std::string&, YAML::anchor_t) {} virtual void OnSequenceStart(const YAML::Mark&, const std::string&,
virtual void OnSequenceEnd() {} YAML::anchor_t) {}
virtual void OnSequenceEnd() {}
virtual void OnMapStart(const YAML::Mark&, const std::string&, YAML::anchor_t) {}
virtual void OnMapEnd() {} virtual void OnMapStart(const YAML::Mark&, const std::string&,
YAML::anchor_t) {}
virtual void OnMapEnd() {}
}; };
void parse(std::istream& input) void parse(std::istream& input) {
{ try {
try { YAML::Node doc = YAML::Load(input);
YAML::Node doc = YAML::Load(input); std::cout << doc << "\n";
std::cout << doc << "\n"; }
} catch(const YAML::Exception& e) { catch (const YAML::Exception& e) {
std::cerr << e.what() << "\n"; std::cerr << e.what() << "\n";
} }
} }
int main(int argc, char **argv) int main(int argc, char** argv) {
{ Params p = ParseArgs(argc, argv);
Params p = ParseArgs(argc, argv);
if(argc > 1) { if (argc > 1) {
std::ifstream fin; std::ifstream fin;
fin.open(argv[1]); fin.open(argv[1]);
parse(fin); parse(fin);
} else { } else {
parse(std::cin); parse(std::cin);
} }
return 0; return 0;
} }
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