diff --git a/include/yaml-cpp/dll.h b/include/yaml-cpp/dll.h index df04cc8..827e0f1 100644 --- a/include/yaml-cpp/dll.h +++ b/include/yaml-cpp/dll.h @@ -30,7 +30,7 @@ // #pragma message( "Defining YAML_CPP_API for DLL import" ) #define YAML_CPP_API __declspec(dllimport) #endif // yaml_cpp_EXPORTS -#else // YAML_CPP_DLL +#else // YAML_CPP_DLL #define YAML_CPP_API #endif // YAML_CPP_DLL diff --git a/include/yaml-cpp/exceptions.h b/include/yaml-cpp/exceptions.h index ffbf7bd..cdf766e 100644 --- a/include/yaml-cpp/exceptions.h +++ b/include/yaml-cpp/exceptions.h @@ -1,208 +1,227 @@ #ifndef 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 #endif - #include "yaml-cpp/mark.h" #include "yaml-cpp/traits.h" #include #include #include -namespace YAML -{ - // error messages - namespace ErrorMsg - { - 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_MAJOR_VERSION = "YAML major version too large"; - const char * const REPEATED_YAML_DIRECTIVE= "repeated YAML directive"; - const char * const TAG_DIRECTIVE_ARGS = "TAG directives must have exactly two arguments"; - 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 TAG_WITH_NO_SUFFIX = "tag handle with no suffix"; - const char * const END_OF_VERBATIM_TAG = "end of verbatim tag not found"; - const char * const END_OF_MAP = "end of map not found"; - const char * const END_OF_MAP_FLOW = "end of map flow not found"; - const char * const END_OF_SEQ = "end of sequence not found"; - const char * const END_OF_SEQ_FLOW = "end of sequence flow not found"; - const char * const MULTIPLE_TAGS = "cannot assign multiple tags to the same node"; - const char * const MULTIPLE_ANCHORS = "cannot assign multiple anchors to the same node"; - const char * const MULTIPLE_ALIASES = "cannot assign multiple aliases to the same node"; - const char * const ALIAS_CONTENT = "aliases can't have any content, *including* tags"; - const char * const INVALID_HEX = "bad character found while scanning hex number"; - const char * const INVALID_UNICODE = "invalid unicode: "; - const char * const INVALID_ESCAPE = "unknown escape character: "; - const char * const UNKNOWN_TOKEN = "unknown token"; - const char * const DOC_IN_SCALAR = "illegal document indicator in scalar"; - const char * const EOF_IN_SCALAR = "illegal EOF in scalar"; - const char * const CHAR_IN_SCALAR = "illegal character in scalar"; - const char * const TAB_IN_INDENTATION = "illegal tab when looking for indentation"; - const char * const FLOW_END = "illegal flow end"; - const char * const BLOCK_ENTRY = "illegal block entry"; - const char * const MAP_KEY = "illegal map key"; - const char * const MAP_VALUE = "illegal map value"; - const char * const ALIAS_NOT_FOUND = "alias not found after *"; - const char * const ANCHOR_NOT_FOUND = "anchor not found after &"; - const char * const CHAR_IN_ALIAS = "illegal character found while scanning alias"; - const char * const CHAR_IN_ANCHOR = "illegal character found while scanning anchor"; - const char * const ZERO_INDENT_IN_BLOCK = "cannot set zero indentation for a block scalar"; - const char * const CHAR_IN_BLOCK = "unexpected character in block scalar"; - const char * const AMBIGUOUS_ANCHOR = "cannot assign the same alias to multiple nodes"; - const char * const UNKNOWN_ANCHOR = "the referenced anchor is not defined"; +namespace YAML { +// error messages +namespace ErrorMsg { +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_MAJOR_VERSION = "YAML major version too large"; +const char* const REPEATED_YAML_DIRECTIVE = "repeated YAML directive"; +const char* const TAG_DIRECTIVE_ARGS = + "TAG directives must have exactly two arguments"; +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 TAG_WITH_NO_SUFFIX = "tag handle with no suffix"; +const char* const END_OF_VERBATIM_TAG = "end of verbatim tag not found"; +const char* const END_OF_MAP = "end of map not found"; +const char* const END_OF_MAP_FLOW = "end of map flow not found"; +const char* const END_OF_SEQ = "end of sequence not found"; +const char* const END_OF_SEQ_FLOW = "end of sequence flow not found"; +const char* const MULTIPLE_TAGS = + "cannot assign multiple tags to the same node"; +const char* const MULTIPLE_ANCHORS = + "cannot assign multiple anchors to the same node"; +const char* const MULTIPLE_ALIASES = + "cannot assign multiple aliases to the same node"; +const char* const ALIAS_CONTENT = + "aliases can't have any content, *including* tags"; +const char* const INVALID_HEX = "bad character found while scanning hex number"; +const char* const INVALID_UNICODE = "invalid unicode: "; +const char* const INVALID_ESCAPE = "unknown escape character: "; +const char* const UNKNOWN_TOKEN = "unknown token"; +const char* const DOC_IN_SCALAR = "illegal document indicator in scalar"; +const char* const EOF_IN_SCALAR = "illegal EOF in scalar"; +const char* const CHAR_IN_SCALAR = "illegal character in scalar"; +const char* const TAB_IN_INDENTATION = + "illegal tab when looking for indentation"; +const char* const FLOW_END = "illegal flow end"; +const char* const BLOCK_ENTRY = "illegal block entry"; +const char* const MAP_KEY = "illegal map key"; +const char* const MAP_VALUE = "illegal map value"; +const char* const ALIAS_NOT_FOUND = "alias not found after *"; +const char* const ANCHOR_NOT_FOUND = "anchor not found after &"; +const char* const CHAR_IN_ALIAS = + "illegal character found while scanning alias"; +const char* const CHAR_IN_ANCHOR = + "illegal character found while scanning anchor"; +const char* const ZERO_INDENT_IN_BLOCK = + "cannot set zero indentation for a block scalar"; +const char* const CHAR_IN_BLOCK = "unexpected character in block scalar"; +const char* const AMBIGUOUS_ANCHOR = + "cannot assign the same alias to multiple nodes"; +const char* const UNKNOWN_ANCHOR = "the referenced anchor is not defined"; - const char * const INVALID_NODE = "invalid node; this may result from using a map iterator as a sequence iterator, or vice-versa"; - const char * const INVALID_SCALAR = "invalid scalar"; - const char * const KEY_NOT_FOUND = "key not found"; - const char * const BAD_CONVERSION = "bad conversion"; - const char * const BAD_DEREFERENCE = "bad dereference"; - const char * const BAD_SUBSCRIPT = "operator[] call on a scalar"; - const char * const BAD_PUSHBACK = "appending to a non-sequence"; - const char * const BAD_INSERT = "inserting in a non-convertible-to-map"; - - const char * const UNMATCHED_GROUP_TAG = "unmatched group tag"; - const char * const UNEXPECTED_END_SEQ = "unexpected end sequence token"; - const char * const UNEXPECTED_END_MAP = "unexpected end map token"; - const char * const SINGLE_QUOTED_CHAR = "invalid character in single-quoted string"; - const char * const INVALID_ANCHOR = "invalid anchor"; - const char * const INVALID_ALIAS = "invalid alias"; - const char * const INVALID_TAG = "invalid tag"; - const char * const BAD_FILE = "bad file"; +const char* const INVALID_NODE = + "invalid node; this may result from using a map iterator as a sequence " + "iterator, or vice-versa"; +const char* const INVALID_SCALAR = "invalid scalar"; +const char* const KEY_NOT_FOUND = "key not found"; +const char* const BAD_CONVERSION = "bad conversion"; +const char* const BAD_DEREFERENCE = "bad dereference"; +const char* const BAD_SUBSCRIPT = "operator[] call on a scalar"; +const char* const BAD_PUSHBACK = "appending to a non-sequence"; +const char* const BAD_INSERT = "inserting in a non-convertible-to-map"; - template - inline const std::string KEY_NOT_FOUND_WITH_KEY(const T&, typename disable_if >::type * = 0) { - return KEY_NOT_FOUND; - } +const char* const UNMATCHED_GROUP_TAG = "unmatched group tag"; +const char* const UNEXPECTED_END_SEQ = "unexpected end sequence token"; +const char* const UNEXPECTED_END_MAP = "unexpected end map token"; +const char* const SINGLE_QUOTED_CHAR = + "invalid character in single-quoted string"; +const char* const INVALID_ANCHOR = "invalid anchor"; +const char* const INVALID_ALIAS = "invalid alias"; +const char* const INVALID_TAG = "invalid tag"; +const char* const BAD_FILE = "bad file"; - inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) { - std::stringstream stream; - stream << KEY_NOT_FOUND << ": " << key; - return stream.str(); - } - - template - inline const std::string KEY_NOT_FOUND_WITH_KEY(const T& key, typename enable_if >::type * = 0) { - std::stringstream stream; - stream << KEY_NOT_FOUND << ": " << key; - return stream.str(); - } - } - - class Exception: public std::runtime_error { - public: - Exception(const Mark& mark_, const std::string& msg_) - : std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {} - virtual ~Exception() throw() {} - - Mark mark; - std::string msg; - - private: - static const std::string build_what(const Mark& mark, const std::string& msg) { - std::stringstream output; - output << "yaml-cpp: error at line " << mark.line+1 << ", column " << mark.column+1 << ": " << msg; - return output.str(); - } - }; - - class ParserException: public Exception { - public: - ParserException(const Mark& mark_, const std::string& msg_) - : Exception(mark_, msg_) {} - }; - - class RepresentationException: public Exception { - public: - RepresentationException(const Mark& mark_, const std::string& msg_) - : Exception(mark_, msg_) {} - }; - - // representation exceptions - class InvalidScalar: public RepresentationException { - public: - InvalidScalar(const Mark& mark_) - : RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {} - }; - - class KeyNotFound: public RepresentationException { - public: - template - KeyNotFound(const Mark& mark_, const T& key_) - : RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {} - }; - - template - class TypedKeyNotFound: public KeyNotFound { - public: - TypedKeyNotFound(const Mark& mark_, const T& key_) - : KeyNotFound(mark_, key_), key(key_) {} - virtual ~TypedKeyNotFound() throw() {} - - T key; - }; - - template - inline TypedKeyNotFound MakeTypedKeyNotFound(const Mark& mark, const T& key) { - return TypedKeyNotFound (mark, key); - } - - class InvalidNode: public RepresentationException { - public: - InvalidNode() - : RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {} - }; - - class BadConversion: public RepresentationException { - public: - BadConversion() - : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_CONVERSION) {} - }; - - template - class TypedBadConversion: public BadConversion { - public: - TypedBadConversion() - : BadConversion() {} - }; - - class BadDereference: public RepresentationException { - public: - BadDereference() - : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {} - }; - - class BadSubscript: public RepresentationException { - public: - BadSubscript() - : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {} - }; - - class BadPushback: public RepresentationException { - public: - 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) {} - }; +template +inline const std::string KEY_NOT_FOUND_WITH_KEY( + const T&, typename disable_if >::type* = 0) { + return KEY_NOT_FOUND; } -#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) { + std::stringstream stream; + stream << KEY_NOT_FOUND << ": " << key; + return stream.str(); +} + +template +inline const std::string KEY_NOT_FOUND_WITH_KEY( + const T& key, typename enable_if >::type* = 0) { + std::stringstream stream; + stream << KEY_NOT_FOUND << ": " << key; + return stream.str(); +} +} + +class Exception : public std::runtime_error { + public: + Exception(const Mark& mark_, const std::string& msg_) + : std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {} + virtual ~Exception() throw() {} + + Mark mark; + std::string msg; + + private: + static const std::string build_what(const Mark& mark, + const std::string& msg) { + std::stringstream output; + output << "yaml-cpp: error at line " << mark.line + 1 << ", column " + << mark.column + 1 << ": " << msg; + return output.str(); + } +}; + +class ParserException : public Exception { + public: + ParserException(const Mark& mark_, const std::string& msg_) + : Exception(mark_, msg_) {} +}; + +class RepresentationException : public Exception { + public: + RepresentationException(const Mark& mark_, const std::string& msg_) + : Exception(mark_, msg_) {} +}; + +// representation exceptions +class InvalidScalar : public RepresentationException { + public: + InvalidScalar(const Mark& mark_) + : RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {} +}; + +class KeyNotFound : public RepresentationException { + public: + template + KeyNotFound(const Mark& mark_, const T& key_) + : RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) { + } +}; + +template +class TypedKeyNotFound : public KeyNotFound { + public: + TypedKeyNotFound(const Mark& mark_, const T& key_) + : KeyNotFound(mark_, key_), key(key_) {} + virtual ~TypedKeyNotFound() throw() {} + + T key; +}; + +template +inline TypedKeyNotFound MakeTypedKeyNotFound(const Mark& mark, + const T& key) { + return TypedKeyNotFound(mark, key); +} + +class InvalidNode : public RepresentationException { + public: + InvalidNode() + : RepresentationException(Mark::null_mark(), ErrorMsg::INVALID_NODE) {} +}; + +class BadConversion : public RepresentationException { + public: + BadConversion() + : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_CONVERSION) {} +}; + +template +class TypedBadConversion : public BadConversion { + public: + TypedBadConversion() : BadConversion() {} +}; + +class BadDereference : public RepresentationException { + public: + BadDereference() + : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {} +}; + +class BadSubscript : public RepresentationException { + public: + BadSubscript() + : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_SUBSCRIPT) {} +}; + +class BadPushback : public RepresentationException { + public: + 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 diff --git a/include/yaml-cpp/node/convert.h b/include/yaml-cpp/node/convert.h index 63ab9d7..76ceee5 100644 --- a/include/yaml-cpp/node/convert.h +++ b/include/yaml-cpp/node/convert.h @@ -1,11 +1,12 @@ #ifndef 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 #endif - #include "yaml-cpp/binary.h" #include "yaml-cpp/node/node.h" #include "yaml-cpp/node/iterator.h" @@ -16,265 +17,259 @@ #include #include -namespace YAML -{ - namespace conversion { - inline bool IsInfinity(const std::string& input) { - return input == ".inf" || input == ".Inf" || input == ".INF" || input == "+.inf" || input == "+.Inf" || input == "+.INF"; - } - - inline bool IsNegativeInfinity(const std::string& input) { - return input == "-.inf" || input == "-.Inf" || input == "-.INF"; - } - - inline bool IsNaN(const std::string& input) { - return input == ".nan" || input == ".NaN" || input == ".NAN"; - } - } - - // std::string - template<> - struct convert { - static Node encode(const std::string& rhs) { - return Node(rhs); - } - - static bool decode(const Node& node, std::string& rhs) { - if(!node.IsScalar()) - return false; - rhs = node.Scalar(); - return true; - } - }; - - // C-strings can only be encoded - template<> - struct convert { - static Node encode(const char *&rhs) { - return Node(rhs); - } - }; +namespace YAML { +namespace conversion { +inline bool IsInfinity(const std::string& input) { + return input == ".inf" || input == ".Inf" || input == ".INF" || + input == "+.inf" || input == "+.Inf" || input == "+.INF"; +} - template - struct convert { - static Node encode(const char (&rhs)[N]) { - return Node(rhs); - } - }; +inline bool IsNegativeInfinity(const std::string& input) { + return input == "-.inf" || input == "-.Inf" || input == "-.INF"; +} - template<> - struct convert<_Null> { - static Node encode(const _Null& /* rhs */) { - return Node(); - } - - static bool decode(const Node& node, _Null& /* rhs */) { - return node.IsNull(); - } - }; - -#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op)\ - template<>\ - struct convert {\ - static Node encode(const type& rhs) {\ - std::stringstream stream;\ - stream.precision(std::numeric_limits::digits10 + 1);\ - stream << rhs;\ - return Node(stream.str());\ - }\ - \ - static bool decode(const Node& node, type& rhs) {\ - if(node.Type() != NodeType::Scalar)\ - return false;\ - const std::string& input = node.Scalar();\ - std::stringstream stream(input);\ - stream.unsetf(std::ios::dec);\ - if((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof())\ - return true;\ - if(std::numeric_limits::has_infinity) {\ - if(conversion::IsInfinity(input)) {\ - rhs = std::numeric_limits::infinity();\ - return true;\ - } else if(conversion::IsNegativeInfinity(input)) {\ - rhs = negative_op std::numeric_limits::infinity();\ - return true;\ - }\ - }\ - \ - if(std::numeric_limits::has_quiet_NaN && conversion::IsNaN(input)) {\ - rhs = std::numeric_limits::quiet_NaN();\ - return true;\ - }\ - \ - return false;\ - }\ - } - -#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type)\ - YAML_DEFINE_CONVERT_STREAMABLE(type, -) +inline bool IsNaN(const std::string& input) { + return input == ".nan" || input == ".NaN" || input == ".NAN"; +} +} -#define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type)\ - YAML_DEFINE_CONVERT_STREAMABLE(type, +) +// std::string +template <> +struct convert { + static Node encode(const std::string& rhs) { return Node(rhs); } + + static bool decode(const Node& node, std::string& rhs) { + if (!node.IsScalar()) + return false; + rhs = node.Scalar(); + return true; + } +}; + +// C-strings can only be encoded +template <> +struct convert { + static Node encode(const char*& rhs) { return Node(rhs); } +}; + +template +struct convert { + static Node encode(const char (&rhs)[N]) { return Node(rhs); } +}; + +template <> +struct convert<_Null> { + static Node encode(const _Null& /* rhs */) { return Node(); } + + static bool decode(const Node& node, _Null& /* rhs */) { + return node.IsNull(); + } +}; + +#define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \ + template <> \ + struct convert { \ + static Node encode(const type& rhs) { \ + std::stringstream stream; \ + stream.precision(std::numeric_limits::digits10 + 1); \ + stream << rhs; \ + return Node(stream.str()); \ + } \ + \ + static bool decode(const Node& node, type& rhs) { \ + if (node.Type() != NodeType::Scalar) \ + return false; \ + const std::string& input = node.Scalar(); \ + std::stringstream stream(input); \ + stream.unsetf(std::ios::dec); \ + if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) \ + return true; \ + if (std::numeric_limits::has_infinity) { \ + if (conversion::IsInfinity(input)) { \ + rhs = std::numeric_limits::infinity(); \ + return true; \ + } else if (conversion::IsNegativeInfinity(input)) { \ + rhs = negative_op std::numeric_limits::infinity(); \ + return true; \ + } \ + } \ + \ + if (std::numeric_limits::has_quiet_NaN && \ + conversion::IsNaN(input)) { \ + rhs = std::numeric_limits::quiet_NaN(); \ + return true; \ + } \ + \ + return false; \ + } \ + } + +#define YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(type) \ + YAML_DEFINE_CONVERT_STREAMABLE(type, -) + +#define YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(type) \ + YAML_DEFINE_CONVERT_STREAMABLE(type, +) + +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long); +YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long); +YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long); + +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); - YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(int); - YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(short); - YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long); - YAML_DEFINE_CONVERT_STREAMABLE_SIGNED(long long); - YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned); - YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned short); - YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long); - YAML_DEFINE_CONVERT_STREAMABLE_UNSIGNED(unsigned long long); - - 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_UNSIGNED #undef YAML_DEFINE_CONVERT_STREAMABLE - - // bool - template<> - struct convert { - static Node encode(bool rhs) { - return rhs ? Node("true") : Node("false"); - } - - static bool decode(const Node& node, bool& rhs); - }; - // std::map - template - struct convert > { - static Node encode(const std::map& rhs) { - Node node(NodeType::Map); - for(typename std::map::const_iterator it=rhs.begin();it!=rhs.end();++it) - node.force_insert(it->first, it->second); - return node; - } - - static bool decode(const Node& node, std::map& rhs) { - if(!node.IsMap()) - return false; +// bool +template <> +struct convert { + static Node encode(bool rhs) { return rhs ? Node("true") : Node("false"); } - rhs.clear(); - for(const_iterator it=node.begin();it!=node.end();++it) + static bool decode(const Node& node, bool& rhs); +}; + +// std::map +template +struct convert > { + static Node encode(const std::map& rhs) { + Node node(NodeType::Map); + for (typename std::map::const_iterator it = rhs.begin(); + it != rhs.end(); ++it) + node.force_insert(it->first, it->second); + return node; + } + + static bool decode(const Node& node, std::map& rhs) { + if (!node.IsMap()) + return false; + + rhs.clear(); + for (const_iterator it = node.begin(); it != node.end(); ++it) #if defined(__GNUC__) && __GNUC__ < 4 -//workaround for GCC 3: - rhs[it->first.template as()] = it->second.template as(); + // workaround for GCC 3: + rhs[it->first.template as()] = it->second.template as(); #else - rhs[it->first.as()] = it->second.as(); + rhs[it->first.as()] = it->second.as(); #endif - return true; - } - }; - - // std::vector - template - struct convert > { - static Node encode(const std::vector& rhs) { - Node node(NodeType::Sequence); - for(typename std::vector::const_iterator it=rhs.begin();it!=rhs.end();++it) - node.push_back(*it); - return node; - } - - static bool decode(const Node& node, std::vector& rhs) { - if(!node.IsSequence()) - return false; - - rhs.clear(); - for(const_iterator it=node.begin();it!=node.end();++it) + return true; + } +}; + +// std::vector +template +struct convert > { + static Node encode(const std::vector& rhs) { + Node node(NodeType::Sequence); + for (typename std::vector::const_iterator it = rhs.begin(); + it != rhs.end(); ++it) + node.push_back(*it); + return node; + } + + static bool decode(const Node& node, std::vector& rhs) { + if (!node.IsSequence()) + return false; + + rhs.clear(); + for (const_iterator it = node.begin(); it != node.end(); ++it) #if defined(__GNUC__) && __GNUC__ < 4 -//workaround for GCC 3: - rhs.push_back(it->template as()); + // workaround for GCC 3: + rhs.push_back(it->template as()); #else - rhs.push_back(it->as()); + rhs.push_back(it->as()); #endif - return true; - } - }; - - // std::list - template - struct convert > { - static Node encode(const std::list& rhs) { - Node node(NodeType::Sequence); - for(typename std::list::const_iterator it=rhs.begin();it!=rhs.end();++it) - node.push_back(*it); - return node; - } - - static bool decode(const Node& node, std::list& rhs) { - if(!node.IsSequence()) - return false; - - rhs.clear(); - for(const_iterator it=node.begin();it!=node.end();++it) + return true; + } +}; + +// std::list +template +struct convert > { + static Node encode(const std::list& rhs) { + Node node(NodeType::Sequence); + for (typename std::list::const_iterator it = rhs.begin(); + it != rhs.end(); ++it) + node.push_back(*it); + return node; + } + + static bool decode(const Node& node, std::list& rhs) { + if (!node.IsSequence()) + return false; + + rhs.clear(); + for (const_iterator it = node.begin(); it != node.end(); ++it) #if defined(__GNUC__) && __GNUC__ < 4 -//workaround for GCC 3: - rhs.push_back(it->template as()); + // workaround for GCC 3: + rhs.push_back(it->template as()); #else - rhs.push_back(it->as()); + rhs.push_back(it->as()); #endif - return true; - } - }; - - // std::pair - template - struct convert > { - static Node encode(const std::pair& rhs) { - Node node(NodeType::Sequence); - node.push_back(rhs.first); - node.push_back(rhs.second); - return node; - } - - static bool decode(const Node& node, std::pair& rhs) { - if(!node.IsSequence()) - return false; - if (node.size() != 2) - return false; + return true; + } +}; + +// std::pair +template +struct convert > { + static Node encode(const std::pair& rhs) { + Node node(NodeType::Sequence); + node.push_back(rhs.first); + node.push_back(rhs.second); + return node; + } + + static bool decode(const Node& node, std::pair& rhs) { + if (!node.IsSequence()) + return false; + if (node.size() != 2) + return false; #if defined(__GNUC__) && __GNUC__ < 4 -//workaround for GCC 3: - rhs.first = node[0].template as(); + // workaround for GCC 3: + rhs.first = node[0].template as(); #else - rhs.first = node[0].as(); + rhs.first = node[0].as(); #endif #if defined(__GNUC__) && __GNUC__ < 4 -//workaround for GCC 3: - rhs.second = node[1].template as(); + // workaround for GCC 3: + rhs.second = node[1].template as(); #else - rhs.second = node[1].as(); + rhs.second = node[1].as(); #endif - return true; - } - }; + return true; + } +}; - // binary - template<> - struct convert { - static Node encode(const Binary& rhs) { - return Node(EncodeBase64(rhs.data(), rhs.size())); - } - - static bool decode(const Node& node, Binary& rhs) { - if(!node.IsScalar()) - return false; - - std::vector data = DecodeBase64(node.Scalar()); - if(data.empty() && !node.Scalar().empty()) - return false; - - rhs.swap(data); - return true; - } - }; +// binary +template <> +struct convert { + static Node encode(const Binary& rhs) { + return Node(EncodeBase64(rhs.data(), rhs.size())); + } + + static bool decode(const Node& node, Binary& rhs) { + if (!node.IsScalar()) + return false; + + std::vector data = DecodeBase64(node.Scalar()); + if (data.empty() && !node.Scalar().empty()) + return false; + + rhs.swap(data); + return true; + } +}; } -#endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#endif // NODE_CONVERT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/detail/bool_type.h b/include/yaml-cpp/node/detail/bool_type.h index 80ed9a4..2c80705 100644 --- a/include/yaml-cpp/node/detail/bool_type.h +++ b/include/yaml-cpp/node/detail/bool_type.h @@ -1,26 +1,26 @@ #ifndef 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 #endif -namespace YAML -{ - namespace detail - { - struct unspecified_bool { - struct NOT_ALLOWED; - static void true_value(NOT_ALLOWED*) {} - }; - typedef void (*unspecified_bool_type)(unspecified_bool::NOT_ALLOWED*); - } +namespace YAML { +namespace detail { +struct unspecified_bool { + struct NOT_ALLOWED; + static void true_value(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;\ -} +#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 +#endif // NODE_DETAIL_BOOL_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/detail/impl.h b/include/yaml-cpp/node/detail/impl.h index ce5fd57..43eaa38 100644 --- a/include/yaml-cpp/node/detail/impl.h +++ b/include/yaml-cpp/node/detail/impl.h @@ -1,168 +1,176 @@ #ifndef 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 #endif - #include "yaml-cpp/node/detail/node.h" #include "yaml-cpp/node/detail/node_data.h" #include -namespace YAML -{ - namespace detail - { - template - struct get_idx { - static node *get(const std::vector& /* sequence */, const Key& /* key */, shared_memory_holder /* pMemory */) { - return 0; - } - }; +namespace YAML { +namespace detail { +template +struct get_idx { + static node* get(const std::vector& /* sequence */, + const Key& /* key */, shared_memory_holder /* pMemory */) { + return 0; + } +}; - template - struct get_idx::value && !boost::is_same::value>::type> { - static node *get(const std::vector& sequence, const Key& key, shared_memory_holder /* pMemory */) { - return key < sequence.size() ? sequence[key] : 0; - } +template +struct get_idx< + Key, typename boost::enable_if_c::value && + !boost::is_same::value>::type> { + static node* get(const std::vector& sequence, const Key& key, + shared_memory_holder /* pMemory */) { + return key < sequence.size() ? sequence[key] : 0; + } - static node *get(std::vector& sequence, const Key& key, shared_memory_holder pMemory) { - if(key > sequence.size()) - return 0; - if(key == sequence.size()) - sequence.push_back(&pMemory->create_node()); - return sequence[key]; - } - }; - - template - struct get_idx >::type> { - static node *get(const std::vector& sequence, const Key& key, shared_memory_holder pMemory) { - return key >= 0 ? get_idx::get(sequence, static_cast(key), pMemory) : 0; - } - static node *get(std::vector& sequence, const Key& key, shared_memory_holder pMemory) { - return key >= 0 ? get_idx::get(sequence, static_cast(key), pMemory) : 0; - } - }; + static node* get(std::vector& sequence, const Key& key, + shared_memory_holder pMemory) { + if (key > sequence.size()) + return 0; + if (key == sequence.size()) + sequence.push_back(&pMemory->create_node()); + return sequence[key]; + } +}; - // indexing - template - inline node& node_data::get(const Key& key, shared_memory_holder pMemory) const - { - switch(m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - return pMemory->create_node(); - case NodeType::Sequence: - if(node *pNode = get_idx::get(m_sequence, key, pMemory)) - return *pNode; - return pMemory->create_node(); - case NodeType::Scalar: - throw BadSubscript(); - } +template +struct get_idx >::type> { + static node* get(const std::vector& sequence, const Key& key, + shared_memory_holder pMemory) { + return key >= 0 ? get_idx::get( + sequence, static_cast(key), pMemory) + : 0; + } + static node* get(std::vector& sequence, const Key& key, + shared_memory_holder pMemory) { + return key >= 0 ? get_idx::get( + sequence, static_cast(key), pMemory) + : 0; + } +}; - for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { - if(equals(*it->first, key, pMemory)) - return *it->second; - } - - return pMemory->create_node(); - } - - template - inline node& node_data::get(const Key& key, shared_memory_holder pMemory) - { - switch(m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - case NodeType::Sequence: - if(node *pNode = get_idx::get(m_sequence, key, pMemory)) { - m_type = NodeType::Sequence; - return *pNode; - } - - convert_to_map(pMemory); - break; - case NodeType::Scalar: - throw BadSubscript(); - } - - for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { - if(equals(*it->first, key, pMemory)) - return *it->second; - } - - node& k = convert_to_node(key, pMemory); - node& v = pMemory->create_node(); - insert_map_pair(k, v); - return v; - } - - template - inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) - { - if(m_type != NodeType::Map) - 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); - return true; - } - } - - return false; - } - - // map - template - inline void node_data::force_insert(const Key& key, const Value& value, shared_memory_holder pMemory) - { - switch(m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - case NodeType::Sequence: - convert_to_map(pMemory); - break; - case NodeType::Scalar: - throw BadInsert(); - } - - node& k = convert_to_node(key, pMemory); - node& v = convert_to_node(value, pMemory); - insert_map_pair(k, v); - } +// indexing +template +inline node& node_data::get(const Key& key, + shared_memory_holder pMemory) const { + switch (m_type) { + case NodeType::Map: + break; + case NodeType::Undefined: + case NodeType::Null: + return pMemory->create_node(); + case NodeType::Sequence: + if (node* pNode = get_idx::get(m_sequence, key, pMemory)) + return *pNode; + return pMemory->create_node(); + case NodeType::Scalar: + throw BadSubscript(); + } - template - inline bool node_data::equals(node& node, const T& rhs, shared_memory_holder pMemory) - { - T lhs; - if(convert::decode(Node(node, pMemory), lhs)) - return lhs == rhs; - return false; - } - - inline bool node_data::equals(node& node, const char *rhs, shared_memory_holder pMemory) - { - return equals(node, rhs, pMemory); - } + for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { + if (equals(*it->first, key, pMemory)) + return *it->second; + } - template - inline node& node_data::convert_to_node(const T& rhs, shared_memory_holder pMemory) - { - Node value = convert::encode(rhs); - value.EnsureNodeExists(); - pMemory->merge(*value.m_pMemory); - return *value.m_pNode; - } - } + return pMemory->create_node(); } -#endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +template +inline node& node_data::get(const Key& key, shared_memory_holder pMemory) { + switch (m_type) { + case NodeType::Map: + break; + case NodeType::Undefined: + case NodeType::Null: + case NodeType::Sequence: + if (node* pNode = get_idx::get(m_sequence, key, pMemory)) { + m_type = NodeType::Sequence; + return *pNode; + } + + convert_to_map(pMemory); + break; + case NodeType::Scalar: + throw BadSubscript(); + } + + for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { + if (equals(*it->first, key, pMemory)) + return *it->second; + } + + node& k = convert_to_node(key, pMemory); + node& v = pMemory->create_node(); + insert_map_pair(k, v); + return v; +} + +template +inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) { + if (m_type != NodeType::Map) + 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); + return true; + } + } + + return false; +} + +// map +template +inline void node_data::force_insert(const Key& key, const Value& value, + shared_memory_holder pMemory) { + switch (m_type) { + case NodeType::Map: + break; + case NodeType::Undefined: + case NodeType::Null: + case NodeType::Sequence: + convert_to_map(pMemory); + break; + case NodeType::Scalar: + throw BadInsert(); + } + + node& k = convert_to_node(key, pMemory); + node& v = convert_to_node(value, pMemory); + insert_map_pair(k, v); +} + +template +inline bool node_data::equals(node& node, const T& rhs, + shared_memory_holder pMemory) { + T lhs; + if (convert::decode(Node(node, pMemory), lhs)) + return lhs == rhs; + return false; +} + +inline bool node_data::equals(node& node, const char* rhs, + shared_memory_holder pMemory) { + return equals(node, rhs, pMemory); +} + +template +inline node& node_data::convert_to_node(const T& rhs, + shared_memory_holder pMemory) { + Node value = convert::encode(rhs); + value.EnsureNodeExists(); + pMemory->merge(*value.m_pMemory); + return *value.m_pNode; +} +} +} + +#endif // NODE_DETAIL_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/detail/iterator.h b/include/yaml-cpp/node/detail/iterator.h index dc699f4..6c0d4b6 100644 --- a/include/yaml-cpp/node/detail/iterator.h +++ b/include/yaml-cpp/node/detail/iterator.h @@ -1,64 +1,66 @@ #ifndef 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 #endif - #include "yaml-cpp/dll.h" #include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/detail/node_iterator.h" #include #include -namespace YAML -{ - namespace detail - { - struct iterator_value; +namespace YAML { +namespace detail { +struct iterator_value; - template - class iterator_base: public boost::iterator_adaptor< - iterator_base, - node_iterator, - V, - std::forward_iterator_tag, - V> - { - private: - template 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 - iterator_base(const iterator_base& rhs, typename boost::enable_if, enabler>::type = enabler()): iterator_base::iterator_adaptor_(rhs.base()), m_pMemory(rhs.m_pMemory) {} - - private: - friend class boost::iterator_core_access; +template +class iterator_base + : public boost::iterator_adaptor, node_iterator, V, + std::forward_iterator_tag, V> { + private: + template + friend class iterator_base; + struct enabler {}; + typedef typename iterator_base::base_type base_type; - void increment() { this->base_reference() = boost::next(this->base()); } - - value_type dereference() const { - const typename base_type::value_type& v = *this->base(); - if(v.pNode) - 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)); - return value_type(); - } - - private: - shared_memory_holder m_pMemory; - }; - } + 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 + iterator_base( + const iterator_base& rhs, + typename boost::enable_if, 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()); } + + value_type dereference() const { + const typename base_type::value_type& v = *this->base(); + if (v.pNode) + 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)); + return value_type(); + } + + 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 diff --git a/include/yaml-cpp/node/detail/iterator_fwd.h b/include/yaml-cpp/node/detail/iterator_fwd.h index c4efb2c..c54a258 100644 --- a/include/yaml-cpp/node/detail/iterator_fwd.h +++ b/include/yaml-cpp/node/detail/iterator_fwd.h @@ -1,27 +1,28 @@ #ifndef 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 #endif - #include "yaml-cpp/dll.h" #include #include #include -namespace YAML -{ - class node; - - namespace detail { - struct iterator_value; - template class iterator_base; - } +namespace YAML { +class node; - typedef detail::iterator_base iterator; - typedef detail::iterator_base const_iterator; +namespace detail { +struct iterator_value; +template +class iterator_base; } -#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +typedef detail::iterator_base iterator; +typedef detail::iterator_base const_iterator; +} + +#endif // VALUE_DETAIL_ITERATOR_FWD_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/detail/memory.h b/include/yaml-cpp/node/detail/memory.h index 243a81a..4584add 100644 --- a/include/yaml-cpp/node/detail/memory.h +++ b/include/yaml-cpp/node/detail/memory.h @@ -1,7 +1,9 @@ #ifndef 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 #endif @@ -9,31 +11,29 @@ #include #include -namespace YAML -{ - namespace detail - { - class memory { - public: - node& create_node(); - void merge(const memory& rhs); - - private: - typedef std::set Nodes; - Nodes m_nodes; - }; +namespace YAML { +namespace detail { +class memory { + public: + node& create_node(); + void merge(const memory& rhs); - class memory_holder { - public: - memory_holder(): m_pMemory(new memory) {} - - node& create_node() { return m_pMemory->create_node(); } - void merge(memory_holder& rhs); - - private: - boost::shared_ptr m_pMemory; - }; - } + private: + typedef std::set Nodes; + Nodes m_nodes; +}; + +class memory_holder { + public: + memory_holder() : m_pMemory(new memory) {} + + node& create_node() { return m_pMemory->create_node(); } + void merge(memory_holder& rhs); + + private: + boost::shared_ptr m_pMemory; +}; +} } -#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#endif // VALUE_DETAIL_MEMORY_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/detail/node.h b/include/yaml-cpp/node/detail/node.h index ce3a76d..20be18c 100644 --- a/include/yaml-cpp/node/detail/node.h +++ b/include/yaml-cpp/node/detail/node.h @@ -1,11 +1,12 @@ #ifndef 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 #endif - #include "yaml-cpp/dll.h" #include "yaml-cpp/node/type.h" #include "yaml-cpp/node/ptr.h" @@ -13,118 +14,134 @@ #include #include -namespace YAML -{ - namespace detail - { - class node: private boost::noncopyable - { - public: - node(): m_pRef(new node_ref) {} +namespace YAML { +namespace detail { +class node : private boost::noncopyable { + public: + node() : m_pRef(new node_ref) {} - bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; } - const node_ref *ref() const { return m_pRef.get(); } - - bool is_defined() const { return m_pRef->is_defined(); } - NodeType::value type() const { return m_pRef->type(); } - - const std::string& scalar() const { return m_pRef->scalar(); } - const std::string& tag() const { return m_pRef->tag(); } - - void mark_defined() { - if(is_defined()) - return; - - m_pRef->mark_defined(); - for(nodes::iterator it=m_dependencies.begin();it!=m_dependencies.end();++it) - (*it)->mark_defined(); - m_dependencies.clear(); - } - - void add_dependency(node& rhs) { - if(is_defined()) - rhs.mark_defined(); - else - m_dependencies.insert(&rhs); - } - - void set_ref(const node& rhs) { - if(rhs.is_defined()) - mark_defined(); - m_pRef = rhs.m_pRef; - } - void set_data(const node& rhs) { - if(rhs.is_defined()) - mark_defined(); - m_pRef->set_data(*rhs.m_pRef); - } - - void set_type(NodeType::value type) { - if(type != NodeType::Undefined) - mark_defined(); - m_pRef->set_type(type); - } - void set_null() { - mark_defined(); - m_pRef->set_null(); - } - void set_scalar(const std::string& scalar) { - mark_defined(); - m_pRef->set_scalar(scalar); - } - void set_tag(const std::string& tag) { - mark_defined(); - m_pRef->set_tag(tag); - } + bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; } + const node_ref* ref() const { return m_pRef.get(); } - // size/iterator - std::size_t size() const { return m_pRef->size(); } - - const_node_iterator begin() const { return static_cast(*m_pRef).begin(); } - node_iterator begin() { return m_pRef->begin(); } - - const_node_iterator end() const { return static_cast(*m_pRef).end(); } - node_iterator end() { return m_pRef->end(); } + bool is_defined() const { return m_pRef->is_defined(); } + NodeType::value type() const { return m_pRef->type(); } - // sequence - void push_back(node& node, shared_memory_holder pMemory) { - m_pRef->push_back(node, pMemory); - node.add_dependency(*this); - } - void insert(node& key, node& value, shared_memory_holder pMemory) { - m_pRef->insert(key, value, pMemory); - key.add_dependency(*this); - value.add_dependency(*this); - } + const std::string& scalar() const { return m_pRef->scalar(); } + const std::string& tag() const { return m_pRef->tag(); } - // indexing - template node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast(*m_pRef).get(key, pMemory); } - template node& get(const Key& key, shared_memory_holder pMemory) { - node& value = m_pRef->get(key, pMemory); - value.add_dependency(*this); - return value; - } - template bool remove(const Key& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); } - - node& get(node& key, shared_memory_holder pMemory) const { return static_cast(*m_pRef).get(key, pMemory); } - node& get(node& key, shared_memory_holder pMemory) { - node& value = m_pRef->get(key, pMemory); - key.add_dependency(*this); - value.add_dependency(*this); - return value; - } - bool remove(node& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); } + void mark_defined() { + if (is_defined()) + return; - // map - template - void force_insert(const Key& key, const Value& value, shared_memory_holder pMemory){ m_pRef->force_insert(key, value, pMemory); } + m_pRef->mark_defined(); + for (nodes::iterator it = m_dependencies.begin(); + it != m_dependencies.end(); ++it) + (*it)->mark_defined(); + m_dependencies.clear(); + } - private: - shared_node_ref m_pRef; - typedef std::set nodes; - nodes m_dependencies; - }; - } + void add_dependency(node& rhs) { + if (is_defined()) + rhs.mark_defined(); + else + m_dependencies.insert(&rhs); + } + + void set_ref(const node& rhs) { + if (rhs.is_defined()) + mark_defined(); + m_pRef = rhs.m_pRef; + } + void set_data(const node& rhs) { + if (rhs.is_defined()) + mark_defined(); + m_pRef->set_data(*rhs.m_pRef); + } + + void set_type(NodeType::value type) { + if (type != NodeType::Undefined) + mark_defined(); + m_pRef->set_type(type); + } + void set_null() { + mark_defined(); + m_pRef->set_null(); + } + void set_scalar(const std::string& scalar) { + mark_defined(); + m_pRef->set_scalar(scalar); + } + void set_tag(const std::string& tag) { + mark_defined(); + m_pRef->set_tag(tag); + } + + // size/iterator + std::size_t size() const { return m_pRef->size(); } + + const_node_iterator begin() const { + return static_cast(*m_pRef).begin(); + } + node_iterator begin() { return m_pRef->begin(); } + + const_node_iterator end() const { + return static_cast(*m_pRef).end(); + } + node_iterator end() { return m_pRef->end(); } + + // sequence + void push_back(node& node, shared_memory_holder pMemory) { + m_pRef->push_back(node, pMemory); + node.add_dependency(*this); + } + void insert(node& key, node& value, shared_memory_holder pMemory) { + m_pRef->insert(key, value, pMemory); + key.add_dependency(*this); + value.add_dependency(*this); + } + + // indexing + template + node& get(const Key& key, shared_memory_holder pMemory) const { + return static_cast(*m_pRef).get(key, pMemory); + } + template + node& get(const Key& key, shared_memory_holder pMemory) { + node& value = m_pRef->get(key, pMemory); + value.add_dependency(*this); + return value; + } + template + bool remove(const Key& key, shared_memory_holder pMemory) { + return m_pRef->remove(key, pMemory); + } + + node& get(node& key, shared_memory_holder pMemory) const { + return static_cast(*m_pRef).get(key, pMemory); + } + node& get(node& key, shared_memory_holder pMemory) { + node& value = m_pRef->get(key, pMemory); + key.add_dependency(*this); + value.add_dependency(*this); + return value; + } + bool remove(node& key, shared_memory_holder pMemory) { + return m_pRef->remove(key, pMemory); + } + + // map + template + 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 nodes; + nodes m_dependencies; +}; +} } -#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#endif // NODE_DETAIL_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/detail/node_data.h b/include/yaml-cpp/node/detail/node_data.h index 413da5f..50dd85a 100644 --- a/include/yaml-cpp/node/detail/node_data.h +++ b/include/yaml-cpp/node/detail/node_data.h @@ -1,11 +1,12 @@ #ifndef 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 #endif - #include "yaml-cpp/dll.h" #include "yaml-cpp/node/iterator.h" #include "yaml-cpp/node/ptr.h" @@ -15,96 +16,99 @@ #include #include -namespace YAML -{ - namespace detail - { - class node_data: private boost::noncopyable - { - public: - node_data(); - - void mark_defined(); - void set_type(NodeType::value type); - void set_tag(const std::string& tag); - void set_null(); - void set_scalar(const std::string& scalar); - - 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& tag() const { return m_tag; } - - // size/iterator - std::size_t size() const; - - const_node_iterator begin() const; - node_iterator begin(); - - const_node_iterator end() const; - node_iterator end(); +namespace YAML { +namespace detail { +class node_data : private boost::noncopyable { + public: + node_data(); - // sequence - void push_back(node& node, shared_memory_holder pMemory); - void insert(node& key, node& value, shared_memory_holder pMemory); + void mark_defined(); + void set_type(NodeType::value type); + void set_tag(const std::string& tag); + void set_null(); + void set_scalar(const std::string& scalar); - // indexing - template node& get(const Key& key, shared_memory_holder pMemory) const; - template node& get(const Key& key, shared_memory_holder pMemory); - template bool remove(const Key& key, shared_memory_holder pMemory); - - node& get(node& key, shared_memory_holder pMemory) const; - node& get(node& key, shared_memory_holder pMemory); - bool remove(node& key, shared_memory_holder pMemory); - - // map - template - void force_insert(const Key& key, const Value& value, shared_memory_holder pMemory); - - public: - static std::string empty_scalar; - - private: - void compute_seq_size() const; - void compute_map_size() const; + 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& tag() const { return m_tag; } - void reset_sequence(); - void reset_map(); - - void insert_map_pair(node& key, node& value); - void convert_to_map(shared_memory_holder pMemory); - void convert_sequence_to_map(shared_memory_holder pMemory); - - template - static bool equals(node& node, const T& rhs, shared_memory_holder pMemory); - static bool equals(node& node, const char *rhs, shared_memory_holder pMemory); - - template - static node& convert_to_node(const T& rhs, shared_memory_holder pMemory); + // size/iterator + std::size_t size() const; - private: - bool m_isDefined; - NodeType::value m_type; - std::string m_tag; - - // scalar - std::string m_scalar; - - // sequence - typedef std::vector node_seq; - node_seq m_sequence; - - mutable std::size_t m_seqSize; - - // map - typedef std::map node_map; - node_map m_map; - - typedef std::pair kv_pair; - typedef std::list kv_pairs; - mutable kv_pairs m_undefinedPairs; - }; - } + const_node_iterator begin() const; + node_iterator begin(); + + const_node_iterator end() const; + node_iterator end(); + + // sequence + void push_back(node& node, shared_memory_holder pMemory); + void insert(node& key, node& value, shared_memory_holder pMemory); + + // indexing + template + node& get(const Key& key, shared_memory_holder pMemory) const; + template + node& get(const Key& key, shared_memory_holder pMemory); + template + bool remove(const Key& key, shared_memory_holder pMemory); + + node& get(node& key, shared_memory_holder pMemory) const; + node& get(node& key, shared_memory_holder pMemory); + bool remove(node& key, shared_memory_holder pMemory); + + // map + template + void force_insert(const Key& key, const Value& value, + shared_memory_holder pMemory); + + public: + static std::string empty_scalar; + + private: + void compute_seq_size() const; + void compute_map_size() const; + + void reset_sequence(); + void reset_map(); + + void insert_map_pair(node& key, node& value); + void convert_to_map(shared_memory_holder pMemory); + void convert_sequence_to_map(shared_memory_holder pMemory); + + template + static bool equals(node& node, const T& rhs, shared_memory_holder pMemory); + static bool equals(node& node, const char* rhs, shared_memory_holder pMemory); + + template + static node& convert_to_node(const T& rhs, shared_memory_holder pMemory); + + private: + bool m_isDefined; + NodeType::value m_type; + std::string m_tag; + + // scalar + std::string m_scalar; + + // sequence + typedef std::vector node_seq; + node_seq m_sequence; + + mutable std::size_t m_seqSize; + + // map + typedef std::map node_map; + node_map m_map; + + typedef std::pair kv_pair; + typedef std::list 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 diff --git a/include/yaml-cpp/node/detail/node_iterator.h b/include/yaml-cpp/node/detail/node_iterator.h index 294921b..6147f63 100644 --- a/include/yaml-cpp/node/detail/node_iterator.h +++ b/include/yaml-cpp/node/detail/node_iterator.h @@ -1,11 +1,12 @@ #ifndef 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 #endif - #include "yaml-cpp/dll.h" #include "yaml-cpp/node/ptr.h" #include @@ -14,126 +15,143 @@ #include #include -namespace YAML -{ - namespace detail - { - struct iterator_type { enum value { None, Sequence, Map }; }; - - template - struct node_iterator_value: public std::pair { - typedef std::pair kv; - - node_iterator_value(): kv(), pNode(0) {} - explicit node_iterator_value(V& rhs): kv(), pNode(&rhs) {} - explicit node_iterator_value(V& key, V& value): kv(&key, &value), pNode(0) {} - - V& operator *() const { return *pNode; } - V& operator ->() const { return *pNode; } - - V *pNode; - }; - - typedef std::vector node_seq; - typedef std::map node_map; - - template - struct node_iterator_type { - typedef node_seq::iterator seq; - typedef node_map::iterator map; - }; - - template - struct node_iterator_type { - typedef node_seq::const_iterator seq; - typedef node_map::const_iterator map; - }; - +namespace YAML { +namespace detail { +struct iterator_type { + enum value { + None, + Sequence, + Map + }; +}; - template - class node_iterator_base: public boost::iterator_facade< - node_iterator_base, - node_iterator_value, - std::forward_iterator_tag, - node_iterator_value > - { - private: - struct enabler {}; - - public: - typedef typename node_iterator_type::seq SeqIter; - typedef typename node_iterator_type::map MapIter; - typedef node_iterator_value value_type; - - node_iterator_base(): m_type(iterator_type::None) {} - explicit node_iterator_base(SeqIter seqIt): 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) { - m_mapIt = increment_until_defined(m_mapIt); - } - - template - node_iterator_base(const node_iterator_base& rhs, typename boost::enable_if, enabler>::type = enabler()) - : m_type(rhs.m_type), m_seqIt(rhs.m_seqIt), m_mapIt(rhs.m_mapIt), m_mapEnd(rhs.m_mapEnd) {} - - private: - friend class boost::iterator_core_access; - template friend class node_iterator_base; - - template - bool equal(const node_iterator_base& rhs) const { - if(m_type != rhs.m_type) - return false; - - switch(m_type) { - case iterator_type::None: return true; - case iterator_type::Sequence: return m_seqIt == rhs.m_seqIt; - case iterator_type::Map: return m_mapIt == rhs.m_mapIt; - } - return true; - } - - void increment() { - switch(m_type) { - case iterator_type::None: break; - case iterator_type::Sequence: - ++m_seqIt; - break; - case iterator_type::Map: - ++m_mapIt; - m_mapIt = increment_until_defined(m_mapIt); - break; - } - } +template +struct node_iterator_value : public std::pair { + typedef std::pair kv; - value_type dereference() const { - switch(m_type) { - case iterator_type::None: return value_type(); - case iterator_type::Sequence: return value_type(**m_seqIt); - case iterator_type::Map: return value_type(*m_mapIt->first, *m_mapIt->second); - } - return value_type(); - } - - MapIter increment_until_defined(MapIter it) { - 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(); - } + node_iterator_value() : kv(), pNode(0) {} + explicit node_iterator_value(V& rhs) : kv(), pNode(&rhs) {} + explicit node_iterator_value(V& key, V& value) : kv(&key, &value), pNode(0) {} - private: - typename iterator_type::value m_type; + V& operator*() const { return *pNode; } + V& operator->() const { return *pNode; } - SeqIter m_seqIt; - MapIter m_mapIt, m_mapEnd; - }; + V* pNode; +}; - typedef node_iterator_base node_iterator; - typedef node_iterator_base const_node_iterator; - } +typedef std::vector node_seq; +typedef std::map node_map; + +template +struct node_iterator_type { + typedef node_seq::iterator seq; + typedef node_map::iterator map; +}; + +template +struct node_iterator_type { + typedef node_seq::const_iterator seq; + typedef node_map::const_iterator map; +}; + +template +class node_iterator_base + : public boost::iterator_facade< + node_iterator_base, node_iterator_value, + std::forward_iterator_tag, node_iterator_value > { + private: + struct enabler {}; + + public: + typedef typename node_iterator_type::seq SeqIter; + typedef typename node_iterator_type::map MapIter; + typedef node_iterator_value value_type; + + node_iterator_base() : m_type(iterator_type::None) {} + explicit node_iterator_base(SeqIter seqIt) + : 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) { + m_mapIt = increment_until_defined(m_mapIt); + } + + template + node_iterator_base( + const node_iterator_base& rhs, + typename boost::enable_if, enabler>::type = + enabler()) + : m_type(rhs.m_type), + m_seqIt(rhs.m_seqIt), + m_mapIt(rhs.m_mapIt), + m_mapEnd(rhs.m_mapEnd) {} + + private: + friend class boost::iterator_core_access; + template + friend class node_iterator_base; + + template + bool equal(const node_iterator_base& rhs) const { + if (m_type != rhs.m_type) + return false; + + switch (m_type) { + case iterator_type::None: + return true; + case iterator_type::Sequence: + return m_seqIt == rhs.m_seqIt; + case iterator_type::Map: + return m_mapIt == rhs.m_mapIt; + } + return true; + } + + void increment() { + switch (m_type) { + case iterator_type::None: + break; + case iterator_type::Sequence: + ++m_seqIt; + break; + case iterator_type::Map: + ++m_mapIt; + m_mapIt = increment_until_defined(m_mapIt); + break; + } + } + + value_type dereference() const { + switch (m_type) { + case iterator_type::None: + return value_type(); + case iterator_type::Sequence: + return value_type(**m_seqIt); + case iterator_type::Map: + return value_type(*m_mapIt->first, *m_mapIt->second); + } + return value_type(); + } + + MapIter increment_until_defined(MapIter it) { + 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_iterator; +typedef node_iterator_base 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 diff --git a/include/yaml-cpp/node/detail/node_ref.h b/include/yaml-cpp/node/detail/node_ref.h index 64cdb98..2b577a3 100644 --- a/include/yaml-cpp/node/detail/node_ref.h +++ b/include/yaml-cpp/node/detail/node_ref.h @@ -1,69 +1,93 @@ #ifndef 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 #endif - #include "yaml-cpp/dll.h" #include "yaml-cpp/node/type.h" #include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/detail/node_data.h" #include -namespace YAML -{ - namespace detail - { - class node_ref: private boost::noncopyable - { - public: - node_ref(): m_pData(new node_data) {} - - bool is_defined() const { return m_pData->is_defined(); } - NodeType::value type() const { return m_pData->type(); } - const std::string& scalar() const { return m_pData->scalar(); } - const std::string& tag() const { return m_pData->tag(); } - - void mark_defined() { m_pData->mark_defined(); } - void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; } - - void set_type(NodeType::value type) { m_pData->set_type(type); } - void set_tag(const std::string& tag) { m_pData->set_tag(tag); } - void set_null() { m_pData->set_null(); } - void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); } - - // size/iterator - std::size_t size() const { return m_pData->size(); } - - const_node_iterator begin() const { return static_cast(*m_pData).begin(); } - node_iterator begin() {return m_pData->begin(); } - - const_node_iterator end() const { return static_cast(*m_pData).end(); } - node_iterator end() {return m_pData->end(); } +namespace YAML { +namespace detail { +class node_ref : private boost::noncopyable { + public: + node_ref() : m_pData(new node_data) {} - // sequence - 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 node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast(*m_pData).get(key, pMemory); } - template node& get(const Key& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); } - template 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(*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 - void force_insert(const Key& key, const Value& value, shared_memory_holder pMemory) { m_pData->force_insert(key, value, pMemory); } + bool is_defined() const { return m_pData->is_defined(); } + NodeType::value type() const { return m_pData->type(); } + const std::string& scalar() const { return m_pData->scalar(); } + const std::string& tag() const { return m_pData->tag(); } - private: - shared_node_data m_pData; - }; - } + void mark_defined() { m_pData->mark_defined(); } + void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; } + + void set_type(NodeType::value type) { m_pData->set_type(type); } + void set_tag(const std::string& tag) { m_pData->set_tag(tag); } + void set_null() { m_pData->set_null(); } + void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); } + + // size/iterator + std::size_t size() const { return m_pData->size(); } + + const_node_iterator begin() const { + return static_cast(*m_pData).begin(); + } + node_iterator begin() { return m_pData->begin(); } + + const_node_iterator end() const { + return static_cast(*m_pData).end(); + } + node_iterator end() { return m_pData->end(); } + + // sequence + 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 + node& get(const Key& key, shared_memory_holder pMemory) const { + return static_cast(*m_pData).get(key, pMemory); + } + template + node& get(const Key& key, shared_memory_holder pMemory) { + return m_pData->get(key, pMemory); + } + template + 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(*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 + 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 diff --git a/include/yaml-cpp/node/emit.h b/include/yaml-cpp/node/emit.h index 7abf80b..2e4b98d 100644 --- a/include/yaml-cpp/node/emit.h +++ b/include/yaml-cpp/node/emit.h @@ -1,23 +1,23 @@ #ifndef 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 #endif #include #include -namespace YAML -{ - class Emitter; - class Node; - - Emitter& operator << (Emitter& out, const Node& node); - std::ostream& operator << (std::ostream& out, const Node& node); - - std::string Dump(const Node& node); +namespace YAML { +class Emitter; +class Node; + +Emitter& operator<<(Emitter& 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 - +#endif // NODE_EMIT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/impl.h b/include/yaml-cpp/node/impl.h index 41c2fcd..425e37f 100644 --- a/include/yaml-cpp/node/impl.h +++ b/include/yaml-cpp/node/impl.h @@ -1,11 +1,12 @@ #ifndef 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 #endif - #include "yaml-cpp/node/node.h" #include "yaml-cpp/node/iterator.h" #include "yaml-cpp/node/detail/memory.h" @@ -13,439 +14,406 @@ #include "yaml-cpp/exceptions.h" #include -namespace YAML -{ - inline Node::Node(): m_isValid(true), m_pNode(NULL) - { - } - - inline Node::Node(NodeType::value type): m_isValid(true), m_pMemory(new detail::memory_holder), m_pNode(&m_pMemory->create_node()) - { - m_pNode->set_type(type); - } - - template - inline Node::Node(const T& rhs): m_isValid(true), m_pMemory(new detail::memory_holder), 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) - { - } +namespace YAML { +inline Node::Node() : m_isValid(true), m_pNode(NULL) {} - inline Node::Node(const Node& rhs): m_isValid(rhs.m_isValid), 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() - { - } - - inline void Node::EnsureNodeExists() const - { - if(!m_isValid) - throw InvalidNode(); - if(!m_pNode) { - 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(); - return m_pNode ? m_pNode->is_defined() : true; - } - - inline NodeType::value Node::Type() const - { - if(!m_isValid) - throw InvalidNode(); - return m_pNode ? m_pNode->type() : NodeType::Null; - } - - // access - - // template helpers - template - struct as_if { - explicit as_if(const Node& node_): node(node_) {} - const Node& node; - - const T operator()(const S& fallback) const { - if(!node.m_pNode) - return fallback; - - T t; - if(convert::decode(node, t)) - return t; - return fallback; - } - }; - - template - struct as_if { - explicit as_if(const Node& node_): node(node_) {} - const Node& node; - - const std::string operator()(const S& fallback) const { - if(node.Type() != NodeType::Scalar) - return fallback; - return node.Scalar(); - } - }; - - template - struct as_if { - explicit as_if(const Node& node_): node(node_) {} - const Node& node; - - const T operator()() const { - if(!node.m_pNode) - throw TypedBadConversion(); - - T t; - if(convert::decode(node, t)) - return t; - throw TypedBadConversion(); - } - }; - - template<> - struct as_if { - explicit as_if(const Node& node_): node(node_) {} - const Node& node; - - const std::string operator()() const { - if(node.Type() != NodeType::Scalar) - throw TypedBadConversion(); - return node.Scalar(); - } - }; - - // access functions - template - inline const T Node::as() const - { - if(!m_isValid) - throw InvalidNode(); - return as_if(*this)(); - } - - template - inline const T Node::as(const S& fallback) const - { - if(!m_isValid) - throw InvalidNode(); - return as_if(*this)(fallback); - } - - inline const std::string& Node::Scalar() const - { - if(!m_isValid) - throw InvalidNode(); - return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar; - } - - inline const std::string& Node::Tag() const - { - if(!m_isValid) - throw InvalidNode(); - return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar; - } - - inline void Node::SetTag(const std::string& tag) - { - if(!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - m_pNode->set_tag(tag); - } - - // assignment - inline bool Node::is(const Node& rhs) const - { - if(!m_isValid || !rhs.m_isValid) - throw InvalidNode(); - if(!m_pNode || !rhs.m_pNode) - return false; - return m_pNode->is(*rhs.m_pNode); - } - - template - inline Node& Node::operator=(const T& rhs) - { - if(!m_isValid) - throw InvalidNode(); - Assign(rhs); - return *this; - } - - inline void Node::reset(const YAML::Node& rhs) - { - if(!m_isValid || !rhs.m_isValid) - throw InvalidNode(); - m_pMemory = rhs.m_pMemory; - m_pNode = rhs.m_pNode; - } - - template - inline void Node::Assign(const T& rhs) - { - if(!m_isValid) - throw InvalidNode(); - AssignData(convert::encode(rhs)); - } - - template<> - inline void Node::Assign(const std::string& rhs) - { - if(!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - m_pNode->set_scalar(rhs); - } - - inline void Node::Assign(const char *rhs) - { - if(!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - m_pNode->set_scalar(rhs); - } - - inline void Node::Assign(char *rhs) - { - if(!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - m_pNode->set_scalar(rhs); - } - - inline Node& Node::operator=(const Node& rhs) - { - if(!m_isValid || !rhs.m_isValid) - throw InvalidNode(); - if(is(rhs)) - return *this; - AssignNode(rhs); - return *this; - } - - inline void Node::AssignData(const Node& rhs) - { - if(!m_isValid || !rhs.m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - rhs.EnsureNodeExists(); - - m_pNode->set_data(*rhs.m_pNode); - m_pMemory->merge(*rhs.m_pMemory); - } - - inline void Node::AssignNode(const Node& rhs) - { - if(!m_isValid || !rhs.m_isValid) - throw InvalidNode(); - rhs.EnsureNodeExists(); - - if(!m_pNode) { - m_pNode = rhs.m_pNode; - m_pMemory = rhs.m_pMemory; - return; - } - - m_pNode->set_ref(*rhs.m_pNode); - m_pMemory->merge(*rhs.m_pMemory); - m_pNode = rhs.m_pNode; - } - - // size/iterator - inline std::size_t Node::size() const - { - if(!m_isValid) - throw InvalidNode(); - return m_pNode ? m_pNode->size() : 0; - } - - inline const_iterator Node::begin() const - { - if(!m_isValid) - throw InvalidNode(); - return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory) : const_iterator(); - } - - inline iterator Node::begin() - { - if(!m_isValid) - throw InvalidNode(); - return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator(); - } - - inline const_iterator Node::end() const - { - if(!m_isValid) - throw InvalidNode(); - return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator(); - } - - inline iterator Node::end() - { - if(!m_isValid) - throw InvalidNode(); - return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator(); - } - - // sequence - template - inline void Node::push_back(const T& rhs) - { - if(!m_isValid) - throw InvalidNode(); - push_back(Node(rhs)); - } - - inline void Node::push_back(const Node& rhs) - { - if(!m_isValid || !rhs.m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - rhs.EnsureNodeExists(); - - m_pNode->push_back(*rhs.m_pNode, m_pMemory); - m_pMemory->merge(*rhs.m_pMemory); - } - - // helpers for indexing - namespace detail { - template - struct to_value_t { - explicit to_value_t(const T& t_): t(t_) {} - const T& t; - typedef const T& return_type; - - const T& operator()() const { return t; } - }; - - template<> - struct to_value_t { - explicit to_value_t(const char *t_): t(t_) {} - const char *t; - typedef std::string return_type; - - const std::string operator()() const { return t; } - }; - - template<> - struct to_value_t { - explicit to_value_t(char *t_): t(t_) {} - const char *t; - typedef std::string return_type; - - const std::string operator()() const { return t; } - }; - - template - struct to_value_t { - explicit to_value_t(const char *t_): t(t_) {} - const char *t; - typedef std::string return_type; - - const std::string operator()() const { return t; } - }; - - // converts C-strings to std::strings so they can be copied - template - inline typename to_value_t::return_type to_value(const T& t) { - return to_value_t(t)(); - } - } - - // indexing - template - inline const Node Node::operator[](const Key& key) const - { - if(!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - detail::node& value = static_cast(*m_pNode).get(detail::to_value(key), m_pMemory); - return Node(value, m_pMemory); - } - - template - inline Node Node::operator[](const Key& key) - { - if(!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory); - return Node(value, m_pMemory); - } - - template - inline bool Node::remove(const Key& key) - { - if(!m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - return m_pNode->remove(detail::to_value(key), m_pMemory); - } - - inline const Node Node::operator[](const Node& key) const - { - if(!m_isValid || !key.m_isValid) - throw InvalidNode(); - EnsureNodeExists(); - key.EnsureNodeExists(); - detail::node& value = static_cast(*m_pNode).get(*key.m_pNode, m_pMemory); - return Node(value, m_pMemory); - } - - inline Node Node::operator[](const Node& key) - { - if(!m_isValid || !key.m_isValid) - throw InvalidNode(); - 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 - 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); - } +inline Node::Node(NodeType::value type) + : m_isValid(true), + m_pMemory(new detail::memory_holder), + m_pNode(&m_pMemory->create_node()) { + m_pNode->set_type(type); } -#endif // NODE_IMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +template +inline Node::Node(const T& rhs) + : m_isValid(true), + m_pMemory(new detail::memory_holder), + 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 Node& rhs) + : m_isValid(rhs.m_isValid), + 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() {} + +inline void Node::EnsureNodeExists() const { + if (!m_isValid) + throw InvalidNode(); + if (!m_pNode) { + 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(); + return m_pNode ? m_pNode->is_defined() : true; +} + +inline NodeType::value Node::Type() const { + if (!m_isValid) + throw InvalidNode(); + return m_pNode ? m_pNode->type() : NodeType::Null; +} + +// access + +// template helpers +template +struct as_if { + explicit as_if(const Node& node_) : node(node_) {} + const Node& node; + + const T operator()(const S& fallback) const { + if (!node.m_pNode) + return fallback; + + T t; + if (convert::decode(node, t)) + return t; + return fallback; + } +}; + +template +struct as_if { + explicit as_if(const Node& node_) : node(node_) {} + const Node& node; + + const std::string operator()(const S& fallback) const { + if (node.Type() != NodeType::Scalar) + return fallback; + return node.Scalar(); + } +}; + +template +struct as_if { + explicit as_if(const Node& node_) : node(node_) {} + const Node& node; + + const T operator()() const { + if (!node.m_pNode) + throw TypedBadConversion(); + + T t; + if (convert::decode(node, t)) + return t; + throw TypedBadConversion(); + } +}; + +template <> +struct as_if { + explicit as_if(const Node& node_) : node(node_) {} + const Node& node; + + const std::string operator()() const { + if (node.Type() != NodeType::Scalar) + throw TypedBadConversion(); + return node.Scalar(); + } +}; + +// access functions +template +inline const T Node::as() const { + if (!m_isValid) + throw InvalidNode(); + return as_if(*this)(); +} + +template +inline const T Node::as(const S& fallback) const { + if (!m_isValid) + throw InvalidNode(); + return as_if(*this)(fallback); +} + +inline const std::string& Node::Scalar() const { + if (!m_isValid) + throw InvalidNode(); + return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar; +} + +inline const std::string& Node::Tag() const { + if (!m_isValid) + throw InvalidNode(); + return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar; +} + +inline void Node::SetTag(const std::string& tag) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + m_pNode->set_tag(tag); +} + +// assignment +inline bool Node::is(const Node& rhs) const { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(); + if (!m_pNode || !rhs.m_pNode) + return false; + return m_pNode->is(*rhs.m_pNode); +} + +template +inline Node& Node::operator=(const T& rhs) { + if (!m_isValid) + throw InvalidNode(); + Assign(rhs); + return *this; +} + +inline void Node::reset(const YAML::Node& rhs) { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(); + m_pMemory = rhs.m_pMemory; + m_pNode = rhs.m_pNode; +} + +template +inline void Node::Assign(const T& rhs) { + if (!m_isValid) + throw InvalidNode(); + AssignData(convert::encode(rhs)); +} + +template <> +inline void Node::Assign(const std::string& rhs) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + m_pNode->set_scalar(rhs); +} + +inline void Node::Assign(const char* rhs) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + m_pNode->set_scalar(rhs); +} + +inline void Node::Assign(char* rhs) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + m_pNode->set_scalar(rhs); +} + +inline Node& Node::operator=(const Node& rhs) { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(); + if (is(rhs)) + return *this; + AssignNode(rhs); + return *this; +} + +inline void Node::AssignData(const Node& rhs) { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + rhs.EnsureNodeExists(); + + m_pNode->set_data(*rhs.m_pNode); + m_pMemory->merge(*rhs.m_pMemory); +} + +inline void Node::AssignNode(const Node& rhs) { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(); + rhs.EnsureNodeExists(); + + if (!m_pNode) { + m_pNode = rhs.m_pNode; + m_pMemory = rhs.m_pMemory; + return; + } + + m_pNode->set_ref(*rhs.m_pNode); + m_pMemory->merge(*rhs.m_pMemory); + m_pNode = rhs.m_pNode; +} + +// size/iterator +inline std::size_t Node::size() const { + if (!m_isValid) + throw InvalidNode(); + return m_pNode ? m_pNode->size() : 0; +} + +inline const_iterator Node::begin() const { + if (!m_isValid) + throw InvalidNode(); + return m_pNode ? const_iterator(m_pNode->begin(), m_pMemory) + : const_iterator(); +} + +inline iterator Node::begin() { + if (!m_isValid) + throw InvalidNode(); + return m_pNode ? iterator(m_pNode->begin(), m_pMemory) : iterator(); +} + +inline const_iterator Node::end() const { + if (!m_isValid) + throw InvalidNode(); + return m_pNode ? const_iterator(m_pNode->end(), m_pMemory) : const_iterator(); +} + +inline iterator Node::end() { + if (!m_isValid) + throw InvalidNode(); + return m_pNode ? iterator(m_pNode->end(), m_pMemory) : iterator(); +} + +// sequence +template +inline void Node::push_back(const T& rhs) { + if (!m_isValid) + throw InvalidNode(); + push_back(Node(rhs)); +} + +inline void Node::push_back(const Node& rhs) { + if (!m_isValid || !rhs.m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + rhs.EnsureNodeExists(); + + m_pNode->push_back(*rhs.m_pNode, m_pMemory); + m_pMemory->merge(*rhs.m_pMemory); +} + +// helpers for indexing +namespace detail { +template +struct to_value_t { + explicit to_value_t(const T& t_) : t(t_) {} + const T& t; + typedef const T& return_type; + + const T& operator()() const { return t; } +}; + +template <> +struct to_value_t { + explicit to_value_t(const char* t_) : t(t_) {} + const char* t; + typedef std::string return_type; + + const std::string operator()() const { return t; } +}; + +template <> +struct to_value_t { + explicit to_value_t(char* t_) : t(t_) {} + const char* t; + typedef std::string return_type; + + const std::string operator()() const { return t; } +}; + +template +struct to_value_t { + explicit to_value_t(const char* t_) : t(t_) {} + const char* t; + typedef std::string return_type; + + const std::string operator()() const { return t; } +}; + +// converts C-strings to std::strings so they can be copied +template +inline typename to_value_t::return_type to_value(const T& t) { + return to_value_t(t)(); +} +} + +// indexing +template +inline const Node Node::operator[](const Key& key) const { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + detail::node& value = static_cast(*m_pNode) + .get(detail::to_value(key), m_pMemory); + return Node(value, m_pMemory); +} + +template +inline Node Node::operator[](const Key& key) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + detail::node& value = m_pNode->get(detail::to_value(key), m_pMemory); + return Node(value, m_pMemory); +} + +template +inline bool Node::remove(const Key& key) { + if (!m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + return m_pNode->remove(detail::to_value(key), m_pMemory); +} + +inline const Node Node::operator[](const Node& key) const { + if (!m_isValid || !key.m_isValid) + throw InvalidNode(); + EnsureNodeExists(); + key.EnsureNodeExists(); + detail::node& value = + static_cast(*m_pNode).get(*key.m_pNode, m_pMemory); + return Node(value, m_pMemory); +} + +inline Node Node::operator[](const Node& key) { + if (!m_isValid || !key.m_isValid) + throw InvalidNode(); + 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 +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 diff --git a/include/yaml-cpp/node/iterator.h b/include/yaml-cpp/node/iterator.h index 98c8851..366a9c8 100644 --- a/include/yaml-cpp/node/iterator.h +++ b/include/yaml-cpp/node/iterator.h @@ -1,11 +1,12 @@ #ifndef 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 #endif - #include "yaml-cpp/dll.h" #include "yaml-cpp/node/node.h" #include "yaml-cpp/node/detail/iterator_fwd.h" @@ -14,15 +15,17 @@ #include #include -namespace YAML -{ - namespace detail { - struct iterator_value: public Node, std::pair { - iterator_value() {} - explicit iterator_value(const Node& rhs): Node(rhs), std::pair(Node(Node::ZombieNode), Node(Node::ZombieNode)) {} - explicit iterator_value(const Node& key, const Node& value): Node(Node::ZombieNode), std::pair(key, value) {} - }; - } +namespace YAML { +namespace detail { +struct iterator_value : public Node, std::pair { + iterator_value() {} + explicit iterator_value(const Node& rhs) + : Node(rhs), + std::pair(Node(Node::ZombieNode), Node(Node::ZombieNode)) {} + explicit iterator_value(const Node& key, const Node& value) + : Node(Node::ZombieNode), std::pair(key, value) {} +}; +} } -#endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#endif // VALUE_ITERATOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/node.h b/include/yaml-cpp/node/node.h index b949850..75df149 100644 --- a/include/yaml-cpp/node/node.h +++ b/include/yaml-cpp/node/node.h @@ -1,11 +1,12 @@ #ifndef 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 #endif - #include "yaml-cpp/dll.h" #include "yaml-cpp/node/ptr.h" #include "yaml-cpp/node/type.h" @@ -13,104 +14,115 @@ #include "yaml-cpp/node/detail/bool_type.h" #include -namespace YAML -{ - class Node - { - public: - friend class NodeBuilder; - friend class NodeEvents; - friend struct detail::iterator_value; - friend class detail::node_data; - template friend class detail::iterator_base; - template friend struct as_if; - - typedef YAML::iterator iterator; - typedef YAML::const_iterator const_iterator; - - Node(); - explicit Node(NodeType::value type); - template explicit Node(const T& rhs); - explicit Node(const detail::iterator_value& rhs); - Node(const Node& rhs); - ~Node(); - - NodeType::value Type() const; - bool IsDefined() const; - bool IsNull() const { return Type() == NodeType::Null; } - bool IsScalar() const { return Type() == NodeType::Scalar; } - bool IsSequence() const { return Type() == NodeType::Sequence; } - bool IsMap() const { return Type() == NodeType::Map; } - - // bool conversions - YAML_CPP_OPERATOR_BOOL(); - bool operator!() const { return !IsDefined(); } - - // access - template const T as() const; - template const T as(const S& fallback) const; - const std::string& Scalar() const; - const std::string& Tag() const; - void SetTag(const std::string& tag); +namespace YAML { +class Node { + public: + friend class NodeBuilder; + friend class NodeEvents; + friend struct detail::iterator_value; + friend class detail::node_data; + template + friend class detail::iterator_base; + template + friend struct as_if; - // assignment - bool is(const Node& rhs) const; - template Node& operator=(const T& rhs); - Node& operator=(const Node& rhs); - void reset(const Node& rhs = Node()); - - // size/iterator - std::size_t size() const; + typedef YAML::iterator iterator; + typedef YAML::const_iterator const_iterator; - const_iterator begin() const; - iterator begin(); - - const_iterator end() const; - iterator end(); - - // sequence - template void push_back(const T& rhs); - void push_back(const Node& rhs); - - // indexing - template const Node operator[](const Key& key) const; - template Node operator[](const Key& key); - template bool remove(const Key& key); + Node(); + explicit Node(NodeType::value type); + template + explicit Node(const T& rhs); + explicit Node(const detail::iterator_value& rhs); + Node(const Node& rhs); + ~Node(); - const Node operator[](const Node& key) const; - Node operator[](const Node& key); - bool remove(const Node& key); - - // map - template - void force_insert(const Key& key, const Value& value); + NodeType::value Type() const; + bool IsDefined() const; + bool IsNull() const { return Type() == NodeType::Null; } + bool IsScalar() const { return Type() == NodeType::Scalar; } + bool IsSequence() const { return Type() == NodeType::Sequence; } + bool IsMap() const { return Type() == NodeType::Map; } - private: - enum Zombie { ZombieNode }; - explicit Node(Zombie); - explicit Node(detail::node& node, detail::shared_memory_holder pMemory); - - void EnsureNodeExists() const; - - template void Assign(const T& rhs); - void Assign(const char *rhs); - void Assign(char *rhs); + // bool conversions + YAML_CPP_OPERATOR_BOOL(); + bool operator!() const { return !IsDefined(); } - void AssignData(const Node& rhs); - void AssignNode(const Node& rhs); - - private: - bool m_isValid; - mutable detail::shared_memory_holder m_pMemory; - mutable detail::node *m_pNode; - }; + // access + template + const T as() const; + template + const T as(const S& fallback) const; + const std::string& Scalar() const; + const std::string& Tag() const; + void SetTag(const std::string& tag); - bool operator==(const Node& lhs, const Node& rhs); - - Node Clone(const Node& node); - - template - struct convert; + // assignment + bool is(const Node& rhs) const; + template + Node& operator=(const T& rhs); + Node& operator=(const Node& rhs); + void reset(const Node& rhs = Node()); + + // size/iterator + std::size_t size() const; + + const_iterator begin() const; + iterator begin(); + + const_iterator end() const; + iterator end(); + + // sequence + template + void push_back(const T& rhs); + void push_back(const Node& rhs); + + // indexing + template + const Node operator[](const Key& key) const; + template + Node operator[](const Key& key); + template + bool remove(const Key& key); + + const Node operator[](const Node& key) const; + Node operator[](const Node& key); + bool remove(const Node& key); + + // map + template + void force_insert(const Key& key, const Value& value); + + private: + enum Zombie { + ZombieNode + }; + explicit Node(Zombie); + explicit Node(detail::node& node, detail::shared_memory_holder pMemory); + + void EnsureNodeExists() const; + + template + void Assign(const T& rhs); + void Assign(const char* rhs); + void Assign(char* rhs); + + void AssignData(const Node& rhs); + void AssignNode(const Node& rhs); + + 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 +struct convert; } -#endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#endif // NODE_NODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/parse.h b/include/yaml-cpp/node/parse.h index 82dbdc1..4e3cb90 100644 --- a/include/yaml-cpp/node/parse.h +++ b/include/yaml-cpp/node/parse.h @@ -1,7 +1,9 @@ #ifndef 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 #endif @@ -9,20 +11,18 @@ #include #include -namespace YAML -{ - class Node; - - Node Load(const std::string& input); - Node Load(const char *input); - Node Load(std::istream& input); - Node LoadFile(const std::string& filename); +namespace YAML { +class Node; - std::vector LoadAll(const std::string& input); - std::vector LoadAll(const char *input); - std::vector LoadAll(std::istream& input); - std::vector LoadAllFromFile(const std::string& filename); +Node Load(const std::string& input); +Node Load(const char* input); +Node Load(std::istream& input); +Node LoadFile(const std::string& filename); + +std::vector LoadAll(const std::string& input); +std::vector LoadAll(const char* input); +std::vector LoadAll(std::istream& input); +std::vector LoadAllFromFile(const std::string& filename); } -#endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - +#endif // VALUE_PARSE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/ptr.h b/include/yaml-cpp/node/ptr.h index 316dbd2..64c8689 100644 --- a/include/yaml-cpp/node/ptr.h +++ b/include/yaml-cpp/node/ptr.h @@ -1,29 +1,29 @@ #ifndef 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 #endif - #include "yaml-cpp/dll.h" #include -namespace YAML -{ - namespace detail { - class node; - class node_ref; - class node_data; - class memory; - class memory_holder; +namespace YAML { +namespace detail { +class node; +class node_ref; +class node_data; +class memory; +class memory_holder; - typedef boost::shared_ptr shared_node; - typedef boost::shared_ptr shared_node_ref; - typedef boost::shared_ptr shared_node_data; - typedef boost::shared_ptr shared_memory_holder; - typedef boost::shared_ptr shared_memory; - } +typedef boost::shared_ptr shared_node; +typedef boost::shared_ptr shared_node_ref; +typedef boost::shared_ptr shared_node_data; +typedef boost::shared_ptr shared_memory_holder; +typedef boost::shared_ptr shared_memory; +} } -#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#endif // VALUE_PTR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/node/type.h b/include/yaml-cpp/node/type.h index 5ac8041..da1bc11 100644 --- a/include/yaml-cpp/node/type.h +++ b/include/yaml-cpp/node/type.h @@ -1,14 +1,22 @@ #ifndef 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 #endif - -namespace YAML -{ - struct NodeType { enum value { Undefined, Null, Scalar, Sequence, Map }; }; +namespace YAML { +struct NodeType { + enum value { + Undefined, + Null, + Scalar, + Sequence, + Map + }; +}; } -#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#endif // VALUE_TYPE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/parser.h b/include/yaml-cpp/parser.h index 8ec926b..18389bb 100644 --- a/include/yaml-cpp/parser.h +++ b/include/yaml-cpp/parser.h @@ -1,47 +1,46 @@ #ifndef 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 #endif - #include "yaml-cpp/dll.h" #include "yaml-cpp/noncopyable.h" #include #include -namespace YAML -{ - struct Directives; - struct Token; - class EventHandler; - class Scanner; +namespace YAML { +struct Directives; +struct Token; +class EventHandler; +class Scanner; - class YAML_CPP_API Parser: private noncopyable - { - public: - Parser(); - Parser(std::istream& in); - ~Parser(); +class YAML_CPP_API Parser : private noncopyable { + public: + 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(); - void HandleDirective(const Token& token); - void HandleYamlDirective(const Token& token); - void HandleTagDirective(const Token& token); - - private: - std::auto_ptr m_pScanner; - std::auto_ptr m_pDirectives; - }; + private: + void ParseDirectives(); + void HandleDirective(const Token& token); + void HandleYamlDirective(const Token& token); + void HandleTagDirective(const Token& token); + + private: + std::auto_ptr m_pScanner; + std::auto_ptr m_pDirectives; +}; } -#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#endif // PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/yaml.h b/include/yaml-cpp/yaml.h index 4e63408..4f09097 100644 --- a/include/yaml-cpp/yaml.h +++ b/include/yaml-cpp/yaml.h @@ -1,7 +1,9 @@ #ifndef 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 #endif @@ -18,4 +20,4 @@ #include "yaml-cpp/node/parse.h" #include "yaml-cpp/node/emit.h" -#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#endif // YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/src/convert.cpp b/src/convert.cpp index dc715f7..50b15bc 100644 --- a/src/convert.cpp +++ b/src/convert.cpp @@ -2,82 +2,72 @@ #include "yaml-cpp/node/impl.h" #include -namespace -{ - // we're not gonna mess with the mess that is all the isupper/etc. functions - bool IsLower(char ch) { return 'a' <= ch && ch <= 'z'; } - bool IsUpper(char ch) { return 'A' <= ch && ch <= 'Z'; } - char ToLower(char ch) { return IsUpper(ch) ? ch + 'a' - 'A' : ch; } - - std::string tolower(const std::string& str) - { - std::string s(str); - std::transform(s.begin(), s.end(), s.begin(), ToLower); - return s; - } - - template - bool IsEntirely(const std::string& str, T func) - { - for(std::size_t i=0;i::decode(const Node& node, bool& rhs) { - if(!node.IsScalar()) - return false; - - // we can't use iostream bool extraction operators as they don't - // recognize all possible values in the table below (taken from - // http://yaml.org/type/bool.html) - static const struct { - std::string truename, falsename; - } names[] = { - { "y", "n" }, - { "yes", "no" }, - { "true", "false" }, - { "on", "off" }, - }; - - if(!IsFlexibleCase(node.Scalar())) - return false; - - for(unsigned i=0;i +bool IsEntirely(const std::string& str, T func) { + for (std::size_t i = 0; i < str.size(); i++) + if (!func(str[i])) + return false; + + return true; +} + +// IsFlexibleCase +// . Returns true if 'str' is: +// . UPPERCASE +// . lowercase +// . Capitalized +bool IsFlexibleCase(const std::string& str) { + if (str.empty()) + return true; + + if (IsEntirely(str, IsLower)) + return true; + + bool firstcaps = IsUpper(str[0]); + std::string rest = str.substr(1); + return firstcaps && (IsEntirely(rest, IsLower) || IsEntirely(rest, IsUpper)); +} +} + +namespace YAML { +bool convert::decode(const Node& node, bool& rhs) { + if (!node.IsScalar()) + return false; + + // we can't use iostream bool extraction operators as they don't + // recognize all possible values in the table below (taken from + // http://yaml.org/type/bool.html) + static const struct { + std::string truename, falsename; + } names[] = {{"y", "n"}, {"yes", "no"}, {"true", "false"}, {"on", "off"}, }; + + if (!IsFlexibleCase(node.Scalar())) + 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; +} } diff --git a/src/emit.cpp b/src/emit.cpp index 1f0a647..5fb593b 100644 --- a/src/emit.cpp +++ b/src/emit.cpp @@ -3,27 +3,23 @@ #include "yaml-cpp/emitter.h" #include "nodeevents.h" -namespace YAML -{ - Emitter& operator << (Emitter& out, const Node& node) - { - EmitFromEvents emitFromEvents(out); - NodeEvents events(node); - events.Emit(emitFromEvents); - return out; - } - - std::ostream& operator << (std::ostream& out, const Node& node) - { - Emitter emitter(out); - emitter << node; - return out; - } - - std::string Dump(const Node& node) - { - Emitter emitter; - emitter << node; - return emitter.c_str(); - } +namespace YAML { +Emitter& operator<<(Emitter& out, const Node& node) { + EmitFromEvents emitFromEvents(out); + NodeEvents events(node); + events.Emit(emitFromEvents); + return out; +} + +std::ostream& operator<<(std::ostream& out, const Node& node) { + Emitter emitter(out); + emitter << node; + return out; +} + +std::string Dump(const Node& node) { + Emitter emitter; + emitter << node; + return emitter.c_str(); +} } diff --git a/src/memory.cpp b/src/memory.cpp index 98d0dfb..1a02bf0 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -1,29 +1,24 @@ #include "yaml-cpp/node/detail/memory.h" #include "yaml-cpp/node/detail/node.h" -namespace YAML -{ - namespace detail - { - void memory_holder::merge(memory_holder& rhs) - { - if(m_pMemory == rhs.m_pMemory) - return; - - m_pMemory->merge(*rhs.m_pMemory); - rhs.m_pMemory = m_pMemory; - } - - node& memory::create_node() - { - shared_node pNode(new node); - m_nodes.insert(pNode); - return *pNode; - } - - void memory::merge(const memory& rhs) - { - m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end()); - } - } +namespace YAML { +namespace detail { +void memory_holder::merge(memory_holder& rhs) { + if (m_pMemory == rhs.m_pMemory) + return; + + m_pMemory->merge(*rhs.m_pMemory); + rhs.m_pMemory = m_pMemory; +} + +node& memory::create_node() { + shared_node pNode(new node); + m_nodes.insert(pNode); + return *pNode; +} + +void memory::merge(const memory& rhs) { + m_nodes.insert(rhs.m_nodes.begin(), rhs.m_nodes.end()); +} +} } diff --git a/src/node.cpp b/src/node.cpp index 2d21aa9..2088e13 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -2,13 +2,11 @@ #include "nodebuilder.h" #include "nodeevents.h" -namespace YAML -{ - Node Clone(const Node& node) - { - NodeEvents events(node); - NodeBuilder builder; - events.Emit(builder); - return builder.Root(); - } +namespace YAML { +Node Clone(const Node& node) { + NodeEvents events(node); + NodeBuilder builder; + events.Emit(builder); + return builder.Root(); +} } diff --git a/src/node_data.cpp b/src/node_data.cpp index 6f82f7b..db80be9 100644 --- a/src/node_data.cpp +++ b/src/node_data.cpp @@ -4,292 +4,280 @@ #include "yaml-cpp/exceptions.h" #include -namespace YAML -{ - namespace detail - { - std::string node_data::empty_scalar; +namespace YAML { +namespace detail { +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; - m_isDefined = true; - } - - void node_data::set_type(NodeType::value type) - { - if(type == NodeType::Undefined) { - m_type = type; - m_isDefined = false; - return; - } - - - m_isDefined = true; - if(type == m_type) - return; - - m_type = type; - - switch(m_type) { - case NodeType::Null: - break; - case NodeType::Scalar: - m_scalar.clear(); - break; - case NodeType::Sequence: - reset_sequence(); - break; - case NodeType::Map: - reset_map(); - break; - case NodeType::Undefined: - assert(false); - break; - } - } - - void node_data::set_tag(const std::string& tag) - { - m_tag = tag; - } - - void node_data::set_null() - { - m_isDefined = true; - m_type = NodeType::Null; - } - - void node_data::set_scalar(const std::string& scalar) - { - m_isDefined = true; - m_type = NodeType::Scalar; - m_scalar = scalar; - } - - // size/iterator - std::size_t node_data::size() const - { - if(!m_isDefined) - return 0; - - switch(m_type) { - case NodeType::Sequence: compute_seq_size(); return m_seqSize; - case NodeType::Map: compute_map_size(); return m_map.size() - m_undefinedPairs.size(); - default: - return 0; - } - return 0; - } - - void node_data::compute_seq_size() const - { - while(m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined()) - m_seqSize++; - } - - void node_data::compute_map_size() const - { - kv_pairs::iterator it = m_undefinedPairs.begin(); - while(it != m_undefinedPairs.end()) { - kv_pairs::iterator jt = boost::next(it); - if(it->first->is_defined() && it->second->is_defined()) - m_undefinedPairs.erase(it); - it = jt; - } - } - - const_node_iterator node_data::begin() const - { - if(!m_isDefined) - return const_node_iterator(); - - switch(m_type) { - case NodeType::Sequence: return const_node_iterator(m_sequence.begin()); - case NodeType::Map: return const_node_iterator(m_map.begin(), m_map.end()); - default: return const_node_iterator(); - } - } - - node_iterator node_data::begin() - { - if(!m_isDefined) - return node_iterator(); - - switch(m_type) { - case NodeType::Sequence: return node_iterator(m_sequence.begin()); - case NodeType::Map: return node_iterator(m_map.begin(), m_map.end()); - default: return node_iterator(); - } - } - - const_node_iterator node_data::end() const - { - if(!m_isDefined) - 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(); - - switch(m_type) { - case NodeType::Sequence: return node_iterator(m_sequence.end()); - 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 */) - { - if(m_type == NodeType::Undefined || m_type == NodeType::Null) { - m_type = NodeType::Sequence; - reset_sequence(); - } - - if(m_type != NodeType::Sequence) - 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: - break; - case NodeType::Undefined: - case NodeType::Null: - case NodeType::Sequence: - convert_to_map(pMemory); - break; - case NodeType::Scalar: - throw BadSubscript(); - } - - insert_map_pair(key, value); - } - - // indexing - node& node_data::get(node& key, shared_memory_holder pMemory) const - { - if(m_type != NodeType::Map) - return pMemory->create_node(); - - for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { - if(it->first->is(key)) - return *it->second; - } - - return pMemory->create_node(); - } - - node& node_data::get(node& key, shared_memory_holder pMemory) - { - switch(m_type) { - case NodeType::Map: - break; - case NodeType::Undefined: - case NodeType::Null: - case NodeType::Sequence: - convert_to_map(pMemory); - break; - case NodeType::Scalar: - throw BadSubscript(); - } - - for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { - if(it->first->is(key)) - return *it->second; - } - - node& value = pMemory->create_node(); - insert_map_pair(key, value); - return value; - } - - bool node_data::remove(node& key, shared_memory_holder /* pMemory */) - { - if(m_type != NodeType::Map) - return false; - - for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) { - if(it->first->is(key)) { - m_map.erase(it); - return true; - } - } - - return false; - } - - void node_data::reset_sequence() - { - m_sequence.clear(); - m_seqSize = 0; - } - - void node_data::reset_map() - { - m_map.clear(); - m_undefinedPairs.clear(); - } - - void node_data::insert_map_pair(node& key, node& value) - { - m_map[&key] = &value; - if(!key.is_defined() || !value.is_defined()) - m_undefinedPairs.push_back(kv_pair(&key, &value)); - } - - void node_data::convert_to_map(shared_memory_holder pMemory) - { - switch(m_type) { - case NodeType::Undefined: - case NodeType::Null: - reset_map(); - m_type = NodeType::Map; - break; - case NodeType::Sequence: - convert_sequence_to_map(pMemory); - break; - case NodeType::Map: - break; - case NodeType::Scalar: - assert(false); - break; - } - } - - void node_data::convert_sequence_to_map(shared_memory_holder pMemory) - { - assert(m_type == NodeType::Sequence); - - reset_map(); - for(std::size_t i=0;icreate_node(); - key.set_scalar(stream.str()); - insert_map_pair(key, *m_sequence[i]); - } - - reset_sequence(); - m_type = NodeType::Map; - } - } +void node_data::mark_defined() { + if (m_type == NodeType::Undefined) + m_type = NodeType::Null; + m_isDefined = true; +} + +void node_data::set_type(NodeType::value type) { + if (type == NodeType::Undefined) { + m_type = type; + m_isDefined = false; + return; + } + + m_isDefined = true; + if (type == m_type) + return; + + m_type = type; + + switch (m_type) { + case NodeType::Null: + break; + case NodeType::Scalar: + m_scalar.clear(); + break; + case NodeType::Sequence: + reset_sequence(); + break; + case NodeType::Map: + reset_map(); + break; + case NodeType::Undefined: + assert(false); + break; + } +} + +void node_data::set_tag(const std::string& tag) { m_tag = tag; } + +void node_data::set_null() { + m_isDefined = true; + m_type = NodeType::Null; +} + +void node_data::set_scalar(const std::string& scalar) { + m_isDefined = true; + m_type = NodeType::Scalar; + m_scalar = scalar; +} + +// size/iterator +std::size_t node_data::size() const { + if (!m_isDefined) + return 0; + + switch (m_type) { + case NodeType::Sequence: + compute_seq_size(); + return m_seqSize; + case NodeType::Map: + compute_map_size(); + return m_map.size() - m_undefinedPairs.size(); + default: + return 0; + } + return 0; +} + +void node_data::compute_seq_size() const { + while (m_seqSize < m_sequence.size() && m_sequence[m_seqSize]->is_defined()) + m_seqSize++; +} + +void node_data::compute_map_size() const { + kv_pairs::iterator it = m_undefinedPairs.begin(); + while (it != m_undefinedPairs.end()) { + kv_pairs::iterator jt = boost::next(it); + if (it->first->is_defined() && it->second->is_defined()) + m_undefinedPairs.erase(it); + it = jt; + } +} + +const_node_iterator node_data::begin() const { + if (!m_isDefined) + return const_node_iterator(); + + switch (m_type) { + case NodeType::Sequence: + return const_node_iterator(m_sequence.begin()); + case NodeType::Map: + return const_node_iterator(m_map.begin(), m_map.end()); + default: + return const_node_iterator(); + } +} + +node_iterator node_data::begin() { + if (!m_isDefined) + return node_iterator(); + + switch (m_type) { + case NodeType::Sequence: + return node_iterator(m_sequence.begin()); + case NodeType::Map: + return node_iterator(m_map.begin(), m_map.end()); + default: + return node_iterator(); + } +} + +const_node_iterator node_data::end() const { + if (!m_isDefined) + 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(); + + switch (m_type) { + case NodeType::Sequence: + return node_iterator(m_sequence.end()); + 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 */) { + if (m_type == NodeType::Undefined || m_type == NodeType::Null) { + m_type = NodeType::Sequence; + reset_sequence(); + } + + if (m_type != NodeType::Sequence) + 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: + break; + case NodeType::Undefined: + case NodeType::Null: + case NodeType::Sequence: + convert_to_map(pMemory); + break; + case NodeType::Scalar: + throw BadSubscript(); + } + + insert_map_pair(key, value); +} + +// indexing +node& node_data::get(node& key, shared_memory_holder pMemory) const { + if (m_type != NodeType::Map) + return pMemory->create_node(); + + for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { + if (it->first->is(key)) + return *it->second; + } + + return pMemory->create_node(); +} + +node& node_data::get(node& key, shared_memory_holder pMemory) { + switch (m_type) { + case NodeType::Map: + break; + case NodeType::Undefined: + case NodeType::Null: + case NodeType::Sequence: + convert_to_map(pMemory); + break; + case NodeType::Scalar: + throw BadSubscript(); + } + + for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { + if (it->first->is(key)) + return *it->second; + } + + node& value = pMemory->create_node(); + insert_map_pair(key, value); + return value; +} + +bool node_data::remove(node& key, shared_memory_holder /* pMemory */) { + if (m_type != NodeType::Map) + return false; + + for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) { + if (it->first->is(key)) { + m_map.erase(it); + return true; + } + } + + return false; +} + +void node_data::reset_sequence() { + m_sequence.clear(); + m_seqSize = 0; +} + +void node_data::reset_map() { + m_map.clear(); + m_undefinedPairs.clear(); +} + +void node_data::insert_map_pair(node& key, node& value) { + m_map[&key] = &value; + if (!key.is_defined() || !value.is_defined()) + m_undefinedPairs.push_back(kv_pair(&key, &value)); +} + +void node_data::convert_to_map(shared_memory_holder pMemory) { + switch (m_type) { + case NodeType::Undefined: + case NodeType::Null: + reset_map(); + m_type = NodeType::Map; + break; + case NodeType::Sequence: + convert_sequence_to_map(pMemory); + break; + case NodeType::Map: + break; + case NodeType::Scalar: + assert(false); + break; + } +} + +void node_data::convert_sequence_to_map(shared_memory_holder pMemory) { + assert(m_type == NodeType::Sequence); + + 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; +} +} } diff --git a/src/nodebuilder.cpp b/src/nodebuilder.cpp index 6735f73..3ef2f7d 100644 --- a/src/nodebuilder.cpp +++ b/src/nodebuilder.cpp @@ -4,135 +4,119 @@ #include "yaml-cpp/node/impl.h" #include -namespace YAML -{ - NodeBuilder::NodeBuilder(): m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0) - { - m_anchors.push_back(0); // since the anchors start at 1 - } - - NodeBuilder::~NodeBuilder() - { - } - - Node NodeBuilder::Root() - { - if(!m_pRoot) - return Node(); - - return Node(*m_pRoot, m_pMemory); - } - - void NodeBuilder::OnDocumentStart(const Mark&) - { - } - - void NodeBuilder::OnDocumentEnd() - { - } - - void NodeBuilder::OnNull(const Mark& /* mark */, anchor_t anchor) - { - detail::node& node = Push(anchor); - node.set_null(); - Pop(); - } - - void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) - { - detail::node& node = *m_anchors[anchor]; - Push(node); - Pop(); - } - - void NodeBuilder::OnScalar(const Mark& /* mark */, const std::string& tag, anchor_t anchor, const std::string& value) - { - detail::node& node = Push(anchor); - node.set_scalar(value); - node.set_tag(tag); - Pop(); - } - - void NodeBuilder::OnSequenceStart(const Mark& /* mark */, const std::string& tag, anchor_t anchor) - { - detail::node& node = Push(anchor); - node.set_tag(tag); - node.set_type(NodeType::Sequence); - } - - void NodeBuilder::OnSequenceEnd() - { - Pop(); - } - - void NodeBuilder::OnMapStart(const Mark& /* mark */, const std::string& tag, anchor_t anchor) - { - detail::node& node = Push(anchor); - node.set_type(NodeType::Map); - node.set_tag(tag); - m_mapDepth++; - } - - void NodeBuilder::OnMapEnd() - { - assert(m_mapDepth > 0); - m_mapDepth--; - Pop(); - } - - detail::node& NodeBuilder::Push(anchor_t anchor) - { - detail::node& node = m_pMemory->create_node(); - RegisterAnchor(anchor, node); - Push(node); - return node; - } - - void NodeBuilder::Push(detail::node& node) - { - const bool needsKey = (!m_stack.empty() && m_stack.back()->type() == NodeType::Map && m_keys.size() < m_mapDepth); - - m_stack.push_back(&node); - if(needsKey) - m_keys.push_back(PushedKey(&node, false)); - } - - void NodeBuilder::Pop() - { - assert(!m_stack.empty()); - if(m_stack.size() == 1) { - m_pRoot = m_stack[0]; - m_stack.pop_back(); - return; - } - - detail::node& node = *m_stack.back(); - m_stack.pop_back(); - - detail::node& collection = *m_stack.back(); - - if(collection.type() == NodeType::Sequence) { - collection.push_back(node, m_pMemory); - } else if(collection.type() == NodeType::Map) { - assert(!m_keys.empty()); - PushedKey& key = m_keys.back(); - if(key.second) { - 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); - } - } +namespace YAML { +NodeBuilder::NodeBuilder() + : m_pMemory(new detail::memory_holder), m_pRoot(0), m_mapDepth(0) { + m_anchors.push_back(0); // since the anchors start at 1 +} + +NodeBuilder::~NodeBuilder() {} + +Node NodeBuilder::Root() { + if (!m_pRoot) + return Node(); + + return Node(*m_pRoot, m_pMemory); +} + +void NodeBuilder::OnDocumentStart(const Mark&) {} + +void NodeBuilder::OnDocumentEnd() {} + +void NodeBuilder::OnNull(const Mark& /* mark */, anchor_t anchor) { + detail::node& node = Push(anchor); + node.set_null(); + Pop(); +} + +void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) { + detail::node& node = *m_anchors[anchor]; + Push(node); + Pop(); +} + +void NodeBuilder::OnScalar(const Mark& /* mark */, const std::string& tag, + anchor_t anchor, const std::string& value) { + detail::node& node = Push(anchor); + node.set_scalar(value); + node.set_tag(tag); + Pop(); +} + +void NodeBuilder::OnSequenceStart(const Mark& /* mark */, + const std::string& tag, anchor_t anchor) { + detail::node& node = Push(anchor); + node.set_tag(tag); + node.set_type(NodeType::Sequence); +} + +void NodeBuilder::OnSequenceEnd() { Pop(); } + +void NodeBuilder::OnMapStart(const Mark& /* mark */, const std::string& tag, + anchor_t anchor) { + detail::node& node = Push(anchor); + node.set_type(NodeType::Map); + node.set_tag(tag); + m_mapDepth++; +} + +void NodeBuilder::OnMapEnd() { + assert(m_mapDepth > 0); + m_mapDepth--; + Pop(); +} + +detail::node& NodeBuilder::Push(anchor_t anchor) { + detail::node& node = m_pMemory->create_node(); + RegisterAnchor(anchor, node); + Push(node); + return node; +} + +void NodeBuilder::Push(detail::node& node) { + const bool needsKey = + (!m_stack.empty() && m_stack.back()->type() == NodeType::Map && + m_keys.size() < m_mapDepth); + + m_stack.push_back(&node); + if (needsKey) + m_keys.push_back(PushedKey(&node, false)); +} + +void NodeBuilder::Pop() { + assert(!m_stack.empty()); + if (m_stack.size() == 1) { + m_pRoot = m_stack[0]; + m_stack.pop_back(); + return; + } + + detail::node& node = *m_stack.back(); + m_stack.pop_back(); + + detail::node& collection = *m_stack.back(); + + if (collection.type() == NodeType::Sequence) { + collection.push_back(node, m_pMemory); + } else if (collection.type() == NodeType::Map) { + assert(!m_keys.empty()); + PushedKey& key = m_keys.back(); + if (key.second) { + 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); + } +} } diff --git a/src/nodebuilder.h b/src/nodebuilder.h index cce91d3..3600561 100644 --- a/src/nodebuilder.h +++ b/src/nodebuilder.h @@ -1,7 +1,9 @@ #ifndef 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 #endif @@ -9,50 +11,50 @@ #include "yaml-cpp/node/ptr.h" #include -namespace YAML -{ - class Node; +namespace YAML { +class Node; - class NodeBuilder: public EventHandler - { - public: - NodeBuilder(); - virtual ~NodeBuilder(); - - Node Root(); - - 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 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, anchor_t anchor); - 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 Nodes; - Nodes m_stack; - Nodes m_anchors; +class NodeBuilder : public EventHandler { + public: + NodeBuilder(); + virtual ~NodeBuilder(); - typedef std::pair PushedKey; - std::vector m_keys; - std::size_t m_mapDepth; - }; + Node Root(); + + 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 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, + anchor_t anchor); + 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 Nodes; + Nodes m_stack; + Nodes m_anchors; + + typedef std::pair PushedKey; + std::vector m_keys; + std::size_t m_mapDepth; +}; } -#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - +#endif // NODE_NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/src/nodeevents.cpp b/src/nodeevents.cpp index 879c2ce..1f07482 100644 --- a/src/nodeevents.cpp +++ b/src/nodeevents.cpp @@ -4,98 +4,96 @@ #include "yaml-cpp/eventhandler.h" #include "yaml-cpp/mark.h" -namespace YAML -{ - void NodeEvents::AliasManager::RegisterReference(const detail::node& node) - { - m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor())); - } - - anchor_t NodeEvents::AliasManager::LookupAnchor(const detail::node& node) const - { - AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref()); - if(it == m_anchorByIdentity.end()) - 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; - - if(node.type() == NodeType::Sequence) { - 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) - { - 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 - { - anchor_t anchor = NullAnchor; - if(IsAliased(node)) { - anchor = am.LookupAnchor(node); - if(anchor) { - handler.OnAlias(Mark(), anchor); - return; - } - - am.RegisterReference(node); - anchor = am.LookupAnchor(node); - } - - switch(node.type()) { - case NodeType::Undefined: - break; - case NodeType::Null: - handler.OnNull(Mark(), anchor); - break; - case NodeType::Scalar: - handler.OnScalar(Mark(), node.tag(), anchor, node.scalar()); - break; - case NodeType::Sequence: - handler.OnSequenceStart(Mark(), node.tag(), anchor); - 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 - { - RefCount::const_iterator it = m_refCount.find(node.ref()); - return it != m_refCount.end() && it->second > 1; - } +namespace YAML { +void NodeEvents::AliasManager::RegisterReference(const detail::node& node) { + m_anchorByIdentity.insert(std::make_pair(node.ref(), _CreateNewAnchor())); +} + +anchor_t NodeEvents::AliasManager::LookupAnchor(const detail::node& node) + const { + AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(node.ref()); + if (it == m_anchorByIdentity.end()) + 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; + + if (node.type() == NodeType::Sequence) { + 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) { + 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 { + anchor_t anchor = NullAnchor; + if (IsAliased(node)) { + anchor = am.LookupAnchor(node); + if (anchor) { + handler.OnAlias(Mark(), anchor); + return; + } + + am.RegisterReference(node); + anchor = am.LookupAnchor(node); + } + + switch (node.type()) { + case NodeType::Undefined: + break; + case NodeType::Null: + handler.OnNull(Mark(), anchor); + break; + case NodeType::Scalar: + handler.OnScalar(Mark(), node.tag(), anchor, node.scalar()); + break; + case NodeType::Sequence: + handler.OnSequenceStart(Mark(), node.tag(), anchor); + 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 { + RefCount::const_iterator it = m_refCount.find(node.ref()); + return it != m_refCount.end() && it->second > 1; +} } diff --git a/src/nodeevents.h b/src/nodeevents.h index ba31226..98b26ba 100644 --- a/src/nodeevents.h +++ b/src/nodeevents.h @@ -1,7 +1,9 @@ #ifndef 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 #endif @@ -10,48 +12,46 @@ #include #include -namespace YAML -{ - class EventHandler; - class Node; - - class NodeEvents - { - public: - explicit NodeEvents(const Node& node); - - void Emit(EventHandler& handler); - - private: - class AliasManager { - public: - AliasManager(): m_curAnchor(0) {} - - void RegisterReference(const detail::node& node); - anchor_t LookupAnchor(const detail::node& node) const; - - private: - anchor_t _CreateNewAnchor() { return ++m_curAnchor; } - - private: - typedef std::map 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 RefCount; - RefCount m_refCount; - }; +namespace YAML { +class EventHandler; +class Node; + +class NodeEvents { + public: + explicit NodeEvents(const Node& node); + + void Emit(EventHandler& handler); + + private: + class AliasManager { + public: + AliasManager() : m_curAnchor(0) {} + + void RegisterReference(const detail::node& node); + anchor_t LookupAnchor(const detail::node& node) const; + + private: + anchor_t _CreateNewAnchor() { return ++m_curAnchor; } + + private: + typedef std::map 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 RefCount; + RefCount m_refCount; +}; } -#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 - +#endif // NODE_NODEEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/src/ostream_wrapper.cpp b/src/ostream_wrapper.cpp index 66cafda..558bd7b 100644 --- a/src/ostream_wrapper.cpp +++ b/src/ostream_wrapper.cpp @@ -2,55 +2,52 @@ #include #include -namespace YAML -{ - ostream_wrapper::ostream_wrapper(): m_buffer(1), m_pStream(0), m_pos(0), m_row(0), m_col(0), m_comment(false) - { - } - - ostream_wrapper::ostream_wrapper(std::ostream& stream): m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false) - { - } +namespace YAML { +ostream_wrapper::ostream_wrapper() + : m_buffer(1), + m_pStream(0), + m_pos(0), + m_row(0), + m_col(0), + m_comment(false) {} - ostream_wrapper::~ostream_wrapper() - { - } - - void ostream_wrapper::write(const std::string& str) - { - if(m_pStream) { - m_pStream->write(str.c_str(), str.size()); - } else { - m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1)); - std::copy(str.begin(), str.end(), &m_buffer[m_pos]); - } - - for(std::size_t i=0;iwrite(str, size); - } else { - 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;iwrite(str.c_str(), str.size()); + } else { + m_buffer.resize(std::max(m_buffer.size(), m_pos + str.size() + 1)); + std::copy(str.begin(), str.end(), &m_buffer[m_pos]); + } + + for (std::size_t i = 0; i < str.size(); i++) + update_pos(str[i]); +} + +void ostream_wrapper::write(const char* str, std::size_t size) { + if (m_pStream) { + m_pStream->write(str, size); + } else { + 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]); +} + +void ostream_wrapper::update_pos(char ch) { + m_pos++; + m_col++; + + if (ch == '\n') { + m_row++; + m_col = 0; + m_comment = false; + } +} } diff --git a/src/parse.cpp b/src/parse.cpp index 1537d55..06292ae 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -7,62 +7,61 @@ #include #include -namespace YAML -{ - Node Load(const std::string& input) { - std::stringstream stream(input); - return Load(stream); - } - - Node Load(const char *input) { - std::stringstream stream(input); - return Load(stream); - } - - Node Load(std::istream& input) { - Parser parser(input); - NodeBuilder builder; - if(!parser.HandleNextDocument(builder)) - return Node(); - - return builder.Root(); - } - - Node LoadFile(const std::string& filename) { - std::ifstream fin(filename.c_str()); - if(!fin) - throw BadFile(); - return Load(fin); - } - - std::vector LoadAll(const std::string& input) { - std::stringstream stream(input); - return LoadAll(stream); - } - - std::vector LoadAll(const char *input) { - std::stringstream stream(input); - return LoadAll(stream); - } - - std::vector LoadAll(std::istream& input) { - std::vector docs; - - Parser parser(input); - while(1) { - NodeBuilder builder; - if(!parser.HandleNextDocument(builder)) - break; - docs.push_back(builder.Root()); - } - - return docs; - } - - std::vector LoadAllFromFile(const std::string& filename) { - std::ifstream fin(filename.c_str()); - if(!fin) - throw BadFile(); - return LoadAll(fin); - } +namespace YAML { +Node Load(const std::string& input) { + std::stringstream stream(input); + return Load(stream); +} + +Node Load(const char* input) { + std::stringstream stream(input); + return Load(stream); +} + +Node Load(std::istream& input) { + Parser parser(input); + NodeBuilder builder; + if (!parser.HandleNextDocument(builder)) + return Node(); + + return builder.Root(); +} + +Node LoadFile(const std::string& filename) { + std::ifstream fin(filename.c_str()); + if (!fin) + throw BadFile(); + return Load(fin); +} + +std::vector LoadAll(const std::string& input) { + std::stringstream stream(input); + return LoadAll(stream); +} + +std::vector LoadAll(const char* input) { + std::stringstream stream(input); + return LoadAll(stream); +} + +std::vector LoadAll(std::istream& input) { + std::vector docs; + + Parser parser(input); + while (1) { + NodeBuilder builder; + if (!parser.HandleNextDocument(builder)) + break; + docs.push_back(builder.Root()); + } + + return docs; +} + +std::vector LoadAllFromFile(const std::string& filename) { + std::ifstream fin(filename.c_str()); + if (!fin) + throw BadFile(); + return LoadAll(fin); +} } diff --git a/src/stream.cpp b/src/stream.cpp index a79fc17..f285e0a 100644 --- a/src/stream.cpp +++ b/src/stream.cpp @@ -50,21 +50,21 @@ static bool s_introFinalState[] = {false, // uis_start false, // uis_utfbe_b1 false, // uis_utf32be_b2 false, // uis_utf32be_bom3 - true, // uis_utf32be - true, // uis_utf16be + true, // uis_utf32be + true, // uis_utf16be false, // uis_utf16be_bom1 false, // uis_utfle_bom1 false, // uis_utf16le_bom2 false, // uis_utf32le_bom3 - true, // uis_utf16le - true, // uis_utf32le + true, // uis_utf16le + true, // uis_utf32le false, // uis_utf8_imp false, // uis_utf16le_imp false, // uis_utf32le_imp3 false, // uis_utf8_bom1 false, // uis_utf8_bom2 - true, // uis_utf8 - true, // uis_error + true, // uis_utf8 + true, // uis_error }; static UtfIntroState s_introTransitions[][uictMax] = { diff --git a/test/emittertests.cpp b/test/emittertests.cpp index cee64f5..7dbb118 100644 --- a/test/emittertests.cpp +++ b/test/emittertests.cpp @@ -3,1162 +3,1197 @@ #include "yaml-cpp/yaml.h" #include -namespace Test -{ - namespace Emitter { - //////////////////////////////////////////////////////////////////////////////////////////////////////// - // correct emitting +namespace Test { +namespace Emitter { +//////////////////////////////////////////////////////////////////////////////////////////////////////// +// correct emitting - void SimpleScalar(YAML::Emitter& out, std::string& desiredOutput) { - out << "Hello, World!"; - desiredOutput = "Hello, World!"; - } - - void SimpleSeq(YAML::Emitter& out, std::string& desiredOutput) { - out << YAML::BeginSeq; - out << "eggs"; - out << "bread"; - out << "milk"; - out << YAML::EndSeq; - - desiredOutput = "- eggs\n- bread\n- milk"; - } - - void SimpleFlowSeq(YAML::Emitter& out, std::string& desiredOutput) { - out << YAML::Flow; - out << YAML::BeginSeq; - out << "Larry"; - out << "Curly"; - out << "Moe"; - out << YAML::EndSeq; - - desiredOutput = "[Larry, Curly, Moe]"; - } - - void EmptyFlowSeq(YAML::Emitter& out, std::string& desiredOutput) { - out << YAML::Flow; - out << YAML::BeginSeq; - out << YAML::EndSeq; - - desiredOutput = "[]"; - } - - void NestedBlockSeq(YAML::Emitter& out, std::string& desiredOutput) { - out << YAML::BeginSeq; - out << "item 1"; - out << YAML::BeginSeq << "subitem 1" << "subitem 2" << YAML::EndSeq; - out << YAML::EndSeq; - - desiredOutput = "- item 1\n-\n - subitem 1\n - subitem 2"; - } - - void NestedFlowSeq(YAML::Emitter& out, std::string& desiredOutput) { - out << YAML::BeginSeq; - out << "one"; - out << YAML::Flow << YAML::BeginSeq << "two" << "three" << YAML::EndSeq; - out << YAML::EndSeq; - - desiredOutput = "- one\n- [two, three]"; - } - - void SimpleMap(YAML::Emitter& out, std::string& desiredOutput) { - out << YAML::BeginMap; - out << YAML::Key << "name"; - out << YAML::Value << "Ryan Braun"; - out << YAML::Key << "position"; - out << YAML::Value << "3B"; - out << YAML::EndMap; - - desiredOutput = "name: Ryan Braun\nposition: 3B"; - } - - void SimpleFlowMap(YAML::Emitter& out, std::string& desiredOutput) { - out << YAML::Flow; - out << YAML::BeginMap; - out << YAML::Key << "shape"; - out << YAML::Value << "square"; - out << YAML::Key << "color"; - out << YAML::Value << "blue"; - out << YAML::EndMap; - - desiredOutput = "{shape: square, color: blue}"; - } - - void MapAndList(YAML::Emitter& out, std::string& desiredOutput) { - out << YAML::BeginMap; - out << YAML::Key << "name"; - out << YAML::Value << "Barack Obama"; - out << YAML::Key << "children"; - out << YAML::Value << YAML::BeginSeq << "Sasha" << "Malia" << YAML::EndSeq; - 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"; - out << YAML::BeginMap; - out << YAML::Key << "pens" << YAML::Value << 8; - out << YAML::Key << "pencils" << YAML::Value << 14; - out << YAML::EndMap; - out << "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"; - out << YAML::Value << "Fred"; - out << YAML::Key << "grades"; - out << YAML::Value; - out << YAML::BeginMap; - out << YAML::Key << "algebra" << YAML::Value << "A"; - out << YAML::Key << "physics" << YAML::Value << "C+"; - out << YAML::Key << "literature" << YAML::Value << "B"; - out << YAML::EndMap; - out << YAML::EndMap; - - desiredOutput = "name: Fred\ngrades:\n algebra: A\n physics: C+\n literature: B"; - } - - void NestedFlowMap(YAML::Emitter& out, std::string& desiredOutput) { - out << YAML::Flow; - out << YAML::BeginMap; - out << YAML::Key << "name"; - out << YAML::Value << "Fred"; - out << YAML::Key << "grades"; - out << YAML::Value; - out << YAML::BeginMap; - out << YAML::Key << "algebra" << YAML::Value << "A"; - out << YAML::Key << "physics" << YAML::Value << "C+"; - out << YAML::Key << "literature" << YAML::Value << "B"; - out << YAML::EndMap; - out << YAML::EndMap; - - desiredOutput = "{name: Fred, grades: {algebra: A, physics: C+, literature: B}}"; - } - - void MapListMix(YAML::Emitter& out, std::string& desiredOutput) { - out << YAML::BeginMap; - out << YAML::Key << "name"; - out << YAML::Value << "Bob"; - out << YAML::Key << "position"; - out << YAML::Value; - out << YAML::Flow << YAML::BeginSeq << 2 << 4 << YAML::EndSeq; - out << YAML::Key << "invincible" << YAML::Value << YAML::OnOffBool << false; - out << YAML::EndMap; - - desiredOutput = "name: Bob\nposition: [2, 4]\ninvincible: off"; - } - - void SimpleLongKey(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::LongKey; - out << YAML::BeginMap; - out << YAML::Key << "height"; - out << YAML::Value << "5'9\""; - out << YAML::Key << "weight"; - out << YAML::Value << 145; - out << YAML::EndMap; - - desiredOutput = "? height\n: 5'9\"\n? weight\n: 145"; - } - - void SingleLongKey(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginMap; - out << YAML::Key << "age"; - out << YAML::Value << "24"; - out << YAML::LongKey << YAML::Key << "height"; - out << YAML::Value << "5'9\""; - out << YAML::Key << "weight"; - out << YAML::Value << 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; - out << YAML::BeginMap; - out << YAML::Key << YAML::BeginSeq << 1 << 3 << YAML::EndSeq; - out << YAML::Value << "monster"; - out << YAML::Key << YAML::Flow << YAML::BeginSeq << 2 << 0 << YAML::EndSeq; - out << YAML::Value << "demon"; - out << YAML::EndMap; - - desiredOutput = "? - 1\n - 3\n: monster\n? [2, 0]\n: demon"; - } - - void AutoLongKey(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginMap; - out << YAML::Key << YAML::BeginSeq << 1 << 3 << YAML::EndSeq; - out << YAML::Value << "monster"; - out << YAML::Key << YAML::Flow << YAML::BeginSeq << 2 << 0 << YAML::EndSeq; - out << YAML::Value << "demon"; - out << YAML::Key << "the origin"; - out << YAML::Value << "angel"; - out << YAML::EndMap; - - desiredOutput = "? - 1\n - 3\n: monster\n[2, 0]: demon\nthe origin: angel"; - } - - void ScalarFormat(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginSeq; - out << "simple scalar"; - out << YAML::SingleQuoted << "explicit single-quoted scalar"; - out << YAML::DoubleQuoted << "explicit double-quoted scalar"; - out << "auto-detected\ndouble-quoted scalar"; - out << "a non-\"auto-detected\" double-quoted scalar"; - out << YAML::Literal << "literal scalar\nthat may span\nmany, many\nlines and have \"whatever\" crazy\tsymbols that we like"; - 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"; - } - - void AutoLongKeyScalar(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginMap; - out << YAML::Key << YAML::Literal << "multi-line\nscalar"; - out << YAML::Value << "and its value"; - out << YAML::EndMap; - - desiredOutput = "? |\n multi-line\n scalar\n: and its value"; - } - - void LongKeyFlowMap(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::Flow; - out << YAML::BeginMap; - out << YAML::Key << "simple key"; - out << YAML::Value << "and value"; - out << YAML::LongKey << YAML::Key << "long key"; - out << YAML::Value << "and its value"; - out << YAML::EndMap; - - desiredOutput = "{simple key: and value, ? long key: and its value}"; - } - - void BlockMapAsKey(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginMap; - out << YAML::Key; - out << YAML::BeginMap; - out << YAML::Key << "key" << YAML::Value << "value"; - out << YAML::Key << "next key" << YAML::Value << "next value"; - out << YAML::EndMap; - out << YAML::Value; - out << "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; - out << YAML::Anchor("fred"); - out << YAML::BeginMap; - out << YAML::Key << "name" << YAML::Value << "Fred"; - out << YAML::Key << "age" << YAML::Value << 42; - out << YAML::EndMap; - out << YAML::Alias("fred"); - out << YAML::EndSeq; - - desiredOutput = "- &fred\n name: Fred\n age: 42\n- *fred"; - } - - void AliasAndAnchorWithNull(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginSeq; - out << YAML::Anchor("fred") << YAML::Null; - out << YAML::Alias("fred"); - out << YAML::EndSeq; - - desiredOutput = "- &fred ~\n- *fred"; - } - - void AliasAndAnchorInFlow(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::Flow << YAML::BeginSeq; - out << YAML::Anchor("fred"); - out << YAML::BeginMap; - out << YAML::Key << "name" << YAML::Value << "Fred"; - out << YAML::Key << "age" << YAML::Value << 42; - out << YAML::EndMap; - out << YAML::Alias("fred"); - out << YAML::EndSeq; - - desiredOutput = "[&fred {name: Fred, age: 42}, *fred]"; - } - - void SimpleVerbatimTag(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::VerbatimTag("!foo") << "bar"; - - desiredOutput = "! bar"; - } - - void VerbatimTagInBlockSeq(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginSeq; - out << YAML::VerbatimTag("!foo") << "bar"; - out << "baz"; - out << YAML::EndSeq; - - desiredOutput = "- ! bar\n- baz"; - } - - void VerbatimTagInFlowSeq(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::Flow << YAML::BeginSeq; - out << YAML::VerbatimTag("!foo") << "bar"; - out << "baz"; - out << YAML::EndSeq; - - desiredOutput = "[! bar, baz]"; - } - - void VerbatimTagInFlowSeqWithNull(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::Flow << YAML::BeginSeq; - out << YAML::VerbatimTag("!foo") << YAML::Null; - out << "baz"; - out << YAML::EndSeq; - - desiredOutput = "[! ~, baz]"; - } - - void VerbatimTagInBlockMap(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginMap; - out << YAML::Key << YAML::VerbatimTag("!foo") << "bar"; - out << YAML::Value << YAML::VerbatimTag("!waz") << "baz"; - out << YAML::EndMap; - - desiredOutput = "! bar: ! baz"; - } - - void VerbatimTagInFlowMap(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::Flow << YAML::BeginMap; - out << YAML::Key << YAML::VerbatimTag("!foo") << "bar"; - out << YAML::Value << "baz"; - out << YAML::EndMap; - - desiredOutput = "{! bar: baz}"; - } - - void VerbatimTagInFlowMapWithNull(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::Flow << YAML::BeginMap; - out << YAML::Key << YAML::VerbatimTag("!foo") << YAML::Null; - out << YAML::Value << "baz"; - out << YAML::EndMap; - - desiredOutput = "{! ~: baz}"; - } - - void VerbatimTagWithEmptySeq(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::VerbatimTag("!foo") << YAML::BeginSeq << YAML::EndSeq; - - desiredOutput = "!\n[]"; - } - - void VerbatimTagWithEmptyMap(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::VerbatimTag("!bar") << YAML::BeginMap << YAML::EndMap; - - desiredOutput = "!\n{}"; - } - - void VerbatimTagWithEmptySeqAndMap(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginSeq; - out << YAML::VerbatimTag("!foo") << YAML::BeginSeq << YAML::EndSeq; - out << YAML::VerbatimTag("!bar") << YAML::BeginMap << YAML::EndMap; - out << YAML::EndSeq; - - desiredOutput = "- !\n []\n- !\n {}"; - } - - void ByKindTagWithScalar(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginSeq; - out << YAML::DoubleQuoted << "12"; - out << "12"; - out << YAML::TagByKind << "12"; - out << YAML::EndSeq; - - desiredOutput = "- \"12\"\n- 12\n- ! 12"; - } - - void LocalTagWithScalar(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::LocalTag("foo") << "bar"; - - desiredOutput = "!foo bar"; - } - - void BadLocalTag(YAML::Emitter& out, std::string& desiredError) - { - out << YAML::LocalTag("e!far") << "bar"; - - desiredError = "invalid tag"; - } - - void ComplexDoc(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginMap; - out << YAML::Key << "receipt"; - out << YAML::Value << "Oz-Ware Purchase Invoice"; - out << YAML::Key << "date"; - out << YAML::Value << "2007-08-06"; - out << YAML::Key << "customer"; - out << YAML::Value; - out << YAML::BeginMap; - out << YAML::Key << "given"; - out << YAML::Value << "Dorothy"; - out << YAML::Key << "family"; - out << YAML::Value << "Gale"; - out << YAML::EndMap; - out << YAML::Key << "items"; - out << YAML::Value; - out << YAML::BeginSeq; - out << YAML::BeginMap; - out << YAML::Key << "part_no"; - out << YAML::Value << "A4786"; - out << YAML::Key << "descrip"; - out << YAML::Value << "Water Bucket (Filled)"; - out << YAML::Key << "price"; - out << YAML::Value << 1.47; - out << YAML::Key << "quantity"; - out << YAML::Value << 4; - out << YAML::EndMap; - out << YAML::BeginMap; - out << YAML::Key << "part_no"; - out << YAML::Value << "E1628"; - out << YAML::Key << "descrip"; - out << YAML::Value << "High Heeled \"Ruby\" Slippers"; - out << YAML::Key << "price"; - out << YAML::Value << 100.27; - out << YAML::Key << "quantity"; - out << YAML::Value << 1; - out << YAML::EndMap; - out << YAML::EndSeq; - out << YAML::Key << "bill-to"; - out << YAML::Value << YAML::Anchor("id001"); - out << YAML::BeginMap; - out << YAML::Key << "street"; - out << YAML::Value << YAML::Literal << "123 Tornado Alley\nSuite 16"; - out << YAML::Key << "city"; - out << YAML::Value << "East Westville"; - out << YAML::Key << "state"; - out << YAML::Value << "KS"; - out << YAML::EndMap; - out << YAML::Key << "ship-to"; - out << YAML::Value << YAML::Alias("id001"); - out << YAML::EndMap; - - 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"; - } - - void STLContainers(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginSeq; - std::vector primes; - primes.push_back(2); - primes.push_back(3); - primes.push_back(5); - primes.push_back(7); - primes.push_back(11); - primes.push_back(13); - out << YAML::Flow << primes; - std::map ages; - ages["Daniel"] = 26; - ages["Jesse"] = 24; - out << ages; - out << YAML::EndSeq; - - desiredOutput = "- [2, 3, 5, 7, 11, 13]\n- Daniel: 26\n Jesse: 24"; - } - - void SimpleComment(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginMap; - out << YAML::Key << "method"; - out << YAML::Value << "least squares" << YAML::Comment("should we change this method?"); - out << YAML::EndMap; - - desiredOutput = "method: least squares # should we change this method?"; - } - - void MultiLineComment(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::BeginSeq; - out << "item 1" << YAML::Comment("really really long\ncomment that couldn't possibly\nfit on one line"); - out << "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"); - out << YAML::Value << "value"; - out << YAML::EndMap; - - desiredOutput = "? long key # long key\n: value"; - } - - void InitialComment(YAML::Emitter& out, std::string& desiredOutput) - { - 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 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 - 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("Hello, World!"), 13); - desiredOutput = "!!binary \"SGVsbG8sIFdvcmxkIQ==\""; - } - - void LongBinary(YAML::Emitter& out, std::string& desiredOutput) - { - out << YAML::Binary(reinterpret_cast("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(""), 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! 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 SimpleScalar(YAML::Emitter& out, std::string& desiredOutput) { + out << "Hello, World!"; + desiredOutput = "Hello, World!"; } +void SimpleSeq(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginSeq; + out << "eggs"; + out << "bread"; + out << "milk"; + out << YAML::EndSeq; + + desiredOutput = "- eggs\n- bread\n- milk"; +} + +void SimpleFlowSeq(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::Flow; + out << YAML::BeginSeq; + out << "Larry"; + out << "Curly"; + out << "Moe"; + out << YAML::EndSeq; + + desiredOutput = "[Larry, Curly, Moe]"; +} + +void EmptyFlowSeq(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::Flow; + out << YAML::BeginSeq; + out << YAML::EndSeq; + + desiredOutput = "[]"; +} + +void NestedBlockSeq(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginSeq; + out << "item 1"; + out << YAML::BeginSeq << "subitem 1" + << "subitem 2" << YAML::EndSeq; + out << YAML::EndSeq; + + desiredOutput = "- item 1\n-\n - subitem 1\n - subitem 2"; +} + +void NestedFlowSeq(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginSeq; + out << "one"; + out << YAML::Flow << YAML::BeginSeq << "two" + << "three" << YAML::EndSeq; + out << YAML::EndSeq; + + desiredOutput = "- one\n- [two, three]"; +} + +void SimpleMap(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginMap; + out << YAML::Key << "name"; + out << YAML::Value << "Ryan Braun"; + out << YAML::Key << "position"; + out << YAML::Value << "3B"; + out << YAML::EndMap; + + desiredOutput = "name: Ryan Braun\nposition: 3B"; +} + +void SimpleFlowMap(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::Flow; + out << YAML::BeginMap; + out << YAML::Key << "shape"; + out << YAML::Value << "square"; + out << YAML::Key << "color"; + out << YAML::Value << "blue"; + out << YAML::EndMap; + + desiredOutput = "{shape: square, color: blue}"; +} + +void MapAndList(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginMap; + out << YAML::Key << "name"; + out << YAML::Value << "Barack Obama"; + out << YAML::Key << "children"; + out << YAML::Value << YAML::BeginSeq << "Sasha" + << "Malia" << YAML::EndSeq; + 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"; + out << YAML::BeginMap; + out << YAML::Key << "pens" << YAML::Value << 8; + out << YAML::Key << "pencils" << YAML::Value << 14; + out << YAML::EndMap; + out << "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"; + out << YAML::Value << "Fred"; + out << YAML::Key << "grades"; + out << YAML::Value; + out << YAML::BeginMap; + out << YAML::Key << "algebra" << YAML::Value << "A"; + out << YAML::Key << "physics" << YAML::Value << "C+"; + out << YAML::Key << "literature" << YAML::Value << "B"; + out << YAML::EndMap; + out << YAML::EndMap; + + desiredOutput = + "name: Fred\ngrades:\n algebra: A\n physics: C+\n literature: B"; +} + +void NestedFlowMap(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::Flow; + out << YAML::BeginMap; + out << YAML::Key << "name"; + out << YAML::Value << "Fred"; + out << YAML::Key << "grades"; + out << YAML::Value; + out << YAML::BeginMap; + out << YAML::Key << "algebra" << YAML::Value << "A"; + out << YAML::Key << "physics" << YAML::Value << "C+"; + out << YAML::Key << "literature" << YAML::Value << "B"; + out << YAML::EndMap; + out << YAML::EndMap; + + desiredOutput = + "{name: Fred, grades: {algebra: A, physics: C+, literature: B}}"; +} + +void MapListMix(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginMap; + out << YAML::Key << "name"; + out << YAML::Value << "Bob"; + out << YAML::Key << "position"; + out << YAML::Value; + out << YAML::Flow << YAML::BeginSeq << 2 << 4 << YAML::EndSeq; + out << YAML::Key << "invincible" << YAML::Value << YAML::OnOffBool << false; + out << YAML::EndMap; + + desiredOutput = "name: Bob\nposition: [2, 4]\ninvincible: off"; +} + +void SimpleLongKey(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::LongKey; + out << YAML::BeginMap; + out << YAML::Key << "height"; + out << YAML::Value << "5'9\""; + out << YAML::Key << "weight"; + out << YAML::Value << 145; + out << YAML::EndMap; + + desiredOutput = "? height\n: 5'9\"\n? weight\n: 145"; +} + +void SingleLongKey(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginMap; + out << YAML::Key << "age"; + out << YAML::Value << "24"; + out << YAML::LongKey << YAML::Key << "height"; + out << YAML::Value << "5'9\""; + out << YAML::Key << "weight"; + out << YAML::Value << 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; + out << YAML::BeginMap; + out << YAML::Key << YAML::BeginSeq << 1 << 3 << YAML::EndSeq; + out << YAML::Value << "monster"; + out << YAML::Key << YAML::Flow << YAML::BeginSeq << 2 << 0 << YAML::EndSeq; + out << YAML::Value << "demon"; + out << YAML::EndMap; + + desiredOutput = "? - 1\n - 3\n: monster\n? [2, 0]\n: demon"; +} + +void AutoLongKey(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginMap; + out << YAML::Key << YAML::BeginSeq << 1 << 3 << YAML::EndSeq; + out << YAML::Value << "monster"; + out << YAML::Key << YAML::Flow << YAML::BeginSeq << 2 << 0 << YAML::EndSeq; + out << YAML::Value << "demon"; + out << YAML::Key << "the origin"; + out << YAML::Value << "angel"; + out << YAML::EndMap; + + desiredOutput = "? - 1\n - 3\n: monster\n[2, 0]: demon\nthe origin: angel"; +} + +void ScalarFormat(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginSeq; + out << "simple scalar"; + out << YAML::SingleQuoted << "explicit single-quoted scalar"; + out << YAML::DoubleQuoted << "explicit double-quoted scalar"; + out << "auto-detected\ndouble-quoted scalar"; + out << "a non-\"auto-detected\" double-quoted scalar"; + out << YAML::Literal << "literal scalar\nthat may span\nmany, many\nlines " + "and have \"whatever\" crazy\tsymbols that we like"; + 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"; +} + +void AutoLongKeyScalar(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginMap; + out << YAML::Key << YAML::Literal << "multi-line\nscalar"; + out << YAML::Value << "and its value"; + out << YAML::EndMap; + + desiredOutput = "? |\n multi-line\n scalar\n: and its value"; +} + +void LongKeyFlowMap(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::Flow; + out << YAML::BeginMap; + out << YAML::Key << "simple key"; + out << YAML::Value << "and value"; + out << YAML::LongKey << YAML::Key << "long key"; + out << YAML::Value << "and its value"; + out << YAML::EndMap; + + desiredOutput = "{simple key: and value, ? long key: and its value}"; +} + +void BlockMapAsKey(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginMap; + out << YAML::Key; + out << YAML::BeginMap; + out << YAML::Key << "key" << YAML::Value << "value"; + out << YAML::Key << "next key" << YAML::Value << "next value"; + out << YAML::EndMap; + out << YAML::Value; + out << "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; + out << YAML::Anchor("fred"); + out << YAML::BeginMap; + out << YAML::Key << "name" << YAML::Value << "Fred"; + out << YAML::Key << "age" << YAML::Value << 42; + out << YAML::EndMap; + out << YAML::Alias("fred"); + out << YAML::EndSeq; + + desiredOutput = "- &fred\n name: Fred\n age: 42\n- *fred"; +} + +void AliasAndAnchorWithNull(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginSeq; + out << YAML::Anchor("fred") << YAML::Null; + out << YAML::Alias("fred"); + out << YAML::EndSeq; + + desiredOutput = "- &fred ~\n- *fred"; +} + +void AliasAndAnchorInFlow(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::Flow << YAML::BeginSeq; + out << YAML::Anchor("fred"); + out << YAML::BeginMap; + out << YAML::Key << "name" << YAML::Value << "Fred"; + out << YAML::Key << "age" << YAML::Value << 42; + out << YAML::EndMap; + out << YAML::Alias("fred"); + out << YAML::EndSeq; + + desiredOutput = "[&fred {name: Fred, age: 42}, *fred]"; +} + +void SimpleVerbatimTag(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::VerbatimTag("!foo") << "bar"; + + desiredOutput = "! bar"; +} + +void VerbatimTagInBlockSeq(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginSeq; + out << YAML::VerbatimTag("!foo") << "bar"; + out << "baz"; + out << YAML::EndSeq; + + desiredOutput = "- ! bar\n- baz"; +} + +void VerbatimTagInFlowSeq(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::Flow << YAML::BeginSeq; + out << YAML::VerbatimTag("!foo") << "bar"; + out << "baz"; + out << YAML::EndSeq; + + desiredOutput = "[! bar, baz]"; +} + +void VerbatimTagInFlowSeqWithNull(YAML::Emitter& out, + std::string& desiredOutput) { + out << YAML::Flow << YAML::BeginSeq; + out << YAML::VerbatimTag("!foo") << YAML::Null; + out << "baz"; + out << YAML::EndSeq; + + desiredOutput = "[! ~, baz]"; +} + +void VerbatimTagInBlockMap(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginMap; + out << YAML::Key << YAML::VerbatimTag("!foo") << "bar"; + out << YAML::Value << YAML::VerbatimTag("!waz") << "baz"; + out << YAML::EndMap; + + desiredOutput = "! bar: ! baz"; +} + +void VerbatimTagInFlowMap(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::Flow << YAML::BeginMap; + out << YAML::Key << YAML::VerbatimTag("!foo") << "bar"; + out << YAML::Value << "baz"; + out << YAML::EndMap; + + desiredOutput = "{! bar: baz}"; +} + +void VerbatimTagInFlowMapWithNull(YAML::Emitter& out, + std::string& desiredOutput) { + out << YAML::Flow << YAML::BeginMap; + out << YAML::Key << YAML::VerbatimTag("!foo") << YAML::Null; + out << YAML::Value << "baz"; + out << YAML::EndMap; + + desiredOutput = "{! ~: baz}"; +} + +void VerbatimTagWithEmptySeq(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::VerbatimTag("!foo") << YAML::BeginSeq << YAML::EndSeq; + + desiredOutput = "!\n[]"; +} + +void VerbatimTagWithEmptyMap(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::VerbatimTag("!bar") << YAML::BeginMap << YAML::EndMap; + + desiredOutput = "!\n{}"; +} + +void VerbatimTagWithEmptySeqAndMap(YAML::Emitter& out, + std::string& desiredOutput) { + out << YAML::BeginSeq; + out << YAML::VerbatimTag("!foo") << YAML::BeginSeq << YAML::EndSeq; + out << YAML::VerbatimTag("!bar") << YAML::BeginMap << YAML::EndMap; + out << YAML::EndSeq; + + desiredOutput = "- !\n []\n- !\n {}"; +} + +void ByKindTagWithScalar(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginSeq; + out << YAML::DoubleQuoted << "12"; + out << "12"; + out << YAML::TagByKind << "12"; + out << YAML::EndSeq; + + desiredOutput = "- \"12\"\n- 12\n- ! 12"; +} + +void LocalTagWithScalar(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::LocalTag("foo") << "bar"; + + desiredOutput = "!foo bar"; +} + +void BadLocalTag(YAML::Emitter& out, std::string& desiredError) { + out << YAML::LocalTag("e!far") << "bar"; + + desiredError = "invalid tag"; +} + +void ComplexDoc(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginMap; + out << YAML::Key << "receipt"; + out << YAML::Value << "Oz-Ware Purchase Invoice"; + out << YAML::Key << "date"; + out << YAML::Value << "2007-08-06"; + out << YAML::Key << "customer"; + out << YAML::Value; + out << YAML::BeginMap; + out << YAML::Key << "given"; + out << YAML::Value << "Dorothy"; + out << YAML::Key << "family"; + out << YAML::Value << "Gale"; + out << YAML::EndMap; + out << YAML::Key << "items"; + out << YAML::Value; + out << YAML::BeginSeq; + out << YAML::BeginMap; + out << YAML::Key << "part_no"; + out << YAML::Value << "A4786"; + out << YAML::Key << "descrip"; + out << YAML::Value << "Water Bucket (Filled)"; + out << YAML::Key << "price"; + out << YAML::Value << 1.47; + out << YAML::Key << "quantity"; + out << YAML::Value << 4; + out << YAML::EndMap; + out << YAML::BeginMap; + out << YAML::Key << "part_no"; + out << YAML::Value << "E1628"; + out << YAML::Key << "descrip"; + out << YAML::Value << "High Heeled \"Ruby\" Slippers"; + out << YAML::Key << "price"; + out << YAML::Value << 100.27; + out << YAML::Key << "quantity"; + out << YAML::Value << 1; + out << YAML::EndMap; + out << YAML::EndSeq; + out << YAML::Key << "bill-to"; + out << YAML::Value << YAML::Anchor("id001"); + out << YAML::BeginMap; + out << YAML::Key << "street"; + out << YAML::Value << YAML::Literal << "123 Tornado Alley\nSuite 16"; + out << YAML::Key << "city"; + out << YAML::Value << "East Westville"; + out << YAML::Key << "state"; + out << YAML::Value << "KS"; + out << YAML::EndMap; + out << YAML::Key << "ship-to"; + out << YAML::Value << YAML::Alias("id001"); + out << YAML::EndMap; + + 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"; +} + +void STLContainers(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginSeq; + std::vector primes; + primes.push_back(2); + primes.push_back(3); + primes.push_back(5); + primes.push_back(7); + primes.push_back(11); + primes.push_back(13); + out << YAML::Flow << primes; + std::map ages; + ages["Daniel"] = 26; + ages["Jesse"] = 24; + out << ages; + out << YAML::EndSeq; + + desiredOutput = "- [2, 3, 5, 7, 11, 13]\n- Daniel: 26\n Jesse: 24"; +} + +void SimpleComment(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginMap; + out << YAML::Key << "method"; + out << YAML::Value << "least squares" + << YAML::Comment("should we change this method?"); + out << YAML::EndMap; + + desiredOutput = "method: least squares # should we change this method?"; +} + +void MultiLineComment(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::BeginSeq; + out << "item 1" << YAML::Comment( + "really really long\ncomment that couldn't " + "possibly\nfit on one line"); + out << "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"); + out << YAML::Value << "value"; + out << YAML::EndMap; + + desiredOutput = "? long key # long key\n: value"; +} + +void InitialComment(YAML::Emitter& out, std::string& desiredOutput) { + 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 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 +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("Hello, World!"), + 13); + desiredOutput = "!!binary \"SGVsbG8sIFdvcmxkIQ==\""; +} + +void LongBinary(YAML::Emitter& out, std::string& desiredOutput) { + out << YAML::Binary( + reinterpret_cast( + "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(""), 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! 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; +} +} diff --git a/test/new-api/nodetests.cpp b/test/new-api/nodetests.cpp index cb6a0c5..8d77c6f 100644 --- a/test/new-api/nodetests.cpp +++ b/test/new-api/nodetests.cpp @@ -9,595 +9,587 @@ #endif namespace { - struct TEST { - TEST(): ok(false) {} - TEST(bool ok_): ok(ok_) {} - TEST(const char *error_): ok(false), error(error_) {} - TEST(const std::string& error_): ok(false), error(error_) {} - - bool ok; - std::string error; - }; +struct TEST { + TEST() : ok(false) {} + TEST(bool ok_) : ok(ok_) {} + TEST(const char* error_) : ok(false), error(error_) {} + TEST(const std::string& error_) : ok(false), error(error_) {} + + bool ok; + std::string error; +}; } -#define YAML_ASSERT(cond)\ - do {\ - if(!(cond))\ - return " Assert failed: " #cond;\ - } while(false) +#define YAML_ASSERT(cond) \ + do { \ + if (!(cond)) \ + return " Assert failed: " #cond; \ + } while (false) -#define YAML_ASSERT_THROWS(cond, exc)\ - do {\ - try {\ - (cond);\ - return " Expression did not throw: " #cond;\ - } catch(const exc&) {\ - } catch(const std::runtime_error& e) {\ - std::stringstream stream;\ - stream << " Expression threw runtime error ther than " #exc ":\n " #cond "\n " << e.what();\ - return stream.str();\ - } catch(...) {\ - return " Expression threw unknown exception, other than " #exc ":\n " #cond;\ - }\ - } while(false) +#define YAML_ASSERT_THROWS(cond, exc) \ + do { \ + try { \ + (cond); \ + return " Expression did not throw: " #cond; \ + } \ + catch (const exc&) { \ + } \ + catch (const std::runtime_error& e) { \ + std::stringstream stream; \ + stream << " Expression threw runtime error ther than " #exc \ + ":\n " #cond "\n " << e.what(); \ + return stream.str(); \ + } \ + catch (...) { \ + return " Expression threw unknown exception, other than " #exc \ + ":\n " #cond; \ + } \ + } while (false) -namespace Test -{ - namespace Node - { - TEST SimpleScalar() - { - YAML::Node node = YAML::Node("Hello, World!"); - YAML_ASSERT(node.IsScalar()); - YAML_ASSERT(node.as() == "Hello, World!"); - return true; - } - - TEST IntScalar() - { - YAML::Node node = YAML::Node(15); - YAML_ASSERT(node.IsScalar()); - YAML_ASSERT(node.as() == 15); - return true; - } - - TEST SimpleAppendSequence() - { - YAML::Node node; - node.push_back(10); - node.push_back("foo"); - node.push_back("monkey"); - YAML_ASSERT(node.IsSequence()); - YAML_ASSERT(node.size() == 3); - YAML_ASSERT(node[0].as() == 10); - YAML_ASSERT(node[1].as() == "foo"); - YAML_ASSERT(node[2].as() == "monkey"); - YAML_ASSERT(node.IsSequence()); - return true; - } - - TEST SimpleAssignSequence() - { - YAML::Node node; - node[0] = 10; - node[1] = "foo"; - node[2] = "monkey"; - YAML_ASSERT(node.IsSequence()); - YAML_ASSERT(node.size() == 3); - YAML_ASSERT(node[0].as() == 10); - YAML_ASSERT(node[1].as() == "foo"); - YAML_ASSERT(node[2].as() == "monkey"); - YAML_ASSERT(node.IsSequence()); - return true; - } - - TEST SimpleMap() - { - YAML::Node node; - node["key"] = "value"; - YAML_ASSERT(node.IsMap()); - YAML_ASSERT(node["key"].as() == "value"); - YAML_ASSERT(node.size() == 1); - return true; - } - - TEST MapWithUndefinedValues() - { - YAML::Node node; - node["key"] = "value"; - node["undefined"]; - YAML_ASSERT(node.IsMap()); - YAML_ASSERT(node["key"].as() == "value"); - YAML_ASSERT(node.size() == 1); - - node["undefined"] = "monkey"; - YAML_ASSERT(node["undefined"].as() == "monkey"); - YAML_ASSERT(node.size() == 2); - - return true; - } - - TEST MapIteratorWithUndefinedValues() - { - YAML::Node node; - node["key"] = "value"; - node["undefined"]; - - std::size_t count = 0; - for(YAML::const_iterator it=node.begin();it!=node.end();++it) - count++; - YAML_ASSERT(count == 1); - return true; - } - - TEST SimpleSubkeys() - { - YAML::Node node; - node["device"]["udid"] = "12345"; - node["device"]["name"] = "iPhone"; - node["device"]["os"] = "4.0"; - node["username"] = "monkey"; - YAML_ASSERT(node["device"]["udid"].as() == "12345"); - YAML_ASSERT(node["device"]["name"].as() == "iPhone"); - YAML_ASSERT(node["device"]["os"].as() == "4.0"); - YAML_ASSERT(node["username"].as() == "monkey"); - return true; - } - - TEST StdVector() - { - std::vector primes; - primes.push_back(2); - primes.push_back(3); - primes.push_back(5); - primes.push_back(7); - primes.push_back(11); - primes.push_back(13); - - YAML::Node node; - node["primes"] = primes; - YAML_ASSERT(node["primes"].as >() == primes); - return true; - } - - TEST StdList() - { - std::list primes; - primes.push_back(2); - primes.push_back(3); - primes.push_back(5); - primes.push_back(7); - primes.push_back(11); - primes.push_back(13); - - YAML::Node node; - node["primes"] = primes; - YAML_ASSERT(node["primes"].as >() == primes); - return true; - } - - TEST StdMap() - { - std::map squares; - squares[0] = 0; - squares[1] = 1; - squares[2] = 4; - squares[3] = 9; - squares[4] = 16; - - YAML::Node node; - node["squares"] = squares; - YAML_ASSERT((node["squares"].as >() == squares)); - return true; - } - - TEST StdPair() - { - std::pair p; - p.first = 5; - p.second = "five"; - - YAML::Node node; - node["pair"] = p; - YAML_ASSERT((node["pair"].as >() == p)); - return true; - } - - TEST SimpleAlias() - { - YAML::Node node; - node["foo"] = "value"; - node["bar"] = node["foo"]; - YAML_ASSERT(node["foo"].as() == "value"); - YAML_ASSERT(node["bar"].as() == "value"); - YAML_ASSERT(node["foo"] == node["bar"]); - YAML_ASSERT(node.size() == 2); - return true; - } - - TEST AliasAsKey() - { - YAML::Node node; - node["foo"] = "value"; - YAML::Node value = node["foo"]; - node[value] = "foo"; - YAML_ASSERT(node["foo"].as() == "value"); - YAML_ASSERT(node[value].as() == "foo"); - YAML_ASSERT(node["value"].as() == "foo"); - YAML_ASSERT(node.size() == 2); - return true; - } - - TEST SelfReferenceSequence() - { - YAML::Node node; - node[0] = node; - YAML_ASSERT(node.IsSequence()); - YAML_ASSERT(node.size() == 1); - YAML_ASSERT(node[0] == node); - YAML_ASSERT(node[0][0] == node); - YAML_ASSERT(node[0][0] == node[0]); - return true; - } - - TEST ValueSelfReferenceMap() - { - YAML::Node node; - node["key"] = node; - YAML_ASSERT(node.IsMap()); - YAML_ASSERT(node.size() == 1); - YAML_ASSERT(node["key"] == node); - YAML_ASSERT(node["key"]["key"] == node); - YAML_ASSERT(node["key"]["key"] == node["key"]); - return true; - } - - TEST KeySelfReferenceMap() - { - YAML::Node node; - node[node] = "value"; - YAML_ASSERT(node.IsMap()); - YAML_ASSERT(node.size() == 1); - YAML_ASSERT(node[node].as() == "value"); - return true; - } - - TEST SelfReferenceMap() - { - YAML::Node node; - node[node] = node; - YAML_ASSERT(node.IsMap()); - YAML_ASSERT(node.size() == 1); - YAML_ASSERT(node[node] == node); - YAML_ASSERT(node[node][node] == node); - YAML_ASSERT(node[node][node] == node[node]); - return true; - } - - TEST TempMapVariable() - { - YAML::Node node; - YAML::Node tmp = node["key"]; - tmp = "value"; - YAML_ASSERT(node.IsMap()); - YAML_ASSERT(node.size() == 1); - YAML_ASSERT(node["key"].as() == "value"); - return true; - } - - TEST TempMapVariableAlias() - { - YAML::Node node; - YAML::Node tmp = node["key"]; - tmp = node["other"]; - node["other"] = "value"; - YAML_ASSERT(node.IsMap()); - YAML_ASSERT(node.size() == 2); - YAML_ASSERT(node["key"].as() == "value"); - YAML_ASSERT(node["other"].as() == "value"); - YAML_ASSERT(node["other"] == node["key"]); - return true; - } - - TEST Bool() - { - YAML::Node node; - node[true] = false; - YAML_ASSERT(node.IsMap()); - YAML_ASSERT(node[true].as() == false); - return true; - } - - TEST AutoBoolConversion() - { - YAML::Node node; - node["foo"] = "bar"; - YAML_ASSERT(static_cast(node["foo"])); - YAML_ASSERT(!node["monkey"]); - YAML_ASSERT(!!node["foo"]); - return true; - } - - TEST Reassign() - { - YAML::Node node = YAML::Load("foo"); - node = YAML::Node(); - return true; - } - - TEST FallbackValues() - { - YAML::Node node = YAML::Load("foo: bar\nx: 2"); - YAML_ASSERT(node["foo"].as() == "bar"); - YAML_ASSERT(node["foo"].as("hello") == "bar"); - YAML_ASSERT(node["baz"].as("hello") == "hello"); - YAML_ASSERT(node["x"].as() == 2); - YAML_ASSERT(node["x"].as(5) == 2); - YAML_ASSERT(node["y"].as(5) == 5); - return true; - } - - TEST NumericConversion() - { - YAML::Node node = YAML::Load("[1.5, 1, .nan, .inf, -.inf, 0x15, 015]"); - YAML_ASSERT(node[0].as() == 1.5f); - YAML_ASSERT(node[0].as() == 1.5); - YAML_ASSERT_THROWS(node[0].as(), YAML::TypedBadConversion); - YAML_ASSERT(node[1].as() == 1); - YAML_ASSERT(node[1].as() == 1.0f); - YAML_ASSERT(node[2].as() != node[2].as()); - YAML_ASSERT(node[3].as() == std::numeric_limits::infinity()); - YAML_ASSERT(node[4].as() == -std::numeric_limits::infinity()); - YAML_ASSERT(node[5].as() == 21); - YAML_ASSERT(node[6].as() == 13); - return true; - } - - TEST Binary() - { - YAML::Node node = YAML::Load("[!!binary \"SGVsbG8sIFdvcmxkIQ==\", !!binary \"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4K\"]"); - YAML_ASSERT(node[0].as() == YAML::Binary(reinterpret_cast("Hello, World!"), 13)); - YAML_ASSERT(node[1].as() == YAML::Binary(reinterpret_cast("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)); - return true; - } - - TEST IterateSequence() - { - YAML::Node node = YAML::Load("[1, 3, 5, 7]"); - int seq[] = {1, 3, 5, 7}; - int i=0; - for(YAML::const_iterator it=node.begin();it!=node.end();++it) { - YAML_ASSERT(i < 4); - int x = seq[i++]; - YAML_ASSERT(it->as() == x); - } - YAML_ASSERT(i == 4); - return true; - } - - TEST IterateMap() - { - YAML::Node node = YAML::Load("{a: A, b: B, c: C}"); - int i=0; - for(YAML::const_iterator it=node.begin();it!=node.end();++it) { - YAML_ASSERT(i < 3); - i++; - YAML_ASSERT(it->first.as() + 'A' - 'a' == it->second.as()); - } - YAML_ASSERT(i == 3); - return true; - } - -#ifdef BOOST_FOREACH - TEST ForEach() - { - YAML::Node node = YAML::Load("[1, 3, 5, 7]"); - int seq[] = {1, 3, 5, 7}; - int i = 0; - BOOST_FOREACH(const YAML::Node &item, node) { - int x = seq[i++]; - YAML_ASSERT(item.as() == x); - } - return true; - } - - TEST ForEachMap() - { - YAML::Node node = YAML::Load("{a: A, b: B, c: C}"); - BOOST_FOREACH(const YAML::const_iterator::value_type &p, node) { - YAML_ASSERT(p.first.as() + 'A' - 'a' == p.second.as()); - } - return true; - } -#endif - - TEST CloneScalar() - { - YAML::Node node = YAML::Load("!foo monkey"); - YAML::Node clone = Clone(node); - YAML_ASSERT(!(node == clone)); - YAML_ASSERT(node.as() == clone.as()); - YAML_ASSERT(node.Tag() == clone.Tag()); - return true; - } - - TEST CloneSeq() - { - YAML::Node node = YAML::Load("[1, 3, 5, 7]"); - YAML::Node clone = Clone(node); - YAML_ASSERT(!(node == clone)); - YAML_ASSERT(clone.Type() == YAML::NodeType::Sequence); - YAML_ASSERT(node.size() == clone.size()); - for(std::size_t i=0;i() == clone[i].as()); - return true; - } - - TEST CloneMap() - { - YAML::Node node = YAML::Load("{foo: bar}"); - YAML::Node clone = Clone(node); - YAML_ASSERT(!(node == clone)); - YAML_ASSERT(clone.Type() == YAML::NodeType::Map); - YAML_ASSERT(node.size() == clone.size()); - YAML_ASSERT(node["foo"].as() == clone["foo"].as()); - return true; - } - - TEST CloneAlias() - { - YAML::Node node = YAML::Load("&foo [*foo]"); - YAML::Node clone = Clone(node); - YAML_ASSERT(!(node == clone)); - YAML_ASSERT(clone.Type() == YAML::NodeType::Sequence); - YAML_ASSERT(node.size() == clone.size()); - YAML_ASSERT(clone == clone[0]); - return true; - } - - TEST ForceInsertIntoMap() - { - YAML::Node node; - node["a"] = "b"; - node.force_insert("x", "y"); - node.force_insert("a", 5); - YAML_ASSERT(node.size() == 3); - YAML_ASSERT(node.Type() == YAML::NodeType::Map); - bool ab = false; - bool a5 = false; - bool xy = false; - for(YAML::const_iterator it=node.begin();it!=node.end();++it) { - if(it->first.as() == "a") { - if(it->second.as() == "b") - ab = true; - else if(it->second.as() == "5") - a5 = true; - } else if(it->first.as() == "x" && it->second.as() == "y") - xy = true; - } - YAML_ASSERT(ab); - YAML_ASSERT(a5); - YAML_ASSERT(xy); - return true; - } - - TEST ResetNode() - { - YAML::Node node = YAML::Load("[1, 2, 3]"); - YAML_ASSERT(!node.IsNull()); - YAML::Node other = node; - node.reset(); - YAML_ASSERT(node.IsNull()); - YAML_ASSERT(!other.IsNull()); - node.reset(other); - YAML_ASSERT(!node.IsNull()); - YAML_ASSERT(other == node); - return true; - } - - TEST DereferenceIteratorError() - { - YAML::Node node = YAML::Load("[{a: b}, 1, 2]"); - YAML_ASSERT_THROWS(node.begin()->first.as(), YAML::InvalidNode); - YAML_ASSERT((*node.begin()).IsMap() == true); - YAML_ASSERT(node.begin()->IsMap() == true); - YAML_ASSERT_THROWS((*node.begin()->begin()).IsDefined(), YAML::InvalidNode); - YAML_ASSERT_THROWS(node.begin()->begin()->IsDefined(), YAML::InvalidNode); - return true; - } - - TEST FloatingPrecision() - { - const double x = 0.123456789; - YAML::Node node = YAML::Node(x); - YAML_ASSERT(node.as() == x); - return true; - } - - TEST EmitEmptyNode() - { - YAML::Node node; - YAML::Emitter emitter; - emitter << node; - YAML_ASSERT(std::string(emitter.c_str()) == ""); - return true; - } - - TEST SpaceChar() - { - YAML::Node node = YAML::Node(' '); - YAML_ASSERT(node.as() == ' '); - return true; - } - } - - void RunNodeTest(TEST (*test)(), const std::string& name, int& passed, int& total) { - TEST ret; - try { - ret = test(); - } catch(const std::exception& e) { - ret.ok = false; - ret.error = e.what(); - } - if(ret.ok) { - passed++; - } else { - std::cout << "Node test failed: " << name << "\n"; - if(ret.error != "") - std::cout << ret.error << "\n"; - } - total++; - } - - bool RunNodeTests() - { - int passed = 0; - int total = 0; - - RunNodeTest(&Node::SimpleScalar, "simple scalar", passed, total); - RunNodeTest(&Node::IntScalar, "int scalar", passed, total); - RunNodeTest(&Node::SimpleAppendSequence, "simple append sequence", passed, total); - RunNodeTest(&Node::SimpleAssignSequence, "simple assign sequence", passed, total); - RunNodeTest(&Node::SimpleMap, "simple map", passed, total); - RunNodeTest(&Node::MapWithUndefinedValues, "map with undefined values", passed, total); - RunNodeTest(&Node::MapIteratorWithUndefinedValues, "map iterator with undefined values", passed, total); - RunNodeTest(&Node::SimpleSubkeys, "simple subkey", passed, total); - RunNodeTest(&Node::StdVector, "std::vector", passed, total); - RunNodeTest(&Node::StdList, "std::list", passed, total); - RunNodeTest(&Node::StdMap, "std::map", passed, total); - RunNodeTest(&Node::StdPair, "std::pair", passed, total); - RunNodeTest(&Node::SimpleAlias, "simple alias", passed, total); - RunNodeTest(&Node::AliasAsKey, "alias as key", passed, total); - RunNodeTest(&Node::SelfReferenceSequence, "self reference sequence", passed, total); - RunNodeTest(&Node::ValueSelfReferenceMap, "value self reference map", passed, total); - RunNodeTest(&Node::KeySelfReferenceMap, "key self reference map", passed, total); - RunNodeTest(&Node::SelfReferenceMap, "self reference map", passed, total); - RunNodeTest(&Node::TempMapVariable, "temp map variable", passed, total); - RunNodeTest(&Node::TempMapVariableAlias, "temp map variable alias", passed, total); - RunNodeTest(&Node::Bool, "bool", passed, total); - RunNodeTest(&Node::AutoBoolConversion, "auto bool conversion", passed, total); - RunNodeTest(&Node::Reassign, "reassign", passed, total); - RunNodeTest(&Node::FallbackValues, "fallback values", passed, total); - RunNodeTest(&Node::NumericConversion, "numeric conversion", passed, total); - RunNodeTest(&Node::Binary, "binary", passed, total); - RunNodeTest(&Node::IterateSequence, "iterate sequence", passed, total); - RunNodeTest(&Node::IterateMap, "iterate map", passed, total); -#ifdef BOOST_FOREACH - RunNodeTest(&Node::ForEach, "for each", passed, total); - RunNodeTest(&Node::ForEachMap, "for each map", passed, total); -#endif - RunNodeTest(&Node::CloneScalar, "clone scalar", passed, total); - RunNodeTest(&Node::CloneSeq, "clone seq", passed, total); - RunNodeTest(&Node::CloneMap, "clone map", passed, total); - RunNodeTest(&Node::CloneAlias, "clone alias", passed, total); - RunNodeTest(&Node::ForceInsertIntoMap, "force insert into map", passed, total); - RunNodeTest(&Node::ResetNode, "reset node", passed, total); - RunNodeTest(&Node::DereferenceIteratorError, "dereference iterator error", passed, total); - RunNodeTest(&Node::FloatingPrecision, "floating precision", passed, total); - RunNodeTest(&Node::EmitEmptyNode, "emit empty node", passed, total); - RunNodeTest(&Node::SpaceChar, "space char", passed, total); - - std::cout << "Node tests: " << passed << "/" << total << " passed\n"; - return passed == total; - } +namespace Test { +namespace Node { +TEST SimpleScalar() { + YAML::Node node = YAML::Node("Hello, World!"); + YAML_ASSERT(node.IsScalar()); + YAML_ASSERT(node.as() == "Hello, World!"); + return true; +} + +TEST IntScalar() { + YAML::Node node = YAML::Node(15); + YAML_ASSERT(node.IsScalar()); + YAML_ASSERT(node.as() == 15); + return true; +} + +TEST SimpleAppendSequence() { + YAML::Node node; + node.push_back(10); + node.push_back("foo"); + node.push_back("monkey"); + YAML_ASSERT(node.IsSequence()); + YAML_ASSERT(node.size() == 3); + YAML_ASSERT(node[0].as() == 10); + YAML_ASSERT(node[1].as() == "foo"); + YAML_ASSERT(node[2].as() == "monkey"); + YAML_ASSERT(node.IsSequence()); + return true; +} + +TEST SimpleAssignSequence() { + YAML::Node node; + node[0] = 10; + node[1] = "foo"; + node[2] = "monkey"; + YAML_ASSERT(node.IsSequence()); + YAML_ASSERT(node.size() == 3); + YAML_ASSERT(node[0].as() == 10); + YAML_ASSERT(node[1].as() == "foo"); + YAML_ASSERT(node[2].as() == "monkey"); + YAML_ASSERT(node.IsSequence()); + return true; +} + +TEST SimpleMap() { + YAML::Node node; + node["key"] = "value"; + YAML_ASSERT(node.IsMap()); + YAML_ASSERT(node["key"].as() == "value"); + YAML_ASSERT(node.size() == 1); + return true; +} + +TEST MapWithUndefinedValues() { + YAML::Node node; + node["key"] = "value"; + node["undefined"]; + YAML_ASSERT(node.IsMap()); + YAML_ASSERT(node["key"].as() == "value"); + YAML_ASSERT(node.size() == 1); + + node["undefined"] = "monkey"; + YAML_ASSERT(node["undefined"].as() == "monkey"); + YAML_ASSERT(node.size() == 2); + + return true; +} + +TEST MapIteratorWithUndefinedValues() { + YAML::Node node; + node["key"] = "value"; + node["undefined"]; + + std::size_t count = 0; + for (YAML::const_iterator it = node.begin(); it != node.end(); ++it) + count++; + YAML_ASSERT(count == 1); + return true; +} + +TEST SimpleSubkeys() { + YAML::Node node; + node["device"]["udid"] = "12345"; + node["device"]["name"] = "iPhone"; + node["device"]["os"] = "4.0"; + node["username"] = "monkey"; + YAML_ASSERT(node["device"]["udid"].as() == "12345"); + YAML_ASSERT(node["device"]["name"].as() == "iPhone"); + YAML_ASSERT(node["device"]["os"].as() == "4.0"); + YAML_ASSERT(node["username"].as() == "monkey"); + return true; +} + +TEST StdVector() { + std::vector primes; + primes.push_back(2); + primes.push_back(3); + primes.push_back(5); + primes.push_back(7); + primes.push_back(11); + primes.push_back(13); + + YAML::Node node; + node["primes"] = primes; + YAML_ASSERT(node["primes"].as >() == primes); + return true; +} + +TEST StdList() { + std::list primes; + primes.push_back(2); + primes.push_back(3); + primes.push_back(5); + primes.push_back(7); + primes.push_back(11); + primes.push_back(13); + + YAML::Node node; + node["primes"] = primes; + YAML_ASSERT(node["primes"].as >() == primes); + return true; +} + +TEST StdMap() { + std::map squares; + squares[0] = 0; + squares[1] = 1; + squares[2] = 4; + squares[3] = 9; + squares[4] = 16; + + YAML::Node node; + node["squares"] = squares; + YAML_ASSERT((node["squares"].as >() == squares)); + return true; +} + +TEST StdPair() { + std::pair p; + p.first = 5; + p.second = "five"; + + YAML::Node node; + node["pair"] = p; + YAML_ASSERT((node["pair"].as >() == p)); + return true; +} + +TEST SimpleAlias() { + YAML::Node node; + node["foo"] = "value"; + node["bar"] = node["foo"]; + YAML_ASSERT(node["foo"].as() == "value"); + YAML_ASSERT(node["bar"].as() == "value"); + YAML_ASSERT(node["foo"] == node["bar"]); + YAML_ASSERT(node.size() == 2); + return true; +} + +TEST AliasAsKey() { + YAML::Node node; + node["foo"] = "value"; + YAML::Node value = node["foo"]; + node[value] = "foo"; + YAML_ASSERT(node["foo"].as() == "value"); + YAML_ASSERT(node[value].as() == "foo"); + YAML_ASSERT(node["value"].as() == "foo"); + YAML_ASSERT(node.size() == 2); + return true; +} + +TEST SelfReferenceSequence() { + YAML::Node node; + node[0] = node; + YAML_ASSERT(node.IsSequence()); + YAML_ASSERT(node.size() == 1); + YAML_ASSERT(node[0] == node); + YAML_ASSERT(node[0][0] == node); + YAML_ASSERT(node[0][0] == node[0]); + return true; +} + +TEST ValueSelfReferenceMap() { + YAML::Node node; + node["key"] = node; + YAML_ASSERT(node.IsMap()); + YAML_ASSERT(node.size() == 1); + YAML_ASSERT(node["key"] == node); + YAML_ASSERT(node["key"]["key"] == node); + YAML_ASSERT(node["key"]["key"] == node["key"]); + return true; +} + +TEST KeySelfReferenceMap() { + YAML::Node node; + node[node] = "value"; + YAML_ASSERT(node.IsMap()); + YAML_ASSERT(node.size() == 1); + YAML_ASSERT(node[node].as() == "value"); + return true; +} + +TEST SelfReferenceMap() { + YAML::Node node; + node[node] = node; + YAML_ASSERT(node.IsMap()); + YAML_ASSERT(node.size() == 1); + YAML_ASSERT(node[node] == node); + YAML_ASSERT(node[node][node] == node); + YAML_ASSERT(node[node][node] == node[node]); + return true; +} + +TEST TempMapVariable() { + YAML::Node node; + YAML::Node tmp = node["key"]; + tmp = "value"; + YAML_ASSERT(node.IsMap()); + YAML_ASSERT(node.size() == 1); + YAML_ASSERT(node["key"].as() == "value"); + return true; +} + +TEST TempMapVariableAlias() { + YAML::Node node; + YAML::Node tmp = node["key"]; + tmp = node["other"]; + node["other"] = "value"; + YAML_ASSERT(node.IsMap()); + YAML_ASSERT(node.size() == 2); + YAML_ASSERT(node["key"].as() == "value"); + YAML_ASSERT(node["other"].as() == "value"); + YAML_ASSERT(node["other"] == node["key"]); + return true; +} + +TEST Bool() { + YAML::Node node; + node[true] = false; + YAML_ASSERT(node.IsMap()); + YAML_ASSERT(node[true].as() == false); + return true; +} + +TEST AutoBoolConversion() { + YAML::Node node; + node["foo"] = "bar"; + YAML_ASSERT(static_cast(node["foo"])); + YAML_ASSERT(!node["monkey"]); + YAML_ASSERT(!!node["foo"]); + return true; +} + +TEST Reassign() { + YAML::Node node = YAML::Load("foo"); + node = YAML::Node(); + return true; +} + +TEST FallbackValues() { + YAML::Node node = YAML::Load("foo: bar\nx: 2"); + YAML_ASSERT(node["foo"].as() == "bar"); + YAML_ASSERT(node["foo"].as("hello") == "bar"); + YAML_ASSERT(node["baz"].as("hello") == "hello"); + YAML_ASSERT(node["x"].as() == 2); + YAML_ASSERT(node["x"].as(5) == 2); + YAML_ASSERT(node["y"].as(5) == 5); + return true; +} + +TEST NumericConversion() { + YAML::Node node = YAML::Load("[1.5, 1, .nan, .inf, -.inf, 0x15, 015]"); + YAML_ASSERT(node[0].as() == 1.5f); + YAML_ASSERT(node[0].as() == 1.5); + YAML_ASSERT_THROWS(node[0].as(), YAML::TypedBadConversion); + YAML_ASSERT(node[1].as() == 1); + YAML_ASSERT(node[1].as() == 1.0f); + YAML_ASSERT(node[2].as() != node[2].as()); + YAML_ASSERT(node[3].as() == std::numeric_limits::infinity()); + YAML_ASSERT(node[4].as() == -std::numeric_limits::infinity()); + YAML_ASSERT(node[5].as() == 21); + YAML_ASSERT(node[6].as() == 13); + return true; +} + +TEST Binary() { + YAML::Node node = YAML::Load( + "[!!binary \"SGVsbG8sIFdvcmxkIQ==\", !!binary " + "\"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieS" + "B0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIG" + "x1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbi" + "B0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZG" + "dlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS" + "4K\"]"); + YAML_ASSERT(node[0].as() == + YAML::Binary( + reinterpret_cast("Hello, World!"), 13)); + YAML_ASSERT(node[1].as() == + YAML::Binary(reinterpret_cast( + "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)); + return true; +} + +TEST IterateSequence() { + YAML::Node node = YAML::Load("[1, 3, 5, 7]"); + int seq[] = {1, 3, 5, 7}; + int i = 0; + for (YAML::const_iterator it = node.begin(); it != node.end(); ++it) { + YAML_ASSERT(i < 4); + int x = seq[i++]; + YAML_ASSERT(it->as() == x); + } + YAML_ASSERT(i == 4); + return true; +} + +TEST IterateMap() { + YAML::Node node = YAML::Load("{a: A, b: B, c: C}"); + int i = 0; + for (YAML::const_iterator it = node.begin(); it != node.end(); ++it) { + YAML_ASSERT(i < 3); + i++; + YAML_ASSERT(it->first.as() + 'A' - 'a' == it->second.as()); + } + YAML_ASSERT(i == 3); + return true; +} + +#ifdef BOOST_FOREACH +TEST ForEach() { + YAML::Node node = YAML::Load("[1, 3, 5, 7]"); + int seq[] = {1, 3, 5, 7}; + int i = 0; + BOOST_FOREACH(const YAML::Node & item, node) { + int x = seq[i++]; + YAML_ASSERT(item.as() == x); + } + return true; +} + +TEST ForEachMap() { + YAML::Node node = YAML::Load("{a: A, b: B, c: C}"); + BOOST_FOREACH(const YAML::const_iterator::value_type & p, node) { + YAML_ASSERT(p.first.as() + 'A' - 'a' == p.second.as()); + } + return true; +} +#endif + +TEST CloneScalar() { + YAML::Node node = YAML::Load("!foo monkey"); + YAML::Node clone = Clone(node); + YAML_ASSERT(!(node == clone)); + YAML_ASSERT(node.as() == clone.as()); + YAML_ASSERT(node.Tag() == clone.Tag()); + return true; +} + +TEST CloneSeq() { + YAML::Node node = YAML::Load("[1, 3, 5, 7]"); + YAML::Node clone = Clone(node); + YAML_ASSERT(!(node == clone)); + YAML_ASSERT(clone.Type() == YAML::NodeType::Sequence); + YAML_ASSERT(node.size() == clone.size()); + for (std::size_t i = 0; i < node.size(); i++) + YAML_ASSERT(node[i].as() == clone[i].as()); + return true; +} + +TEST CloneMap() { + YAML::Node node = YAML::Load("{foo: bar}"); + YAML::Node clone = Clone(node); + YAML_ASSERT(!(node == clone)); + YAML_ASSERT(clone.Type() == YAML::NodeType::Map); + YAML_ASSERT(node.size() == clone.size()); + YAML_ASSERT(node["foo"].as() == clone["foo"].as()); + return true; +} + +TEST CloneAlias() { + YAML::Node node = YAML::Load("&foo [*foo]"); + YAML::Node clone = Clone(node); + YAML_ASSERT(!(node == clone)); + YAML_ASSERT(clone.Type() == YAML::NodeType::Sequence); + YAML_ASSERT(node.size() == clone.size()); + YAML_ASSERT(clone == clone[0]); + return true; +} + +TEST ForceInsertIntoMap() { + YAML::Node node; + node["a"] = "b"; + node.force_insert("x", "y"); + node.force_insert("a", 5); + YAML_ASSERT(node.size() == 3); + YAML_ASSERT(node.Type() == YAML::NodeType::Map); + bool ab = false; + bool a5 = false; + bool xy = false; + for (YAML::const_iterator it = node.begin(); it != node.end(); ++it) { + if (it->first.as() == "a") { + if (it->second.as() == "b") + ab = true; + else if (it->second.as() == "5") + a5 = true; + } else if (it->first.as() == "x" && + it->second.as() == "y") + xy = true; + } + YAML_ASSERT(ab); + YAML_ASSERT(a5); + YAML_ASSERT(xy); + return true; +} + +TEST ResetNode() { + YAML::Node node = YAML::Load("[1, 2, 3]"); + YAML_ASSERT(!node.IsNull()); + YAML::Node other = node; + node.reset(); + YAML_ASSERT(node.IsNull()); + YAML_ASSERT(!other.IsNull()); + node.reset(other); + YAML_ASSERT(!node.IsNull()); + YAML_ASSERT(other == node); + return true; +} + +TEST DereferenceIteratorError() { + YAML::Node node = YAML::Load("[{a: b}, 1, 2]"); + YAML_ASSERT_THROWS(node.begin()->first.as(), YAML::InvalidNode); + YAML_ASSERT((*node.begin()).IsMap() == true); + YAML_ASSERT(node.begin()->IsMap() == true); + YAML_ASSERT_THROWS((*node.begin()->begin()).IsDefined(), YAML::InvalidNode); + YAML_ASSERT_THROWS(node.begin()->begin()->IsDefined(), YAML::InvalidNode); + return true; +} + +TEST FloatingPrecision() { + const double x = 0.123456789; + YAML::Node node = YAML::Node(x); + YAML_ASSERT(node.as() == x); + return true; +} + +TEST EmitEmptyNode() { + YAML::Node node; + YAML::Emitter emitter; + emitter << node; + YAML_ASSERT(std::string(emitter.c_str()) == ""); + return true; +} + +TEST SpaceChar() { + YAML::Node node = YAML::Node(' '); + YAML_ASSERT(node.as() == ' '); + return true; +} +} + +void RunNodeTest(TEST (*test)(), const std::string& name, int& passed, + int& total) { + TEST ret; + try { + ret = test(); + } + catch (const std::exception& e) { + ret.ok = false; + ret.error = e.what(); + } + if (ret.ok) { + passed++; + } else { + std::cout << "Node test failed: " << name << "\n"; + if (ret.error != "") + std::cout << ret.error << "\n"; + } + total++; +} + +bool RunNodeTests() { + int passed = 0; + int total = 0; + + RunNodeTest(&Node::SimpleScalar, "simple scalar", passed, total); + RunNodeTest(&Node::IntScalar, "int scalar", passed, total); + RunNodeTest(&Node::SimpleAppendSequence, "simple append sequence", passed, + total); + RunNodeTest(&Node::SimpleAssignSequence, "simple assign sequence", passed, + total); + RunNodeTest(&Node::SimpleMap, "simple map", passed, total); + RunNodeTest(&Node::MapWithUndefinedValues, "map with undefined values", + passed, total); + RunNodeTest(&Node::MapIteratorWithUndefinedValues, + "map iterator with undefined values", passed, total); + RunNodeTest(&Node::SimpleSubkeys, "simple subkey", passed, total); + RunNodeTest(&Node::StdVector, "std::vector", passed, total); + RunNodeTest(&Node::StdList, "std::list", passed, total); + RunNodeTest(&Node::StdMap, "std::map", passed, total); + RunNodeTest(&Node::StdPair, "std::pair", passed, total); + RunNodeTest(&Node::SimpleAlias, "simple alias", passed, total); + RunNodeTest(&Node::AliasAsKey, "alias as key", passed, total); + RunNodeTest(&Node::SelfReferenceSequence, "self reference sequence", passed, + total); + RunNodeTest(&Node::ValueSelfReferenceMap, "value self reference map", passed, + total); + RunNodeTest(&Node::KeySelfReferenceMap, "key self reference map", passed, + total); + RunNodeTest(&Node::SelfReferenceMap, "self reference map", passed, total); + RunNodeTest(&Node::TempMapVariable, "temp map variable", passed, total); + RunNodeTest(&Node::TempMapVariableAlias, "temp map variable alias", passed, + total); + RunNodeTest(&Node::Bool, "bool", passed, total); + RunNodeTest(&Node::AutoBoolConversion, "auto bool conversion", passed, total); + RunNodeTest(&Node::Reassign, "reassign", passed, total); + RunNodeTest(&Node::FallbackValues, "fallback values", passed, total); + RunNodeTest(&Node::NumericConversion, "numeric conversion", passed, total); + RunNodeTest(&Node::Binary, "binary", passed, total); + RunNodeTest(&Node::IterateSequence, "iterate sequence", passed, total); + RunNodeTest(&Node::IterateMap, "iterate map", passed, total); +#ifdef BOOST_FOREACH + RunNodeTest(&Node::ForEach, "for each", passed, total); + RunNodeTest(&Node::ForEachMap, "for each map", passed, total); +#endif + RunNodeTest(&Node::CloneScalar, "clone scalar", passed, total); + RunNodeTest(&Node::CloneSeq, "clone seq", passed, total); + RunNodeTest(&Node::CloneMap, "clone map", passed, total); + RunNodeTest(&Node::CloneAlias, "clone alias", passed, total); + RunNodeTest(&Node::ForceInsertIntoMap, "force insert into map", passed, + total); + RunNodeTest(&Node::ResetNode, "reset node", passed, total); + RunNodeTest(&Node::DereferenceIteratorError, "dereference iterator error", + passed, total); + RunNodeTest(&Node::FloatingPrecision, "floating precision", passed, total); + RunNodeTest(&Node::EmitEmptyNode, "emit empty node", passed, total); + RunNodeTest(&Node::SpaceChar, "space char", passed, total); + + std::cout << "Node tests: " << passed << "/" << total << " passed\n"; + return passed == total; +} } diff --git a/test/new-api/parsertests.cpp b/test/new-api/parsertests.cpp index 1d50ca6..2662ab4 100644 --- a/test/new-api/parsertests.cpp +++ b/test/new-api/parsertests.cpp @@ -1,8 +1,5 @@ #include "parsertests.h" namespace Test { - bool RunParserTests() - { - return true; - } +bool RunParserTests() { return true; } } diff --git a/test/new-api/spectests.cpp b/test/new-api/spectests.cpp index 328ae7a..52b4e7e 100644 --- a/test/new-api/spectests.cpp +++ b/test/new-api/spectests.cpp @@ -3,1363 +3,1423 @@ #include "yaml-cpp/yaml.h" #include -#define YAML_ASSERT(cond) do { if(!(cond)) return " Assert failed: " #cond; } while(false) +#define YAML_ASSERT(cond) \ + do { \ + if (!(cond)) \ + return " Assert failed: " #cond; \ + } while (false) -namespace Test -{ - namespace Spec - { - // 2.1 - TEST SeqScalars() { - YAML::Node doc = YAML::Load(ex2_1); - YAML_ASSERT(doc.IsSequence()); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc[0].as() == "Mark McGwire"); - YAML_ASSERT(doc[1].as() == "Sammy Sosa"); - YAML_ASSERT(doc[2].as() == "Ken Griffey"); - return true; - } - - // 2.2 - TEST MappingScalarsToScalars() { - YAML::Node doc = YAML::Load(ex2_2); - YAML_ASSERT(doc.IsMap()); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["hr"].as() == "65"); - YAML_ASSERT(doc["avg"].as() == "0.278"); - YAML_ASSERT(doc["rbi"].as() == "147"); - return true; - } - - // 2.3 - TEST MappingScalarsToSequences() { - YAML::Node doc = YAML::Load(ex2_3); - YAML_ASSERT(doc.IsMap()); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["american"].size() == 3); - YAML_ASSERT(doc["american"][0].as() == "Boston Red Sox"); - YAML_ASSERT(doc["american"][1].as() == "Detroit Tigers"); - YAML_ASSERT(doc["american"][2].as() == "New York Yankees"); - YAML_ASSERT(doc["national"].size() == 3); - YAML_ASSERT(doc["national"][0].as() == "New York Mets"); - YAML_ASSERT(doc["national"][1].as() == "Chicago Cubs"); - YAML_ASSERT(doc["national"][2].as() == "Atlanta Braves"); - return true; - } - - // 2.4 - TEST SequenceOfMappings() { - YAML::Node doc = YAML::Load(ex2_4); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc[0].size() == 3); - YAML_ASSERT(doc[0]["name"].as() == "Mark McGwire"); - YAML_ASSERT(doc[0]["hr"].as() == "65"); - YAML_ASSERT(doc[0]["avg"].as() == "0.278"); - YAML_ASSERT(doc[1].size() == 3); - YAML_ASSERT(doc[1]["name"].as() == "Sammy Sosa"); - YAML_ASSERT(doc[1]["hr"].as() == "63"); - YAML_ASSERT(doc[1]["avg"].as() == "0.288"); - return true; - } - - // 2.5 - TEST SequenceOfSequences() { - YAML::Node doc = YAML::Load(ex2_5); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc[0].size() == 3); - YAML_ASSERT(doc[0][0].as() == "name"); - YAML_ASSERT(doc[0][1].as() == "hr"); - YAML_ASSERT(doc[0][2].as() == "avg"); - YAML_ASSERT(doc[1].size() == 3); - YAML_ASSERT(doc[1][0].as() == "Mark McGwire"); - YAML_ASSERT(doc[1][1].as() == "65"); - YAML_ASSERT(doc[1][2].as() == "0.278"); - YAML_ASSERT(doc[2].size() == 3); - YAML_ASSERT(doc[2][0].as() == "Sammy Sosa"); - YAML_ASSERT(doc[2][1].as() == "63"); - YAML_ASSERT(doc[2][2].as() == "0.288"); - return true; - } - - // 2.6 - TEST MappingOfMappings() { - YAML::Node doc = YAML::Load(ex2_6); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["Mark McGwire"].size() == 2); - YAML_ASSERT(doc["Mark McGwire"]["hr"].as() == "65"); - YAML_ASSERT(doc["Mark McGwire"]["avg"].as() == "0.278"); - YAML_ASSERT(doc["Sammy Sosa"].size() == 2); - YAML_ASSERT(doc["Sammy Sosa"]["hr"].as() == "63"); - YAML_ASSERT(doc["Sammy Sosa"]["avg"].as() == "0.288"); - return true; - } - - // 2.7 - TEST TwoDocumentsInAStream() { - std::vector 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() == "Mark McGwire"); - YAML_ASSERT(doc[1].as() == "Sammy Sosa"); - YAML_ASSERT(doc[2].as() == "Ken Griffey"); - } - - { - YAML::Node doc = docs[1]; - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc[0].as() == "Chicago Cubs"); - YAML_ASSERT(doc[1].as() == "St Louis Cardinals"); - } - return true; - } - - // 2.8 - TEST PlayByPlayFeed() { - std::vector 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() == "20:03:20"); - YAML_ASSERT(doc["player"].as() == "Sammy Sosa"); - YAML_ASSERT(doc["action"].as() == "strike (miss)"); - } - - { - YAML::Node doc = docs[1]; - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["time"].as() == "20:03:47"); - YAML_ASSERT(doc["player"].as() == "Sammy Sosa"); - YAML_ASSERT(doc["action"].as() == "grand slam"); - } - return true; - } - - // 2.9 - TEST SingleDocumentWithTwoComments() { - YAML::Node doc = YAML::Load(ex2_9); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["hr"].size() == 2); - YAML_ASSERT(doc["hr"][0].as() == "Mark McGwire"); - YAML_ASSERT(doc["hr"][1].as() == "Sammy Sosa"); - YAML_ASSERT(doc["rbi"].size() == 2); - YAML_ASSERT(doc["rbi"][0].as() == "Sammy Sosa"); - YAML_ASSERT(doc["rbi"][1].as() == "Ken Griffey"); - return true; - } - - // 2.10 - TEST SimpleAnchor() { - YAML::Node doc = YAML::Load(ex2_10); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["hr"].size() == 2); - YAML_ASSERT(doc["hr"][0].as() == "Mark McGwire"); - YAML_ASSERT(doc["hr"][1].as() == "Sammy Sosa"); - YAML_ASSERT(doc["rbi"].size() == 2); - YAML_ASSERT(doc["rbi"][0].as() == "Sammy Sosa"); - YAML_ASSERT(doc["rbi"][1].as() == "Ken Griffey"); - return true; - } - - // 2.11 - TEST MappingBetweenSequences() { - YAML::Node doc = YAML::Load(ex2_11); - - std::vector tigers_cubs; - tigers_cubs.push_back("Detroit Tigers"); - tigers_cubs.push_back("Chicago cubs"); - - std::vector 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[tigers_cubs][0].as() == "2001-07-23"); - YAML_ASSERT(doc[yankees_braves].size() == 3); - YAML_ASSERT(doc[yankees_braves][0].as() == "2001-07-02"); - YAML_ASSERT(doc[yankees_braves][1].as() == "2001-08-12"); - YAML_ASSERT(doc[yankees_braves][2].as() == "2001-08-14"); - return true; - } - - // 2.12 - TEST CompactNestedMapping() { - YAML::Node doc = YAML::Load(ex2_12); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc[0].size() == 2); - YAML_ASSERT(doc[0]["item"].as() == "Super Hoop"); - YAML_ASSERT(doc[0]["quantity"].as() == 1); - YAML_ASSERT(doc[1].size() == 2); - YAML_ASSERT(doc[1]["item"].as() == "Basketball"); - YAML_ASSERT(doc[1]["quantity"].as() == 4); - YAML_ASSERT(doc[2].size() == 2); - YAML_ASSERT(doc[2]["item"].as() == "Big Shoes"); - YAML_ASSERT(doc[2]["quantity"].as() == 1); - return true; - } - - // 2.13 - TEST InLiteralsNewlinesArePreserved() { - YAML::Node doc = YAML::Load(ex2_13); - YAML_ASSERT(doc.as() == - "\\//||\\/||\n" - "// || ||__"); - return true; - } - - // 2.14 - TEST InFoldedScalarsNewlinesBecomeSpaces() { - YAML::Node doc = YAML::Load(ex2_14); - YAML_ASSERT(doc.as() == "Mark McGwire's year was crippled by a knee injury."); - return true; - } - - // 2.15 - TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines() { - YAML::Node doc = YAML::Load(ex2_15); - YAML_ASSERT(doc.as() == - "Sammy Sosa completed another fine season with great stats.\n\n" - " 63 Home Runs\n" - " 0.288 Batting Average\n\n" - "What a year!"); - return true; - } - - // 2.16 - TEST IndentationDeterminesScope() { - YAML::Node doc = YAML::Load(ex2_16); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["name"].as() == "Mark McGwire"); - YAML_ASSERT(doc["accomplishment"].as() == "Mark set a major league home run record in 1998.\n"); - YAML_ASSERT(doc["stats"].as() == "65 Home Runs\n0.278 Batting Average\n"); - return true; - } - - // 2.17 - TEST QuotedScalars() { - YAML::Node doc = YAML::Load(ex2_17); - YAML_ASSERT(doc.size() == 6); - YAML_ASSERT(doc["unicode"].as() == "Sosa did fine.\xe2\x98\xba"); - YAML_ASSERT(doc["control"].as() == "\b1998\t1999\t2000\n"); - YAML_ASSERT(doc["hex esc"].as() == "\x0d\x0a is \r\n"); - YAML_ASSERT(doc["single"].as() == "\"Howdy!\" he cried."); - YAML_ASSERT(doc["quoted"].as() == " # Not a 'comment'."); - YAML_ASSERT(doc["tie-fighter"].as() == "|\\-*-/|"); - return true; - } - - // 2.18 - TEST MultiLineFlowScalars() { - YAML::Node doc = YAML::Load(ex2_18); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["plain"].as() == "This unquoted scalar spans many lines."); - YAML_ASSERT(doc["quoted"].as() == "So does this quoted scalar.\n"); - return true; - } - - // TODO: 2.19 - 2.22 schema tags - - // 2.23 - TEST VariousExplicitTags() { - YAML::Node doc = YAML::Load(ex2_23); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["not-date"].Tag() == "tag:yaml.org,2002:str"); - YAML_ASSERT(doc["not-date"].as() == "2002-04-28"); - YAML_ASSERT(doc["picture"].Tag() == "tag:yaml.org,2002:binary"); - YAML_ASSERT(doc["picture"].as() == - "R0lGODlhDAAMAIQAAP//9/X\n" - "17unp5WZmZgAAAOfn515eXv\n" - "Pz7Y6OjuDg4J+fn5OTk6enp\n" - "56enmleECcgggoBADs=\n" - ); - YAML_ASSERT(doc["application specific tag"].Tag() == "!something"); - YAML_ASSERT(doc["application specific tag"].as() == - "The semantics of the tag\n" - "above may be different for\n" - "different documents." - ); - return true; - } - - // 2.24 - TEST GlobalTags() { - YAML::Node doc = YAML::Load(ex2_24); - YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:shape"); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc[0].Tag() == "tag:clarkevans.com,2002:circle"); - YAML_ASSERT(doc[0].size() == 2); - YAML_ASSERT(doc[0]["center"].size() == 2); - YAML_ASSERT(doc[0]["center"]["x"].as() == 73); - YAML_ASSERT(doc[0]["center"]["y"].as() == 129); - YAML_ASSERT(doc[0]["radius"].as() == 7); - YAML_ASSERT(doc[1].Tag() == "tag:clarkevans.com,2002:line"); - YAML_ASSERT(doc[1].size() == 2); - YAML_ASSERT(doc[1]["start"].size() == 2); - YAML_ASSERT(doc[1]["start"]["x"].as() == 73); - YAML_ASSERT(doc[1]["start"]["y"].as() == 129); - YAML_ASSERT(doc[1]["finish"].size() == 2); - YAML_ASSERT(doc[1]["finish"]["x"].as() == 89); - YAML_ASSERT(doc[1]["finish"]["y"].as() == 102); - YAML_ASSERT(doc[2].Tag() == "tag:clarkevans.com,2002:label"); - YAML_ASSERT(doc[2].size() == 3); - YAML_ASSERT(doc[2]["start"].size() == 2); - YAML_ASSERT(doc[2]["start"]["x"].as() == 73); - YAML_ASSERT(doc[2]["start"]["y"].as() == 129); - YAML_ASSERT(doc[2]["color"].as() == "0xFFEEBB"); - YAML_ASSERT(doc[2]["text"].as() == "Pretty vector drawing."); - return true; - } - - // 2.25 - TEST UnorderedSets() { - YAML::Node doc = YAML::Load(ex2_25); - YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:set"); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["Mark McGwire"].IsNull()); - YAML_ASSERT(doc["Sammy Sosa"].IsNull()); - YAML_ASSERT(doc["Ken Griffey"].IsNull()); - return true; - } - - // 2.26 - TEST OrderedMappings() { - YAML::Node doc = YAML::Load(ex2_26); - YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:omap"); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc[0].size() == 1); - YAML_ASSERT(doc[0]["Mark McGwire"].as() == 65); - YAML_ASSERT(doc[1].size() == 1); - YAML_ASSERT(doc[1]["Sammy Sosa"].as() == 63); - YAML_ASSERT(doc[2].size() == 1); - YAML_ASSERT(doc[2]["Ken Griffey"].as() == 58); - return true; - } - - // 2.27 - TEST Invoice() { - YAML::Node doc = YAML::Load(ex2_27); - YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:invoice"); - YAML_ASSERT(doc.size() == 8); - YAML_ASSERT(doc["invoice"].as() == 34843); - YAML_ASSERT(doc["date"].as() == "2001-01-23"); - YAML_ASSERT(doc["bill-to"].size() == 3); - YAML_ASSERT(doc["bill-to"]["given"].as() == "Chris"); - YAML_ASSERT(doc["bill-to"]["family"].as() == "Dumars"); - YAML_ASSERT(doc["bill-to"]["address"].size() == 4); - YAML_ASSERT(doc["bill-to"]["address"]["lines"].as() == "458 Walkman Dr.\nSuite #292\n"); - YAML_ASSERT(doc["bill-to"]["address"]["city"].as() == "Royal Oak"); - YAML_ASSERT(doc["bill-to"]["address"]["state"].as() == "MI"); - YAML_ASSERT(doc["bill-to"]["address"]["postal"].as() == "48046"); - YAML_ASSERT(doc["ship-to"].size() == 3); - YAML_ASSERT(doc["ship-to"]["given"].as() == "Chris"); - YAML_ASSERT(doc["ship-to"]["family"].as() == "Dumars"); - YAML_ASSERT(doc["ship-to"]["address"].size() == 4); - YAML_ASSERT(doc["ship-to"]["address"]["lines"].as() == "458 Walkman Dr.\nSuite #292\n"); - YAML_ASSERT(doc["ship-to"]["address"]["city"].as() == "Royal Oak"); - YAML_ASSERT(doc["ship-to"]["address"]["state"].as() == "MI"); - YAML_ASSERT(doc["ship-to"]["address"]["postal"].as() == "48046"); - YAML_ASSERT(doc["product"].size() == 2); - YAML_ASSERT(doc["product"][0].size() == 4); - YAML_ASSERT(doc["product"][0]["sku"].as() == "BL394D"); - YAML_ASSERT(doc["product"][0]["quantity"].as() == 4); - YAML_ASSERT(doc["product"][0]["description"].as() == "Basketball"); - YAML_ASSERT(doc["product"][0]["price"].as() == "450.00"); - YAML_ASSERT(doc["product"][1].size() == 4); - YAML_ASSERT(doc["product"][1]["sku"].as() == "BL4438H"); - YAML_ASSERT(doc["product"][1]["quantity"].as() == 1); - YAML_ASSERT(doc["product"][1]["description"].as() == "Super Hoop"); - YAML_ASSERT(doc["product"][1]["price"].as() == "2392.00"); - YAML_ASSERT(doc["tax"].as() == "251.42"); - YAML_ASSERT(doc["total"].as() == "4443.52"); - YAML_ASSERT(doc["comments"].as() == "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338."); - return true; - } - - // 2.28 - TEST LogFile() { - std::vector docs = YAML::LoadAll(ex2_28); - YAML_ASSERT(docs.size() == 3); - - { - YAML::Node doc = docs[0]; - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["Time"].as() == "2001-11-23 15:01:42 -5"); - YAML_ASSERT(doc["User"].as() == "ed"); - YAML_ASSERT(doc["Warning"].as() == "This is an error message for the log file"); - } - - { - YAML::Node doc = docs[1]; - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["Time"].as() == "2001-11-23 15:02:31 -5"); - YAML_ASSERT(doc["User"].as() == "ed"); - YAML_ASSERT(doc["Warning"].as() == "A slightly different error message."); - } - - { - YAML::Node doc = docs[2]; - YAML_ASSERT(doc.size() == 4); - YAML_ASSERT(doc["Date"].as() == "2001-11-23 15:03:17 -5"); - YAML_ASSERT(doc["User"].as() == "ed"); - YAML_ASSERT(doc["Fatal"].as() == "Unknown variable \"bar\""); - YAML_ASSERT(doc["Stack"].size() == 2); - YAML_ASSERT(doc["Stack"][0].size() == 3); - YAML_ASSERT(doc["Stack"][0]["file"].as() == "TopClass.py"); - YAML_ASSERT(doc["Stack"][0]["line"].as() == "23"); - YAML_ASSERT(doc["Stack"][0]["code"].as() == "x = MoreObject(\"345\\n\")\n"); - YAML_ASSERT(doc["Stack"][1].size() == 3); - YAML_ASSERT(doc["Stack"][1]["file"].as() == "MoreClass.py"); - YAML_ASSERT(doc["Stack"][1]["line"].as() == "58"); - YAML_ASSERT(doc["Stack"][1]["code"].as() == "foo = bar"); - } - return true; - } - - // TODO: 5.1 - 5.2 BOM - - // 5.3 - TEST BlockStructureIndicators() { - YAML::Node doc = YAML::Load(ex5_3); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["sequence"].size() == 2); - YAML_ASSERT(doc["sequence"][0].as() == "one"); - YAML_ASSERT(doc["sequence"][1].as() == "two"); - YAML_ASSERT(doc["mapping"].size() == 2); - YAML_ASSERT(doc["mapping"]["sky"].as() == "blue"); - YAML_ASSERT(doc["mapping"]["sea"].as() == "green"); - return true; - } - - // 5.4 - TEST FlowStructureIndicators() { - YAML::Node doc = YAML::Load(ex5_4); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["sequence"].size() == 2); - YAML_ASSERT(doc["sequence"][0].as() == "one"); - YAML_ASSERT(doc["sequence"][1].as() == "two"); - YAML_ASSERT(doc["mapping"].size() == 2); - YAML_ASSERT(doc["mapping"]["sky"].as() == "blue"); - YAML_ASSERT(doc["mapping"]["sea"].as() == "green"); - return true; - } - - // 5.5 - TEST CommentIndicator() { - YAML::Node doc = YAML::Load(ex5_5); - YAML_ASSERT(doc.IsNull()); - return true; - } - - // 5.6 - TEST NodePropertyIndicators() { - YAML::Node doc = YAML::Load(ex5_6); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["anchored"].as() == "value"); // TODO: assert tag - YAML_ASSERT(doc["alias"].as() == "value"); - return true; - } - - // 5.7 - TEST BlockScalarIndicators() { - YAML::Node doc = YAML::Load(ex5_7); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["literal"].as() == "some\ntext\n"); - YAML_ASSERT(doc["folded"].as() == "some text\n"); - return true; - } - - // 5.8 - TEST QuotedScalarIndicators() { - YAML::Node doc = YAML::Load(ex5_8); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["single"].as() == "text"); - YAML_ASSERT(doc["double"].as() == "text"); - return true; - } - - // TODO: 5.9 directive - // TODO: 5.10 reserved indicator - - // 5.11 - TEST LineBreakCharacters() { - YAML::Node doc = YAML::Load(ex5_11); - YAML_ASSERT(doc.as() == "Line break (no glyph)\nLine break (glyphed)\n"); - return true; - } - - // 5.12 - TEST TabsAndSpaces() { - YAML::Node doc = YAML::Load(ex5_12); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["quoted"].as() == "Quoted\t"); - YAML_ASSERT(doc["block"].as() == - "void main() {\n" - "\tprintf(\"Hello, world!\\n\");\n" - "}"); - return true; - } - - // 5.13 - TEST EscapedCharacters() { - YAML::Node doc = YAML::Load(ex5_13); - YAML_ASSERT(doc.as() == "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.14 - TEST InvalidEscapedCharacters() { - try { - YAML::Load(ex5_14); - } catch(const YAML::ParserException& e) { - YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::INVALID_ESCAPE) + "c"); - return true; - } - - return false; - } - - // 6.1 - TEST IndentationSpaces() { - YAML::Node doc = YAML::Load(ex6_1); - YAML_ASSERT(doc.size() == 1); - YAML_ASSERT(doc["Not indented"].size() == 2); - YAML_ASSERT(doc["Not indented"]["By one space"].as() == "By four\n spaces\n"); - YAML_ASSERT(doc["Not indented"]["Flow style"].size() == 3); - YAML_ASSERT(doc["Not indented"]["Flow style"][0].as() == "By two"); - YAML_ASSERT(doc["Not indented"]["Flow style"][1].as() == "Also by two"); - YAML_ASSERT(doc["Not indented"]["Flow style"][2].as() == "Still by two"); - return true; - } - - // 6.2 - TEST IndentationIndicators() { - YAML::Node doc = YAML::Load(ex6_2); - YAML_ASSERT(doc.size() == 1); - YAML_ASSERT(doc["a"].size() == 2); - YAML_ASSERT(doc["a"][0].as() == "b"); - YAML_ASSERT(doc["a"][1].size() == 2); - YAML_ASSERT(doc["a"][1][0].as() == "c"); - YAML_ASSERT(doc["a"][1][1].as() == "d"); - return true; - } - - // 6.3 - TEST SeparationSpaces() { - YAML::Node doc = YAML::Load(ex6_3); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc[0].size() == 1); - YAML_ASSERT(doc[0]["foo"].as() == "bar"); - YAML_ASSERT(doc[1].size() == 2); - YAML_ASSERT(doc[1][0].as() == "baz"); - YAML_ASSERT(doc[1][1].as() == "baz"); - return true; - } - - // 6.4 - TEST LinePrefixes() { - YAML::Node doc = YAML::Load(ex6_4); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["plain"].as() == "text lines"); - YAML_ASSERT(doc["quoted"].as() == "text lines"); - YAML_ASSERT(doc["block"].as() == "text\n \tlines\n"); - return true; - } - - // 6.5 - TEST EmptyLines() { - YAML::Node doc = YAML::Load(ex6_5); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["Folding"].as() == "Empty line\nas a line feed"); - YAML_ASSERT(doc["Chomping"].as() == "Clipped empty lines\n"); - return true; - } - - // 6.6 - TEST LineFolding() { - YAML::Node doc = YAML::Load(ex6_6); - YAML_ASSERT(doc.as() == "trimmed\n\n\nas space"); - return true; - } - - // 6.7 - TEST BlockFolding() { - YAML::Node doc = YAML::Load(ex6_7); - YAML_ASSERT(doc.as() == "foo \n\n\t bar\n\nbaz\n"); - return true; - } - - // 6.8 - TEST FlowFolding() { - YAML::Node doc = YAML::Load(ex6_8); - YAML_ASSERT(doc.as() == " foo\nbar\nbaz "); - return true; - } - - // 6.9 - TEST SeparatedComment() { - YAML::Node doc = YAML::Load(ex6_9); - YAML_ASSERT(doc.size() == 1); - YAML_ASSERT(doc["key"].as() == "value"); - return true; - } - - // 6.10 - TEST CommentLines() { - YAML::Node doc = YAML::Load(ex6_10); - YAML_ASSERT(doc.IsNull()); - return true; - } - - // 6.11 - TEST MultiLineComments() { - YAML::Node doc = YAML::Load(ex6_11); - YAML_ASSERT(doc.size() == 1); - YAML_ASSERT(doc["key"].as() == "value"); - return true; - } - - // 6.12 - TEST SeparationSpacesII() { - YAML::Node doc = YAML::Load(ex6_12); - - std::map sammy; - sammy["first"] = "Sammy"; - sammy["last"] = "Sosa"; - - YAML_ASSERT(doc.size() == 1); - YAML_ASSERT(doc[sammy].size() == 2); - YAML_ASSERT(doc[sammy]["hr"].as() == 65); - YAML_ASSERT(doc[sammy]["avg"].as() == "0.278"); - return true; - } - - // 6.13 - TEST ReservedDirectives() { - YAML::Node doc = YAML::Load(ex6_13); - YAML_ASSERT(doc.as() == "foo"); - return true; - } - - // 6.14 - TEST YAMLDirective() { - YAML::Node doc = YAML::Load(ex6_14); - YAML_ASSERT(doc.as() == "foo"); - return true; - } - - // 6.15 - TEST InvalidRepeatedYAMLDirective() { - try { - YAML::Load(ex6_15); - } catch(const YAML::ParserException& e) { - YAML_ASSERT(e.msg == YAML::ErrorMsg::REPEATED_YAML_DIRECTIVE); - return true; - } - - return " No exception was thrown"; - } - - // 6.16 - TEST TagDirective() { - YAML::Node doc = YAML::Load(ex6_16); - YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:str"); - YAML_ASSERT(doc.as() == "foo"); - return true; - } - - // 6.17 - TEST InvalidRepeatedTagDirective() { - try { - YAML::Load(ex6_17); - } catch(const YAML::ParserException& e) { - if(e.msg == YAML::ErrorMsg::REPEATED_TAG_DIRECTIVE) - return true; - - throw; - } - - return " No exception was thrown"; - } - - // 6.18 - TEST PrimaryTagHandle() { - std::vector docs = YAML::LoadAll(ex6_18); - YAML_ASSERT(docs.size() == 2); - - { - YAML::Node doc = docs[0]; - YAML_ASSERT(doc.Tag() == "!foo"); - YAML_ASSERT(doc.as() == "bar"); - } - - { - YAML::Node doc = docs[1]; - YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo"); - YAML_ASSERT(doc.as() == "bar"); - } - return true; - } - - // 6.19 - TEST SecondaryTagHandle() { - YAML::Node doc = YAML::Load(ex6_19); - YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/int"); - YAML_ASSERT(doc.as() == "1 - 3"); - return true; - } - - // 6.20 - TEST TagHandles() { - YAML::Node doc = YAML::Load(ex6_20); - YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo"); - YAML_ASSERT(doc.as() == "bar"); - return true; - } - - // 6.21 - TEST LocalTagPrefix() { - std::vector docs = YAML::LoadAll(ex6_21); - YAML_ASSERT(docs.size() == 2); - - { - YAML::Node doc = docs[0]; - YAML_ASSERT(doc.Tag() == "!my-light"); - YAML_ASSERT(doc.as() == "fluorescent"); - } - - { - YAML::Node doc = docs[1]; - YAML_ASSERT(doc.Tag() == "!my-light"); - YAML_ASSERT(doc.as() == "green"); - } - return true; - } - - // 6.22 - TEST GlobalTagPrefix() { - YAML::Node doc = YAML::Load(ex6_22); - YAML_ASSERT(doc.size() == 1); - YAML_ASSERT(doc[0].Tag() == "tag:example.com,2000:app/foo"); - YAML_ASSERT(doc[0].as() == "bar"); - return true; - } - - // 6.23 - TEST NodeProperties() { - YAML::Node doc = YAML::Load(ex6_23); - YAML_ASSERT(doc.size() == 2); - for(YAML::const_iterator it=doc.begin();it!=doc.end();++it) { - if(it->first.as() == "foo") { - YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str"); - YAML_ASSERT(it->second.Tag() == "tag:yaml.org,2002:str"); - YAML_ASSERT(it->second.as() == "bar"); - } else if(it->first.as() == "baz") { - YAML_ASSERT(it->second.as() == "foo"); - } else - return " unknown key"; - } - - return true; - } - - // 6.24 - TEST VerbatimTags() { - YAML::Node doc = YAML::Load(ex6_24); - YAML_ASSERT(doc.size() == 1); - for(YAML::const_iterator it=doc.begin();it!=doc.end();++it) { - YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str"); - YAML_ASSERT(it->first.as() == "foo"); - YAML_ASSERT(it->second.Tag() == "!bar"); - YAML_ASSERT(it->second.as() == "baz"); - } - return true; - } - - // 6.25 - TEST InvalidVerbatimTags() { - YAML::Node doc = YAML::Load(ex6_25); - return " not implemented yet"; // TODO: check tags (but we probably will say these are valid, I think) - } - - // 6.26 - TEST TagShorthands() { - YAML::Node doc = YAML::Load(ex6_26); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc[0].Tag() == "!local"); - YAML_ASSERT(doc[0].as() == "foo"); - YAML_ASSERT(doc[1].Tag() == "tag:yaml.org,2002:str"); - YAML_ASSERT(doc[1].as() == "bar"); - YAML_ASSERT(doc[2].Tag() == "tag:example.com,2000:app/tag%21"); - YAML_ASSERT(doc[2].as() == "baz"); - return true; - } - - // 6.27 - TEST InvalidTagShorthands() { - bool threw = false; - try { - YAML::Load(ex6_27a); - } catch(const YAML::ParserException& e) { - threw = true; - if(e.msg != YAML::ErrorMsg::TAG_WITH_NO_SUFFIX) - throw; - } - - if(!threw) - return " No exception was thrown for a tag with no suffix"; - - YAML::Load(ex6_27b); // TODO: should we reject this one (since !h! is not declared)? - return " not implemented yet"; - } - - // 6.28 - TEST NonSpecificTags() { - YAML::Node doc = YAML::Load(ex6_28); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc[0].as() == "12"); // TODO: check tags. How? - YAML_ASSERT(doc[1].as() == 12); - YAML_ASSERT(doc[2].as() == "12"); - return true; - } - - // 6.29 - TEST NodeAnchors() { - YAML::Node doc = YAML::Load(ex6_29); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["First occurrence"].as() == "Value"); - YAML_ASSERT(doc["Second occurrence"].as() == "Value"); - return true; - } - - // 7.1 - TEST AliasNodes() { - YAML::Node doc = YAML::Load(ex7_1); - YAML_ASSERT(doc.size() == 4); - YAML_ASSERT(doc["First occurrence"].as() == "Foo"); - YAML_ASSERT(doc["Second occurrence"].as() == "Foo"); - YAML_ASSERT(doc["Override anchor"].as() == "Bar"); - YAML_ASSERT(doc["Reuse anchor"].as() == "Bar"); - return true; - } - - // 7.2 - TEST EmptyNodes() { - YAML::Node doc = YAML::Load(ex7_2); - YAML_ASSERT(doc.size() == 2); - for(YAML::const_iterator it=doc.begin();it!=doc.end();++it) { - if(it->first.as() == "foo") { - YAML_ASSERT(it->second.Tag() == "tag:yaml.org,2002:str"); - YAML_ASSERT(it->second.as() == ""); - } else if(it->first.as() == "") { - YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str"); - YAML_ASSERT(it->second.as() == "bar"); - } else - return " unexpected key"; - } - return true; - } - - // 7.3 - TEST CompletelyEmptyNodes() { - YAML::Node doc = YAML::Load(ex7_3); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["foo"].IsNull()); - YAML_ASSERT(doc[YAML::Null].as() == "bar"); - return true; - } - - // 7.4 - TEST DoubleQuotedImplicitKeys() { - YAML::Node doc = YAML::Load(ex7_4); - YAML_ASSERT(doc.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]["implicit flow key"].as() == "value"); - return true; - } - - // 7.5 - TEST DoubleQuotedLineBreaks() { - YAML::Node doc = YAML::Load(ex7_5); - YAML_ASSERT(doc.as() == "folded to a space,\nto a line feed, or \t \tnon-content"); - return true; - } - - // 7.6 - TEST DoubleQuotedLines() { - YAML::Node doc = YAML::Load(ex7_6); - YAML_ASSERT(doc.as() == " 1st non-empty\n2nd non-empty 3rd non-empty "); - return true; - } - - // 7.7 - TEST SingleQuotedCharacters() { - YAML::Node doc = YAML::Load(ex7_7); - YAML_ASSERT(doc.as() == "here's to \"quotes\""); - return true; - } - - // 7.8 - TEST SingleQuotedImplicitKeys() { - YAML::Node doc = YAML::Load(ex7_8); - YAML_ASSERT(doc.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]["implicit flow key"].as() == "value"); - return true; - } - - // 7.9 - TEST SingleQuotedLines() { - YAML::Node doc = YAML::Load(ex7_9); - YAML_ASSERT(doc.as() == " 1st non-empty\n2nd non-empty 3rd non-empty "); - return true; - } - - // 7.10 - TEST PlainCharacters() { - YAML::Node doc = YAML::Load(ex7_10); - YAML_ASSERT(doc.size() == 6); - YAML_ASSERT(doc[0].as() == "::vector"); - YAML_ASSERT(doc[1].as() == ": - ()"); - YAML_ASSERT(doc[2].as() == "Up, up, and away!"); - YAML_ASSERT(doc[3].as() == -123); - YAML_ASSERT(doc[4].as() == "http://example.com/foo#bar"); - YAML_ASSERT(doc[5].size() == 5); - YAML_ASSERT(doc[5][0].as() == "::vector"); - YAML_ASSERT(doc[5][1].as() == ": - ()"); - YAML_ASSERT(doc[5][2].as() == "Up, up, and away!"); - YAML_ASSERT(doc[5][3].as() == -123); - YAML_ASSERT(doc[5][4].as() == "http://example.com/foo#bar"); - return true; - } - - // 7.11 - TEST PlainImplicitKeys() { - YAML::Node doc = YAML::Load(ex7_11); - YAML_ASSERT(doc.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]["implicit flow key"].as() == "value"); - return true; - } - - // 7.12 - TEST PlainLines() { - YAML::Node doc = YAML::Load(ex7_12); - YAML_ASSERT(doc.as() == "1st non-empty\n2nd non-empty 3rd non-empty"); - return true; - } - - // 7.13 - TEST FlowSequence() { - YAML::Node doc = YAML::Load(ex7_13); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc[0].size() == 2); - YAML_ASSERT(doc[0][0].as() == "one"); - YAML_ASSERT(doc[0][1].as() == "two"); - YAML_ASSERT(doc[1].size() == 2); - YAML_ASSERT(doc[1][0].as() == "three"); - YAML_ASSERT(doc[1][1].as() == "four"); - return true; - } - - // 7.14 - TEST FlowSequenceEntries() { - YAML::Node doc = YAML::Load(ex7_14); - YAML_ASSERT(doc.size() == 5); - YAML_ASSERT(doc[0].as() == "double quoted"); - YAML_ASSERT(doc[1].as() == "single quoted"); - YAML_ASSERT(doc[2].as() == "plain text"); - YAML_ASSERT(doc[3].size() == 1); - YAML_ASSERT(doc[3][0].as() == "nested"); - YAML_ASSERT(doc[4].size() == 1); - YAML_ASSERT(doc[4]["single"].as() == "pair"); - return true; - } - - // 7.15 - TEST FlowMappings() { - YAML::Node doc = YAML::Load(ex7_15); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc[0].size() == 2); - YAML_ASSERT(doc[0]["one"].as() == "two"); - YAML_ASSERT(doc[0]["three"].as() == "four"); - YAML_ASSERT(doc[1].size() == 2); - YAML_ASSERT(doc[1]["five"].as() == "six"); - YAML_ASSERT(doc[1]["seven"].as() == "eight"); - return true; - } - - // 7.16 - TEST FlowMappingEntries() { - YAML::Node doc = YAML::Load(ex7_16); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["explicit"].as() == "entry"); - YAML_ASSERT(doc["implicit"].as() == "entry"); - YAML_ASSERT(doc[YAML::Null].IsNull()); - return true; - } - - // 7.17 - TEST FlowMappingSeparateValues() { - YAML::Node doc = YAML::Load(ex7_17); - YAML_ASSERT(doc.size() == 4); - YAML_ASSERT(doc["unquoted"].as() == "separate"); - YAML_ASSERT(doc["http://foo.com"].IsNull()); - YAML_ASSERT(doc["omitted value"].IsNull()); - YAML_ASSERT(doc[YAML::Null].as() == "omitted key"); - return true; - } - - // 7.18 - TEST FlowMappingAdjacentValues() { - YAML::Node doc = YAML::Load(ex7_18); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["adjacent"].as() == "value"); - YAML_ASSERT(doc["readable"].as() == "value"); - YAML_ASSERT(doc["empty"].IsNull()); - return true; - } - - // 7.19 - TEST SinglePairFlowMappings() { - YAML::Node doc = YAML::Load(ex7_19); - YAML_ASSERT(doc.size() == 1); - YAML_ASSERT(doc[0].size() == 1); - YAML_ASSERT(doc[0]["foo"].as() == "bar"); - return true; - } - - // 7.20 - TEST SinglePairExplicitEntry() { - YAML::Node doc = YAML::Load(ex7_20); - YAML_ASSERT(doc.size() == 1); - YAML_ASSERT(doc[0].size() == 1); - YAML_ASSERT(doc[0]["foo bar"].as() == "baz"); - return true; - } - - // 7.21 - TEST SinglePairImplicitEntries() { - YAML::Node doc = YAML::Load(ex7_21); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc[0].size() == 1); - YAML_ASSERT(doc[0][0].size() == 1); - YAML_ASSERT(doc[0][0]["YAML"].as() == "separate"); - YAML_ASSERT(doc[1].size() == 1); - YAML_ASSERT(doc[1][0].size() == 1); - YAML_ASSERT(doc[1][0][YAML::Null].as() == "empty key entry"); - YAML_ASSERT(doc[2].size() == 1); - YAML_ASSERT(doc[2][0].size() == 1); - - std::map key; - key["JSON"] = "like"; - YAML_ASSERT(doc[2][0][key].as() == "adjacent"); - return true; - } - - // 7.22 - TEST InvalidImplicitKeys() { - try { - YAML::Load(ex7_22); - } catch(const YAML::Exception& e) { - if(e.msg == YAML::ErrorMsg::END_OF_SEQ_FLOW) - return true; - - throw; - } - return " no exception thrown"; - } - - // 7.23 - TEST FlowContent() { - YAML::Node doc = YAML::Load(ex7_23); - YAML_ASSERT(doc.size() == 5); - YAML_ASSERT(doc[0].size() == 2); - YAML_ASSERT(doc[0][0].as() == "a"); - YAML_ASSERT(doc[0][1].as() == "b"); - YAML_ASSERT(doc[1].size() == 1); - YAML_ASSERT(doc[1]["a"].as() == "b"); - YAML_ASSERT(doc[2].as() == "a"); - YAML_ASSERT(doc[3].as() == 'b'); - YAML_ASSERT(doc[4].as() == "c"); - return true; - } - - // 7.24 - TEST FlowNodes() { - YAML::Node doc = YAML::Load(ex7_24); - YAML_ASSERT(doc.size() == 5); - YAML_ASSERT(doc[0].Tag() == "tag:yaml.org,2002:str"); - YAML_ASSERT(doc[0].as() == "a"); - YAML_ASSERT(doc[1].as() == 'b'); - YAML_ASSERT(doc[2].as() == "c"); - YAML_ASSERT(doc[3].as() == "c"); - YAML_ASSERT(doc[4].Tag() == "tag:yaml.org,2002:str"); - YAML_ASSERT(doc[4].as() == ""); - return true; - } - - // 8.1 - TEST BlockScalarHeader() { - YAML::Node doc = YAML::Load(ex8_1); - YAML_ASSERT(doc.size() == 4); - YAML_ASSERT(doc[0].as() == "literal\n"); - YAML_ASSERT(doc[1].as() == " folded\n"); - YAML_ASSERT(doc[2].as() == "keep\n\n"); - YAML_ASSERT(doc[3].as() == " strip"); - return true; - } - - // 8.2 - TEST BlockIndentationHeader() { - YAML::Node doc = YAML::Load(ex8_2); - YAML_ASSERT(doc.size() == 4); - YAML_ASSERT(doc[0].as() == "detected\n"); - YAML_ASSERT(doc[1].as() == "\n\n# detected\n"); - YAML_ASSERT(doc[2].as() == " explicit\n"); - YAML_ASSERT(doc[3].as() == "\t\ndetected\n"); - return true; - } - - // 8.3 - TEST InvalidBlockScalarIndentationIndicators() { - { - bool threw = false; - try { - YAML::Load(ex8_3a); - } catch(const YAML::Exception& e) { - if(e.msg != YAML::ErrorMsg::END_OF_SEQ) - throw; - - threw = true; - } - - if(!threw) - return " no exception thrown for less indented auto-detecting indentation for a literal block scalar"; - } - - { - bool threw = false; - try { - YAML::Load(ex8_3b); - } catch(const YAML::Exception& e) { - if(e.msg != YAML::ErrorMsg::END_OF_SEQ) - throw; - - threw = true; - } - - if(!threw) - return " no exception thrown for less indented auto-detecting indentation for a folded block scalar"; - } - - { - bool threw = false; - try { - YAML::Load(ex8_3c); - } catch(const YAML::Exception& e) { - if(e.msg != YAML::ErrorMsg::END_OF_SEQ) - throw; - - threw = true; - } - - if(!threw) - return " no exception thrown for less indented explicit indentation for a literal block scalar"; - } - - return true; - } - - // 8.4 - TEST ChompingFinalLineBreak() { - YAML::Node doc = YAML::Load(ex8_4); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["strip"].as() == "text"); - YAML_ASSERT(doc["clip"].as() == "text\n"); - YAML_ASSERT(doc["keep"].as() == "text\n"); - return true; - } - - // 8.5 - TEST ChompingTrailingLines() { - YAML::Node doc = YAML::Load(ex8_5); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["strip"].as() == "# text"); - YAML_ASSERT(doc["clip"].as() == "# text\n"); - YAML_ASSERT(doc["keep"].as() == "# text\n"); // Note: I believe this is a bug in the YAML spec - it should be "# text\n\n" - return true; - } - - // 8.6 - TEST EmptyScalarChomping() { - YAML::Node doc = YAML::Load(ex8_6); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["strip"].as() == ""); - YAML_ASSERT(doc["clip"].as() == ""); - YAML_ASSERT(doc["keep"].as() == "\n"); - return true; - } - - // 8.7 - TEST LiteralScalar() { - YAML::Node doc = YAML::Load(ex8_7); - YAML_ASSERT(doc.as() == "literal\n\ttext\n"); - return true; - } - - // 8.8 - TEST LiteralContent() { - YAML::Node doc = YAML::Load(ex8_8); - YAML_ASSERT(doc.as() == "\n\nliteral\n \n\ntext\n"); - return true; - } - - // 8.9 - TEST FoldedScalar() { - YAML::Node doc = YAML::Load(ex8_9); - YAML_ASSERT(doc.as() == "folded text\n"); - return true; - } - - // 8.10 - TEST FoldedLines() { - YAML::Node doc = YAML::Load(ex8_10); - YAML_ASSERT(doc.as() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n"); - return true; - } - - // 8.11 - TEST MoreIndentedLines() { - YAML::Node doc = YAML::Load(ex8_11); - YAML_ASSERT(doc.as() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n"); - return true; - } - - // 8.12 - TEST EmptySeparationLines() { - YAML::Node doc = YAML::Load(ex8_12); - YAML_ASSERT(doc.as() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n"); - return true; - } - - // 8.13 - TEST FinalEmptyLines() { - YAML::Node doc = YAML::Load(ex8_13); - YAML_ASSERT(doc.as() == "\nfolded line\nnext line\n * bullet\n\n * list\n * lines\n\nlast line\n"); - return true; - } - - // 8.14 - TEST BlockSequence() { - YAML::Node doc = YAML::Load(ex8_14); - YAML_ASSERT(doc.size() == 1); - YAML_ASSERT(doc["block sequence"].size() == 2); - YAML_ASSERT(doc["block sequence"][0].as() == "one"); - YAML_ASSERT(doc["block sequence"][1].size() == 1); - YAML_ASSERT(doc["block sequence"][1]["two"].as() == "three"); - return true; - } - - // 8.15 - TEST BlockSequenceEntryTypes() { - YAML::Node doc = YAML::Load(ex8_15); - YAML_ASSERT(doc.size() == 4); - YAML_ASSERT(doc[0].IsNull()); - YAML_ASSERT(doc[1].as() == "block node\n"); - YAML_ASSERT(doc[2].size() == 2); - YAML_ASSERT(doc[2][0].as() == "one"); - YAML_ASSERT(doc[2][1].as() == "two"); - YAML_ASSERT(doc[3].size() == 1); - YAML_ASSERT(doc[3]["one"].as() == "two"); - return true; - } - - // 8.16 - TEST BlockMappings() { - YAML::Node doc = YAML::Load(ex8_16); - YAML_ASSERT(doc.size() == 1); - YAML_ASSERT(doc["block mapping"].size() == 1); - YAML_ASSERT(doc["block mapping"]["key"].as() == "value"); - return true; - } - - // 8.17 - TEST ExplicitBlockMappingEntries() { - YAML::Node doc = YAML::Load(ex8_17); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["explicit key"].IsNull()); - YAML_ASSERT(doc["block key\n"].size() == 2); - YAML_ASSERT(doc["block key\n"][0].as() == "one"); - YAML_ASSERT(doc["block key\n"][1].as() == "two"); - return true; - } - - // 8.18 - TEST ImplicitBlockMappingEntries() { - YAML::Node doc = YAML::Load(ex8_18); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc["plain key"].as() == "in-line value"); - YAML_ASSERT(doc[YAML::Null].IsNull()); - YAML_ASSERT(doc["quoted key"].size() == 1); - YAML_ASSERT(doc["quoted key"][0].as() == "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() == "yellow"); - YAML_ASSERT(doc[1].size() == 1); - std::map key; - key["earth"] = "blue"; - YAML_ASSERT(doc[1][key].size() == 1); - YAML_ASSERT(doc[1][key]["moon"].as() == "white"); - return true; - } - - // 8.20 - TEST BlockNodeTypes() { - YAML::Node doc = YAML::Load(ex8_20); - YAML_ASSERT(doc.size() == 3); - YAML_ASSERT(doc[0].as() == "flow in block"); - YAML_ASSERT(doc[1].as() == "Block scalar\n"); - YAML_ASSERT(doc[2].size() == 1); - YAML_ASSERT(doc[2]["foo"].as() == "bar"); - return true; - } - - // 8.21 - TEST BlockScalarNodes() { - YAML::Node doc = YAML::Load(ex8_21); - YAML_ASSERT(doc.size() == 2); - YAML_ASSERT(doc["literal"].as() == "value"); // Note: I believe this is a bug in the YAML spec - it should be "value\n" - YAML_ASSERT(doc["folded"].as() == "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() == "entry"); - YAML_ASSERT(doc["sequence"][1].size() == 1); - YAML_ASSERT(doc["sequence"][1][0].as() == "nested"); - YAML_ASSERT(doc["mapping"].size() == 1); - YAML_ASSERT(doc["mapping"]["foo"].as() == "bar"); - return true; - } - } +namespace Test { +namespace Spec { +// 2.1 +TEST SeqScalars() { + YAML::Node doc = YAML::Load(ex2_1); + YAML_ASSERT(doc.IsSequence()); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc[0].as() == "Mark McGwire"); + YAML_ASSERT(doc[1].as() == "Sammy Sosa"); + YAML_ASSERT(doc[2].as() == "Ken Griffey"); + return true; +} + +// 2.2 +TEST MappingScalarsToScalars() { + YAML::Node doc = YAML::Load(ex2_2); + YAML_ASSERT(doc.IsMap()); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["hr"].as() == "65"); + YAML_ASSERT(doc["avg"].as() == "0.278"); + YAML_ASSERT(doc["rbi"].as() == "147"); + return true; +} + +// 2.3 +TEST MappingScalarsToSequences() { + YAML::Node doc = YAML::Load(ex2_3); + YAML_ASSERT(doc.IsMap()); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["american"].size() == 3); + YAML_ASSERT(doc["american"][0].as() == "Boston Red Sox"); + YAML_ASSERT(doc["american"][1].as() == "Detroit Tigers"); + YAML_ASSERT(doc["american"][2].as() == "New York Yankees"); + YAML_ASSERT(doc["national"].size() == 3); + YAML_ASSERT(doc["national"][0].as() == "New York Mets"); + YAML_ASSERT(doc["national"][1].as() == "Chicago Cubs"); + YAML_ASSERT(doc["national"][2].as() == "Atlanta Braves"); + return true; +} + +// 2.4 +TEST SequenceOfMappings() { + YAML::Node doc = YAML::Load(ex2_4); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc[0].size() == 3); + YAML_ASSERT(doc[0]["name"].as() == "Mark McGwire"); + YAML_ASSERT(doc[0]["hr"].as() == "65"); + YAML_ASSERT(doc[0]["avg"].as() == "0.278"); + YAML_ASSERT(doc[1].size() == 3); + YAML_ASSERT(doc[1]["name"].as() == "Sammy Sosa"); + YAML_ASSERT(doc[1]["hr"].as() == "63"); + YAML_ASSERT(doc[1]["avg"].as() == "0.288"); + return true; +} + +// 2.5 +TEST SequenceOfSequences() { + YAML::Node doc = YAML::Load(ex2_5); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc[0].size() == 3); + YAML_ASSERT(doc[0][0].as() == "name"); + YAML_ASSERT(doc[0][1].as() == "hr"); + YAML_ASSERT(doc[0][2].as() == "avg"); + YAML_ASSERT(doc[1].size() == 3); + YAML_ASSERT(doc[1][0].as() == "Mark McGwire"); + YAML_ASSERT(doc[1][1].as() == "65"); + YAML_ASSERT(doc[1][2].as() == "0.278"); + YAML_ASSERT(doc[2].size() == 3); + YAML_ASSERT(doc[2][0].as() == "Sammy Sosa"); + YAML_ASSERT(doc[2][1].as() == "63"); + YAML_ASSERT(doc[2][2].as() == "0.288"); + return true; +} + +// 2.6 +TEST MappingOfMappings() { + YAML::Node doc = YAML::Load(ex2_6); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["Mark McGwire"].size() == 2); + YAML_ASSERT(doc["Mark McGwire"]["hr"].as() == "65"); + YAML_ASSERT(doc["Mark McGwire"]["avg"].as() == "0.278"); + YAML_ASSERT(doc["Sammy Sosa"].size() == 2); + YAML_ASSERT(doc["Sammy Sosa"]["hr"].as() == "63"); + YAML_ASSERT(doc["Sammy Sosa"]["avg"].as() == "0.288"); + return true; +} + +// 2.7 +TEST TwoDocumentsInAStream() { + std::vector 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() == "Mark McGwire"); + YAML_ASSERT(doc[1].as() == "Sammy Sosa"); + YAML_ASSERT(doc[2].as() == "Ken Griffey"); + } + + { + YAML::Node doc = docs[1]; + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc[0].as() == "Chicago Cubs"); + YAML_ASSERT(doc[1].as() == "St Louis Cardinals"); + } + return true; +} + +// 2.8 +TEST PlayByPlayFeed() { + std::vector 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() == "20:03:20"); + YAML_ASSERT(doc["player"].as() == "Sammy Sosa"); + YAML_ASSERT(doc["action"].as() == "strike (miss)"); + } + + { + YAML::Node doc = docs[1]; + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["time"].as() == "20:03:47"); + YAML_ASSERT(doc["player"].as() == "Sammy Sosa"); + YAML_ASSERT(doc["action"].as() == "grand slam"); + } + return true; +} + +// 2.9 +TEST SingleDocumentWithTwoComments() { + YAML::Node doc = YAML::Load(ex2_9); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["hr"].size() == 2); + YAML_ASSERT(doc["hr"][0].as() == "Mark McGwire"); + YAML_ASSERT(doc["hr"][1].as() == "Sammy Sosa"); + YAML_ASSERT(doc["rbi"].size() == 2); + YAML_ASSERT(doc["rbi"][0].as() == "Sammy Sosa"); + YAML_ASSERT(doc["rbi"][1].as() == "Ken Griffey"); + return true; +} + +// 2.10 +TEST SimpleAnchor() { + YAML::Node doc = YAML::Load(ex2_10); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["hr"].size() == 2); + YAML_ASSERT(doc["hr"][0].as() == "Mark McGwire"); + YAML_ASSERT(doc["hr"][1].as() == "Sammy Sosa"); + YAML_ASSERT(doc["rbi"].size() == 2); + YAML_ASSERT(doc["rbi"][0].as() == "Sammy Sosa"); + YAML_ASSERT(doc["rbi"][1].as() == "Ken Griffey"); + return true; +} + +// 2.11 +TEST MappingBetweenSequences() { + YAML::Node doc = YAML::Load(ex2_11); + + std::vector tigers_cubs; + tigers_cubs.push_back("Detroit Tigers"); + tigers_cubs.push_back("Chicago cubs"); + + std::vector 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[tigers_cubs][0].as() == "2001-07-23"); + YAML_ASSERT(doc[yankees_braves].size() == 3); + YAML_ASSERT(doc[yankees_braves][0].as() == "2001-07-02"); + YAML_ASSERT(doc[yankees_braves][1].as() == "2001-08-12"); + YAML_ASSERT(doc[yankees_braves][2].as() == "2001-08-14"); + return true; +} + +// 2.12 +TEST CompactNestedMapping() { + YAML::Node doc = YAML::Load(ex2_12); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc[0].size() == 2); + YAML_ASSERT(doc[0]["item"].as() == "Super Hoop"); + YAML_ASSERT(doc[0]["quantity"].as() == 1); + YAML_ASSERT(doc[1].size() == 2); + YAML_ASSERT(doc[1]["item"].as() == "Basketball"); + YAML_ASSERT(doc[1]["quantity"].as() == 4); + YAML_ASSERT(doc[2].size() == 2); + YAML_ASSERT(doc[2]["item"].as() == "Big Shoes"); + YAML_ASSERT(doc[2]["quantity"].as() == 1); + return true; +} + +// 2.13 +TEST InLiteralsNewlinesArePreserved() { + YAML::Node doc = YAML::Load(ex2_13); + YAML_ASSERT(doc.as() == + "\\//||\\/||\n" + "// || ||__"); + return true; +} + +// 2.14 +TEST InFoldedScalarsNewlinesBecomeSpaces() { + YAML::Node doc = YAML::Load(ex2_14); + YAML_ASSERT(doc.as() == + "Mark McGwire's year was crippled by a knee injury."); + return true; +} + +// 2.15 +TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines() { + YAML::Node doc = YAML::Load(ex2_15); + YAML_ASSERT(doc.as() == + "Sammy Sosa completed another fine season with great stats.\n\n" + " 63 Home Runs\n" + " 0.288 Batting Average\n\n" + "What a year!"); + return true; +} + +// 2.16 +TEST IndentationDeterminesScope() { + YAML::Node doc = YAML::Load(ex2_16); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["name"].as() == "Mark McGwire"); + YAML_ASSERT(doc["accomplishment"].as() == + "Mark set a major league home run record in 1998.\n"); + YAML_ASSERT(doc["stats"].as() == + "65 Home Runs\n0.278 Batting Average\n"); + return true; +} + +// 2.17 +TEST QuotedScalars() { + YAML::Node doc = YAML::Load(ex2_17); + YAML_ASSERT(doc.size() == 6); + YAML_ASSERT(doc["unicode"].as() == "Sosa did fine.\xe2\x98\xba"); + YAML_ASSERT(doc["control"].as() == "\b1998\t1999\t2000\n"); + YAML_ASSERT(doc["hex esc"].as() == "\x0d\x0a is \r\n"); + YAML_ASSERT(doc["single"].as() == "\"Howdy!\" he cried."); + YAML_ASSERT(doc["quoted"].as() == " # Not a 'comment'."); + YAML_ASSERT(doc["tie-fighter"].as() == "|\\-*-/|"); + return true; +} + +// 2.18 +TEST MultiLineFlowScalars() { + YAML::Node doc = YAML::Load(ex2_18); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["plain"].as() == + "This unquoted scalar spans many lines."); + YAML_ASSERT(doc["quoted"].as() == + "So does this quoted scalar.\n"); + return true; +} + +// TODO: 2.19 - 2.22 schema tags + +// 2.23 +TEST VariousExplicitTags() { + YAML::Node doc = YAML::Load(ex2_23); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["not-date"].Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(doc["not-date"].as() == "2002-04-28"); + YAML_ASSERT(doc["picture"].Tag() == "tag:yaml.org,2002:binary"); + YAML_ASSERT(doc["picture"].as() == + "R0lGODlhDAAMAIQAAP//9/X\n" + "17unp5WZmZgAAAOfn515eXv\n" + "Pz7Y6OjuDg4J+fn5OTk6enp\n" + "56enmleECcgggoBADs=\n"); + YAML_ASSERT(doc["application specific tag"].Tag() == "!something"); + YAML_ASSERT(doc["application specific tag"].as() == + "The semantics of the tag\n" + "above may be different for\n" + "different documents."); + return true; +} + +// 2.24 +TEST GlobalTags() { + YAML::Node doc = YAML::Load(ex2_24); + YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:shape"); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc[0].Tag() == "tag:clarkevans.com,2002:circle"); + YAML_ASSERT(doc[0].size() == 2); + YAML_ASSERT(doc[0]["center"].size() == 2); + YAML_ASSERT(doc[0]["center"]["x"].as() == 73); + YAML_ASSERT(doc[0]["center"]["y"].as() == 129); + YAML_ASSERT(doc[0]["radius"].as() == 7); + YAML_ASSERT(doc[1].Tag() == "tag:clarkevans.com,2002:line"); + YAML_ASSERT(doc[1].size() == 2); + YAML_ASSERT(doc[1]["start"].size() == 2); + YAML_ASSERT(doc[1]["start"]["x"].as() == 73); + YAML_ASSERT(doc[1]["start"]["y"].as() == 129); + YAML_ASSERT(doc[1]["finish"].size() == 2); + YAML_ASSERT(doc[1]["finish"]["x"].as() == 89); + YAML_ASSERT(doc[1]["finish"]["y"].as() == 102); + YAML_ASSERT(doc[2].Tag() == "tag:clarkevans.com,2002:label"); + YAML_ASSERT(doc[2].size() == 3); + YAML_ASSERT(doc[2]["start"].size() == 2); + YAML_ASSERT(doc[2]["start"]["x"].as() == 73); + YAML_ASSERT(doc[2]["start"]["y"].as() == 129); + YAML_ASSERT(doc[2]["color"].as() == "0xFFEEBB"); + YAML_ASSERT(doc[2]["text"].as() == "Pretty vector drawing."); + return true; +} + +// 2.25 +TEST UnorderedSets() { + YAML::Node doc = YAML::Load(ex2_25); + YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:set"); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["Mark McGwire"].IsNull()); + YAML_ASSERT(doc["Sammy Sosa"].IsNull()); + YAML_ASSERT(doc["Ken Griffey"].IsNull()); + return true; +} + +// 2.26 +TEST OrderedMappings() { + YAML::Node doc = YAML::Load(ex2_26); + YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:omap"); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc[0].size() == 1); + YAML_ASSERT(doc[0]["Mark McGwire"].as() == 65); + YAML_ASSERT(doc[1].size() == 1); + YAML_ASSERT(doc[1]["Sammy Sosa"].as() == 63); + YAML_ASSERT(doc[2].size() == 1); + YAML_ASSERT(doc[2]["Ken Griffey"].as() == 58); + return true; +} + +// 2.27 +TEST Invoice() { + YAML::Node doc = YAML::Load(ex2_27); + YAML_ASSERT(doc.Tag() == "tag:clarkevans.com,2002:invoice"); + YAML_ASSERT(doc.size() == 8); + YAML_ASSERT(doc["invoice"].as() == 34843); + YAML_ASSERT(doc["date"].as() == "2001-01-23"); + YAML_ASSERT(doc["bill-to"].size() == 3); + YAML_ASSERT(doc["bill-to"]["given"].as() == "Chris"); + YAML_ASSERT(doc["bill-to"]["family"].as() == "Dumars"); + YAML_ASSERT(doc["bill-to"]["address"].size() == 4); + YAML_ASSERT(doc["bill-to"]["address"]["lines"].as() == + "458 Walkman Dr.\nSuite #292\n"); + YAML_ASSERT(doc["bill-to"]["address"]["city"].as() == + "Royal Oak"); + YAML_ASSERT(doc["bill-to"]["address"]["state"].as() == "MI"); + YAML_ASSERT(doc["bill-to"]["address"]["postal"].as() == "48046"); + YAML_ASSERT(doc["ship-to"].size() == 3); + YAML_ASSERT(doc["ship-to"]["given"].as() == "Chris"); + YAML_ASSERT(doc["ship-to"]["family"].as() == "Dumars"); + YAML_ASSERT(doc["ship-to"]["address"].size() == 4); + YAML_ASSERT(doc["ship-to"]["address"]["lines"].as() == + "458 Walkman Dr.\nSuite #292\n"); + YAML_ASSERT(doc["ship-to"]["address"]["city"].as() == + "Royal Oak"); + YAML_ASSERT(doc["ship-to"]["address"]["state"].as() == "MI"); + YAML_ASSERT(doc["ship-to"]["address"]["postal"].as() == "48046"); + YAML_ASSERT(doc["product"].size() == 2); + YAML_ASSERT(doc["product"][0].size() == 4); + YAML_ASSERT(doc["product"][0]["sku"].as() == "BL394D"); + YAML_ASSERT(doc["product"][0]["quantity"].as() == 4); + YAML_ASSERT(doc["product"][0]["description"].as() == + "Basketball"); + YAML_ASSERT(doc["product"][0]["price"].as() == "450.00"); + YAML_ASSERT(doc["product"][1].size() == 4); + YAML_ASSERT(doc["product"][1]["sku"].as() == "BL4438H"); + YAML_ASSERT(doc["product"][1]["quantity"].as() == 1); + YAML_ASSERT(doc["product"][1]["description"].as() == + "Super Hoop"); + YAML_ASSERT(doc["product"][1]["price"].as() == "2392.00"); + YAML_ASSERT(doc["tax"].as() == "251.42"); + YAML_ASSERT(doc["total"].as() == "4443.52"); + YAML_ASSERT( + doc["comments"].as() == + "Late afternoon is best. Backup contact is Nancy Billsmer @ 338-4338."); + return true; +} + +// 2.28 +TEST LogFile() { + std::vector docs = YAML::LoadAll(ex2_28); + YAML_ASSERT(docs.size() == 3); + + { + YAML::Node doc = docs[0]; + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["Time"].as() == "2001-11-23 15:01:42 -5"); + YAML_ASSERT(doc["User"].as() == "ed"); + YAML_ASSERT(doc["Warning"].as() == + "This is an error message for the log file"); + } + + { + YAML::Node doc = docs[1]; + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["Time"].as() == "2001-11-23 15:02:31 -5"); + YAML_ASSERT(doc["User"].as() == "ed"); + YAML_ASSERT(doc["Warning"].as() == + "A slightly different error message."); + } + + { + YAML::Node doc = docs[2]; + YAML_ASSERT(doc.size() == 4); + YAML_ASSERT(doc["Date"].as() == "2001-11-23 15:03:17 -5"); + YAML_ASSERT(doc["User"].as() == "ed"); + YAML_ASSERT(doc["Fatal"].as() == "Unknown variable \"bar\""); + YAML_ASSERT(doc["Stack"].size() == 2); + YAML_ASSERT(doc["Stack"][0].size() == 3); + YAML_ASSERT(doc["Stack"][0]["file"].as() == "TopClass.py"); + YAML_ASSERT(doc["Stack"][0]["line"].as() == "23"); + YAML_ASSERT(doc["Stack"][0]["code"].as() == + "x = MoreObject(\"345\\n\")\n"); + YAML_ASSERT(doc["Stack"][1].size() == 3); + YAML_ASSERT(doc["Stack"][1]["file"].as() == "MoreClass.py"); + YAML_ASSERT(doc["Stack"][1]["line"].as() == "58"); + YAML_ASSERT(doc["Stack"][1]["code"].as() == "foo = bar"); + } + return true; +} + +// TODO: 5.1 - 5.2 BOM + +// 5.3 +TEST BlockStructureIndicators() { + YAML::Node doc = YAML::Load(ex5_3); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["sequence"].size() == 2); + YAML_ASSERT(doc["sequence"][0].as() == "one"); + YAML_ASSERT(doc["sequence"][1].as() == "two"); + YAML_ASSERT(doc["mapping"].size() == 2); + YAML_ASSERT(doc["mapping"]["sky"].as() == "blue"); + YAML_ASSERT(doc["mapping"]["sea"].as() == "green"); + return true; +} + +// 5.4 +TEST FlowStructureIndicators() { + YAML::Node doc = YAML::Load(ex5_4); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["sequence"].size() == 2); + YAML_ASSERT(doc["sequence"][0].as() == "one"); + YAML_ASSERT(doc["sequence"][1].as() == "two"); + YAML_ASSERT(doc["mapping"].size() == 2); + YAML_ASSERT(doc["mapping"]["sky"].as() == "blue"); + YAML_ASSERT(doc["mapping"]["sea"].as() == "green"); + return true; +} + +// 5.5 +TEST CommentIndicator() { + YAML::Node doc = YAML::Load(ex5_5); + YAML_ASSERT(doc.IsNull()); + return true; +} + +// 5.6 +TEST NodePropertyIndicators() { + YAML::Node doc = YAML::Load(ex5_6); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["anchored"].as() == + "value"); // TODO: assert tag + YAML_ASSERT(doc["alias"].as() == "value"); + return true; +} + +// 5.7 +TEST BlockScalarIndicators() { + YAML::Node doc = YAML::Load(ex5_7); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["literal"].as() == "some\ntext\n"); + YAML_ASSERT(doc["folded"].as() == "some text\n"); + return true; +} + +// 5.8 +TEST QuotedScalarIndicators() { + YAML::Node doc = YAML::Load(ex5_8); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["single"].as() == "text"); + YAML_ASSERT(doc["double"].as() == "text"); + return true; +} + +// TODO: 5.9 directive +// TODO: 5.10 reserved indicator + +// 5.11 +TEST LineBreakCharacters() { + YAML::Node doc = YAML::Load(ex5_11); + YAML_ASSERT(doc.as() == + "Line break (no glyph)\nLine break (glyphed)\n"); + return true; +} + +// 5.12 +TEST TabsAndSpaces() { + YAML::Node doc = YAML::Load(ex5_12); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["quoted"].as() == "Quoted\t"); + YAML_ASSERT(doc["block"].as() == + "void main() {\n" + "\tprintf(\"Hello, world!\\n\");\n" + "}"); + return true; +} + +// 5.13 +TEST EscapedCharacters() { + YAML::Node doc = YAML::Load(ex5_13); + YAML_ASSERT(doc.as() == + "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.14 +TEST InvalidEscapedCharacters() { + try { + YAML::Load(ex5_14); + } + catch (const YAML::ParserException& e) { + YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::INVALID_ESCAPE) + "c"); + return true; + } + + return false; +} + +// 6.1 +TEST IndentationSpaces() { + YAML::Node doc = YAML::Load(ex6_1); + YAML_ASSERT(doc.size() == 1); + YAML_ASSERT(doc["Not indented"].size() == 2); + YAML_ASSERT(doc["Not indented"]["By one space"].as() == + "By four\n spaces\n"); + YAML_ASSERT(doc["Not indented"]["Flow style"].size() == 3); + YAML_ASSERT(doc["Not indented"]["Flow style"][0].as() == + "By two"); + YAML_ASSERT(doc["Not indented"]["Flow style"][1].as() == + "Also by two"); + YAML_ASSERT(doc["Not indented"]["Flow style"][2].as() == + "Still by two"); + return true; +} + +// 6.2 +TEST IndentationIndicators() { + YAML::Node doc = YAML::Load(ex6_2); + YAML_ASSERT(doc.size() == 1); + YAML_ASSERT(doc["a"].size() == 2); + YAML_ASSERT(doc["a"][0].as() == "b"); + YAML_ASSERT(doc["a"][1].size() == 2); + YAML_ASSERT(doc["a"][1][0].as() == "c"); + YAML_ASSERT(doc["a"][1][1].as() == "d"); + return true; +} + +// 6.3 +TEST SeparationSpaces() { + YAML::Node doc = YAML::Load(ex6_3); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc[0].size() == 1); + YAML_ASSERT(doc[0]["foo"].as() == "bar"); + YAML_ASSERT(doc[1].size() == 2); + YAML_ASSERT(doc[1][0].as() == "baz"); + YAML_ASSERT(doc[1][1].as() == "baz"); + return true; +} + +// 6.4 +TEST LinePrefixes() { + YAML::Node doc = YAML::Load(ex6_4); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["plain"].as() == "text lines"); + YAML_ASSERT(doc["quoted"].as() == "text lines"); + YAML_ASSERT(doc["block"].as() == "text\n \tlines\n"); + return true; +} + +// 6.5 +TEST EmptyLines() { + YAML::Node doc = YAML::Load(ex6_5); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["Folding"].as() == "Empty line\nas a line feed"); + YAML_ASSERT(doc["Chomping"].as() == "Clipped empty lines\n"); + return true; +} + +// 6.6 +TEST LineFolding() { + YAML::Node doc = YAML::Load(ex6_6); + YAML_ASSERT(doc.as() == "trimmed\n\n\nas space"); + return true; +} + +// 6.7 +TEST BlockFolding() { + YAML::Node doc = YAML::Load(ex6_7); + YAML_ASSERT(doc.as() == "foo \n\n\t bar\n\nbaz\n"); + return true; +} + +// 6.8 +TEST FlowFolding() { + YAML::Node doc = YAML::Load(ex6_8); + YAML_ASSERT(doc.as() == " foo\nbar\nbaz "); + return true; +} + +// 6.9 +TEST SeparatedComment() { + YAML::Node doc = YAML::Load(ex6_9); + YAML_ASSERT(doc.size() == 1); + YAML_ASSERT(doc["key"].as() == "value"); + return true; +} + +// 6.10 +TEST CommentLines() { + YAML::Node doc = YAML::Load(ex6_10); + YAML_ASSERT(doc.IsNull()); + return true; +} + +// 6.11 +TEST MultiLineComments() { + YAML::Node doc = YAML::Load(ex6_11); + YAML_ASSERT(doc.size() == 1); + YAML_ASSERT(doc["key"].as() == "value"); + return true; +} + +// 6.12 +TEST SeparationSpacesII() { + YAML::Node doc = YAML::Load(ex6_12); + + std::map sammy; + sammy["first"] = "Sammy"; + sammy["last"] = "Sosa"; + + YAML_ASSERT(doc.size() == 1); + YAML_ASSERT(doc[sammy].size() == 2); + YAML_ASSERT(doc[sammy]["hr"].as() == 65); + YAML_ASSERT(doc[sammy]["avg"].as() == "0.278"); + return true; +} + +// 6.13 +TEST ReservedDirectives() { + YAML::Node doc = YAML::Load(ex6_13); + YAML_ASSERT(doc.as() == "foo"); + return true; +} + +// 6.14 +TEST YAMLDirective() { + YAML::Node doc = YAML::Load(ex6_14); + YAML_ASSERT(doc.as() == "foo"); + return true; +} + +// 6.15 +TEST InvalidRepeatedYAMLDirective() { + try { + YAML::Load(ex6_15); + } + catch (const YAML::ParserException& e) { + YAML_ASSERT(e.msg == YAML::ErrorMsg::REPEATED_YAML_DIRECTIVE); + return true; + } + + return " No exception was thrown"; +} + +// 6.16 +TEST TagDirective() { + YAML::Node doc = YAML::Load(ex6_16); + YAML_ASSERT(doc.Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(doc.as() == "foo"); + return true; +} + +// 6.17 +TEST InvalidRepeatedTagDirective() { + try { + YAML::Load(ex6_17); + } + catch (const YAML::ParserException& e) { + if (e.msg == YAML::ErrorMsg::REPEATED_TAG_DIRECTIVE) + return true; + + throw; + } + + return " No exception was thrown"; +} + +// 6.18 +TEST PrimaryTagHandle() { + std::vector docs = YAML::LoadAll(ex6_18); + YAML_ASSERT(docs.size() == 2); + + { + YAML::Node doc = docs[0]; + YAML_ASSERT(doc.Tag() == "!foo"); + YAML_ASSERT(doc.as() == "bar"); + } + + { + YAML::Node doc = docs[1]; + YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo"); + YAML_ASSERT(doc.as() == "bar"); + } + return true; +} + +// 6.19 +TEST SecondaryTagHandle() { + YAML::Node doc = YAML::Load(ex6_19); + YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/int"); + YAML_ASSERT(doc.as() == "1 - 3"); + return true; +} + +// 6.20 +TEST TagHandles() { + YAML::Node doc = YAML::Load(ex6_20); + YAML_ASSERT(doc.Tag() == "tag:example.com,2000:app/foo"); + YAML_ASSERT(doc.as() == "bar"); + return true; +} + +// 6.21 +TEST LocalTagPrefix() { + std::vector docs = YAML::LoadAll(ex6_21); + YAML_ASSERT(docs.size() == 2); + + { + YAML::Node doc = docs[0]; + YAML_ASSERT(doc.Tag() == "!my-light"); + YAML_ASSERT(doc.as() == "fluorescent"); + } + + { + YAML::Node doc = docs[1]; + YAML_ASSERT(doc.Tag() == "!my-light"); + YAML_ASSERT(doc.as() == "green"); + } + return true; +} + +// 6.22 +TEST GlobalTagPrefix() { + YAML::Node doc = YAML::Load(ex6_22); + YAML_ASSERT(doc.size() == 1); + YAML_ASSERT(doc[0].Tag() == "tag:example.com,2000:app/foo"); + YAML_ASSERT(doc[0].as() == "bar"); + return true; +} + +// 6.23 +TEST NodeProperties() { + YAML::Node doc = YAML::Load(ex6_23); + YAML_ASSERT(doc.size() == 2); + for (YAML::const_iterator it = doc.begin(); it != doc.end(); ++it) { + if (it->first.as() == "foo") { + YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(it->second.Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(it->second.as() == "bar"); + } else if (it->first.as() == "baz") { + YAML_ASSERT(it->second.as() == "foo"); + } else + return " unknown key"; + } + + return true; +} + +// 6.24 +TEST VerbatimTags() { + YAML::Node doc = YAML::Load(ex6_24); + YAML_ASSERT(doc.size() == 1); + for (YAML::const_iterator it = doc.begin(); it != doc.end(); ++it) { + YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(it->first.as() == "foo"); + YAML_ASSERT(it->second.Tag() == "!bar"); + YAML_ASSERT(it->second.as() == "baz"); + } + return true; +} + +// 6.25 +TEST InvalidVerbatimTags() { + YAML::Node doc = YAML::Load(ex6_25); + return " not implemented yet"; // TODO: check tags (but we probably will say + // these are valid, I think) +} + +// 6.26 +TEST TagShorthands() { + YAML::Node doc = YAML::Load(ex6_26); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc[0].Tag() == "!local"); + YAML_ASSERT(doc[0].as() == "foo"); + YAML_ASSERT(doc[1].Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(doc[1].as() == "bar"); + YAML_ASSERT(doc[2].Tag() == "tag:example.com,2000:app/tag%21"); + YAML_ASSERT(doc[2].as() == "baz"); + return true; +} + +// 6.27 +TEST InvalidTagShorthands() { + bool threw = false; + try { + YAML::Load(ex6_27a); + } + catch (const YAML::ParserException& e) { + threw = true; + if (e.msg != YAML::ErrorMsg::TAG_WITH_NO_SUFFIX) + throw; + } + + if (!threw) + return " No exception was thrown for a tag with no suffix"; + + YAML::Load( + ex6_27b); // TODO: should we reject this one (since !h! is not declared)? + return " not implemented yet"; +} + +// 6.28 +TEST NonSpecificTags() { + YAML::Node doc = YAML::Load(ex6_28); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc[0].as() == "12"); // TODO: check tags. How? + YAML_ASSERT(doc[1].as() == 12); + YAML_ASSERT(doc[2].as() == "12"); + return true; +} + +// 6.29 +TEST NodeAnchors() { + YAML::Node doc = YAML::Load(ex6_29); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["First occurrence"].as() == "Value"); + YAML_ASSERT(doc["Second occurrence"].as() == "Value"); + return true; +} + +// 7.1 +TEST AliasNodes() { + YAML::Node doc = YAML::Load(ex7_1); + YAML_ASSERT(doc.size() == 4); + YAML_ASSERT(doc["First occurrence"].as() == "Foo"); + YAML_ASSERT(doc["Second occurrence"].as() == "Foo"); + YAML_ASSERT(doc["Override anchor"].as() == "Bar"); + YAML_ASSERT(doc["Reuse anchor"].as() == "Bar"); + return true; +} + +// 7.2 +TEST EmptyNodes() { + YAML::Node doc = YAML::Load(ex7_2); + YAML_ASSERT(doc.size() == 2); + for (YAML::const_iterator it = doc.begin(); it != doc.end(); ++it) { + if (it->first.as() == "foo") { + YAML_ASSERT(it->second.Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(it->second.as() == ""); + } else if (it->first.as() == "") { + YAML_ASSERT(it->first.Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(it->second.as() == "bar"); + } else + return " unexpected key"; + } + return true; +} + +// 7.3 +TEST CompletelyEmptyNodes() { + YAML::Node doc = YAML::Load(ex7_3); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["foo"].IsNull()); + YAML_ASSERT(doc[YAML::Null].as() == "bar"); + return true; +} + +// 7.4 +TEST DoubleQuotedImplicitKeys() { + YAML::Node doc = YAML::Load(ex7_4); + YAML_ASSERT(doc.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]["implicit flow key"] + .as() == "value"); + return true; +} + +// 7.5 +TEST DoubleQuotedLineBreaks() { + YAML::Node doc = YAML::Load(ex7_5); + YAML_ASSERT(doc.as() == + "folded to a space,\nto a line feed, or \t \tnon-content"); + return true; +} + +// 7.6 +TEST DoubleQuotedLines() { + YAML::Node doc = YAML::Load(ex7_6); + YAML_ASSERT(doc.as() == + " 1st non-empty\n2nd non-empty 3rd non-empty "); + return true; +} + +// 7.7 +TEST SingleQuotedCharacters() { + YAML::Node doc = YAML::Load(ex7_7); + YAML_ASSERT(doc.as() == "here's to \"quotes\""); + return true; +} + +// 7.8 +TEST SingleQuotedImplicitKeys() { + YAML::Node doc = YAML::Load(ex7_8); + YAML_ASSERT(doc.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]["implicit flow key"] + .as() == "value"); + return true; +} + +// 7.9 +TEST SingleQuotedLines() { + YAML::Node doc = YAML::Load(ex7_9); + YAML_ASSERT(doc.as() == + " 1st non-empty\n2nd non-empty 3rd non-empty "); + return true; +} + +// 7.10 +TEST PlainCharacters() { + YAML::Node doc = YAML::Load(ex7_10); + YAML_ASSERT(doc.size() == 6); + YAML_ASSERT(doc[0].as() == "::vector"); + YAML_ASSERT(doc[1].as() == ": - ()"); + YAML_ASSERT(doc[2].as() == "Up, up, and away!"); + YAML_ASSERT(doc[3].as() == -123); + YAML_ASSERT(doc[4].as() == "http://example.com/foo#bar"); + YAML_ASSERT(doc[5].size() == 5); + YAML_ASSERT(doc[5][0].as() == "::vector"); + YAML_ASSERT(doc[5][1].as() == ": - ()"); + YAML_ASSERT(doc[5][2].as() == "Up, up, and away!"); + YAML_ASSERT(doc[5][3].as() == -123); + YAML_ASSERT(doc[5][4].as() == "http://example.com/foo#bar"); + return true; +} + +// 7.11 +TEST PlainImplicitKeys() { + YAML::Node doc = YAML::Load(ex7_11); + YAML_ASSERT(doc.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]["implicit flow key"] + .as() == "value"); + return true; +} + +// 7.12 +TEST PlainLines() { + YAML::Node doc = YAML::Load(ex7_12); + YAML_ASSERT(doc.as() == + "1st non-empty\n2nd non-empty 3rd non-empty"); + return true; +} + +// 7.13 +TEST FlowSequence() { + YAML::Node doc = YAML::Load(ex7_13); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc[0].size() == 2); + YAML_ASSERT(doc[0][0].as() == "one"); + YAML_ASSERT(doc[0][1].as() == "two"); + YAML_ASSERT(doc[1].size() == 2); + YAML_ASSERT(doc[1][0].as() == "three"); + YAML_ASSERT(doc[1][1].as() == "four"); + return true; +} + +// 7.14 +TEST FlowSequenceEntries() { + YAML::Node doc = YAML::Load(ex7_14); + YAML_ASSERT(doc.size() == 5); + YAML_ASSERT(doc[0].as() == "double quoted"); + YAML_ASSERT(doc[1].as() == "single quoted"); + YAML_ASSERT(doc[2].as() == "plain text"); + YAML_ASSERT(doc[3].size() == 1); + YAML_ASSERT(doc[3][0].as() == "nested"); + YAML_ASSERT(doc[4].size() == 1); + YAML_ASSERT(doc[4]["single"].as() == "pair"); + return true; +} + +// 7.15 +TEST FlowMappings() { + YAML::Node doc = YAML::Load(ex7_15); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc[0].size() == 2); + YAML_ASSERT(doc[0]["one"].as() == "two"); + YAML_ASSERT(doc[0]["three"].as() == "four"); + YAML_ASSERT(doc[1].size() == 2); + YAML_ASSERT(doc[1]["five"].as() == "six"); + YAML_ASSERT(doc[1]["seven"].as() == "eight"); + return true; +} + +// 7.16 +TEST FlowMappingEntries() { + YAML::Node doc = YAML::Load(ex7_16); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["explicit"].as() == "entry"); + YAML_ASSERT(doc["implicit"].as() == "entry"); + YAML_ASSERT(doc[YAML::Null].IsNull()); + return true; +} + +// 7.17 +TEST FlowMappingSeparateValues() { + YAML::Node doc = YAML::Load(ex7_17); + YAML_ASSERT(doc.size() == 4); + YAML_ASSERT(doc["unquoted"].as() == "separate"); + YAML_ASSERT(doc["http://foo.com"].IsNull()); + YAML_ASSERT(doc["omitted value"].IsNull()); + YAML_ASSERT(doc[YAML::Null].as() == "omitted key"); + return true; +} + +// 7.18 +TEST FlowMappingAdjacentValues() { + YAML::Node doc = YAML::Load(ex7_18); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["adjacent"].as() == "value"); + YAML_ASSERT(doc["readable"].as() == "value"); + YAML_ASSERT(doc["empty"].IsNull()); + return true; +} + +// 7.19 +TEST SinglePairFlowMappings() { + YAML::Node doc = YAML::Load(ex7_19); + YAML_ASSERT(doc.size() == 1); + YAML_ASSERT(doc[0].size() == 1); + YAML_ASSERT(doc[0]["foo"].as() == "bar"); + return true; +} + +// 7.20 +TEST SinglePairExplicitEntry() { + YAML::Node doc = YAML::Load(ex7_20); + YAML_ASSERT(doc.size() == 1); + YAML_ASSERT(doc[0].size() == 1); + YAML_ASSERT(doc[0]["foo bar"].as() == "baz"); + return true; +} + +// 7.21 +TEST SinglePairImplicitEntries() { + YAML::Node doc = YAML::Load(ex7_21); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc[0].size() == 1); + YAML_ASSERT(doc[0][0].size() == 1); + YAML_ASSERT(doc[0][0]["YAML"].as() == "separate"); + YAML_ASSERT(doc[1].size() == 1); + YAML_ASSERT(doc[1][0].size() == 1); + YAML_ASSERT(doc[1][0][YAML::Null].as() == "empty key entry"); + YAML_ASSERT(doc[2].size() == 1); + YAML_ASSERT(doc[2][0].size() == 1); + + std::map key; + key["JSON"] = "like"; + YAML_ASSERT(doc[2][0][key].as() == "adjacent"); + return true; +} + +// 7.22 +TEST InvalidImplicitKeys() { + try { + YAML::Load(ex7_22); + } + catch (const YAML::Exception& e) { + if (e.msg == YAML::ErrorMsg::END_OF_SEQ_FLOW) + return true; + + throw; + } + return " no exception thrown"; +} + +// 7.23 +TEST FlowContent() { + YAML::Node doc = YAML::Load(ex7_23); + YAML_ASSERT(doc.size() == 5); + YAML_ASSERT(doc[0].size() == 2); + YAML_ASSERT(doc[0][0].as() == "a"); + YAML_ASSERT(doc[0][1].as() == "b"); + YAML_ASSERT(doc[1].size() == 1); + YAML_ASSERT(doc[1]["a"].as() == "b"); + YAML_ASSERT(doc[2].as() == "a"); + YAML_ASSERT(doc[3].as() == 'b'); + YAML_ASSERT(doc[4].as() == "c"); + return true; +} + +// 7.24 +TEST FlowNodes() { + YAML::Node doc = YAML::Load(ex7_24); + YAML_ASSERT(doc.size() == 5); + YAML_ASSERT(doc[0].Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(doc[0].as() == "a"); + YAML_ASSERT(doc[1].as() == 'b'); + YAML_ASSERT(doc[2].as() == "c"); + YAML_ASSERT(doc[3].as() == "c"); + YAML_ASSERT(doc[4].Tag() == "tag:yaml.org,2002:str"); + YAML_ASSERT(doc[4].as() == ""); + return true; +} + +// 8.1 +TEST BlockScalarHeader() { + YAML::Node doc = YAML::Load(ex8_1); + YAML_ASSERT(doc.size() == 4); + YAML_ASSERT(doc[0].as() == "literal\n"); + YAML_ASSERT(doc[1].as() == " folded\n"); + YAML_ASSERT(doc[2].as() == "keep\n\n"); + YAML_ASSERT(doc[3].as() == " strip"); + return true; +} + +// 8.2 +TEST BlockIndentationHeader() { + YAML::Node doc = YAML::Load(ex8_2); + YAML_ASSERT(doc.size() == 4); + YAML_ASSERT(doc[0].as() == "detected\n"); + YAML_ASSERT(doc[1].as() == "\n\n# detected\n"); + YAML_ASSERT(doc[2].as() == " explicit\n"); + YAML_ASSERT(doc[3].as() == "\t\ndetected\n"); + return true; +} + +// 8.3 +TEST InvalidBlockScalarIndentationIndicators() { + { + bool threw = false; + try { + YAML::Load(ex8_3a); + } + catch (const YAML::Exception& e) { + if (e.msg != YAML::ErrorMsg::END_OF_SEQ) + throw; + + threw = true; + } + + if (!threw) + return " no exception thrown for less indented auto-detecting " + "indentation for a literal block scalar"; + } + + { + bool threw = false; + try { + YAML::Load(ex8_3b); + } + catch (const YAML::Exception& e) { + if (e.msg != YAML::ErrorMsg::END_OF_SEQ) + throw; + + threw = true; + } + + if (!threw) + return " no exception thrown for less indented auto-detecting " + "indentation for a folded block scalar"; + } + + { + bool threw = false; + try { + YAML::Load(ex8_3c); + } + catch (const YAML::Exception& e) { + if (e.msg != YAML::ErrorMsg::END_OF_SEQ) + throw; + + threw = true; + } + + if (!threw) + return " no exception thrown for less indented explicit indentation for " + "a literal block scalar"; + } + + return true; +} + +// 8.4 +TEST ChompingFinalLineBreak() { + YAML::Node doc = YAML::Load(ex8_4); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["strip"].as() == "text"); + YAML_ASSERT(doc["clip"].as() == "text\n"); + YAML_ASSERT(doc["keep"].as() == "text\n"); + return true; +} + +// 8.5 +TEST ChompingTrailingLines() { + YAML::Node doc = YAML::Load(ex8_5); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["strip"].as() == "# text"); + YAML_ASSERT(doc["clip"].as() == "# text\n"); + YAML_ASSERT(doc["keep"].as() == "# text\n"); // Note: I believe + // this is a bug in + // the YAML spec - + // it should be "# + // text\n\n" + return true; +} + +// 8.6 +TEST EmptyScalarChomping() { + YAML::Node doc = YAML::Load(ex8_6); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["strip"].as() == ""); + YAML_ASSERT(doc["clip"].as() == ""); + YAML_ASSERT(doc["keep"].as() == "\n"); + return true; +} + +// 8.7 +TEST LiteralScalar() { + YAML::Node doc = YAML::Load(ex8_7); + YAML_ASSERT(doc.as() == "literal\n\ttext\n"); + return true; +} + +// 8.8 +TEST LiteralContent() { + YAML::Node doc = YAML::Load(ex8_8); + YAML_ASSERT(doc.as() == "\n\nliteral\n \n\ntext\n"); + return true; +} + +// 8.9 +TEST FoldedScalar() { + YAML::Node doc = YAML::Load(ex8_9); + YAML_ASSERT(doc.as() == "folded text\n"); + return true; +} + +// 8.10 +TEST FoldedLines() { + YAML::Node doc = YAML::Load(ex8_10); + YAML_ASSERT(doc.as() == + "\nfolded line\nnext line\n * bullet\n\n * list\n * " + "lines\n\nlast line\n"); + return true; +} + +// 8.11 +TEST MoreIndentedLines() { + YAML::Node doc = YAML::Load(ex8_11); + YAML_ASSERT(doc.as() == + "\nfolded line\nnext line\n * bullet\n\n * list\n * " + "lines\n\nlast line\n"); + return true; +} + +// 8.12 +TEST EmptySeparationLines() { + YAML::Node doc = YAML::Load(ex8_12); + YAML_ASSERT(doc.as() == + "\nfolded line\nnext line\n * bullet\n\n * list\n * " + "lines\n\nlast line\n"); + return true; +} + +// 8.13 +TEST FinalEmptyLines() { + YAML::Node doc = YAML::Load(ex8_13); + YAML_ASSERT(doc.as() == + "\nfolded line\nnext line\n * bullet\n\n * list\n * " + "lines\n\nlast line\n"); + return true; +} + +// 8.14 +TEST BlockSequence() { + YAML::Node doc = YAML::Load(ex8_14); + YAML_ASSERT(doc.size() == 1); + YAML_ASSERT(doc["block sequence"].size() == 2); + YAML_ASSERT(doc["block sequence"][0].as() == "one"); + YAML_ASSERT(doc["block sequence"][1].size() == 1); + YAML_ASSERT(doc["block sequence"][1]["two"].as() == "three"); + return true; +} + +// 8.15 +TEST BlockSequenceEntryTypes() { + YAML::Node doc = YAML::Load(ex8_15); + YAML_ASSERT(doc.size() == 4); + YAML_ASSERT(doc[0].IsNull()); + YAML_ASSERT(doc[1].as() == "block node\n"); + YAML_ASSERT(doc[2].size() == 2); + YAML_ASSERT(doc[2][0].as() == "one"); + YAML_ASSERT(doc[2][1].as() == "two"); + YAML_ASSERT(doc[3].size() == 1); + YAML_ASSERT(doc[3]["one"].as() == "two"); + return true; +} + +// 8.16 +TEST BlockMappings() { + YAML::Node doc = YAML::Load(ex8_16); + YAML_ASSERT(doc.size() == 1); + YAML_ASSERT(doc["block mapping"].size() == 1); + YAML_ASSERT(doc["block mapping"]["key"].as() == "value"); + return true; +} + +// 8.17 +TEST ExplicitBlockMappingEntries() { + YAML::Node doc = YAML::Load(ex8_17); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["explicit key"].IsNull()); + YAML_ASSERT(doc["block key\n"].size() == 2); + YAML_ASSERT(doc["block key\n"][0].as() == "one"); + YAML_ASSERT(doc["block key\n"][1].as() == "two"); + return true; +} + +// 8.18 +TEST ImplicitBlockMappingEntries() { + YAML::Node doc = YAML::Load(ex8_18); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc["plain key"].as() == "in-line value"); + YAML_ASSERT(doc[YAML::Null].IsNull()); + YAML_ASSERT(doc["quoted key"].size() == 1); + YAML_ASSERT(doc["quoted key"][0].as() == "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() == "yellow"); + YAML_ASSERT(doc[1].size() == 1); + std::map key; + key["earth"] = "blue"; + YAML_ASSERT(doc[1][key].size() == 1); + YAML_ASSERT(doc[1][key]["moon"].as() == "white"); + return true; +} + +// 8.20 +TEST BlockNodeTypes() { + YAML::Node doc = YAML::Load(ex8_20); + YAML_ASSERT(doc.size() == 3); + YAML_ASSERT(doc[0].as() == "flow in block"); + YAML_ASSERT(doc[1].as() == "Block scalar\n"); + YAML_ASSERT(doc[2].size() == 1); + YAML_ASSERT(doc[2]["foo"].as() == "bar"); + return true; +} + +// 8.21 +TEST BlockScalarNodes() { + YAML::Node doc = YAML::Load(ex8_21); + YAML_ASSERT(doc.size() == 2); + YAML_ASSERT(doc["literal"].as() == "value"); // Note: I believe + // this is a bug in + // the YAML spec - + // it should be + // "value\n" + YAML_ASSERT(doc["folded"].as() == "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() == "entry"); + YAML_ASSERT(doc["sequence"][1].size() == 1); + YAML_ASSERT(doc["sequence"][1][0].as() == "nested"); + YAML_ASSERT(doc["mapping"].size() == 1); + YAML_ASSERT(doc["mapping"]["foo"].as() == "bar"); + return true; +} +} } diff --git a/test/nodetests.h b/test/nodetests.h index 733e782..6728758 100644 --- a/test/nodetests.h +++ b/test/nodetests.h @@ -1,13 +1,14 @@ #ifndef 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 #endif namespace Test { - bool RunNodeTests(); +bool RunNodeTests(); } -#endif // NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A6666 - +#endif // NODETESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A6666 diff --git a/test/tests.cpp b/test/tests.cpp index efe82fc..3c20995 100644 --- a/test/tests.cpp +++ b/test/tests.cpp @@ -9,25 +9,22 @@ #include #include -namespace Test -{ - void RunAll() - { - bool passed = true; - if(!RunParserTests()) - passed = false; - - if(!RunEmitterTests()) - passed = false; +namespace Test { +void RunAll() { + bool passed = true; + if (!RunParserTests()) + passed = false; - if(!RunSpecTests()) - passed = false; + if (!RunEmitterTests()) + passed = false; - if(!RunNodeTests()) - passed = false; + if (!RunSpecTests()) + passed = false; - if(passed) - std::cout << "All tests passed!\n"; - } + if (!RunNodeTests()) + passed = false; + + if (passed) + std::cout << "All tests passed!\n"; +} } - diff --git a/util/parse.cpp b/util/parse.cpp index ca112e0..7794177 100644 --- a/util/parse.cpp +++ b/util/parse.cpp @@ -5,56 +5,57 @@ #include struct Params { - bool hasFile; - std::string fileName; + bool hasFile; + std::string fileName; }; -Params ParseArgs(int argc, char **argv) { - Params p; +Params ParseArgs(int argc, char** argv) { + Params p; - std::vector args(argv + 1, argv + argc); - - return p; + std::vector args(argv + 1, argv + argc); + + return p; } -class NullEventHandler: public YAML::EventHandler -{ -public: - virtual void OnDocumentStart(const YAML::Mark&) {} - virtual void OnDocumentEnd() {} - - virtual void OnNull(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, const std::string&) {} - - virtual void OnSequenceStart(const YAML::Mark&, const std::string&, YAML::anchor_t) {} - virtual void OnSequenceEnd() {} - - virtual void OnMapStart(const YAML::Mark&, const std::string&, YAML::anchor_t) {} - virtual void OnMapEnd() {} +class NullEventHandler : public YAML::EventHandler { + public: + virtual void OnDocumentStart(const YAML::Mark&) {} + virtual void OnDocumentEnd() {} + + virtual void OnNull(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, + const std::string&) {} + + virtual void OnSequenceStart(const YAML::Mark&, const std::string&, + YAML::anchor_t) {} + virtual void OnSequenceEnd() {} + + virtual void OnMapStart(const YAML::Mark&, const std::string&, + YAML::anchor_t) {} + virtual void OnMapEnd() {} }; -void parse(std::istream& input) -{ - try { - YAML::Node doc = YAML::Load(input); - std::cout << doc << "\n"; - } catch(const YAML::Exception& e) { - std::cerr << e.what() << "\n"; - } +void parse(std::istream& input) { + try { + YAML::Node doc = YAML::Load(input); + std::cout << doc << "\n"; + } + catch (const YAML::Exception& e) { + std::cerr << e.what() << "\n"; + } } -int main(int argc, char **argv) -{ - Params p = ParseArgs(argc, argv); +int main(int argc, char** argv) { + Params p = ParseArgs(argc, argv); - if(argc > 1) { - std::ifstream fin; - fin.open(argv[1]); - parse(fin); - } else { - parse(std::cin); - } + if (argc > 1) { + std::ifstream fin; + fin.open(argv[1]); + parse(fin); + } else { + parse(std::cin); + } - return 0; + return 0; }