mirror of
https://github.com/RPCS3/yaml-cpp.git
synced 2026-07-25 20:55:22 -04:00
Compare commits
186 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| beb524489c | |||
| 4ffb93c12b | |||
| ae06a40fe6 | |||
| 315b00065b | |||
| 6f02f7556e | |||
| fa0af88dfe | |||
| bce845bb1f | |||
| ed570b9f7c | |||
| 59b0e986bf | |||
| cffb98d15b | |||
| 3e1ba0f3b4 | |||
| d0b5bf4b7b | |||
| 7db39e66b8 | |||
| 94eb7f1dbd | |||
| 5733b77b84 | |||
| 98bebfb628 | |||
| 7c4cc9bf5f | |||
| fa885d1813 | |||
| da4614eb8b | |||
| 4dcd222d1f | |||
| 7bdd31b34b | |||
| a4b8521efe | |||
| 7037562998 | |||
| f3ff6ffc55 | |||
| e3ff87ecde | |||
| 45ac700fff | |||
| 2aab5acab4 | |||
| e9d760eea9 | |||
| d485d0a834 | |||
| 973ac4b3bd | |||
| e91a152e06 | |||
| 5217149ed4 | |||
| e7ac6b3bf1 | |||
| 9a1f4f9a0d | |||
| 07443495c8 | |||
| 729fb4d30b | |||
| 91163d2296 | |||
| 75477ade65 | |||
| 0e1638d7b5 | |||
| 19673ff01a | |||
| 1db573dd30 | |||
| 873ad336f8 | |||
| 0d41a7de7c | |||
| 1b240d3576 | |||
| 4b6a0b382c | |||
| b789a1c5f9 | |||
| a1460169e6 | |||
| abe0af76c5 | |||
| 8e636436f8 | |||
| 8c33523b15 | |||
| 81c2e6b6ca | |||
| ba11f5ae15 | |||
| d92ca21bcc | |||
| 487f381ae9 | |||
| d506dae914 | |||
| 7a89920441 | |||
| 382f1ba3c7 | |||
| ae41e58ca3 | |||
| 72919adf55 | |||
| 1507fcd36d | |||
| b1ce042535 | |||
| 9b78bd459b | |||
| c225a55344 | |||
| 555fb5c3a0 | |||
| 2160bb2bcc | |||
| 946d3260d7 | |||
| 2f3821ca98 | |||
| 980c4cb0ce | |||
| 670a3e952a | |||
| 5b7f931cd7 | |||
| ff6e6bdfd5 | |||
| a84c1af98a | |||
| 3e0179fd6e | |||
| 6c8600ab52 | |||
| 174f2c1fe7 | |||
| 11f98f1cc6 | |||
| 464bb70114 | |||
| 781fb4d093 | |||
| b113c37819 | |||
| 6f44e89b7f | |||
| b929eb94a0 | |||
| a7b8879494 | |||
| 81f5348ea9 | |||
| 620c58abec | |||
| d2e037396e | |||
| 1cde7fbfc0 | |||
| 9585797b41 | |||
| 441a230509 | |||
| e06104d77c | |||
| 67f49d96d9 | |||
| 820f45b10b | |||
| 9a1a3974c6 | |||
| e76521c0e9 | |||
| b952bc594f | |||
| 24b0663828 | |||
| 5139ebf7ba | |||
| b51a32ae14 | |||
| 69ef85526a | |||
| de1c6171ee | |||
| 9245f9253a | |||
| b3a5a519f2 | |||
| 9d0e0c6a48 | |||
| f9c0725684 | |||
| a6d5902ebf | |||
| 2768927782 | |||
| 5c54431b3b | |||
| 7214ffc107 | |||
| d98f9d8713 | |||
| 27bd791ea0 | |||
| 5a2a317d62 | |||
| f8d81fff8c | |||
| 043bbddcf0 | |||
| 9969ff512e | |||
| 14cdec770c | |||
| 6e4317e37c | |||
| 907be0660c | |||
| 3ed09b89f8 | |||
| 1406b84016 | |||
| c175be7d4c | |||
| 9d403d08f0 | |||
| 45322566c7 | |||
| a45f083e00 | |||
| 5c0db0d21b | |||
| 80db86e771 | |||
| b16f958660 | |||
| ec2ecad197 | |||
| 813817f1ab | |||
| d45bb667b6 | |||
| cc87c83b01 | |||
| 09d7ab365f | |||
| 2eab1e025e | |||
| 2e2c489e29 | |||
| f3a2c8497a | |||
| 771cc6fa25 | |||
| ef630abeee | |||
| cadc04ce47 | |||
| 4cfa233888 | |||
| 03e6b5b991 | |||
| c0c55fe50b | |||
| a8a0fb41cb | |||
| 6c2946bf58 | |||
| 115cf601e9 | |||
| 2a0ddc8cb2 | |||
| dacc631968 | |||
| d98007b0be | |||
| ed488e5197 | |||
| 2be40919de | |||
| 2ccbfeff47 | |||
| 901d16a96f | |||
| d56b54b34f | |||
| f7358701f2 | |||
| 4c5a488f68 | |||
| 8180a85a3b | |||
| 121c2e577f | |||
| c1966ba3fc | |||
| 852e5b63e5 | |||
| b6a0ef207b | |||
| ed6c294749 | |||
| 07d4cac48f | |||
| 2b8628922f | |||
| 0683cbf859 | |||
| 5f8252ee6f | |||
| ff99f85a6d | |||
| 0d5a97bffe | |||
| 6c193d6fbd | |||
| d076252dff | |||
| 2e27c5d9c3 | |||
| 72b443375c | |||
| 43ea59a4ed | |||
| 01ef70a6f9 | |||
| c63ebbd878 | |||
| 11706abbb7 | |||
| 49a75b2d78 | |||
| a224c7818b | |||
| 8fca02fb2a | |||
| de29068110 | |||
| 4e435b1321 | |||
| 873dbc2421 | |||
| 31f7db5a0d | |||
| a3961d047f | |||
| 8ae7b48188 | |||
| bcbca461de | |||
| 4ed7f62431 | |||
| e22eea26b1 | |||
| 110a7f06a8 | |||
| bb55b0ba91 |
+7
-12
@@ -10,22 +10,17 @@ if(IPHONE)
|
||||
endif(IPHONE)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
set(CMAKE_CXX_FLAGS "-O2 -Wall -Wextra -pedantic -Wno-long-long ${CMAKE_CXX_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "-O2 -Wall -pedantic -Wextra ${CMAKE_CXX_FLAGS}")
|
||||
endif(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
if(MSVC)
|
||||
set(LIB_TYPE) # I can't figure out how CMake handles Windows shared libraries
|
||||
set(CMAKE_CXX_FLAGS "/W3 /wd4127 /wd4355 /D_SCL_SECURE_NO_WARNINGS ${CMAKE_CXX_FLAGS}")
|
||||
endif(MSVC)
|
||||
|
||||
set(YAML_CPP_VERSION_MAJOR "0")
|
||||
set(YAML_CPP_VERSION_MINOR "2")
|
||||
set(YAML_CPP_VERSION_PATCH "5")
|
||||
set(YAML_CPP_VERSION_PATCH "2")
|
||||
set(YAML_CPP_VERSION "${YAML_CPP_VERSION_MAJOR}.${YAML_CPP_VERSION_MINOR}.${YAML_CPP_VERSION_PATCH}")
|
||||
|
||||
enable_testing()
|
||||
|
||||
option(YAML_CPP_BUILD_TOOLS "Enables or disables testing and parse tools" true)
|
||||
option(YAML_CPP_BUILD_TOOLS "Enables or disables yaml-reader and parse tools" true)
|
||||
|
||||
if(WIN32)
|
||||
set(_library_dir bin) # .dll are in PATH, like executables
|
||||
@@ -43,9 +38,9 @@ set(_INSTALL_DESTINATIONS
|
||||
ARCHIVE DESTINATION lib${LIB_SUFFIX}
|
||||
)
|
||||
#
|
||||
file(GLOB public_headers include/[a-z]*.h)
|
||||
file(GLOB private_headers src/[a-z]*.h)
|
||||
file(GLOB sources src/[a-z]*.cpp)
|
||||
file(GLOB public_headers include/*.h)
|
||||
file(GLOB private_headers src/*.h)
|
||||
file(GLOB sources src/*.cpp)
|
||||
|
||||
include_directories(${YAML_CPP_SOURCE_DIR}/include)
|
||||
add_library(yaml-cpp
|
||||
@@ -72,6 +67,6 @@ if(UNIX)
|
||||
endif(UNIX)
|
||||
|
||||
if(YAML_CPP_BUILD_TOOLS)
|
||||
add_subdirectory (test)
|
||||
add_subdirectory (yaml-reader)
|
||||
add_subdirectory (util)
|
||||
endif(YAML_CPP_BUILD_TOOLS)
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef ALIASMANAGER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define ALIASMANAGER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#include "anchor.h"
|
||||
#include <map>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
|
||||
class AliasManager
|
||||
{
|
||||
public:
|
||||
AliasManager();
|
||||
|
||||
void RegisterReference(const Node& node);
|
||||
|
||||
const Node *LookupReference(const Node& node) const;
|
||||
anchor_t LookupAnchor(const Node& node) const;
|
||||
|
||||
private:
|
||||
const Node *_LookupReference(const Node& oldIdentity) const;
|
||||
anchor_t _CreateNewAnchor();
|
||||
|
||||
private:
|
||||
typedef std::map<const Node*, const Node*> NodeByNode;
|
||||
NodeByNode m_newIdentityByOldIdentity;
|
||||
|
||||
typedef std::map<const Node*, anchor_t> AnchorByIdentity;
|
||||
AnchorByIdentity m_anchorByIdentity;
|
||||
|
||||
anchor_t m_curAnchor;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ALIASMANAGER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
typedef std::size_t anchor_t;
|
||||
const anchor_t NullAnchor = 0;
|
||||
}
|
||||
|
||||
#endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
@@ -1,40 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "anchor.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
/// AnchorDict
|
||||
/// . An object that stores and retrieves values correlating to anchor_t
|
||||
/// values.
|
||||
/// . Efficient implementation that can make assumptions about how anchor_t
|
||||
/// values are assigned by the Parser class.
|
||||
template <class T>
|
||||
class AnchorDict
|
||||
{
|
||||
public:
|
||||
void Register(anchor_t anchor, T value)
|
||||
{
|
||||
if (anchor > m_data.size())
|
||||
{
|
||||
m_data.resize(anchor);
|
||||
}
|
||||
m_data[anchor - 1] = value;
|
||||
}
|
||||
|
||||
T Get(anchor_t anchor) const
|
||||
{
|
||||
return m_data[anchor - 1];
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<T> m_data;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
+19
-7
@@ -5,7 +5,6 @@
|
||||
|
||||
|
||||
#include "null.h"
|
||||
#include "traits.h"
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
@@ -19,13 +18,26 @@ namespace YAML
|
||||
bool Convert(const std::string& input, bool& output);
|
||||
bool Convert(const std::string& input, _Null& output);
|
||||
|
||||
template <typename T>
|
||||
inline bool Convert(const std::string& input, T& output, typename enable_if<is_numeric<T> >::type * = 0) {
|
||||
std::stringstream stream(input);
|
||||
stream.unsetf(std::ios::dec);
|
||||
stream >> output;
|
||||
return !!stream;
|
||||
#define YAML_MAKE_STREAM_CONVERT(type) \
|
||||
inline bool Convert(const std::string& input, type& output) { \
|
||||
std::stringstream stream(input); \
|
||||
stream >> output; \
|
||||
return !stream.fail(); \
|
||||
}
|
||||
|
||||
YAML_MAKE_STREAM_CONVERT(char)
|
||||
YAML_MAKE_STREAM_CONVERT(unsigned char)
|
||||
YAML_MAKE_STREAM_CONVERT(int)
|
||||
YAML_MAKE_STREAM_CONVERT(unsigned int)
|
||||
YAML_MAKE_STREAM_CONVERT(short)
|
||||
YAML_MAKE_STREAM_CONVERT(unsigned short)
|
||||
YAML_MAKE_STREAM_CONVERT(long)
|
||||
YAML_MAKE_STREAM_CONVERT(unsigned long)
|
||||
YAML_MAKE_STREAM_CONVERT(float)
|
||||
YAML_MAKE_STREAM_CONVERT(double)
|
||||
YAML_MAKE_STREAM_CONVERT(long double)
|
||||
|
||||
#undef YAML_MAKE_STREAM_CONVERT
|
||||
}
|
||||
|
||||
#endif // CONVERSION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef CRT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define CRT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
// for detecting memory leaks
|
||||
#ifdef _DEBUG
|
||||
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <stdlib.h>
|
||||
#include <crtdbg.h>
|
||||
|
||||
#endif // _DEBUG
|
||||
|
||||
|
||||
#endif // CRT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
@@ -1,43 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#include "eventhandler.h"
|
||||
#include <stack>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Emitter;
|
||||
|
||||
class EmitFromEvents: public EventHandler
|
||||
{
|
||||
public:
|
||||
EmitFromEvents(Emitter& emitter);
|
||||
|
||||
virtual void OnDocumentStart(const Mark& mark);
|
||||
virtual void OnDocumentEnd();
|
||||
|
||||
virtual void OnNull(const std::string& tag, 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:
|
||||
void BeginNode();
|
||||
void EmitProps(const std::string& tag, anchor_t anchor);
|
||||
|
||||
private:
|
||||
Emitter& m_emitter;
|
||||
|
||||
struct State { enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue }; };
|
||||
std::stack<State::value> m_stateStack;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
+10
-63
@@ -9,7 +9,6 @@
|
||||
#include "null.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
@@ -46,23 +45,16 @@ namespace YAML
|
||||
|
||||
// overloads of write
|
||||
Emitter& Write(const std::string& str);
|
||||
Emitter& Write(const char *str);
|
||||
Emitter& Write(int i);
|
||||
Emitter& Write(bool b);
|
||||
Emitter& Write(float f);
|
||||
Emitter& Write(double d);
|
||||
Emitter& Write(const _Alias& alias);
|
||||
Emitter& Write(const _Anchor& anchor);
|
||||
Emitter& Write(const _Tag& tag);
|
||||
Emitter& Write(const _Comment& comment);
|
||||
Emitter& Write(const _Null& null);
|
||||
|
||||
template <typename T>
|
||||
Emitter& WriteIntegralType(T value);
|
||||
|
||||
template <typename T>
|
||||
Emitter& WriteStreamable(T value);
|
||||
|
||||
private:
|
||||
void PreWriteIntegralType(std::stringstream& str);
|
||||
void PostWriteIntegralType(const std::stringstream& str);
|
||||
|
||||
private:
|
||||
enum ATOMIC_TYPE { AT_SCALAR, AT_SEQ, AT_BLOCK_SEQ, AT_FLOW_SEQ, AT_MAP, AT_BLOCK_MAP, AT_FLOW_MAP };
|
||||
|
||||
@@ -77,69 +69,24 @@ namespace YAML
|
||||
void EmitEndMap();
|
||||
void EmitKey();
|
||||
void EmitValue();
|
||||
void EmitKindTag();
|
||||
void EmitTag(bool verbatim, const _Tag& tag);
|
||||
|
||||
private:
|
||||
ostream m_stream;
|
||||
std::auto_ptr <EmitterState> m_pState;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline Emitter& Emitter::WriteIntegralType(T value)
|
||||
{
|
||||
if(!good())
|
||||
return *this;
|
||||
|
||||
std::stringstream str;
|
||||
PreWriteIntegralType(str);
|
||||
str << value;
|
||||
PostWriteIntegralType(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Emitter& Emitter::WriteStreamable(T value)
|
||||
{
|
||||
if(!good())
|
||||
return *this;
|
||||
|
||||
PreAtomicWrite();
|
||||
EmitSeparationIfNecessary();
|
||||
|
||||
std::stringstream str;
|
||||
str << value;
|
||||
m_stream << str.str();
|
||||
|
||||
PostAtomicWrite();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// overloads of insertion
|
||||
inline Emitter& operator << (Emitter& emitter, const std::string& v) { return emitter.Write(v); }
|
||||
inline Emitter& operator << (Emitter& emitter, bool v) { return emitter.Write(v); }
|
||||
inline Emitter& operator << (Emitter& emitter, const _Alias& v) { return emitter.Write(v); }
|
||||
inline Emitter& operator << (Emitter& emitter, const _Anchor& v) { return emitter.Write(v); }
|
||||
inline Emitter& operator << (Emitter& emitter, const _Tag& v) { return emitter.Write(v); }
|
||||
inline Emitter& operator << (Emitter& emitter, const _Comment& v) { return emitter.Write(v); }
|
||||
inline Emitter& operator << (Emitter& emitter, const _Null& v) { return emitter.Write(v); }
|
||||
|
||||
inline Emitter& operator << (Emitter& emitter, const char *v) { return emitter.Write(std::string(v)); }
|
||||
|
||||
inline Emitter& operator << (Emitter& emitter, int v) { return emitter.WriteIntegralType(v); }
|
||||
inline Emitter& operator << (Emitter& emitter, unsigned int v) { return emitter.WriteIntegralType(v); }
|
||||
inline Emitter& operator << (Emitter& emitter, short v) { return emitter.WriteIntegralType(v); }
|
||||
inline Emitter& operator << (Emitter& emitter, unsigned short v) { return emitter.WriteIntegralType(v); }
|
||||
inline Emitter& operator << (Emitter& emitter, long v) { return emitter.WriteIntegralType(v); }
|
||||
inline Emitter& operator << (Emitter& emitter, unsigned long v) { return emitter.WriteIntegralType(v); }
|
||||
|
||||
inline Emitter& operator << (Emitter& emitter, float v) { return emitter.WriteStreamable(v); }
|
||||
inline Emitter& operator << (Emitter& emitter, double v) { return emitter.WriteStreamable(v); }
|
||||
template <typename T>
|
||||
inline Emitter& operator << (Emitter& emitter, T v) {
|
||||
return emitter.Write(v);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline Emitter& operator << (Emitter& emitter, EMITTER_MANIP value) {
|
||||
return emitter.SetLocalValue(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline Emitter& operator << (Emitter& emitter, _Indent indent) {
|
||||
return emitter.SetLocalIndent(indent);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ namespace YAML
|
||||
enum EMITTER_MANIP {
|
||||
// general manipulators
|
||||
Auto,
|
||||
TagByKind,
|
||||
|
||||
// output character set
|
||||
EmitNonAscii,
|
||||
@@ -81,26 +80,6 @@ namespace YAML
|
||||
inline _Anchor Anchor(const std::string content) {
|
||||
return _Anchor(content);
|
||||
}
|
||||
|
||||
struct _Tag {
|
||||
explicit _Tag(const std::string& content_)
|
||||
: content(content_), verbatim(true)
|
||||
{
|
||||
}
|
||||
std::string content;
|
||||
bool verbatim;
|
||||
};
|
||||
|
||||
typedef _Tag VerbatimTag;
|
||||
|
||||
struct LocalTag : public _Tag
|
||||
{
|
||||
explicit LocalTag(const std::string& content_)
|
||||
: _Tag(content_)
|
||||
{
|
||||
verbatim = false;
|
||||
}
|
||||
};
|
||||
|
||||
struct _Comment {
|
||||
_Comment(const std::string& content_): content(content_) {}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#include "anchor.h"
|
||||
#include <string>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct Mark;
|
||||
|
||||
class EventHandler
|
||||
{
|
||||
public:
|
||||
virtual ~EventHandler() {}
|
||||
|
||||
virtual void OnDocumentStart(const Mark& mark) = 0;
|
||||
virtual void OnDocumentEnd() = 0;
|
||||
|
||||
virtual void OnNull(const std::string& tag, anchor_t anchor) = 0;
|
||||
virtual void OnAlias(const Mark& mark, anchor_t anchor) = 0;
|
||||
virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value) = 0;
|
||||
|
||||
virtual void OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor) = 0;
|
||||
virtual void OnSequenceEnd() = 0;
|
||||
|
||||
virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor) = 0;
|
||||
virtual void OnMapEnd() = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
+6
-30
@@ -5,7 +5,6 @@
|
||||
|
||||
|
||||
#include "mark.h"
|
||||
#include "traits.h"
|
||||
#include <exception>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
@@ -18,12 +17,7 @@ namespace YAML
|
||||
const std::string YAML_DIRECTIVE_ARGS = "YAML directives must have exactly one argument";
|
||||
const std::string YAML_VERSION = "bad YAML version: ";
|
||||
const std::string YAML_MAJOR_VERSION = "YAML major version too large";
|
||||
const std::string REPEATED_YAML_DIRECTIVE= "repeated YAML directive";
|
||||
const std::string TAG_DIRECTIVE_ARGS = "TAG directives must have exactly two arguments";
|
||||
const std::string REPEATED_TAG_DIRECTIVE = "repeated TAG directive";
|
||||
const std::string CHAR_IN_TAG_HANDLE = "illegal character found while scanning tag handle";
|
||||
const std::string TAG_WITH_NO_SUFFIX = "tag handle with no suffix";
|
||||
const std::string END_OF_VERBATIM_TAG = "end of verbatim tag not found";
|
||||
const std::string END_OF_MAP = "end of map not found";
|
||||
const std::string END_OF_MAP_FLOW = "end of map flow not found";
|
||||
const std::string END_OF_SEQ = "end of sequence not found";
|
||||
@@ -63,27 +57,10 @@ namespace YAML
|
||||
const std::string SINGLE_QUOTED_CHAR = "invalid character in single-quoted string";
|
||||
const std::string INVALID_ANCHOR = "invalid anchor";
|
||||
const std::string INVALID_ALIAS = "invalid alias";
|
||||
const std::string INVALID_TAG = "invalid tag";
|
||||
const std::string EXPECTED_KEY_TOKEN = "expected key token";
|
||||
const std::string EXPECTED_VALUE_TOKEN = "expected value token";
|
||||
const std::string UNEXPECTED_KEY_TOKEN = "unexpected key token";
|
||||
const std::string UNEXPECTED_VALUE_TOKEN = "unexpected value token";
|
||||
|
||||
template <typename T>
|
||||
inline const std::string KEY_NOT_FOUND_WITH_KEY(const T&, typename disable_if<is_numeric<T> >::type * = 0) {
|
||||
return KEY_NOT_FOUND;
|
||||
}
|
||||
|
||||
inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) {
|
||||
return KEY_NOT_FOUND + ": " + key;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline const std::string KEY_NOT_FOUND_WITH_KEY(const T& key, typename enable_if<is_numeric<T> >::type * = 0) {
|
||||
std::stringstream stream;
|
||||
stream << KEY_NOT_FOUND << ": " << key;
|
||||
return stream.str();
|
||||
}
|
||||
}
|
||||
|
||||
class Exception: public std::exception {
|
||||
@@ -125,23 +102,22 @@ namespace YAML
|
||||
|
||||
class KeyNotFound: public RepresentationException {
|
||||
public:
|
||||
template <typename T>
|
||||
KeyNotFound(const Mark& mark_, const T& key_)
|
||||
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {}
|
||||
KeyNotFound(const Mark& mark_)
|
||||
: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND) {}
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class TypedKeyNotFound: public KeyNotFound {
|
||||
public:
|
||||
TypedKeyNotFound(const Mark& mark_, const T& key_)
|
||||
: KeyNotFound(mark_, key_), key(key_) {}
|
||||
virtual ~TypedKeyNotFound() throw() {}
|
||||
: KeyNotFound(mark_), key(key_) {}
|
||||
~TypedKeyNotFound() throw() {}
|
||||
|
||||
T key;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline TypedKeyNotFound <T> MakeTypedKeyNotFound(const Mark& mark, const T& key) {
|
||||
TypedKeyNotFound <T> MakeTypedKeyNotFound(const Mark& mark, const T& key) {
|
||||
return TypedKeyNotFound <T> (mark, key);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
#ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct Mark;
|
||||
|
||||
// GraphBuilderInterface
|
||||
// . Abstraction of node creation
|
||||
// . pParentNode is always NULL or the return value of one of the NewXXX()
|
||||
// functions.
|
||||
class GraphBuilderInterface
|
||||
{
|
||||
public:
|
||||
// Create and return a new node with a null value.
|
||||
virtual void *NewNull(const std::string& tag, void *pParentNode) = 0;
|
||||
|
||||
// Create and return a new node with the given tag and value.
|
||||
virtual void *NewScalar(const Mark& mark, const std::string& tag, void *pParentNode, const std::string& value) = 0;
|
||||
|
||||
// Create and return a new sequence node
|
||||
virtual void *NewSequence(const Mark& mark, const std::string& tag, void *pParentNode) = 0;
|
||||
// Add pNode to pSequence. pNode was created with one of the NewXxx()
|
||||
// functions and pSequence with NewSequence().
|
||||
virtual void AppendToSequence(void *pSequence, void *pNode) = 0;
|
||||
// Note that no moew entries will be added to pSequence
|
||||
virtual void SequenceComplete(void *pSequence) {(void)pSequence;}
|
||||
|
||||
// Create and return a new map node
|
||||
virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) = 0;
|
||||
// Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode
|
||||
// were created with one of the NewXxx() methods and pMap with NewMap().
|
||||
virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0;
|
||||
// Note that no more assignments will be made in pMap
|
||||
virtual void MapComplete(void *pMap) {(void)pMap;}
|
||||
|
||||
// Return the node that should be used in place of an alias referencing
|
||||
// pNode (pNode by default)
|
||||
virtual void *AnchorReference(const Mark& mark, void *pNode) {(void)mark; return pNode;}
|
||||
};
|
||||
|
||||
// Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines
|
||||
// Node, Sequence, and Map types. Sequence and Map must derive from Node
|
||||
// (unless Node is defined as void). Impl must also implement function with
|
||||
// all of the same names as the virtual functions in GraphBuilderInterface
|
||||
// -- including the ones with default implementations -- but with the
|
||||
// prototypes changed to accept an explicit Node*, Sequence*, or Map* where
|
||||
// appropriate.
|
||||
template <class Impl>
|
||||
class GraphBuilder : public GraphBuilderInterface
|
||||
{
|
||||
public:
|
||||
typedef typename Impl::Node Node;
|
||||
typedef typename Impl::Sequence Sequence;
|
||||
typedef typename Impl::Map Map;
|
||||
|
||||
GraphBuilder(Impl& impl) : m_impl(impl)
|
||||
{
|
||||
Map* pMap = NULL;
|
||||
Sequence* pSeq = NULL;
|
||||
Node* pNode = NULL;
|
||||
|
||||
// Type consistency checks
|
||||
pNode = pMap;
|
||||
pNode = pSeq;
|
||||
}
|
||||
|
||||
GraphBuilderInterface& AsBuilderInterface() {return *this;}
|
||||
|
||||
virtual void *NewNull(const std::string& tag, void* pParentNode) {
|
||||
return CheckType<Node>(m_impl.NewNull(tag, AsNode(pParentNode)));
|
||||
}
|
||||
|
||||
virtual void *NewScalar(const Mark& mark, const std::string& tag, void *pParentNode, const std::string& value) {
|
||||
return CheckType<Node>(m_impl.NewScalar(mark, tag, AsNode(pParentNode), value));
|
||||
}
|
||||
|
||||
virtual void *NewSequence(const Mark& mark, const std::string& tag, void *pParentNode) {
|
||||
return CheckType<Sequence>(m_impl.NewSequence(mark, tag, AsNode(pParentNode)));
|
||||
}
|
||||
virtual void AppendToSequence(void *pSequence, void *pNode) {
|
||||
m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode));
|
||||
}
|
||||
virtual void SequenceComplete(void *pSequence) {
|
||||
m_impl.SequenceComplete(AsSequence(pSequence));
|
||||
}
|
||||
|
||||
virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) {
|
||||
return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode)));
|
||||
}
|
||||
virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) {
|
||||
m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode));
|
||||
}
|
||||
virtual void MapComplete(void *pMap) {
|
||||
m_impl.MapComplete(AsMap(pMap));
|
||||
}
|
||||
|
||||
virtual void *AnchorReference(const Mark& mark, void *pNode) {
|
||||
return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode)));
|
||||
}
|
||||
|
||||
private:
|
||||
Impl& m_impl;
|
||||
|
||||
// Static check for pointer to T
|
||||
template <class T, class U>
|
||||
static T* CheckType(U* p) {return p;}
|
||||
|
||||
static Node *AsNode(void *pNode) {return static_cast<Node*>(pNode);}
|
||||
static Sequence *AsSequence(void *pSeq) {return static_cast<Sequence*>(pSeq);}
|
||||
static Map *AsMap(void *pMap) {return static_cast<Map*>(pMap);}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
+12
-17
@@ -9,6 +9,7 @@
|
||||
#include "iterator.h"
|
||||
#include "mark.h"
|
||||
#include "noncopyable.h"
|
||||
#include "parserstate.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -17,12 +18,9 @@
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class AliasManager;
|
||||
class Content;
|
||||
class Scanner;
|
||||
class Emitter;
|
||||
class EventHandler;
|
||||
struct NodeProperties;
|
||||
|
||||
enum CONTENT_TYPE { CT_NONE, CT_SCALAR, CT_SEQUENCE, CT_MAP };
|
||||
|
||||
@@ -34,16 +32,7 @@ namespace YAML
|
||||
|
||||
void Clear();
|
||||
std::auto_ptr<Node> Clone() const;
|
||||
void EmitEvents(EventHandler& eventHandler) const;
|
||||
void EmitEvents(AliasManager& am, EventHandler& eventHandler) const;
|
||||
|
||||
void Init(CONTENT_TYPE type, const Mark& mark, const std::string& tag);
|
||||
void InitNull(const std::string& tag);
|
||||
void InitAlias(const Mark& mark, const Node& identity);
|
||||
|
||||
void SetData(const std::string& data);
|
||||
void Append(std::auto_ptr<Node> pNode);
|
||||
void Insert(std::auto_ptr<Node> pKey, std::auto_ptr<Node> pValue);
|
||||
void Parse(Scanner *pScanner, const ParserState& state);
|
||||
|
||||
CONTENT_TYPE GetType() const;
|
||||
|
||||
@@ -86,9 +75,6 @@ namespace YAML
|
||||
const Node *Identity() const { return m_pIdentity; }
|
||||
bool IsAlias() const { return m_alias; }
|
||||
bool IsReferenced() const { return m_referenced; }
|
||||
|
||||
// for tags
|
||||
const std::string GetTag() const { return IsAlias() ? m_pIdentity->GetTag() : m_tag; }
|
||||
|
||||
// emitting
|
||||
friend Emitter& operator << (Emitter& out, const Node& node);
|
||||
@@ -108,10 +94,19 @@ namespace YAML
|
||||
|
||||
template <typename T>
|
||||
const Node *FindValueForKey(const T& key) const;
|
||||
|
||||
// helper for cloning
|
||||
Node(const Mark& mark, const std::string& anchor, const std::string& tag, const Content *pContent);
|
||||
|
||||
// helpers for parsing
|
||||
void ParseHeader(Scanner *pScanner, const ParserState& state);
|
||||
void ParseTag(Scanner *pScanner, const ParserState& state);
|
||||
void ParseAnchor(Scanner *pScanner, const ParserState& state);
|
||||
void ParseAlias(Scanner *pScanner, const ParserState& state);
|
||||
|
||||
private:
|
||||
Mark m_mark;
|
||||
std::string m_tag;
|
||||
std::string m_anchor, m_tag;
|
||||
Content *m_pContent;
|
||||
bool m_alias;
|
||||
const Node *m_pIdentity;
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NODEPROPERTIES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODEPROPERTIES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct NodeProperties {
|
||||
std::string tag;
|
||||
std::string anchor;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NODEPROPERTIES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
@@ -52,10 +52,9 @@ namespace YAML
|
||||
int operator,(flag, flag);
|
||||
|
||||
template<typename T>
|
||||
char operator,(flag, T const&);
|
||||
void operator,(flag, T const&);
|
||||
|
||||
char operator,(int, flag);
|
||||
int operator,(char, flag);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
||||
+11
-24
@@ -4,20 +4,19 @@
|
||||
#define PARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "graphbuilder.h"
|
||||
#include "node.h"
|
||||
#include "parserstate.h"
|
||||
#include "noncopyable.h"
|
||||
#include <ios>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct Directives;
|
||||
struct Mark;
|
||||
struct Token;
|
||||
class EventHandler;
|
||||
class GraphBuilderInterface;
|
||||
class Node;
|
||||
class Scanner;
|
||||
struct Token;
|
||||
|
||||
class Parser: private noncopyable
|
||||
{
|
||||
@@ -29,30 +28,18 @@ namespace YAML
|
||||
operator bool() const;
|
||||
|
||||
void Load(std::istream& in);
|
||||
bool HandleNextDocument(EventHandler& eventHandler);
|
||||
|
||||
void *BuildNextDocumentGraph(GraphBuilderInterface& graphBuilder);
|
||||
template <class Builder>
|
||||
typename Builder::Node *BuildNextDocumentGraph(Builder& graphBuilder)
|
||||
{
|
||||
GraphBuilder<Builder> wrapper(graphBuilder); // Must be lvalue to make C++ happy
|
||||
return static_cast<typename Builder::Node *>(
|
||||
BuildNextDocumentGraph(wrapper.AsBuilderInterface())
|
||||
);
|
||||
}
|
||||
|
||||
bool GetNextDocument(Node& document);
|
||||
void PrintTokens(std::ostream& out);
|
||||
|
||||
private:
|
||||
void ParseDirectives();
|
||||
void HandleDirective(const Token& token);
|
||||
void HandleYamlDirective(const Token& token);
|
||||
void HandleTagDirective(const Token& token);
|
||||
|
||||
void HandleDirective(Token *pToken);
|
||||
void HandleYamlDirective(Token *pToken);
|
||||
void HandleTagDirective(Token *pToken);
|
||||
|
||||
private:
|
||||
std::auto_ptr<Scanner> m_pScanner;
|
||||
std::auto_ptr<Directives> m_pDirectives;
|
||||
ParserState m_state;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct Version {
|
||||
int major, minor;
|
||||
};
|
||||
|
||||
struct ParserState
|
||||
{
|
||||
Version version;
|
||||
std::map <std::string, std::string> tags;
|
||||
|
||||
void Reset();
|
||||
std::string TranslateTag(const std::string& handle) const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // PARSERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
@@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef STLNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define STLNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
template <typename T>
|
||||
void operator >> (const Node& node, std::vector<T>& v)
|
||||
{
|
||||
v.clear();
|
||||
v.resize(node.size());
|
||||
for(unsigned i=0;i<node.size();++i)
|
||||
node[i] >> v[i];
|
||||
}
|
||||
|
||||
|
||||
template <typename K, typename V>
|
||||
void operator >> (const Node& node, std::map<K, V>& m)
|
||||
{
|
||||
m.clear();
|
||||
for(Iterator it=node.begin();it!=node.end();++it) {
|
||||
K k;
|
||||
V v;
|
||||
it.first() >> k;
|
||||
it.second() >> v;
|
||||
m[k] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // STLNODE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
@@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
template <typename>
|
||||
struct is_numeric { enum { value = false }; };
|
||||
|
||||
template <> struct is_numeric <char> { enum { value = true }; };
|
||||
template <> struct is_numeric <unsigned char> { enum { value = true }; };
|
||||
template <> struct is_numeric <int> { enum { value = true }; };
|
||||
template <> struct is_numeric <unsigned int> { enum { value = true }; };
|
||||
template <> struct is_numeric <long int> { enum { value = true }; };
|
||||
template <> struct is_numeric <unsigned long int> { enum { value = true }; };
|
||||
template <> struct is_numeric <short int> { enum { value = true }; };
|
||||
template <> struct is_numeric <unsigned short int> { enum { value = true }; };
|
||||
template <> struct is_numeric <long long> { enum { value = true }; };
|
||||
template <> struct is_numeric <unsigned long long> { enum { value = true }; };
|
||||
template <> struct is_numeric <float> { enum { value = true }; };
|
||||
template <> struct is_numeric <double> { enum { value = true }; };
|
||||
template <> struct is_numeric <long double> { enum { value = true }; };
|
||||
|
||||
template <bool, class T = void>
|
||||
struct enable_if_c {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct enable_if_c<false, T> {};
|
||||
|
||||
template <class Cond, class T = void>
|
||||
struct enable_if : public enable_if_c<Cond::value, T> {};
|
||||
|
||||
template <bool, class T = void>
|
||||
struct disable_if_c {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct disable_if_c<true, T> {};
|
||||
|
||||
template <class Cond, class T = void>
|
||||
struct disable_if : public disable_if_c<Cond::value, T> {};
|
||||
}
|
||||
|
||||
#endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
+1
-1
@@ -4,9 +4,9 @@
|
||||
#define YAML_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "crt.h"
|
||||
#include "parser.h"
|
||||
#include "node.h"
|
||||
#include "stlnode.h"
|
||||
#include "iterator.h"
|
||||
#include "emitter.h"
|
||||
#include "stlemitter.h"
|
||||
|
||||
+1
-1
@@ -21,4 +21,4 @@ make install
|
||||
|
||||
If you don't want to use CMake, just add all .cpp files to a makefile. yaml-cpp does not need any special build settings, so no 'configure' file is necessary.
|
||||
|
||||
(Note: this is pretty tedious. It's sooo much easier to use CMake.)
|
||||
(Note: this is pretty tedious. It's sooo much easier to use CMake.)
|
||||
+1
-1
@@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
THE SOFTWARE.
|
||||
+17
-6
@@ -1,11 +1,27 @@
|
||||
#include "crt.h"
|
||||
#include "aliascontent.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
AliasContent::AliasContent(Content* pNodeContent): m_pRef(pNodeContent)
|
||||
AliasContent::AliasContent(Content* pNodeContent)
|
||||
: m_pRef(pNodeContent)
|
||||
{
|
||||
}
|
||||
|
||||
Content *AliasContent::Clone() const
|
||||
{
|
||||
return 0; // TODO: how to clone an alias?
|
||||
}
|
||||
|
||||
void AliasContent::Parse(Scanner * /*pScanner*/, const ParserState& /*state*/)
|
||||
{
|
||||
}
|
||||
|
||||
void AliasContent::Write(Emitter&) const
|
||||
{
|
||||
// no content (just an alias)
|
||||
}
|
||||
|
||||
bool AliasContent::GetBegin(std::vector <Node *>::const_iterator& i) const
|
||||
{
|
||||
return m_pRef->GetBegin(i);
|
||||
@@ -56,11 +72,6 @@ namespace YAML
|
||||
return m_pRef->GetScalar(scalar);
|
||||
}
|
||||
|
||||
void AliasContent::EmitEvents(AliasManager& am, EventHandler& eventHandler, const Mark& mark, const std::string& tag, anchor_t anchor) const
|
||||
{
|
||||
m_pRef->EmitEvents(am, eventHandler, mark, tag, anchor);
|
||||
}
|
||||
|
||||
int AliasContent::Compare(Content *pContent)
|
||||
{
|
||||
return m_pRef->Compare(pContent);
|
||||
|
||||
+5
-1
@@ -12,6 +12,11 @@ namespace YAML
|
||||
{
|
||||
public:
|
||||
AliasContent(Content *pNodeContent);
|
||||
|
||||
virtual Content *Clone() const;
|
||||
|
||||
virtual void Parse(Scanner* pScanner, const ParserState& state);
|
||||
virtual void Write(Emitter&) const;
|
||||
|
||||
virtual bool GetBegin(std::vector <Node *>::const_iterator&) const;
|
||||
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator&) const;
|
||||
@@ -24,7 +29,6 @@ namespace YAML
|
||||
virtual bool IsSequence() const;
|
||||
|
||||
virtual bool GetScalar(std::string& s) const;
|
||||
virtual void EmitEvents(AliasManager& am, EventHandler& eventHandler, const Mark& mark, const std::string& tag, anchor_t anchor) const;
|
||||
|
||||
virtual int Compare(Content *);
|
||||
virtual int Compare(Scalar *);
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
#include "aliasmanager.h"
|
||||
#include "node.h"
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
AliasManager::AliasManager(): m_curAnchor(0)
|
||||
{
|
||||
}
|
||||
|
||||
void AliasManager::RegisterReference(const Node& node)
|
||||
{
|
||||
const Node *pIdentity = node.Identity();
|
||||
m_newIdentityByOldIdentity.insert(std::make_pair(pIdentity, &node));
|
||||
m_anchorByIdentity.insert(std::make_pair(&node, _CreateNewAnchor()));
|
||||
}
|
||||
|
||||
const Node *AliasManager::LookupReference(const Node& node) const
|
||||
{
|
||||
const Node *pIdentity = node.Identity();
|
||||
return _LookupReference(*pIdentity);
|
||||
}
|
||||
|
||||
anchor_t AliasManager::LookupAnchor(const Node& node) const
|
||||
{
|
||||
AnchorByIdentity::const_iterator it = m_anchorByIdentity.find(&node);
|
||||
if(it == m_anchorByIdentity.end())
|
||||
assert(false); // TODO: throw
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const Node *AliasManager::_LookupReference(const Node& oldIdentity) const
|
||||
{
|
||||
NodeByNode::const_iterator it = m_newIdentityByOldIdentity.find(&oldIdentity);
|
||||
if(it == m_newIdentityByOldIdentity.end())
|
||||
return 0;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
anchor_t AliasManager::_CreateNewAnchor()
|
||||
{
|
||||
return ++m_curAnchor;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <stack>
|
||||
#include <cassert>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct CollectionType {
|
||||
enum value { None, BlockMap, BlockSeq, FlowMap, FlowSeq, CompactMap };
|
||||
};
|
||||
|
||||
class CollectionStack
|
||||
{
|
||||
public:
|
||||
CollectionType::value GetCurCollectionType() const {
|
||||
if(collectionStack.empty())
|
||||
return CollectionType::None;
|
||||
return collectionStack.top();
|
||||
}
|
||||
|
||||
void PushCollectionType(CollectionType::value type) { collectionStack.push(type); }
|
||||
void PopCollectionType(CollectionType::value type) { assert(type == GetCurCollectionType()); collectionStack.pop(); }
|
||||
|
||||
private:
|
||||
std::stack<CollectionType::value> collectionStack;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
+3
-11
@@ -1,21 +1,13 @@
|
||||
#include "crt.h"
|
||||
#include "content.h"
|
||||
#include "node.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
void Content::SetData(const std::string&)
|
||||
Content::Content()
|
||||
{
|
||||
assert(false); // TODO: throw
|
||||
}
|
||||
|
||||
void Content::Append(std::auto_ptr<Node>)
|
||||
Content::~Content()
|
||||
{
|
||||
assert(false); // TODO: throw
|
||||
}
|
||||
|
||||
void Content::Insert(std::auto_ptr<Node>, std::auto_ptr<Node>)
|
||||
{
|
||||
assert(false); // TODO: throw
|
||||
}
|
||||
}
|
||||
|
||||
+14
-17
@@ -4,30 +4,32 @@
|
||||
#define CONTENT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "anchor.h"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "parserstate.h"
|
||||
#include "exceptions.h"
|
||||
#include "ltnode.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct Mark;
|
||||
struct NodeProperties;
|
||||
class AliasManager;
|
||||
class EventHandler;
|
||||
class Map;
|
||||
class Scanner;
|
||||
class Parser;
|
||||
class Node;
|
||||
class Scalar;
|
||||
class Scanner;
|
||||
class Sequence;
|
||||
class Map;
|
||||
class Emitter;
|
||||
|
||||
class Content
|
||||
{
|
||||
public:
|
||||
Content() {}
|
||||
virtual ~Content() {}
|
||||
Content();
|
||||
virtual ~Content();
|
||||
|
||||
virtual Content *Clone() const = 0;
|
||||
|
||||
virtual void Parse(Scanner *pScanner, const ParserState& state) = 0;
|
||||
virtual void Write(Emitter& out) const = 0;
|
||||
|
||||
virtual bool GetBegin(std::vector <Node *>::const_iterator&) const { return false; }
|
||||
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator&) const { return false; }
|
||||
@@ -38,11 +40,6 @@ namespace YAML
|
||||
virtual bool IsScalar() const { return false; }
|
||||
virtual bool IsMap() const { return false; }
|
||||
virtual bool IsSequence() const { return false; }
|
||||
|
||||
virtual void SetData(const std::string& data);
|
||||
virtual void Append(std::auto_ptr<Node> pNode);
|
||||
virtual void Insert(std::auto_ptr<Node> pKey, std::auto_ptr<Node> pValue);
|
||||
virtual void EmitEvents(AliasManager& am, EventHandler& eventHandler, const Mark& mark, const std::string& tag, anchor_t anchor) const = 0;
|
||||
|
||||
// extraction
|
||||
virtual bool GetScalar(std::string&) const { return false; }
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#include "directives.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
Directives::Directives()
|
||||
{
|
||||
// version
|
||||
version.isDefault = true;
|
||||
version.major = 1;
|
||||
version.minor = 2;
|
||||
}
|
||||
|
||||
const std::string Directives::TranslateTagHandle(const std::string& handle) const
|
||||
{
|
||||
std::map <std::string, std::string>::const_iterator it = tags.find(handle);
|
||||
if(it == tags.end()) {
|
||||
if(handle == "!!")
|
||||
return "tag:yaml.org,2002:";
|
||||
return handle;
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct Version {
|
||||
bool isDefault;
|
||||
int major, minor;
|
||||
};
|
||||
|
||||
struct Directives {
|
||||
Directives();
|
||||
|
||||
const std::string TranslateTagHandle(const std::string& handle) const;
|
||||
|
||||
Version version;
|
||||
std::map<std::string, std::string> tags;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
@@ -1,106 +0,0 @@
|
||||
#include "emitfromevents.h"
|
||||
#include "emitter.h"
|
||||
#include "null.h"
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
std::string ToString(YAML::anchor_t anchor) {
|
||||
std::stringstream stream;
|
||||
stream << anchor;
|
||||
return stream.str();
|
||||
}
|
||||
}
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
EmitFromEvents::EmitFromEvents(Emitter& emitter): m_emitter(emitter)
|
||||
{
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnDocumentStart(const Mark&)
|
||||
{
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnDocumentEnd()
|
||||
{
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnNull(const std::string& tag, anchor_t anchor)
|
||||
{
|
||||
BeginNode();
|
||||
EmitProps(tag, anchor);
|
||||
if(tag.empty())
|
||||
m_emitter << Null;
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor)
|
||||
{
|
||||
BeginNode();
|
||||
m_emitter << Alias(ToString(anchor));
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnScalar(const Mark&, const std::string& tag, anchor_t anchor, const std::string& value)
|
||||
{
|
||||
BeginNode();
|
||||
EmitProps(tag, anchor);
|
||||
m_emitter << value;
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag, anchor_t anchor)
|
||||
{
|
||||
BeginNode();
|
||||
EmitProps(tag, anchor);
|
||||
m_emitter << BeginSeq;
|
||||
m_stateStack.push(State::WaitingForSequenceEntry);
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnSequenceEnd()
|
||||
{
|
||||
m_emitter << EndSeq;
|
||||
assert(m_stateStack.top() == State::WaitingForSequenceEntry);
|
||||
m_stateStack.pop();
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag, anchor_t anchor)
|
||||
{
|
||||
BeginNode();
|
||||
EmitProps(tag, anchor);
|
||||
m_emitter << BeginMap;
|
||||
m_stateStack.push(State::WaitingForKey);
|
||||
}
|
||||
|
||||
void EmitFromEvents::OnMapEnd()
|
||||
{
|
||||
m_emitter << EndMap;
|
||||
assert(m_stateStack.top() == State::WaitingForKey);
|
||||
m_stateStack.pop();
|
||||
}
|
||||
|
||||
void EmitFromEvents::BeginNode()
|
||||
{
|
||||
if(m_stateStack.empty())
|
||||
return;
|
||||
|
||||
switch(m_stateStack.top()) {
|
||||
case State::WaitingForKey:
|
||||
m_emitter << Key;
|
||||
m_stateStack.top() = State::WaitingForValue;
|
||||
break;
|
||||
case State::WaitingForValue:
|
||||
m_emitter << Value;
|
||||
m_stateStack.top() = State::WaitingForKey;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor)
|
||||
{
|
||||
if(!tag.empty())
|
||||
m_emitter << VerbatimTag(tag);
|
||||
if(anchor)
|
||||
m_emitter << Anchor(ToString(anchor));
|
||||
}
|
||||
}
|
||||
+54
-55
@@ -120,9 +120,6 @@ namespace YAML
|
||||
case Value:
|
||||
EmitValue();
|
||||
break;
|
||||
case TagByKind:
|
||||
EmitKindTag();
|
||||
break;
|
||||
default:
|
||||
m_pState->SetLocalValue(value);
|
||||
break;
|
||||
@@ -149,8 +146,6 @@ namespace YAML
|
||||
switch(curState) {
|
||||
// document-level
|
||||
case ES_WAITING_FOR_DOC:
|
||||
m_stream << "---";
|
||||
m_pState->RequireSeparation();
|
||||
m_pState->SwitchState(ES_WRITING_DOC);
|
||||
return true;
|
||||
case ES_WRITING_DOC:
|
||||
@@ -328,10 +323,7 @@ namespace YAML
|
||||
EMITTER_STATE curState = m_pState->GetCurState();
|
||||
EMITTER_MANIP flowType = m_pState->GetFlowType(GT_SEQ);
|
||||
if(flowType == Block) {
|
||||
if(curState == ES_WRITING_BLOCK_SEQ_ENTRY ||
|
||||
curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE ||
|
||||
curState == ES_WRITING_DOC
|
||||
) {
|
||||
if(curState == ES_WRITING_BLOCK_SEQ_ENTRY || curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE) {
|
||||
m_stream << "\n";
|
||||
m_pState->UnsetSeparation();
|
||||
}
|
||||
@@ -362,12 +354,8 @@ namespace YAML
|
||||
// to a flow sequence if it is
|
||||
assert(curState == ES_DONE_WITH_BLOCK_SEQ_ENTRY || curState == ES_WAITING_FOR_BLOCK_SEQ_ENTRY);
|
||||
if(curState == ES_WAITING_FOR_BLOCK_SEQ_ENTRY) {
|
||||
// Note: only one of these will actually output anything for a given situation
|
||||
EmitSeparationIfNecessary();
|
||||
unsigned curIndent = m_pState->GetCurIndent();
|
||||
m_stream << IndentTo(curIndent);
|
||||
|
||||
m_stream << "[]";
|
||||
m_stream << IndentTo(curIndent) << "[]";
|
||||
}
|
||||
} else if(flowType == FT_FLOW) {
|
||||
// Note: flow sequences are allowed to be empty
|
||||
@@ -396,10 +384,7 @@ namespace YAML
|
||||
EMITTER_STATE curState = m_pState->GetCurState();
|
||||
EMITTER_MANIP flowType = m_pState->GetFlowType(GT_MAP);
|
||||
if(flowType == Block) {
|
||||
if(curState == ES_WRITING_BLOCK_SEQ_ENTRY ||
|
||||
curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE ||
|
||||
curState == ES_WRITING_DOC
|
||||
) {
|
||||
if(curState == ES_WRITING_BLOCK_SEQ_ENTRY || curState == ES_WRITING_BLOCK_MAP_KEY || curState == ES_WRITING_BLOCK_MAP_VALUE) {
|
||||
m_stream << "\n";
|
||||
m_pState->UnsetSeparation();
|
||||
}
|
||||
@@ -430,11 +415,8 @@ namespace YAML
|
||||
// to a flow sequence if it is
|
||||
assert(curState == ES_DONE_WITH_BLOCK_MAP_VALUE || curState == ES_WAITING_FOR_BLOCK_MAP_ENTRY);
|
||||
if(curState == ES_WAITING_FOR_BLOCK_MAP_ENTRY) {
|
||||
// Note: only one of these will actually output anything for a given situation
|
||||
EmitSeparationIfNecessary();
|
||||
unsigned curIndent = m_pState->GetCurIndent();
|
||||
m_stream << IndentTo(curIndent);
|
||||
m_stream << "{}";
|
||||
m_stream << IndentTo(curIndent) << "{}";
|
||||
}
|
||||
} else if(flowType == FT_FLOW) {
|
||||
// Note: flow maps are allowed to be empty
|
||||
@@ -552,12 +534,24 @@ namespace YAML
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Emitter::PreWriteIntegralType(std::stringstream& str)
|
||||
Emitter& Emitter::Write(const char *str)
|
||||
{
|
||||
if(!good())
|
||||
return *this;
|
||||
|
||||
return Write(std::string(str));
|
||||
}
|
||||
|
||||
Emitter& Emitter::Write(int i)
|
||||
{
|
||||
if(!good())
|
||||
return *this;
|
||||
|
||||
PreAtomicWrite();
|
||||
EmitSeparationIfNecessary();
|
||||
|
||||
EMITTER_MANIP intFmt = m_pState->GetIntFormat();
|
||||
std::stringstream str;
|
||||
switch(intFmt) {
|
||||
case Dec:
|
||||
str << std::dec;
|
||||
@@ -565,18 +559,18 @@ namespace YAML
|
||||
case Hex:
|
||||
str << std::hex;
|
||||
break;
|
||||
case Oct:
|
||||
case Oct:
|
||||
str << std::oct;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Emitter::PostWriteIntegralType(const std::stringstream& str)
|
||||
{
|
||||
|
||||
str << i;
|
||||
m_stream << str.str();
|
||||
|
||||
PostAtomicWrite();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Emitter& Emitter::Write(bool b)
|
||||
@@ -618,6 +612,38 @@ namespace YAML
|
||||
return *this;
|
||||
}
|
||||
|
||||
Emitter& Emitter::Write(float f)
|
||||
{
|
||||
if(!good())
|
||||
return *this;
|
||||
|
||||
PreAtomicWrite();
|
||||
EmitSeparationIfNecessary();
|
||||
|
||||
std::stringstream str;
|
||||
str << f;
|
||||
m_stream << str.str();
|
||||
|
||||
PostAtomicWrite();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Emitter& Emitter::Write(double d)
|
||||
{
|
||||
if(!good())
|
||||
return *this;
|
||||
|
||||
PreAtomicWrite();
|
||||
EmitSeparationIfNecessary();
|
||||
|
||||
std::stringstream str;
|
||||
str << d;
|
||||
m_stream << str.str();
|
||||
|
||||
PostAtomicWrite();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Emitter& Emitter::Write(const _Alias& alias)
|
||||
{
|
||||
if(!good())
|
||||
@@ -649,33 +675,6 @@ namespace YAML
|
||||
return *this;
|
||||
}
|
||||
|
||||
Emitter& Emitter::Write(const _Tag& tag)
|
||||
{
|
||||
if(!good())
|
||||
return *this;
|
||||
|
||||
EmitTag(tag.verbatim, tag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Emitter::EmitTag(bool verbatim, const _Tag& tag)
|
||||
{
|
||||
PreAtomicWrite();
|
||||
EmitSeparationIfNecessary();
|
||||
if(!Utils::WriteTag(m_stream, tag.content, verbatim)) {
|
||||
m_pState->SetError(ErrorMsg::INVALID_TAG);
|
||||
return;
|
||||
}
|
||||
m_pState->RequireSeparation();
|
||||
// Note: no PostAtomicWrite() because we need another value for this node
|
||||
}
|
||||
|
||||
void Emitter::EmitKindTag()
|
||||
{
|
||||
_Tag tag("");
|
||||
EmitTag(false, tag);
|
||||
}
|
||||
|
||||
Emitter& Emitter::Write(const _Comment& comment)
|
||||
{
|
||||
if(!good())
|
||||
|
||||
+7
-27
@@ -129,7 +129,7 @@ namespace YAML
|
||||
|
||||
bool IsValidPlainScalar(const std::string& str, bool inFlow, bool allowOnlyAscii) {
|
||||
// first check the start
|
||||
const RegEx& start = (inFlow ? Exp::PlainScalarInFlow() : Exp::PlainScalar());
|
||||
const RegEx& start = (inFlow ? Exp::PlainScalarInFlow : Exp::PlainScalar);
|
||||
if(!start.Matches(str))
|
||||
return false;
|
||||
|
||||
@@ -138,12 +138,12 @@ namespace YAML
|
||||
return false;
|
||||
|
||||
// then check until something is disallowed
|
||||
const RegEx& disallowed = (inFlow ? Exp::EndScalarInFlow() : Exp::EndScalar())
|
||||
|| (Exp::BlankOrBreak() + Exp::Comment())
|
||||
|| Exp::NotPrintable()
|
||||
|| Exp::Utf8_ByteOrderMark()
|
||||
|| Exp::Break()
|
||||
|| Exp::Tab();
|
||||
const RegEx& disallowed = (inFlow ? Exp::EndScalarInFlow : Exp::EndScalar)
|
||||
|| (Exp::BlankOrBreak + Exp::Comment)
|
||||
|| Exp::NotPrintable
|
||||
|| Exp::Utf8_ByteOrderMark
|
||||
|| Exp::Break
|
||||
|| Exp::Tab;
|
||||
StringCharSource buffer(str.c_str(), str.size());
|
||||
while(buffer) {
|
||||
if(disallowed.Matches(buffer))
|
||||
@@ -293,26 +293,6 @@ namespace YAML
|
||||
out << "&";
|
||||
return WriteAliasName(out, str);
|
||||
}
|
||||
|
||||
bool WriteTag(ostream& out, const std::string& str, bool verbatim)
|
||||
{
|
||||
out << (verbatim ? "!<" : "!");
|
||||
StringCharSource buffer(str.c_str(), str.size());
|
||||
const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag();
|
||||
while(buffer) {
|
||||
int n = reValid.Match(buffer);
|
||||
if(n <= 0)
|
||||
return false;
|
||||
|
||||
while(--n >= 0) {
|
||||
out << buffer[0];
|
||||
++buffer;
|
||||
}
|
||||
}
|
||||
if (verbatim)
|
||||
out << ">";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ namespace YAML
|
||||
bool WriteComment(ostream& out, const std::string& str, int postCommentIndent);
|
||||
bool WriteAlias(ostream& out, const std::string& str);
|
||||
bool WriteAnchor(ostream& out, const std::string& str);
|
||||
bool WriteTag(ostream& out, const std::string& str, bool verbatim);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "crt.h"
|
||||
#include "exp.h"
|
||||
#include "exceptions.h"
|
||||
#include <sstream>
|
||||
|
||||
@@ -17,153 +17,50 @@ namespace YAML
|
||||
namespace Exp
|
||||
{
|
||||
// misc
|
||||
inline const RegEx& Space() {
|
||||
static const RegEx e = RegEx(' ');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Tab() {
|
||||
static const RegEx e = RegEx('\t');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Blank() {
|
||||
static const RegEx e = Space() || Tab();
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Break() {
|
||||
static const RegEx e = RegEx('\n') || RegEx("\r\n");
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& BlankOrBreak() {
|
||||
static const RegEx e = Blank() || Break();
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Digit() {
|
||||
static const RegEx e = RegEx('0', '9');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Alpha() {
|
||||
static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& AlphaNumeric() {
|
||||
static const RegEx e = Alpha() || Digit();
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Word() {
|
||||
static const RegEx e = AlphaNumeric() || RegEx('-');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Hex() {
|
||||
static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f');
|
||||
return e;
|
||||
}
|
||||
const RegEx Space = RegEx(' ');
|
||||
const RegEx Tab = RegEx('\t');
|
||||
const RegEx Blank = Space || Tab;
|
||||
const RegEx Break = RegEx('\n') || RegEx("\r\n");
|
||||
const RegEx BlankOrBreak = Blank || Break;
|
||||
const RegEx Digit = RegEx('0', '9');
|
||||
const RegEx Alpha = RegEx('a', 'z') || RegEx('A', 'Z');
|
||||
const RegEx AlphaNumeric = Alpha || Digit;
|
||||
const RegEx Hex = Digit || RegEx('A', 'F') || RegEx('a', 'f');
|
||||
// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec. 5.1)
|
||||
inline const RegEx& NotPrintable() {
|
||||
static const RegEx e = RegEx(0) ||
|
||||
RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) ||
|
||||
RegEx(0x0E, 0x1F) ||
|
||||
(RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F')));
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Utf8_ByteOrderMark() {
|
||||
static const RegEx e = RegEx("\xEF\xBB\xBF");
|
||||
return e;
|
||||
}
|
||||
const RegEx NotPrintable = RegEx(0) ||
|
||||
RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) ||
|
||||
RegEx(0x0E, 0x1F) ||
|
||||
(RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F')));
|
||||
const RegEx Utf8_ByteOrderMark = RegEx("\xEF\xBB\xBF");
|
||||
|
||||
// actual tags
|
||||
|
||||
inline const RegEx& DocStart() {
|
||||
static const RegEx e = RegEx("---") + (BlankOrBreak() || RegEx());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& DocEnd() {
|
||||
static const RegEx e = RegEx("...") + (BlankOrBreak() || RegEx());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& DocIndicator() {
|
||||
static const RegEx e = DocStart() || DocEnd();
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& BlockEntry() {
|
||||
static const RegEx e = RegEx('-') + (BlankOrBreak() || RegEx());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Key() {
|
||||
static const RegEx e = RegEx('?');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& KeyInFlow() {
|
||||
static const RegEx e = RegEx('?') + BlankOrBreak();
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Value() {
|
||||
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& ValueInFlow() {
|
||||
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx(",}", REGEX_OR));
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& ValueInJSONFlow() {
|
||||
static const RegEx e = RegEx(':');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx Comment() {
|
||||
static const RegEx e = RegEx('#');
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& AnchorEnd() {
|
||||
static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak();
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& URI() {
|
||||
static const RegEx e = Word() || RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) || (RegEx('%') + Hex() + Hex());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Tag() {
|
||||
static const RegEx e = Word() || RegEx("#;/?:@&=+$_.~*'", REGEX_OR) || (RegEx('%') + Hex() + Hex());
|
||||
return e;
|
||||
}
|
||||
const RegEx DocStart = RegEx("---") + (BlankOrBreak || RegEx());
|
||||
const RegEx DocEnd = RegEx("...") + (BlankOrBreak || RegEx());
|
||||
const RegEx DocIndicator = DocStart || DocEnd;
|
||||
const RegEx BlockEntry = RegEx('-') + (BlankOrBreak || RegEx());
|
||||
const RegEx Key = RegEx('?'),
|
||||
KeyInFlow = RegEx('?') + BlankOrBreak;
|
||||
const RegEx Value = RegEx(':') + (BlankOrBreak || RegEx()),
|
||||
ValueInFlow = RegEx(':') + (BlankOrBreak || RegEx(",}", REGEX_OR));
|
||||
const RegEx Comment = RegEx('#');
|
||||
const RegEx AnchorEnd = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak;
|
||||
|
||||
// Plain scalar rules:
|
||||
// . Cannot start with a blank.
|
||||
// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
|
||||
// . In the block context - ? : must be not be followed with a space.
|
||||
// . In the flow context ? is illegal and : and - must not be followed with a space.
|
||||
inline const RegEx& PlainScalar() {
|
||||
static const RegEx e = !(BlankOrBreak() || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-?:", REGEX_OR) + Blank()));
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& PlainScalarInFlow() {
|
||||
static const RegEx e = !(BlankOrBreak() || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-:", REGEX_OR) + Blank()));
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& EndScalar() {
|
||||
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& EndScalarInFlow() {
|
||||
static const RegEx e = (RegEx(':') + (BlankOrBreak() || RegEx(",]}", REGEX_OR))) || RegEx(",?[]{}", REGEX_OR);
|
||||
return e;
|
||||
}
|
||||
const RegEx PlainScalar = !(BlankOrBreak || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-?:", REGEX_OR) + Blank)),
|
||||
PlainScalarInFlow = !(BlankOrBreak || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-:", REGEX_OR) + Blank));
|
||||
const RegEx EndScalar = RegEx(':') + (BlankOrBreak || RegEx()),
|
||||
EndScalarInFlow = (RegEx(':') + (BlankOrBreak || RegEx(",]}", REGEX_OR))) || RegEx(",?[]{}", REGEX_OR);
|
||||
|
||||
inline const RegEx& EscSingleQuote() {
|
||||
static const RegEx e = RegEx("\'\'");
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& EscBreak() {
|
||||
static const RegEx e = RegEx('\\') + Break();
|
||||
return e;
|
||||
}
|
||||
const RegEx EscSingleQuote = RegEx("\'\'");
|
||||
const RegEx EscBreak = RegEx('\\') + Break;
|
||||
|
||||
inline const RegEx& ChompIndicator() {
|
||||
static const RegEx e = RegEx("+-", REGEX_OR);
|
||||
return e;
|
||||
}
|
||||
inline const RegEx& Chomp() {
|
||||
static const RegEx e = (ChompIndicator() + Digit()) || (Digit() + ChompIndicator()) || ChompIndicator() || Digit();
|
||||
return e;
|
||||
}
|
||||
const RegEx ChompIndicator = RegEx("+-", REGEX_OR);
|
||||
const RegEx Chomp = (ChompIndicator + Digit) || (Digit + ChompIndicator) || ChompIndicator || Digit;
|
||||
|
||||
// and some functions
|
||||
std::string Escape(Stream& in);
|
||||
@@ -182,8 +79,6 @@ namespace YAML
|
||||
const char Tag = '!';
|
||||
const char LiteralScalar = '|';
|
||||
const char FoldedScalar = '>';
|
||||
const char VerbatimTagStart = '<';
|
||||
const char VerbatimTagEnd = '>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
#include "graphbuilderadapter.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
int GraphBuilderAdapter::ContainerFrame::sequenceMarker;
|
||||
|
||||
void GraphBuilderAdapter::OnNull(const std::string& tag, anchor_t anchor)
|
||||
{
|
||||
void *pParent = GetCurrentParent();
|
||||
void *pNode = m_builder.NewNull(tag, pParent);
|
||||
RegisterAnchor(anchor, pNode);
|
||||
|
||||
DispositionNode(pNode);
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::OnAlias(const Mark& mark, anchor_t anchor)
|
||||
{
|
||||
void *pReffedNode = m_anchors.Get(anchor);
|
||||
DispositionNode(m_builder.AnchorReference(mark, pReffedNode));
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value)
|
||||
{
|
||||
void *pParent = GetCurrentParent();
|
||||
void *pNode = m_builder.NewScalar(mark, tag, pParent, value);
|
||||
RegisterAnchor(anchor, pNode);
|
||||
|
||||
DispositionNode(pNode);
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor)
|
||||
{
|
||||
void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent());
|
||||
m_containers.push(ContainerFrame(pNode));
|
||||
RegisterAnchor(anchor, pNode);
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::OnSequenceEnd()
|
||||
{
|
||||
void *pSequence = m_containers.top().pContainer;
|
||||
m_containers.pop();
|
||||
|
||||
DispositionNode(pSequence);
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor)
|
||||
{
|
||||
void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent());
|
||||
m_containers.push(ContainerFrame(pNode, m_pKeyNode));
|
||||
m_pKeyNode = NULL;
|
||||
RegisterAnchor(anchor, pNode);
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::OnMapEnd()
|
||||
{
|
||||
void *pMap = m_containers.top().pContainer;
|
||||
m_pKeyNode = m_containers.top().pPrevKeyNode;
|
||||
m_containers.pop();
|
||||
DispositionNode(pMap);
|
||||
}
|
||||
|
||||
void *GraphBuilderAdapter::GetCurrentParent() const
|
||||
{
|
||||
if (m_containers.empty()) {
|
||||
return NULL;
|
||||
}
|
||||
return m_containers.top().pContainer;
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::RegisterAnchor(anchor_t anchor, void *pNode)
|
||||
{
|
||||
if (anchor) {
|
||||
m_anchors.Register(anchor, pNode);
|
||||
}
|
||||
}
|
||||
|
||||
void GraphBuilderAdapter::DispositionNode(void *pNode)
|
||||
{
|
||||
if (m_containers.empty()) {
|
||||
m_pRootNode = pNode;
|
||||
return;
|
||||
}
|
||||
|
||||
void *pContainer = m_containers.top().pContainer;
|
||||
if (m_containers.top().isMap()) {
|
||||
if (m_pKeyNode) {
|
||||
m_builder.AssignInMap(pContainer, m_pKeyNode, pNode);
|
||||
m_pKeyNode = NULL;
|
||||
} else {
|
||||
m_pKeyNode = pNode;
|
||||
}
|
||||
} else {
|
||||
m_builder.AppendToSequence(pContainer, pNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
#ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#include <map>
|
||||
#include <stack>
|
||||
#include "anchordict.h"
|
||||
#include "eventhandler.h"
|
||||
#include "graphbuilder.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class GraphBuilderAdapter : public EventHandler
|
||||
{
|
||||
public:
|
||||
GraphBuilderAdapter(GraphBuilderInterface& builder)
|
||||
: m_builder(builder), m_pRootNode(NULL), m_pKeyNode(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void OnDocumentStart(const Mark& mark) {(void)mark;}
|
||||
virtual void OnDocumentEnd() {}
|
||||
|
||||
virtual void OnNull(const std::string& tag, 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();
|
||||
|
||||
void *RootNode() const {return m_pRootNode;}
|
||||
|
||||
private:
|
||||
struct ContainerFrame
|
||||
{
|
||||
ContainerFrame(void *pSequence)
|
||||
: pContainer(pSequence), pPrevKeyNode(&sequenceMarker)
|
||||
{}
|
||||
ContainerFrame(void *pMap, void* pPrevKeyNode)
|
||||
: pContainer(pMap), pPrevKeyNode(pPrevKeyNode)
|
||||
{}
|
||||
|
||||
void *pContainer;
|
||||
void *pPrevKeyNode;
|
||||
|
||||
bool isMap() const {return pPrevKeyNode != &sequenceMarker;}
|
||||
|
||||
private:
|
||||
static int sequenceMarker;
|
||||
};
|
||||
typedef std::stack<ContainerFrame> ContainerStack;
|
||||
typedef AnchorDict<void*> AnchorMap;
|
||||
|
||||
GraphBuilderInterface& m_builder;
|
||||
ContainerStack m_containers;
|
||||
AnchorMap m_anchors;
|
||||
void *m_pRootNode;
|
||||
void *m_pKeyNode;
|
||||
|
||||
void *GetCurrentParent() const;
|
||||
void RegisterAnchor(anchor_t anchor, void *pNode);
|
||||
void DispositionNode(void *pNode);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "crt.h"
|
||||
#include "node.h"
|
||||
#include "exceptions.h"
|
||||
#include "iterpriv.h"
|
||||
|
||||
+111
-13
@@ -1,13 +1,26 @@
|
||||
#include "crt.h"
|
||||
#include "map.h"
|
||||
#include "node.h"
|
||||
#include "eventhandler.h"
|
||||
#include "scanner.h"
|
||||
#include "token.h"
|
||||
#include "exceptions.h"
|
||||
#include "emitter.h"
|
||||
#include <memory>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
Map::Map()
|
||||
{
|
||||
}
|
||||
|
||||
Map::Map(const node_map& data)
|
||||
{
|
||||
for(node_map::const_iterator it=data.begin();it!=data.end();++it) {
|
||||
std::auto_ptr<Node> pKey = it->first->Clone();
|
||||
std::auto_ptr<Node> pValue = it->second->Clone();
|
||||
m_data[pKey.release()] = pValue.release();
|
||||
}
|
||||
}
|
||||
|
||||
Map::~Map()
|
||||
{
|
||||
@@ -23,6 +36,11 @@ namespace YAML
|
||||
m_data.clear();
|
||||
}
|
||||
|
||||
Content *Map::Clone() const
|
||||
{
|
||||
return new Map(m_data);
|
||||
}
|
||||
|
||||
bool Map::GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const
|
||||
{
|
||||
it = m_data.begin();
|
||||
@@ -40,23 +58,103 @@ namespace YAML
|
||||
return m_data.size();
|
||||
}
|
||||
|
||||
void Map::Insert(std::auto_ptr<Node> pKey, std::auto_ptr<Node> pValue)
|
||||
void Map::Parse(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
node_map::const_iterator it = m_data.find(pKey.get());
|
||||
if(it != m_data.end())
|
||||
return;
|
||||
|
||||
m_data[pKey.release()] = pValue.release();
|
||||
Clear();
|
||||
|
||||
// split based on start token
|
||||
switch(pScanner->peek().type) {
|
||||
case Token::BLOCK_MAP_START: ParseBlock(pScanner, state); break;
|
||||
case Token::FLOW_MAP_START: ParseFlow(pScanner, state); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void Map::EmitEvents(AliasManager& am, EventHandler& eventHandler, const Mark& mark, const std::string& tag, anchor_t anchor) const
|
||||
void Map::ParseBlock(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
eventHandler.OnMapStart(mark, tag, anchor);
|
||||
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it) {
|
||||
it->first->EmitEvents(am, eventHandler);
|
||||
it->second->EmitEvents(am, eventHandler);
|
||||
// eat start token
|
||||
pScanner->pop();
|
||||
|
||||
while(1) {
|
||||
if(pScanner->empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP);
|
||||
|
||||
Token token = pScanner->peek();
|
||||
if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END)
|
||||
throw ParserException(token.mark, ErrorMsg::END_OF_MAP);
|
||||
|
||||
if(token.type == Token::BLOCK_MAP_END) {
|
||||
pScanner->pop();
|
||||
break;
|
||||
}
|
||||
|
||||
std::auto_ptr <Node> pKey(new Node), pValue(new Node);
|
||||
|
||||
// grab key (if non-null)
|
||||
if(token.type == Token::KEY) {
|
||||
pScanner->pop();
|
||||
pKey->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
// now grab value (optional)
|
||||
if(!pScanner->empty() && pScanner->peek().type == Token::VALUE) {
|
||||
pScanner->pop();
|
||||
pValue->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
// assign the map with the actual pointers
|
||||
m_data[pKey.release()] = pValue.release();
|
||||
}
|
||||
eventHandler.OnMapEnd();
|
||||
}
|
||||
|
||||
void Map::ParseFlow(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
// eat start token
|
||||
pScanner->pop();
|
||||
|
||||
while(1) {
|
||||
if(pScanner->empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW);
|
||||
|
||||
Token& token = pScanner->peek();
|
||||
// first check for end
|
||||
if(token.type == Token::FLOW_MAP_END) {
|
||||
pScanner->pop();
|
||||
break;
|
||||
}
|
||||
|
||||
std::auto_ptr <Node> pKey(new Node), pValue(new Node);
|
||||
|
||||
// grab key (if non-null)
|
||||
if(token.type == Token::KEY) {
|
||||
pScanner->pop();
|
||||
pKey->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
// now grab value (optional)
|
||||
if(!pScanner->empty() && pScanner->peek().type == Token::VALUE) {
|
||||
pScanner->pop();
|
||||
pValue->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
|
||||
Token& nextToken = pScanner->peek();
|
||||
if(nextToken.type == Token::FLOW_ENTRY)
|
||||
pScanner->pop();
|
||||
else if(nextToken.type != Token::FLOW_MAP_END)
|
||||
throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
|
||||
|
||||
// assign the map with the actual pointers
|
||||
m_data[pKey.release()] = pValue.release();
|
||||
}
|
||||
}
|
||||
|
||||
void Map::Write(Emitter& out) const
|
||||
{
|
||||
out << BeginMap;
|
||||
for(node_map::const_iterator it=m_data.begin();it!=m_data.end();++it)
|
||||
out << Key << *it->first << Value << *it->second;
|
||||
out << EndMap;
|
||||
}
|
||||
|
||||
int Map::Compare(Content *pContent)
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "content.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
@@ -19,16 +18,17 @@ namespace YAML
|
||||
|
||||
public:
|
||||
Map();
|
||||
Map(const node_map& data);
|
||||
virtual ~Map();
|
||||
|
||||
void Clear();
|
||||
virtual Content *Clone() const;
|
||||
|
||||
virtual bool GetBegin(std::map <Node *, Node *, ltnode>::const_iterator& it) const;
|
||||
virtual bool GetEnd(std::map <Node *, Node *, ltnode>::const_iterator& it) const;
|
||||
virtual std::size_t GetSize() const;
|
||||
|
||||
virtual void Insert(std::auto_ptr<Node> pKey, std::auto_ptr<Node> pValue);
|
||||
virtual void EmitEvents(AliasManager& am, EventHandler& eventHandler, const Mark& mark, const std::string& tag, anchor_t anchor) const;
|
||||
virtual void Parse(Scanner *pScanner, const ParserState& state);
|
||||
virtual void Write(Emitter& out) const;
|
||||
|
||||
virtual bool IsMap() const { return true; }
|
||||
|
||||
@@ -38,6 +38,10 @@ namespace YAML
|
||||
virtual int Compare(Sequence *) { return 1; }
|
||||
virtual int Compare(Map *pMap);
|
||||
|
||||
private:
|
||||
void ParseBlock(Scanner *pScanner, const ParserState& state);
|
||||
void ParseFlow(Scanner *pScanner, const ParserState& state);
|
||||
|
||||
private:
|
||||
node_map m_data;
|
||||
};
|
||||
|
||||
+132
-96
@@ -1,21 +1,15 @@
|
||||
#include "crt.h"
|
||||
#include "node.h"
|
||||
#include "aliascontent.h"
|
||||
#include "aliasmanager.h"
|
||||
#include "content.h"
|
||||
#include "emitfromevents.h"
|
||||
#include "emitter.h"
|
||||
#include "eventhandler.h"
|
||||
#include "graphbuilderadapter.h"
|
||||
#include "iterpriv.h"
|
||||
#include "map.h"
|
||||
#include "nodebuilder.h"
|
||||
#include "nodeproperties.h"
|
||||
#include "scalar.h"
|
||||
#include "scanner.h"
|
||||
#include "sequence.h"
|
||||
#include "tag.h"
|
||||
#include "token.h"
|
||||
#include <cassert>
|
||||
#include "scanner.h"
|
||||
#include "content.h"
|
||||
#include "parser.h"
|
||||
#include "scalar.h"
|
||||
#include "sequence.h"
|
||||
#include "map.h"
|
||||
#include "aliascontent.h"
|
||||
#include "iterpriv.h"
|
||||
#include "emitter.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace YAML
|
||||
@@ -26,10 +20,17 @@ namespace YAML
|
||||
return *pNode1 < *pNode2;
|
||||
}
|
||||
|
||||
Node::Node(): m_pContent(0), m_alias(false), m_pIdentity(this), m_referenced(false)
|
||||
Node::Node(): m_pContent(0), m_alias(false), m_pIdentity(this), m_referenced(true)
|
||||
{
|
||||
}
|
||||
|
||||
Node::Node(const Mark& mark, const std::string& anchor, const std::string& tag, const Content *pContent)
|
||||
: m_mark(mark), m_anchor(anchor), m_tag(tag), m_pContent(0), m_alias(false), m_pIdentity(this), m_referenced(false)
|
||||
{
|
||||
if(m_pContent)
|
||||
m_pContent = pContent->Clone();
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
Clear();
|
||||
@@ -41,107 +42,131 @@ namespace YAML
|
||||
m_pContent = 0;
|
||||
m_alias = false;
|
||||
m_referenced = false;
|
||||
m_anchor.clear();
|
||||
m_tag.clear();
|
||||
}
|
||||
|
||||
std::auto_ptr<Node> Node::Clone() const
|
||||
{
|
||||
std::auto_ptr<Node> pNode(new Node);
|
||||
NodeBuilder nodeBuilder(*pNode);
|
||||
GraphBuilder<NodeBuilder> graphBuilder(nodeBuilder);
|
||||
GraphBuilderAdapter eventHandler(graphBuilder);
|
||||
EmitEvents(eventHandler);
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void Node::EmitEvents(EventHandler& eventHandler) const
|
||||
{
|
||||
eventHandler.OnDocumentStart(m_mark);
|
||||
AliasManager am;
|
||||
EmitEvents(am, eventHandler);
|
||||
eventHandler.OnDocumentEnd();
|
||||
}
|
||||
|
||||
void Node::EmitEvents(AliasManager& am, EventHandler& eventHandler) const
|
||||
{
|
||||
anchor_t anchor = NullAnchor;
|
||||
if(m_referenced || m_alias) {
|
||||
if(const Node *pOther = am.LookupReference(*this)) {
|
||||
eventHandler.OnAlias(m_mark, am.LookupAnchor(*pOther));
|
||||
return;
|
||||
}
|
||||
|
||||
am.RegisterReference(*this);
|
||||
anchor = am.LookupAnchor(*this);
|
||||
}
|
||||
if(m_alias)
|
||||
throw std::runtime_error("yaml-cpp: Can't clone alias"); // TODO: what to do about aliases?
|
||||
|
||||
if(m_pContent)
|
||||
m_pContent->EmitEvents(am, eventHandler, m_mark, GetTag(), anchor);
|
||||
else
|
||||
eventHandler.OnNull(GetTag(), anchor);
|
||||
return std::auto_ptr<Node> (new Node(m_mark, m_anchor, m_tag, m_pContent));
|
||||
}
|
||||
|
||||
void Node::Init(CONTENT_TYPE type, const Mark& mark, const std::string& tag)
|
||||
void Node::Parse(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
Clear();
|
||||
m_mark = mark;
|
||||
m_tag = tag;
|
||||
m_alias = false;
|
||||
m_pIdentity = this;
|
||||
m_referenced = false;
|
||||
|
||||
switch(type) {
|
||||
case CT_SCALAR:
|
||||
// an empty node *is* a possibility
|
||||
if(pScanner->empty())
|
||||
return;
|
||||
|
||||
// save location
|
||||
m_mark = pScanner->peek().mark;
|
||||
|
||||
ParseHeader(pScanner, state);
|
||||
|
||||
// is this an alias? if so, its contents are an alias to
|
||||
// a previously defined anchor
|
||||
if(m_alias) {
|
||||
// the scanner throws an exception if it doesn't know this anchor name
|
||||
const Node *pReferencedNode = pScanner->Retrieve(m_anchor);
|
||||
m_pIdentity = pReferencedNode;
|
||||
|
||||
// mark the referenced node for the sake of the client code
|
||||
pReferencedNode->m_referenced = true;
|
||||
|
||||
// use of an Alias object keeps the referenced content from
|
||||
// being deleted twice
|
||||
Content *pAliasedContent = pReferencedNode->m_pContent;
|
||||
if(pAliasedContent)
|
||||
m_pContent = new AliasContent(pAliasedContent);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// now split based on what kind of node we should be
|
||||
switch(pScanner->peek().type) {
|
||||
case Token::SCALAR:
|
||||
m_pContent = new Scalar;
|
||||
break;
|
||||
case CT_SEQUENCE:
|
||||
case Token::FLOW_SEQ_START:
|
||||
case Token::BLOCK_SEQ_START:
|
||||
m_pContent = new Sequence;
|
||||
break;
|
||||
case CT_MAP:
|
||||
case Token::FLOW_MAP_START:
|
||||
case Token::BLOCK_MAP_START:
|
||||
m_pContent = new Map;
|
||||
break;
|
||||
default:
|
||||
m_pContent = 0;
|
||||
// std::stringstream str;
|
||||
// str << TokenNames[pScanner->peek().type];
|
||||
// throw std::runtime_error(str.str());
|
||||
break;
|
||||
}
|
||||
|
||||
// Have to save anchor before parsing to allow for aliases as
|
||||
// contained node (recursive structure)
|
||||
if(!m_anchor.empty())
|
||||
pScanner->Save(m_anchor, this);
|
||||
|
||||
if(m_pContent)
|
||||
m_pContent->Parse(pScanner, state);
|
||||
}
|
||||
|
||||
// ParseHeader
|
||||
// . Grabs any tag, alias, or anchor tokens and deals with them.
|
||||
void Node::ParseHeader(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
while(1) {
|
||||
if(pScanner->empty())
|
||||
return;
|
||||
|
||||
switch(pScanner->peek().type) {
|
||||
case Token::TAG: ParseTag(pScanner, state); break;
|
||||
case Token::ANCHOR: ParseAnchor(pScanner, state); break;
|
||||
case Token::ALIAS: ParseAlias(pScanner, state); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::InitNull(const std::string& tag)
|
||||
void Node::ParseTag(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
Clear();
|
||||
m_tag = tag;
|
||||
m_alias = false;
|
||||
m_pIdentity = this;
|
||||
m_referenced = false;
|
||||
}
|
||||
Token& token = pScanner->peek();
|
||||
if(m_tag != "")
|
||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS);
|
||||
|
||||
void Node::InitAlias(const Mark& mark, const Node& identity)
|
||||
{
|
||||
Clear();
|
||||
m_mark = mark;
|
||||
m_alias = true;
|
||||
m_pIdentity = &identity;
|
||||
if(identity.m_pContent)
|
||||
m_pContent = new AliasContent(identity.m_pContent);
|
||||
identity.m_referenced = true;
|
||||
}
|
||||
m_tag = state.TranslateTag(token.value);
|
||||
|
||||
void Node::SetData(const std::string& data)
|
||||
{
|
||||
assert(m_pContent); // TODO: throw
|
||||
m_pContent->SetData(data);
|
||||
}
|
||||
|
||||
void Node::Append(std::auto_ptr<Node> pNode)
|
||||
{
|
||||
assert(m_pContent); // TODO: throw
|
||||
m_pContent->Append(pNode);
|
||||
for(std::size_t i=0;i<token.params.size();i++)
|
||||
m_tag += token.params[i];
|
||||
pScanner->pop();
|
||||
}
|
||||
|
||||
void Node::Insert(std::auto_ptr<Node> pKey, std::auto_ptr<Node> pValue)
|
||||
void Node::ParseAnchor(Scanner *pScanner, const ParserState& /*state*/)
|
||||
{
|
||||
assert(m_pContent); // TODO: throw
|
||||
m_pContent->Insert(pKey, pValue);
|
||||
Token& token = pScanner->peek();
|
||||
if(m_anchor != "")
|
||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
|
||||
|
||||
m_anchor = token.value;
|
||||
m_alias = false;
|
||||
pScanner->pop();
|
||||
}
|
||||
|
||||
void Node::ParseAlias(Scanner *pScanner, const ParserState& /*state*/)
|
||||
{
|
||||
Token& token = pScanner->peek();
|
||||
if(m_anchor != "")
|
||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ALIASES);
|
||||
if(m_tag != "")
|
||||
throw ParserException(token.mark, ErrorMsg::ALIAS_CONTENT);
|
||||
|
||||
m_anchor = token.value;
|
||||
m_alias = true;
|
||||
pScanner->pop();
|
||||
}
|
||||
|
||||
CONTENT_TYPE Node::GetType() const
|
||||
@@ -217,10 +242,7 @@ namespace YAML
|
||||
bool Node::GetScalar(std::string& s) const
|
||||
{
|
||||
if(!m_pContent) {
|
||||
if(m_tag.empty())
|
||||
s = "~";
|
||||
else
|
||||
s = "";
|
||||
s = "~";
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -229,8 +251,22 @@ namespace YAML
|
||||
|
||||
Emitter& operator << (Emitter& out, const Node& node)
|
||||
{
|
||||
EmitFromEvents emitFromEvents(out);
|
||||
node.EmitEvents(emitFromEvents);
|
||||
// write anchor/alias
|
||||
if(node.m_anchor != "") {
|
||||
if(node.m_alias)
|
||||
out << Alias(node.m_anchor);
|
||||
else
|
||||
out << Anchor(node.m_anchor);
|
||||
}
|
||||
|
||||
// TODO: write tag
|
||||
|
||||
// write content
|
||||
if(node.m_pContent)
|
||||
node.m_pContent->Write(out);
|
||||
else if(!node.m_alias)
|
||||
out << Null;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
#include "nodebuilder.h"
|
||||
#include "mark.h"
|
||||
#include "node.h"
|
||||
#include "nodeproperties.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
NodeBuilder::NodeBuilder(Node& root): m_root(root), m_initializedRoot(false)
|
||||
{
|
||||
m_root.Clear();
|
||||
}
|
||||
|
||||
NodeBuilder::NodeBuilder(const NodeBuilder& o): m_root(o.m_root), m_initializedRoot(o.m_initializedRoot)
|
||||
{
|
||||
}
|
||||
|
||||
NodeBuilder::~NodeBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
Node *NodeBuilder::NewNull(const std::string& tag, Node *pParent)
|
||||
{
|
||||
(void)pParent;
|
||||
Node *pNode = NewNode();
|
||||
pNode->InitNull(tag);
|
||||
return pNode;
|
||||
}
|
||||
|
||||
Node *NodeBuilder::AnchorReference(const Mark& mark, Node *pNode)
|
||||
{
|
||||
Node *pAlias = NewNode();
|
||||
pAlias->InitAlias(mark, *pNode);
|
||||
return pAlias;
|
||||
}
|
||||
|
||||
Node *NodeBuilder::NewScalar(const Mark& mark, const std::string& tag, Node *pParent, const std::string& value)
|
||||
{
|
||||
(void)pParent;
|
||||
Node *pNode = NewNode();
|
||||
pNode->Init(CT_SCALAR, mark, tag);
|
||||
pNode->SetData(value);
|
||||
return pNode;
|
||||
}
|
||||
|
||||
NodeBuilder::Sequence *NodeBuilder::NewSequence(const Mark& mark, const std::string& tag, Node *pParent)
|
||||
{
|
||||
(void)pParent;
|
||||
Node *pNode = NewNode();
|
||||
pNode->Init(CT_SEQUENCE, mark, tag);
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void NodeBuilder::AppendToSequence(Sequence *pSequence, Node *pNode)
|
||||
{
|
||||
std::auto_ptr<Node> apNode(m_unlinked.pop(pNode));
|
||||
assert(apNode.get());
|
||||
pSequence->Append(apNode);
|
||||
}
|
||||
|
||||
NodeBuilder::Map *NodeBuilder::NewMap(const Mark& mark, const std::string& tag, Node* pParent)
|
||||
{
|
||||
(void)pParent;
|
||||
Node *pNode = NewNode();
|
||||
pNode->Init(CT_MAP, mark, tag);
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void NodeBuilder::AssignInMap(Map *pMap, Node *pKeyNode, Node *pValueNode)
|
||||
{
|
||||
std::auto_ptr<Node> apKeyNode(m_unlinked.pop(pKeyNode));
|
||||
std::auto_ptr<Node> apValueNode(m_unlinked.pop(pValueNode));
|
||||
assert(apKeyNode.get() && apValueNode.get());
|
||||
pMap->Insert(apKeyNode, apValueNode);
|
||||
}
|
||||
|
||||
Node* NodeBuilder::NewNode()
|
||||
{
|
||||
if(!m_initializedRoot) {
|
||||
m_initializedRoot = true;
|
||||
return &m_root;
|
||||
}
|
||||
|
||||
std::auto_ptr<Node> pNode(new Node);
|
||||
Node* pResult = pNode.get();
|
||||
// Save the pointer in a collection that will free it on exception
|
||||
m_unlinked.push(pNode);
|
||||
return pResult;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
|
||||
#include "ptr_stack.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
class Mark;
|
||||
|
||||
class NodeBuilder
|
||||
{
|
||||
public:
|
||||
typedef YAML::Node Node;
|
||||
typedef YAML::Node Map;
|
||||
typedef YAML::Node Sequence;
|
||||
|
||||
explicit NodeBuilder(Node& root);
|
||||
NodeBuilder(const NodeBuilder& o);
|
||||
virtual ~NodeBuilder();
|
||||
|
||||
Node *NewNull(const std::string& tag, Node *pParent);
|
||||
Node *AnchorReference(const Mark& mark, Node *pNode);
|
||||
Node *NewScalar(const Mark& mark, const std::string& tag, Node *pParent, const std::string& value);
|
||||
|
||||
Sequence *NewSequence(const Mark& mark, const std::string& tag, Node *pParent);
|
||||
void AppendToSequence(Sequence *pSequence, Node *pNode);
|
||||
void SequenceComplete(Sequence *pSequence) {(void)pSequence;}
|
||||
|
||||
Map *NewMap(const Mark& mark, const std::string& tag, Node *pParent);
|
||||
void AssignInMap(Map *pMap, Node *pKeyNode, Node *pValueNode);
|
||||
void MapComplete(Map *pMap) {(void)pMap;}
|
||||
|
||||
private:
|
||||
Node* NewNode();
|
||||
|
||||
private:
|
||||
Node& m_root;
|
||||
bool m_initializedRoot;
|
||||
|
||||
ptr_stack<Node> m_unlinked;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NODEBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
+52
-71
@@ -1,14 +1,8 @@
|
||||
#include "crt.h"
|
||||
#include "parser.h"
|
||||
#include "directives.h"
|
||||
#include "eventhandler.h"
|
||||
#include "exceptions.h"
|
||||
#include "graphbuilderadapter.h"
|
||||
#include "node.h"
|
||||
#include "nodebuilder.h"
|
||||
#include "scanner.h"
|
||||
#include "singledocparser.h"
|
||||
#include "tag.h"
|
||||
#include "token.h"
|
||||
#include "exceptions.h"
|
||||
#include <sstream>
|
||||
#include <cstdio>
|
||||
|
||||
@@ -35,38 +29,7 @@ namespace YAML
|
||||
void Parser::Load(std::istream& in)
|
||||
{
|
||||
m_pScanner.reset(new Scanner(in));
|
||||
m_pDirectives.reset(new Directives);
|
||||
}
|
||||
|
||||
// HandleNextDocument
|
||||
// . Handles the next document
|
||||
// . Throws a ParserException on error.
|
||||
// . Returns false if there are no more documents
|
||||
bool Parser::HandleNextDocument(EventHandler& eventHandler)
|
||||
{
|
||||
if(!m_pScanner.get())
|
||||
return false;
|
||||
|
||||
ParseDirectives();
|
||||
if(m_pScanner->empty())
|
||||
return false;
|
||||
|
||||
SingleDocParser sdp(*m_pScanner, *m_pDirectives);
|
||||
sdp.HandleDocument(eventHandler);
|
||||
return true;
|
||||
}
|
||||
|
||||
// BuildNextDocumentGraph
|
||||
// . Builds a graph of the next document
|
||||
// . Returns NULL if there are no more documents
|
||||
void *Parser::BuildNextDocumentGraph(GraphBuilderInterface& graphBuilder)
|
||||
{
|
||||
GraphBuilderAdapter eventHandler(graphBuilder);
|
||||
if (HandleNextDocument(eventHandler)) {
|
||||
return eventHandler.RootNode();
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
m_state.Reset();
|
||||
}
|
||||
|
||||
// GetNextDocument
|
||||
@@ -74,8 +37,34 @@ namespace YAML
|
||||
// . Throws a ParserException on error.
|
||||
bool Parser::GetNextDocument(Node& document)
|
||||
{
|
||||
NodeBuilder builder(document);
|
||||
return BuildNextDocumentGraph(builder);
|
||||
if(!m_pScanner.get())
|
||||
return false;
|
||||
|
||||
// clear node
|
||||
document.Clear();
|
||||
|
||||
// first read directives
|
||||
ParseDirectives();
|
||||
|
||||
// we better have some tokens in the queue
|
||||
if(m_pScanner->empty())
|
||||
return false;
|
||||
|
||||
// first eat doc start (optional)
|
||||
if(m_pScanner->peek().type == Token::DOC_START)
|
||||
m_pScanner->pop();
|
||||
|
||||
// now parse our root node
|
||||
document.Parse(m_pScanner.get(), m_state);
|
||||
|
||||
// and finally eat any doc ends we see
|
||||
while(!m_pScanner->empty() && m_pScanner->peek().type == Token::DOC_END)
|
||||
m_pScanner->pop();
|
||||
|
||||
// clear anchors from the scanner, which are no longer relevant
|
||||
m_pScanner->ClearAnchors();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ParseDirectives
|
||||
@@ -95,59 +84,51 @@ namespace YAML
|
||||
// we keep the directives from the last document if none are specified;
|
||||
// but if any directives are specific, then we reset them
|
||||
if(!readDirective)
|
||||
m_pDirectives.reset(new Directives);
|
||||
m_state.Reset();
|
||||
|
||||
readDirective = true;
|
||||
HandleDirective(token);
|
||||
HandleDirective(&token);
|
||||
m_pScanner->pop();
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::HandleDirective(const Token& token)
|
||||
void Parser::HandleDirective(Token *pToken)
|
||||
{
|
||||
if(token.value == "YAML")
|
||||
HandleYamlDirective(token);
|
||||
else if(token.value == "TAG")
|
||||
HandleTagDirective(token);
|
||||
if(pToken->value == "YAML")
|
||||
HandleYamlDirective(pToken);
|
||||
else if(pToken->value == "TAG")
|
||||
HandleTagDirective(pToken);
|
||||
}
|
||||
|
||||
// HandleYamlDirective
|
||||
// . Should be of the form 'major.minor' (like a version number)
|
||||
void Parser::HandleYamlDirective(const Token& token)
|
||||
void Parser::HandleYamlDirective(Token *pToken)
|
||||
{
|
||||
if(token.params.size() != 1)
|
||||
throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
|
||||
|
||||
if(!m_pDirectives->version.isDefault)
|
||||
throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE);
|
||||
if(pToken->params.size() != 1)
|
||||
throw ParserException(pToken->mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
|
||||
|
||||
std::stringstream str(token.params[0]);
|
||||
str >> m_pDirectives->version.major;
|
||||
std::stringstream str(pToken->params[0]);
|
||||
str >> m_state.version.major;
|
||||
str.get();
|
||||
str >> m_pDirectives->version.minor;
|
||||
str >> m_state.version.minor;
|
||||
if(!str || str.peek() != EOF)
|
||||
throw ParserException(token.mark, ErrorMsg::YAML_VERSION + token.params[0]);
|
||||
throw ParserException(pToken->mark, ErrorMsg::YAML_VERSION + pToken->params[0]);
|
||||
|
||||
if(m_pDirectives->version.major > 1)
|
||||
throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION);
|
||||
if(m_state.version.major > 1)
|
||||
throw ParserException(pToken->mark, ErrorMsg::YAML_MAJOR_VERSION);
|
||||
|
||||
m_pDirectives->version.isDefault = false;
|
||||
// TODO: warning on major == 1, minor > 2?
|
||||
}
|
||||
|
||||
// HandleTagDirective
|
||||
// . Should be of the form 'handle prefix', where 'handle' is converted to 'prefix' in the file.
|
||||
void Parser::HandleTagDirective(const Token& token)
|
||||
void Parser::HandleTagDirective(Token *pToken)
|
||||
{
|
||||
if(token.params.size() != 2)
|
||||
throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS);
|
||||
if(pToken->params.size() != 2)
|
||||
throw ParserException(pToken->mark, ErrorMsg::TAG_DIRECTIVE_ARGS);
|
||||
|
||||
const std::string& handle = token.params[0];
|
||||
const std::string& prefix = token.params[1];
|
||||
if(m_pDirectives->tags.find(handle) != m_pDirectives->tags.end())
|
||||
throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE);
|
||||
|
||||
m_pDirectives->tags[handle] = prefix;
|
||||
std::string handle = pToken->params[0], prefix = pToken->params[1];
|
||||
m_state.tags[handle] = prefix;
|
||||
}
|
||||
|
||||
void Parser::PrintTokens(std::ostream& out)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "crt.h"
|
||||
#include "parserstate.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
void ParserState::Reset()
|
||||
{
|
||||
// version
|
||||
version.major = 1;
|
||||
version.minor = 2;
|
||||
|
||||
// and tags
|
||||
tags.clear();
|
||||
tags["!"] = "!";
|
||||
tags["!!"] = "tag:yaml.org,2002:";
|
||||
}
|
||||
|
||||
std::string ParserState::TranslateTag(const std::string& handle) const
|
||||
{
|
||||
std::map <std::string, std::string>::const_iterator it = tags.find(handle);
|
||||
if(it == tags.end())
|
||||
return handle;
|
||||
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "noncopyable.h"
|
||||
|
||||
template <typename T>
|
||||
class ptr_stack : private YAML::noncopyable
|
||||
{
|
||||
public:
|
||||
ptr_stack() {}
|
||||
~ptr_stack() { clear(); }
|
||||
|
||||
void clear() {
|
||||
for(unsigned i=0;i<m_data.size();i++)
|
||||
delete m_data[i];
|
||||
m_data.clear();
|
||||
}
|
||||
|
||||
std::size_t size() const { return m_data.size(); }
|
||||
bool empty() const { return m_data.empty(); }
|
||||
|
||||
void push(std::auto_ptr<T> t) {
|
||||
// Make sure that the space is available before releasing the
|
||||
// auto_ptr to it. NULL can be deleted safely.
|
||||
m_data.push_back(NULL);
|
||||
m_data.back() = t.release();
|
||||
}
|
||||
std::auto_ptr<T> pop() {
|
||||
std::auto_ptr<T> t(m_data.back());
|
||||
m_data.pop_back();
|
||||
return t;
|
||||
}
|
||||
std::auto_ptr<T> pop(T* val) {
|
||||
typename std::vector<T*>::reverse_iterator itVal =
|
||||
std::find(m_data.rbegin(), m_data.rend(), val);
|
||||
std::auto_ptr<T> t;
|
||||
if (itVal != m_data.rend()) {
|
||||
t.reset(*itVal);
|
||||
m_data.erase((itVal + 1).base());
|
||||
}
|
||||
return t;
|
||||
}
|
||||
T& top() const { return *m_data.back(); }
|
||||
|
||||
private:
|
||||
std::vector<T*> m_data;
|
||||
};
|
||||
|
||||
#endif // PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "crt.h"
|
||||
#include "regex.h"
|
||||
|
||||
namespace YAML
|
||||
|
||||
+1
-1
@@ -37,12 +37,12 @@ namespace YAML
|
||||
|
||||
int Match(const std::string& str) const;
|
||||
int Match(const Stream& in) const;
|
||||
template <typename Source> int Match(const Source& source) const;
|
||||
|
||||
private:
|
||||
RegEx(REGEX_OP op);
|
||||
|
||||
template <typename Source> bool IsValidSource(const Source& source) const;
|
||||
template <typename Source> int Match(const Source& source) const;
|
||||
template <typename Source> int MatchUnchecked(const Source& source) const;
|
||||
|
||||
template <typename Source> int MatchOpEmpty(const Source& source) const;
|
||||
|
||||
+24
-3
@@ -1,5 +1,10 @@
|
||||
#include "crt.h"
|
||||
#include "scalar.h"
|
||||
#include "eventhandler.h"
|
||||
#include "scanner.h"
|
||||
#include "token.h"
|
||||
#include "exceptions.h"
|
||||
#include "node.h"
|
||||
#include "emitter.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
@@ -7,13 +12,29 @@ namespace YAML
|
||||
{
|
||||
}
|
||||
|
||||
Scalar::Scalar(const std::string& data): m_data(data)
|
||||
{
|
||||
}
|
||||
|
||||
Scalar::~Scalar()
|
||||
{
|
||||
}
|
||||
|
||||
void Scalar::EmitEvents(AliasManager&, EventHandler& eventHandler, const Mark& mark, const std::string& tag, anchor_t anchor) const
|
||||
Content *Scalar::Clone() const
|
||||
{
|
||||
eventHandler.OnScalar(mark, tag, anchor, m_data);
|
||||
return new Scalar(m_data);
|
||||
}
|
||||
|
||||
void Scalar::Parse(Scanner *pScanner, const ParserState& /*state*/)
|
||||
{
|
||||
Token& token = pScanner->peek();
|
||||
m_data = token.value;
|
||||
pScanner->pop();
|
||||
}
|
||||
|
||||
void Scalar::Write(Emitter& out) const
|
||||
{
|
||||
out << m_data;
|
||||
}
|
||||
|
||||
int Scalar::Compare(Content *pContent)
|
||||
|
||||
+5
-2
@@ -13,12 +13,15 @@ namespace YAML
|
||||
{
|
||||
public:
|
||||
Scalar();
|
||||
Scalar(const std::string& data);
|
||||
virtual ~Scalar();
|
||||
|
||||
virtual void SetData(const std::string& data) { m_data = data; }
|
||||
virtual Content *Clone() const;
|
||||
|
||||
virtual void Parse(Scanner *pScanner, const ParserState& state);
|
||||
virtual void Write(Emitter& out) const;
|
||||
|
||||
virtual bool IsScalar() const { return true; }
|
||||
virtual void EmitEvents(AliasManager& am, EventHandler& eventHandler, const Mark& mark, const std::string& tag, anchor_t anchor) const;
|
||||
|
||||
// extraction
|
||||
virtual bool GetScalar(std::string& scalar) const {
|
||||
|
||||
+69
-67
@@ -1,22 +1,19 @@
|
||||
#include "crt.h"
|
||||
#include "scanner.h"
|
||||
#include "token.h"
|
||||
#include "exceptions.h"
|
||||
#include "exp.h"
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
Scanner::Scanner(std::istream& in)
|
||||
: INPUT(in), m_startedStream(false), m_endedStream(false), m_simpleKeyAllowed(false), m_canBeJSONFlow(false)
|
||||
: INPUT(in), m_startedStream(false), m_endedStream(false), m_simpleKeyAllowed(false)
|
||||
{
|
||||
}
|
||||
|
||||
Scanner::~Scanner()
|
||||
{
|
||||
for(unsigned i=0;i<m_indentRefs.size();i++)
|
||||
delete m_indentRefs[i];
|
||||
m_indentRefs.clear();
|
||||
}
|
||||
|
||||
// empty
|
||||
@@ -32,8 +29,13 @@ namespace YAML
|
||||
void Scanner::pop()
|
||||
{
|
||||
EnsureTokensInQueue();
|
||||
if(!m_tokens.empty())
|
||||
if(!m_tokens.empty()) {
|
||||
// Saved anchors shouldn't survive popping the document end marker
|
||||
if (m_tokens.front().type == Token::DOC_END) {
|
||||
ClearAnchors();
|
||||
}
|
||||
m_tokens.pop();
|
||||
}
|
||||
}
|
||||
|
||||
// peek
|
||||
@@ -114,10 +116,10 @@ namespace YAML
|
||||
return ScanDirective();
|
||||
|
||||
// document token
|
||||
if(INPUT.column() == 0 && Exp::DocStart().Matches(INPUT))
|
||||
if(INPUT.column() == 0 && Exp::DocStart.Matches(INPUT))
|
||||
return ScanDocStart();
|
||||
|
||||
if(INPUT.column() == 0 && Exp::DocEnd().Matches(INPUT))
|
||||
if(INPUT.column() == 0 && Exp::DocEnd.Matches(INPUT))
|
||||
return ScanDocEnd();
|
||||
|
||||
// flow start/end/entry
|
||||
@@ -131,13 +133,13 @@ namespace YAML
|
||||
return ScanFlowEntry();
|
||||
|
||||
// block/map stuff
|
||||
if(Exp::BlockEntry().Matches(INPUT))
|
||||
if(Exp::BlockEntry.Matches(INPUT))
|
||||
return ScanBlockEntry();
|
||||
|
||||
if((InBlockContext() ? Exp::Key() : Exp::KeyInFlow()).Matches(INPUT))
|
||||
if((InBlockContext() ? Exp::Key : Exp::KeyInFlow).Matches(INPUT))
|
||||
return ScanKey();
|
||||
|
||||
if(GetValueRegex().Matches(INPUT))
|
||||
if((InBlockContext() ? Exp::Value : Exp::ValueInFlow).Matches(INPUT))
|
||||
return ScanValue();
|
||||
|
||||
// alias/anchor
|
||||
@@ -156,7 +158,7 @@ namespace YAML
|
||||
return ScanQuotedScalar();
|
||||
|
||||
// plain scalars
|
||||
if((InBlockContext() ? Exp::PlainScalar() : Exp::PlainScalarInFlow()).Matches(INPUT))
|
||||
if((InBlockContext() ? Exp::PlainScalar : Exp::PlainScalarInFlow).Matches(INPUT))
|
||||
return ScanPlainScalar();
|
||||
|
||||
// don't know what it is!
|
||||
@@ -170,24 +172,24 @@ namespace YAML
|
||||
while(1) {
|
||||
// first eat whitespace
|
||||
while(INPUT && IsWhitespaceToBeEaten(INPUT.peek())) {
|
||||
if(InBlockContext() && Exp::Tab().Matches(INPUT))
|
||||
if(InBlockContext() && Exp::Tab.Matches(INPUT))
|
||||
m_simpleKeyAllowed = false;
|
||||
INPUT.eat(1);
|
||||
}
|
||||
|
||||
// then eat a comment
|
||||
if(Exp::Comment().Matches(INPUT)) {
|
||||
if(Exp::Comment.Matches(INPUT)) {
|
||||
// eat until line break
|
||||
while(INPUT && !Exp::Break().Matches(INPUT))
|
||||
while(INPUT && !Exp::Break.Matches(INPUT))
|
||||
INPUT.eat(1);
|
||||
}
|
||||
|
||||
// if it's NOT a line break, then we're done!
|
||||
if(!Exp::Break().Matches(INPUT))
|
||||
if(!Exp::Break.Matches(INPUT))
|
||||
break;
|
||||
|
||||
// otherwise, let's eat the line break and keep going
|
||||
int n = Exp::Break().Match(INPUT);
|
||||
int n = Exp::Break.Match(INPUT);
|
||||
INPUT.eat(n);
|
||||
|
||||
// oh yeah, and let's get rid of that simple key
|
||||
@@ -221,25 +223,14 @@ namespace YAML
|
||||
return false;
|
||||
}
|
||||
|
||||
// GetValueRegex
|
||||
// . Get the appropriate regex to check if it's a value token
|
||||
const RegEx& Scanner::GetValueRegex() const
|
||||
{
|
||||
if(InBlockContext())
|
||||
return Exp::Value();
|
||||
|
||||
return m_canBeJSONFlow ? Exp::ValueInJSONFlow() : Exp::ValueInFlow();
|
||||
}
|
||||
|
||||
// StartStream
|
||||
// . Set the initial conditions for starting a stream.
|
||||
void Scanner::StartStream()
|
||||
{
|
||||
m_startedStream = true;
|
||||
m_simpleKeyAllowed = true;
|
||||
IndentMarker *pIndent = new IndentMarker(-1, IndentMarker::NONE);
|
||||
m_indentRefs.push_back(pIndent);
|
||||
m_indents.push(pIndent);
|
||||
m_indents.push(IndentMarker(-1, IndentMarker::NONE));
|
||||
m_anchors.clear();
|
||||
}
|
||||
|
||||
// EndStream
|
||||
@@ -257,22 +248,6 @@ namespace YAML
|
||||
m_endedStream = true;
|
||||
}
|
||||
|
||||
Token *Scanner::PushToken(Token::TYPE type)
|
||||
{
|
||||
m_tokens.push(Token(type, INPUT.mark()));
|
||||
return &m_tokens.back();
|
||||
}
|
||||
|
||||
Token::TYPE Scanner::GetStartTokenFor(IndentMarker::INDENT_TYPE type) const
|
||||
{
|
||||
switch(type) {
|
||||
case IndentMarker::SEQ: return Token::BLOCK_SEQ_START;
|
||||
case IndentMarker::MAP: return Token::BLOCK_MAP_START;
|
||||
case IndentMarker::NONE: assert(false); break;
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
|
||||
// PushIndentTo
|
||||
// . Pushes an indentation onto the stack, and enqueues the
|
||||
// proper token (sequence start or mapping start).
|
||||
@@ -283,9 +258,8 @@ namespace YAML
|
||||
if(InFlowContext())
|
||||
return 0;
|
||||
|
||||
std::auto_ptr<IndentMarker> pIndent(new IndentMarker(column, type));
|
||||
IndentMarker& indent = *pIndent;
|
||||
const IndentMarker& lastIndent = *m_indents.top();
|
||||
IndentMarker indent(column, type);
|
||||
const IndentMarker& lastIndent = m_indents.top();
|
||||
|
||||
// is this actually an indentation?
|
||||
if(indent.column < lastIndent.column)
|
||||
@@ -294,18 +268,22 @@ namespace YAML
|
||||
return 0;
|
||||
|
||||
// push a start token
|
||||
indent.pStartToken = PushToken(GetStartTokenFor(type));
|
||||
if(type == IndentMarker::SEQ)
|
||||
m_tokens.push(Token(Token::BLOCK_SEQ_START, INPUT.mark()));
|
||||
else if(type == IndentMarker::MAP)
|
||||
m_tokens.push(Token(Token::BLOCK_MAP_START, INPUT.mark()));
|
||||
else
|
||||
assert(false);
|
||||
indent.pStartToken = &m_tokens.back();
|
||||
|
||||
// and then the indent
|
||||
m_indents.push(&indent);
|
||||
m_indentRefs.push_back(pIndent.release());
|
||||
return m_indentRefs.back();
|
||||
m_indents.push(indent);
|
||||
return &m_indents.top();
|
||||
}
|
||||
|
||||
// PopIndentToHere
|
||||
// . Pops indentations off the stack until we reach the current indentation level,
|
||||
// and enqueues the proper token each time.
|
||||
// . Then pops all invalid indentations off.
|
||||
void Scanner::PopIndentToHere()
|
||||
{
|
||||
// are we in flow?
|
||||
@@ -314,17 +292,14 @@ namespace YAML
|
||||
|
||||
// now pop away
|
||||
while(!m_indents.empty()) {
|
||||
const IndentMarker& indent = *m_indents.top();
|
||||
const IndentMarker& indent = m_indents.top();
|
||||
if(indent.column < INPUT.column())
|
||||
break;
|
||||
if(indent.column == INPUT.column() && !(indent.type == IndentMarker::SEQ && !Exp::BlockEntry().Matches(INPUT)))
|
||||
if(indent.column == INPUT.column() && !(indent.type == IndentMarker::SEQ && !Exp::BlockEntry.Matches(INPUT)))
|
||||
break;
|
||||
|
||||
PopIndent();
|
||||
}
|
||||
|
||||
while(!m_indents.empty() && m_indents.top()->status == IndentMarker::INVALID)
|
||||
PopIndent();
|
||||
}
|
||||
|
||||
// PopAllIndents
|
||||
@@ -338,7 +313,7 @@ namespace YAML
|
||||
|
||||
// now pop away
|
||||
while(!m_indents.empty()) {
|
||||
const IndentMarker& indent = *m_indents.top();
|
||||
const IndentMarker& indent = m_indents.top();
|
||||
if(indent.type == IndentMarker::NONE)
|
||||
break;
|
||||
|
||||
@@ -350,17 +325,17 @@ namespace YAML
|
||||
// . Pops a single indent, pushing the proper token
|
||||
void Scanner::PopIndent()
|
||||
{
|
||||
const IndentMarker& indent = *m_indents.top();
|
||||
IndentMarker indent = m_indents.top();
|
||||
IndentMarker::INDENT_TYPE type = indent.type;
|
||||
m_indents.pop();
|
||||
|
||||
if(indent.status != IndentMarker::VALID) {
|
||||
if(!indent.isValid) {
|
||||
InvalidateSimpleKey();
|
||||
return;
|
||||
}
|
||||
|
||||
if(indent.type == IndentMarker::SEQ)
|
||||
if(type == IndentMarker::SEQ)
|
||||
m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark()));
|
||||
else if(indent.type == IndentMarker::MAP)
|
||||
else if(type == IndentMarker::MAP)
|
||||
m_tokens.push(Token(Token::BLOCK_MAP_END, INPUT.mark()));
|
||||
}
|
||||
|
||||
@@ -369,7 +344,30 @@ namespace YAML
|
||||
{
|
||||
if(m_indents.empty())
|
||||
return 0;
|
||||
return m_indents.top()->column;
|
||||
return m_indents.top().column;
|
||||
}
|
||||
|
||||
// Save
|
||||
// . Saves a pointer to the Node object referenced by a particular anchor
|
||||
// name.
|
||||
void Scanner::Save(const std::string& anchor, Node* value)
|
||||
{
|
||||
m_anchors[anchor] = value;
|
||||
}
|
||||
|
||||
// Retrieve
|
||||
// . Retrieves a pointer previously saved for an anchor name.
|
||||
// . Throws an exception if the anchor has not been defined.
|
||||
const Node *Scanner::Retrieve(const std::string& anchor) const
|
||||
{
|
||||
typedef std::map<std::string, const Node *> map;
|
||||
|
||||
map::const_iterator itNode = m_anchors.find(anchor);
|
||||
|
||||
if(m_anchors.end() == itNode)
|
||||
ThrowParserException(ErrorMsg::UNKNOWN_ANCHOR);
|
||||
|
||||
return itNode->second;
|
||||
}
|
||||
|
||||
// ThrowParserException
|
||||
@@ -385,5 +383,9 @@ namespace YAML
|
||||
}
|
||||
throw ParserException(mark, msg);
|
||||
}
|
||||
}
|
||||
|
||||
void Scanner::ClearAnchors()
|
||||
{
|
||||
m_anchors.clear();
|
||||
}
|
||||
}
|
||||
|
||||
+9
-11
@@ -16,7 +16,6 @@
|
||||
namespace YAML
|
||||
{
|
||||
class Node;
|
||||
class RegEx;
|
||||
|
||||
class Scanner
|
||||
{
|
||||
@@ -29,15 +28,19 @@ namespace YAML
|
||||
void pop();
|
||||
Token& peek();
|
||||
|
||||
// anchor management
|
||||
void Save(const std::string& anchor, Node* value);
|
||||
const Node *Retrieve(const std::string& anchor) const;
|
||||
void ClearAnchors();
|
||||
|
||||
private:
|
||||
struct IndentMarker {
|
||||
enum INDENT_TYPE { MAP, SEQ, NONE };
|
||||
enum STATUS { VALID, INVALID, UNKNOWN };
|
||||
IndentMarker(int column_, INDENT_TYPE type_): column(column_), type(type_), status(VALID), pStartToken(0) {}
|
||||
IndentMarker(int column_, INDENT_TYPE type_): column(column_), type(type_), isValid(true), pStartToken(0) {}
|
||||
|
||||
int column;
|
||||
INDENT_TYPE type;
|
||||
STATUS status;
|
||||
bool isValid;
|
||||
Token *pStartToken;
|
||||
};
|
||||
|
||||
@@ -50,13 +53,11 @@ namespace YAML
|
||||
void ScanToNextToken();
|
||||
void StartStream();
|
||||
void EndStream();
|
||||
Token *PushToken(Token::TYPE type);
|
||||
|
||||
bool InFlowContext() const { return !m_flows.empty(); }
|
||||
bool InBlockContext() const { return m_flows.empty(); }
|
||||
int GetFlowLevel() const { return m_flows.size(); }
|
||||
|
||||
Token::TYPE GetStartTokenFor(IndentMarker::INDENT_TYPE type) const;
|
||||
IndentMarker *PushIndentTo(int column, IndentMarker::INDENT_TYPE type);
|
||||
void PopIndentToHere();
|
||||
void PopAllIndents();
|
||||
@@ -74,7 +75,6 @@ namespace YAML
|
||||
void ThrowParserException(const std::string& msg) const;
|
||||
|
||||
bool IsWhitespaceToBeEaten(char ch);
|
||||
const RegEx& GetValueRegex() const;
|
||||
|
||||
struct SimpleKey {
|
||||
SimpleKey(const Mark& mark_, int flowLevel_);
|
||||
@@ -117,13 +117,11 @@ namespace YAML
|
||||
// state info
|
||||
bool m_startedStream, m_endedStream;
|
||||
bool m_simpleKeyAllowed;
|
||||
bool m_canBeJSONFlow;
|
||||
std::stack <SimpleKey> m_simpleKeys;
|
||||
std::stack <IndentMarker *> m_indents;
|
||||
std::vector <IndentMarker *> m_indentRefs; // for "garbage collection"
|
||||
std::stack <IndentMarker> m_indents;
|
||||
std::stack <FLOW_MARKER> m_flows;
|
||||
std::map <std::string, const Node *> m_anchors;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
+13
-14
@@ -1,3 +1,4 @@
|
||||
#include "crt.h"
|
||||
#include "scanscalar.h"
|
||||
#include "scanner.h"
|
||||
#include "exp.h"
|
||||
@@ -31,13 +32,12 @@ namespace YAML
|
||||
// Phase #1: scan until line ending
|
||||
|
||||
std::size_t lastNonWhitespaceChar = scalar.size();
|
||||
bool escapedNewline = false;
|
||||
while(!params.end.Matches(INPUT) && !Exp::Break().Matches(INPUT)) {
|
||||
while(!params.end.Matches(INPUT) && !Exp::Break.Matches(INPUT)) {
|
||||
if(!INPUT)
|
||||
break;
|
||||
|
||||
// document indicator?
|
||||
if(INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT)) {
|
||||
if(INPUT.column() == 0 && Exp::DocIndicator.Matches(INPUT)) {
|
||||
if(params.onDocIndicator == BREAK)
|
||||
break;
|
||||
else if(params.onDocIndicator == THROW)
|
||||
@@ -48,12 +48,11 @@ namespace YAML
|
||||
pastOpeningBreak = true;
|
||||
|
||||
// escaped newline? (only if we're escaping on slash)
|
||||
if(params.escape == '\\' && Exp::EscBreak().Matches(INPUT)) {
|
||||
// eat escape character and get out (but preserve trailing whitespace!)
|
||||
INPUT.get();
|
||||
if(params.escape == '\\' && Exp::EscBreak.Matches(INPUT)) {
|
||||
int n = Exp::EscBreak.Match(INPUT);
|
||||
INPUT.eat(n);
|
||||
lastNonWhitespaceChar = scalar.size();
|
||||
escapedNewline = true;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
// escape this?
|
||||
@@ -78,7 +77,7 @@ namespace YAML
|
||||
}
|
||||
|
||||
// doc indicator?
|
||||
if(params.onDocIndicator == BREAK && INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT))
|
||||
if(params.onDocIndicator == BREAK && INPUT.column() == 0 && Exp::DocIndicator.Matches(INPUT))
|
||||
break;
|
||||
|
||||
// are we done via character match?
|
||||
@@ -95,7 +94,7 @@ namespace YAML
|
||||
|
||||
// ********************************
|
||||
// Phase #2: eat line ending
|
||||
n = Exp::Break().Match(INPUT);
|
||||
n = Exp::Break.Match(INPUT);
|
||||
INPUT.eat(n);
|
||||
|
||||
// ********************************
|
||||
@@ -110,7 +109,7 @@ namespace YAML
|
||||
params.indent = std::max(params.indent, INPUT.column());
|
||||
|
||||
// and then the rest of the whitespace
|
||||
while(Exp::Blank().Matches(INPUT)) {
|
||||
while(Exp::Blank.Matches(INPUT)) {
|
||||
// we check for tabs that masquerade as indentation
|
||||
if(INPUT.peek() == '\t'&& INPUT.column() < params.indent && params.onTabInIndentation == THROW)
|
||||
throw ParserException(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION);
|
||||
@@ -122,8 +121,8 @@ namespace YAML
|
||||
}
|
||||
|
||||
// was this an empty line?
|
||||
bool nextEmptyLine = Exp::Break().Matches(INPUT);
|
||||
bool nextMoreIndented = Exp::Blank().Matches(INPUT);
|
||||
bool nextEmptyLine = Exp::Break.Matches(INPUT);
|
||||
bool nextMoreIndented = Exp::Blank.Matches(INPUT);
|
||||
if(params.fold == FOLD_BLOCK && foldedNewlineCount == 0 && nextEmptyLine)
|
||||
foldedNewlineStartedMoreIndented = moreIndented;
|
||||
|
||||
@@ -151,7 +150,7 @@ namespace YAML
|
||||
case FOLD_FLOW:
|
||||
if(nextEmptyLine)
|
||||
scalar += "\n";
|
||||
else if(!emptyLine && !nextEmptyLine && !escapedNewline)
|
||||
else if(!emptyLine && !nextEmptyLine)
|
||||
scalar += " ";
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -40,4 +40,3 @@ namespace YAML
|
||||
}
|
||||
|
||||
#endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
#include "scanner.h"
|
||||
#include "regex.h"
|
||||
#include "exp.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
const std::string ScanVerbatimTag(Stream& INPUT)
|
||||
{
|
||||
std::string tag;
|
||||
|
||||
// eat the start character
|
||||
INPUT.get();
|
||||
|
||||
while(INPUT) {
|
||||
if(INPUT.peek() == Keys::VerbatimTagEnd) {
|
||||
// eat the end character
|
||||
INPUT.get();
|
||||
return tag;
|
||||
}
|
||||
|
||||
int n = Exp::URI().Match(INPUT);
|
||||
if(n <= 0)
|
||||
break;
|
||||
|
||||
tag += INPUT.get(n);
|
||||
}
|
||||
|
||||
throw ParserException(INPUT.mark(), ErrorMsg::END_OF_VERBATIM_TAG);
|
||||
}
|
||||
|
||||
const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle)
|
||||
{
|
||||
std::string tag;
|
||||
canBeHandle = true;
|
||||
Mark firstNonWordChar;
|
||||
|
||||
while(INPUT) {
|
||||
if(INPUT.peek() == Keys::Tag) {
|
||||
if(!canBeHandle)
|
||||
throw ParserException(firstNonWordChar, ErrorMsg::CHAR_IN_TAG_HANDLE);
|
||||
break;
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
if(canBeHandle) {
|
||||
n = Exp::Word().Match(INPUT);
|
||||
if(n <= 0) {
|
||||
canBeHandle = false;
|
||||
firstNonWordChar = INPUT.mark();
|
||||
}
|
||||
}
|
||||
|
||||
if(!canBeHandle)
|
||||
n = Exp::Tag().Match(INPUT);
|
||||
|
||||
if(n <= 0)
|
||||
break;
|
||||
|
||||
tag += INPUT.get(n);
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
const std::string ScanTagSuffix(Stream& INPUT)
|
||||
{
|
||||
std::string tag;
|
||||
|
||||
while(INPUT) {
|
||||
int n = Exp::Tag().Match(INPUT);
|
||||
if(n <= 0)
|
||||
break;
|
||||
|
||||
tag += INPUT.get(n);
|
||||
}
|
||||
|
||||
if(tag.empty())
|
||||
throw ParserException(INPUT.mark(), ErrorMsg::TAG_WITH_NO_SUFFIX);
|
||||
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include <string>
|
||||
#include "stream.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
const std::string ScanVerbatimTag(Stream& INPUT);
|
||||
const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle);
|
||||
const std::string ScanTagSuffix(Stream& INPUT);
|
||||
}
|
||||
|
||||
#endif // SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
+48
-70
@@ -1,10 +1,9 @@
|
||||
#include "crt.h"
|
||||
#include "scanner.h"
|
||||
#include "token.h"
|
||||
#include "exceptions.h"
|
||||
#include "exp.h"
|
||||
#include "scanscalar.h"
|
||||
#include "scantag.h"
|
||||
#include "tag.h"
|
||||
#include <sstream>
|
||||
|
||||
namespace YAML
|
||||
@@ -24,34 +23,36 @@ namespace YAML
|
||||
PopAllSimpleKeys();
|
||||
|
||||
m_simpleKeyAllowed = false;
|
||||
m_canBeJSONFlow = false;
|
||||
|
||||
// store pos and eat indicator
|
||||
Token token(Token::DIRECTIVE, INPUT.mark());
|
||||
Mark mark = INPUT.mark();
|
||||
INPUT.eat(1);
|
||||
|
||||
// read name
|
||||
while(INPUT && !Exp::BlankOrBreak().Matches(INPUT))
|
||||
token.value += INPUT.get();
|
||||
while(INPUT && !Exp::BlankOrBreak.Matches(INPUT))
|
||||
name += INPUT.get();
|
||||
|
||||
// read parameters
|
||||
while(1) {
|
||||
// first get rid of whitespace
|
||||
while(Exp::Blank().Matches(INPUT))
|
||||
while(Exp::Blank.Matches(INPUT))
|
||||
INPUT.eat(1);
|
||||
|
||||
// break on newline or comment
|
||||
if(!INPUT || Exp::Break().Matches(INPUT) || Exp::Comment().Matches(INPUT))
|
||||
if(!INPUT || Exp::Break.Matches(INPUT) || Exp::Comment.Matches(INPUT))
|
||||
break;
|
||||
|
||||
// now read parameter
|
||||
std::string param;
|
||||
while(INPUT && !Exp::BlankOrBreak().Matches(INPUT))
|
||||
while(INPUT && !Exp::BlankOrBreak.Matches(INPUT))
|
||||
param += INPUT.get();
|
||||
|
||||
token.params.push_back(param);
|
||||
params.push_back(param);
|
||||
}
|
||||
|
||||
Token token(Token::DIRECTIVE, mark);
|
||||
token.value = name;
|
||||
token.params = params;
|
||||
m_tokens.push(token);
|
||||
}
|
||||
|
||||
@@ -61,7 +62,6 @@ namespace YAML
|
||||
PopAllIndents();
|
||||
PopAllSimpleKeys();
|
||||
m_simpleKeyAllowed = false;
|
||||
m_canBeJSONFlow = false;
|
||||
|
||||
// eat
|
||||
Mark mark = INPUT.mark();
|
||||
@@ -75,7 +75,6 @@ namespace YAML
|
||||
PopAllIndents();
|
||||
PopAllSimpleKeys();
|
||||
m_simpleKeyAllowed = false;
|
||||
m_canBeJSONFlow = false;
|
||||
|
||||
// eat
|
||||
Mark mark = INPUT.mark();
|
||||
@@ -89,7 +88,6 @@ namespace YAML
|
||||
// flows can be simple keys
|
||||
InsertPotentialSimpleKey();
|
||||
m_simpleKeyAllowed = true;
|
||||
m_canBeJSONFlow = false;
|
||||
|
||||
// eat
|
||||
Mark mark = INPUT.mark();
|
||||
@@ -107,15 +105,10 @@ namespace YAML
|
||||
throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END);
|
||||
|
||||
// we might have a solo entry in the flow context
|
||||
if(InFlowContext()) {
|
||||
if(m_flows.top() == FLOW_MAP && VerifySimpleKey())
|
||||
m_tokens.push(Token(Token::VALUE, INPUT.mark()));
|
||||
else if(m_flows.top() == FLOW_SEQ)
|
||||
InvalidateSimpleKey();
|
||||
}
|
||||
if(VerifySimpleKey())
|
||||
m_tokens.push(Token(Token::VALUE, INPUT.mark()));
|
||||
|
||||
m_simpleKeyAllowed = false;
|
||||
m_canBeJSONFlow = true;
|
||||
|
||||
// eat
|
||||
Mark mark = INPUT.mark();
|
||||
@@ -134,16 +127,11 @@ namespace YAML
|
||||
// FlowEntry
|
||||
void Scanner::ScanFlowEntry()
|
||||
{
|
||||
// we might have a solo entry in the flow context
|
||||
if(InFlowContext()) {
|
||||
if(m_flows.top() == FLOW_MAP && VerifySimpleKey())
|
||||
m_tokens.push(Token(Token::VALUE, INPUT.mark()));
|
||||
else if(m_flows.top() == FLOW_SEQ)
|
||||
InvalidateSimpleKey();
|
||||
}
|
||||
// we might have a solo entry in the flow context
|
||||
if(VerifySimpleKey())
|
||||
m_tokens.push(Token(Token::VALUE, INPUT.mark()));
|
||||
|
||||
m_simpleKeyAllowed = true;
|
||||
m_canBeJSONFlow = false;
|
||||
|
||||
// eat
|
||||
Mark mark = INPUT.mark();
|
||||
@@ -164,7 +152,6 @@ namespace YAML
|
||||
|
||||
PushIndentTo(INPUT.column(), IndentMarker::SEQ);
|
||||
m_simpleKeyAllowed = true;
|
||||
m_canBeJSONFlow = false;
|
||||
|
||||
// eat
|
||||
Mark mark = INPUT.mark();
|
||||
@@ -197,7 +184,6 @@ namespace YAML
|
||||
{
|
||||
// and check that simple key
|
||||
bool isSimpleKey = VerifySimpleKey();
|
||||
m_canBeJSONFlow = false;
|
||||
|
||||
if(isSimpleKey) {
|
||||
// can't follow a simple key with another simple key (dunno why, though - it seems fine)
|
||||
@@ -230,7 +216,6 @@ namespace YAML
|
||||
// insert a potential simple key
|
||||
InsertPotentialSimpleKey();
|
||||
m_simpleKeyAllowed = false;
|
||||
m_canBeJSONFlow = false;
|
||||
|
||||
// eat the indicator
|
||||
Mark mark = INPUT.mark();
|
||||
@@ -238,7 +223,7 @@ namespace YAML
|
||||
alias = (indicator == Keys::Alias);
|
||||
|
||||
// now eat the content
|
||||
while(Exp::AlphaNumeric().Matches(INPUT))
|
||||
while(Exp::AlphaNumeric.Matches(INPUT))
|
||||
name += INPUT.get();
|
||||
|
||||
// we need to have read SOMETHING!
|
||||
@@ -246,7 +231,7 @@ namespace YAML
|
||||
throw ParserException(INPUT.mark(), alias ? ErrorMsg::ALIAS_NOT_FOUND : ErrorMsg::ANCHOR_NOT_FOUND);
|
||||
|
||||
// and needs to end correctly
|
||||
if(INPUT && !Exp::AnchorEnd().Matches(INPUT))
|
||||
if(INPUT && !Exp::AnchorEnd.Matches(INPUT))
|
||||
throw ParserException(INPUT.mark(), alias ? ErrorMsg::CHAR_IN_ALIAS : ErrorMsg::CHAR_IN_ANCHOR);
|
||||
|
||||
// and we're done
|
||||
@@ -258,40 +243,37 @@ namespace YAML
|
||||
// Tag
|
||||
void Scanner::ScanTag()
|
||||
{
|
||||
std::string handle, suffix;
|
||||
|
||||
// insert a potential simple key
|
||||
InsertPotentialSimpleKey();
|
||||
m_simpleKeyAllowed = false;
|
||||
m_canBeJSONFlow = false;
|
||||
|
||||
Token token(Token::TAG, INPUT.mark());
|
||||
|
||||
// eat the indicator
|
||||
INPUT.get();
|
||||
|
||||
if(INPUT && INPUT.peek() == Keys::VerbatimTagStart){
|
||||
std::string tag = ScanVerbatimTag(INPUT);
|
||||
Mark mark = INPUT.mark();
|
||||
handle += INPUT.get();
|
||||
|
||||
token.value = tag;
|
||||
token.data = Tag::VERBATIM;
|
||||
// read the handle
|
||||
while(INPUT && INPUT.peek() != Keys::Tag && !Exp::BlankOrBreak.Matches(INPUT))
|
||||
handle += INPUT.get();
|
||||
|
||||
// is there a suffix?
|
||||
if(INPUT.peek() == Keys::Tag) {
|
||||
// eat the indicator
|
||||
handle += INPUT.get();
|
||||
|
||||
// then read it
|
||||
while(INPUT && !Exp::BlankOrBreak.Matches(INPUT))
|
||||
suffix += INPUT.get();
|
||||
} else {
|
||||
bool canBeHandle;
|
||||
token.value = ScanTagHandle(INPUT, canBeHandle);
|
||||
if(!canBeHandle && token.value.empty())
|
||||
token.data = Tag::NON_SPECIFIC;
|
||||
else if(token.value.empty())
|
||||
token.data = Tag::SECONDARY_HANDLE;
|
||||
else
|
||||
token.data = Tag::PRIMARY_HANDLE;
|
||||
|
||||
// is there a suffix?
|
||||
if(canBeHandle && INPUT.peek() == Keys::Tag) {
|
||||
// eat the indicator
|
||||
INPUT.get();
|
||||
token.params.push_back(ScanTagSuffix(INPUT));
|
||||
token.data = Tag::NAMED_HANDLE;
|
||||
}
|
||||
// this is a bit weird: we keep just the '!' as the handle and move the rest to the suffix
|
||||
suffix = handle.substr(1);
|
||||
handle = "!";
|
||||
}
|
||||
|
||||
Token token(Token::TAG, mark);
|
||||
token.value = handle;
|
||||
token.params.push_back(suffix);
|
||||
m_tokens.push(token);
|
||||
}
|
||||
|
||||
@@ -302,7 +284,7 @@ namespace YAML
|
||||
|
||||
// set up the scanning parameters
|
||||
ScanScalarParams params;
|
||||
params.end = (InFlowContext() ? Exp::EndScalarInFlow() : Exp::EndScalar()) || (Exp::BlankOrBreak() + Exp::Comment());
|
||||
params.end = (InFlowContext() ? Exp::EndScalarInFlow : Exp::EndScalar) || (Exp::BlankOrBreak + Exp::Comment);
|
||||
params.eatEnd = false;
|
||||
params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1);
|
||||
params.fold = FOLD_FLOW;
|
||||
@@ -320,7 +302,6 @@ namespace YAML
|
||||
|
||||
// can have a simple key only if we ended the scalar by starting a new line
|
||||
m_simpleKeyAllowed = params.leadingSpaces;
|
||||
m_canBeJSONFlow = false;
|
||||
|
||||
// finally, check and see if we ended on an illegal character
|
||||
//if(Exp::IllegalCharInScalar.Matches(INPUT))
|
||||
@@ -328,7 +309,6 @@ namespace YAML
|
||||
|
||||
Token token(Token::SCALAR, mark);
|
||||
token.value = scalar;
|
||||
token.params.push_back(Token::PLAIN_SCALAR);
|
||||
m_tokens.push(token);
|
||||
}
|
||||
|
||||
@@ -343,7 +323,7 @@ namespace YAML
|
||||
|
||||
// setup the scanning parameters
|
||||
ScanScalarParams params;
|
||||
params.end = (single ? RegEx(quote) && !Exp::EscSingleQuote() : RegEx(quote));
|
||||
params.end = (single ? RegEx(quote) && !Exp::EscSingleQuote : RegEx(quote));
|
||||
params.eatEnd = true;
|
||||
params.escape = (single ? '\'' : '\\');
|
||||
params.indent = 0;
|
||||
@@ -364,7 +344,6 @@ namespace YAML
|
||||
// and scan
|
||||
scalar = ScanScalar(INPUT, params);
|
||||
m_simpleKeyAllowed = false;
|
||||
m_canBeJSONFlow = true;
|
||||
|
||||
Token token(Token::SCALAR, mark);
|
||||
token.value = scalar;
|
||||
@@ -390,14 +369,14 @@ namespace YAML
|
||||
|
||||
// eat chomping/indentation indicators
|
||||
params.chomp = CLIP;
|
||||
int n = Exp::Chomp().Match(INPUT);
|
||||
int n = Exp::Chomp.Match(INPUT);
|
||||
for(int i=0;i<n;i++) {
|
||||
char ch = INPUT.get();
|
||||
if(ch == '+')
|
||||
params.chomp = KEEP;
|
||||
else if(ch == '-')
|
||||
params.chomp = STRIP;
|
||||
else if(Exp::Digit().Matches(ch)) {
|
||||
else if(Exp::Digit.Matches(ch)) {
|
||||
if(ch == '0')
|
||||
throw ParserException(INPUT.mark(), ErrorMsg::ZERO_INDENT_IN_BLOCK);
|
||||
|
||||
@@ -407,16 +386,16 @@ namespace YAML
|
||||
}
|
||||
|
||||
// now eat whitespace
|
||||
while(Exp::Blank().Matches(INPUT))
|
||||
while(Exp::Blank.Matches(INPUT))
|
||||
INPUT.eat(1);
|
||||
|
||||
// and comments to the end of the line
|
||||
if(Exp::Comment().Matches(INPUT))
|
||||
while(INPUT && !Exp::Break().Matches(INPUT))
|
||||
if(Exp::Comment.Matches(INPUT))
|
||||
while(INPUT && !Exp::Break.Matches(INPUT))
|
||||
INPUT.eat(1);
|
||||
|
||||
// if it's not a line break, then we ran into a bad character inline
|
||||
if(INPUT && !Exp::Break().Matches(INPUT))
|
||||
if(INPUT && !Exp::Break.Matches(INPUT))
|
||||
throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_BLOCK);
|
||||
|
||||
// set the initial indentation
|
||||
@@ -431,7 +410,6 @@ namespace YAML
|
||||
|
||||
// simple keys always ok after block scalars (since we're gonna start a new line anyways)
|
||||
m_simpleKeyAllowed = true;
|
||||
m_canBeJSONFlow = false;
|
||||
|
||||
Token token(Token::SCALAR, mark);
|
||||
token.value = scalar;
|
||||
|
||||
+89
-8
@@ -1,6 +1,9 @@
|
||||
#include "crt.h"
|
||||
#include "sequence.h"
|
||||
#include "eventhandler.h"
|
||||
#include "node.h"
|
||||
#include "scanner.h"
|
||||
#include "token.h"
|
||||
#include "emitter.h"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace YAML
|
||||
@@ -10,6 +13,12 @@ namespace YAML
|
||||
|
||||
}
|
||||
|
||||
Sequence::Sequence(const std::vector<Node *>& data)
|
||||
{
|
||||
for(std::size_t i=0;i<data.size();i++)
|
||||
m_data.push_back(data[i]->Clone().release());
|
||||
}
|
||||
|
||||
Sequence::~Sequence()
|
||||
{
|
||||
Clear();
|
||||
@@ -22,6 +31,11 @@ namespace YAML
|
||||
m_data.clear();
|
||||
}
|
||||
|
||||
Content *Sequence::Clone() const
|
||||
{
|
||||
return new Sequence(m_data);
|
||||
}
|
||||
|
||||
bool Sequence::GetBegin(std::vector <Node *>::const_iterator& it) const
|
||||
{
|
||||
it = m_data.begin();
|
||||
@@ -46,17 +60,84 @@ namespace YAML
|
||||
return m_data.size();
|
||||
}
|
||||
|
||||
void Sequence::Append(std::auto_ptr<Node> pNode)
|
||||
void Sequence::Parse(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
m_data.push_back(pNode.release());
|
||||
Clear();
|
||||
|
||||
// split based on start token
|
||||
switch(pScanner->peek().type) {
|
||||
case Token::BLOCK_SEQ_START: ParseBlock(pScanner, state); break;
|
||||
case Token::FLOW_SEQ_START: ParseFlow(pScanner, state); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void Sequence::EmitEvents(AliasManager& am, EventHandler& eventHandler, const Mark& mark, const std::string& tag, anchor_t anchor) const
|
||||
|
||||
void Sequence::ParseBlock(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
eventHandler.OnSequenceStart(mark, tag, anchor);
|
||||
// eat start token
|
||||
pScanner->pop();
|
||||
|
||||
while(1) {
|
||||
if(pScanner->empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ);
|
||||
|
||||
Token token = pScanner->peek();
|
||||
if(token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
|
||||
throw ParserException(token.mark, ErrorMsg::END_OF_SEQ);
|
||||
|
||||
pScanner->pop();
|
||||
if(token.type == Token::BLOCK_SEQ_END)
|
||||
break;
|
||||
|
||||
Node *pNode = new Node;
|
||||
m_data.push_back(pNode);
|
||||
|
||||
// check for null
|
||||
if(!pScanner->empty()) {
|
||||
const Token& token = pScanner->peek();
|
||||
if(token.type == Token::BLOCK_ENTRY || token.type == Token::BLOCK_SEQ_END)
|
||||
continue;
|
||||
}
|
||||
|
||||
pNode->Parse(pScanner, state);
|
||||
}
|
||||
}
|
||||
|
||||
void Sequence::ParseFlow(Scanner *pScanner, const ParserState& state)
|
||||
{
|
||||
// eat start token
|
||||
pScanner->pop();
|
||||
|
||||
while(1) {
|
||||
if(pScanner->empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ_FLOW);
|
||||
|
||||
// first check for end
|
||||
if(pScanner->peek().type == Token::FLOW_SEQ_END) {
|
||||
pScanner->pop();
|
||||
break;
|
||||
}
|
||||
|
||||
// then read the node
|
||||
Node *pNode = new Node;
|
||||
m_data.push_back(pNode);
|
||||
pNode->Parse(pScanner, state);
|
||||
|
||||
// now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node)
|
||||
Token& token = pScanner->peek();
|
||||
if(token.type == Token::FLOW_ENTRY)
|
||||
pScanner->pop();
|
||||
else if(token.type != Token::FLOW_SEQ_END)
|
||||
throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW);
|
||||
}
|
||||
}
|
||||
|
||||
void Sequence::Write(Emitter& out) const
|
||||
{
|
||||
out << BeginSeq;
|
||||
for(std::size_t i=0;i<m_data.size();i++)
|
||||
m_data[i]->EmitEvents(am, eventHandler);
|
||||
eventHandler.OnSequenceEnd();
|
||||
out << *m_data[i];
|
||||
out << EndSeq;
|
||||
}
|
||||
|
||||
int Sequence::Compare(Content *pContent)
|
||||
|
||||
+8
-2
@@ -15,17 +15,19 @@ namespace YAML
|
||||
{
|
||||
public:
|
||||
Sequence();
|
||||
Sequence(const std::vector<Node *>& data);
|
||||
virtual ~Sequence();
|
||||
|
||||
void Clear();
|
||||
virtual Content *Clone() const;
|
||||
|
||||
virtual bool GetBegin(std::vector <Node *>::const_iterator& it) const;
|
||||
virtual bool GetEnd(std::vector <Node *>::const_iterator& it) const;
|
||||
virtual Node *GetNode(std::size_t i) const;
|
||||
virtual std::size_t GetSize() const;
|
||||
|
||||
virtual void Append(std::auto_ptr<Node> pNode);
|
||||
virtual void EmitEvents(AliasManager& am, EventHandler& eventHandler, const Mark& mark, const std::string& tag, anchor_t anchor) const;
|
||||
virtual void Parse(Scanner *pScanner, const ParserState& state);
|
||||
virtual void Write(Emitter& out) const;
|
||||
|
||||
virtual bool IsSequence() const { return true; }
|
||||
|
||||
@@ -35,6 +37,10 @@ namespace YAML
|
||||
virtual int Compare(Sequence *pSeq);
|
||||
virtual int Compare(Map *) { return -1; }
|
||||
|
||||
private:
|
||||
void ParseBlock(Scanner *pScanner, const ParserState& state);
|
||||
void ParseFlow(Scanner *pScanner, const ParserState& state);
|
||||
|
||||
protected:
|
||||
std::vector <Node *> m_data;
|
||||
};
|
||||
|
||||
+13
-14
@@ -1,3 +1,4 @@
|
||||
#include "crt.h"
|
||||
#include "scanner.h"
|
||||
#include "token.h"
|
||||
#include "exceptions.h"
|
||||
@@ -12,11 +13,9 @@ namespace YAML
|
||||
|
||||
void Scanner::SimpleKey::Validate()
|
||||
{
|
||||
// Note: pIndent will *not* be garbage here;
|
||||
// we "garbage collect" them so we can
|
||||
// always refer to them
|
||||
// Note: pIndent will *not* be garbage here; see below
|
||||
if(pIndent)
|
||||
pIndent->status = IndentMarker::VALID;
|
||||
pIndent->isValid = true;
|
||||
if(pMapStart)
|
||||
pMapStart->status = Token::VALID;
|
||||
if(pKey)
|
||||
@@ -25,8 +24,8 @@ namespace YAML
|
||||
|
||||
void Scanner::SimpleKey::Invalidate()
|
||||
{
|
||||
if(pIndent)
|
||||
pIndent->status = IndentMarker::INVALID;
|
||||
// Note: pIndent might be a garbage pointer here, but that's ok
|
||||
// An indent will only be popped if the simple key is invalid
|
||||
if(pMapStart)
|
||||
pMapStart->status = Token::INVALID;
|
||||
if(pKey)
|
||||
@@ -38,6 +37,9 @@ namespace YAML
|
||||
{
|
||||
if(!m_simpleKeyAllowed)
|
||||
return false;
|
||||
|
||||
if(InFlowContext() && m_flows.top() != FLOW_MAP)
|
||||
return false;
|
||||
|
||||
return !ExistsActiveSimpleKey();
|
||||
}
|
||||
@@ -65,13 +67,11 @@ namespace YAML
|
||||
SimpleKey key(INPUT.mark(), GetFlowLevel());
|
||||
|
||||
// first add a map start, if necessary
|
||||
if(InBlockContext()) {
|
||||
key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP);
|
||||
if(key.pIndent) {
|
||||
key.pIndent->status = IndentMarker::UNKNOWN;
|
||||
key.pMapStart = key.pIndent->pStartToken;
|
||||
key.pMapStart->status = Token::UNVERIFIED;
|
||||
}
|
||||
key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP);
|
||||
if(key.pIndent) {
|
||||
key.pIndent->isValid = false;
|
||||
key.pMapStart = key.pIndent->pStartToken;
|
||||
key.pMapStart->status = Token::UNVERIFIED;
|
||||
}
|
||||
|
||||
// then add the (now unverified) key
|
||||
@@ -136,4 +136,3 @@ namespace YAML
|
||||
m_simpleKeys.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,381 +0,0 @@
|
||||
#include "singledocparser.h"
|
||||
#include "collectionstack.h"
|
||||
#include "directives.h"
|
||||
#include "eventhandler.h"
|
||||
#include "exceptions.h"
|
||||
#include "scanner.h"
|
||||
#include "tag.h"
|
||||
#include "token.h"
|
||||
#include <sstream>
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives): m_scanner(scanner), m_directives(directives), m_pCollectionStack(new CollectionStack), m_curAnchor(0)
|
||||
{
|
||||
}
|
||||
|
||||
SingleDocParser::~SingleDocParser()
|
||||
{
|
||||
}
|
||||
|
||||
// HandleDocument
|
||||
// . Handles the next document
|
||||
// . Throws a ParserException on error.
|
||||
void SingleDocParser::HandleDocument(EventHandler& eventHandler)
|
||||
{
|
||||
assert(!m_scanner.empty()); // guaranteed that there are tokens
|
||||
assert(!m_curAnchor);
|
||||
|
||||
eventHandler.OnDocumentStart(m_scanner.peek().mark);
|
||||
|
||||
// eat doc start
|
||||
if(m_scanner.peek().type == Token::DOC_START)
|
||||
m_scanner.pop();
|
||||
|
||||
// recurse!
|
||||
HandleNode(eventHandler);
|
||||
|
||||
eventHandler.OnDocumentEnd();
|
||||
|
||||
// and finally eat any doc ends we see
|
||||
while(!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END)
|
||||
m_scanner.pop();
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleNode(EventHandler& eventHandler)
|
||||
{
|
||||
// an empty node *is* a possibility
|
||||
if(m_scanner.empty()) {
|
||||
eventHandler.OnNull("", NullAnchor);
|
||||
return;
|
||||
}
|
||||
|
||||
// save location
|
||||
Mark mark = m_scanner.peek().mark;
|
||||
|
||||
// special case: a value node by itself must be a map, with no header
|
||||
if(m_scanner.peek().type == Token::VALUE) {
|
||||
eventHandler.OnMapStart(mark, "", NullAnchor);
|
||||
HandleMap(eventHandler);
|
||||
eventHandler.OnMapEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
// special case: an alias node
|
||||
if(m_scanner.peek().type == Token::ALIAS) {
|
||||
eventHandler.OnAlias(mark, LookupAnchor(mark, m_scanner.peek().value));
|
||||
m_scanner.pop();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string tag;
|
||||
anchor_t anchor;
|
||||
ParseProperties(tag, anchor);
|
||||
|
||||
if (tag.empty()) {
|
||||
const Token& token = m_scanner.peek();
|
||||
const std::vector<std::string>& tparams = token.params;
|
||||
if (token.type != Token::SCALAR ||
|
||||
std::find(tparams.begin(), tparams.end(), Token::PLAIN_SCALAR) != tparams.end()) {
|
||||
tag = "?";
|
||||
} else {
|
||||
tag = "!";
|
||||
}
|
||||
}
|
||||
|
||||
// now split based on what kind of node we should be
|
||||
switch(m_scanner.peek().type) {
|
||||
case Token::SCALAR:
|
||||
eventHandler.OnScalar(mark, tag, anchor, m_scanner.peek().value);
|
||||
m_scanner.pop();
|
||||
return;
|
||||
case Token::FLOW_SEQ_START:
|
||||
case Token::BLOCK_SEQ_START:
|
||||
eventHandler.OnSequenceStart(mark, tag, anchor);
|
||||
HandleSequence(eventHandler);
|
||||
eventHandler.OnSequenceEnd();
|
||||
return;
|
||||
case Token::FLOW_MAP_START:
|
||||
case Token::BLOCK_MAP_START:
|
||||
eventHandler.OnMapStart(mark, tag, anchor);
|
||||
HandleMap(eventHandler);
|
||||
eventHandler.OnMapEnd();
|
||||
return;
|
||||
case Token::KEY:
|
||||
// compact maps can only go in a flow sequence
|
||||
if(m_pCollectionStack->GetCurCollectionType() == CollectionType::FlowSeq) {
|
||||
eventHandler.OnMapStart(mark, tag, anchor);
|
||||
HandleMap(eventHandler);
|
||||
eventHandler.OnMapEnd();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
eventHandler.OnNull(tag, anchor);
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleSequence(EventHandler& eventHandler)
|
||||
{
|
||||
// split based on start token
|
||||
switch(m_scanner.peek().type) {
|
||||
case Token::BLOCK_SEQ_START: HandleBlockSequence(eventHandler); break;
|
||||
case Token::FLOW_SEQ_START: HandleFlowSequence(eventHandler); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler)
|
||||
{
|
||||
// eat start token
|
||||
m_scanner.pop();
|
||||
m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq);
|
||||
|
||||
while(1) {
|
||||
if(m_scanner.empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ);
|
||||
|
||||
Token token = m_scanner.peek();
|
||||
if(token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
|
||||
throw ParserException(token.mark, ErrorMsg::END_OF_SEQ);
|
||||
|
||||
m_scanner.pop();
|
||||
if(token.type == Token::BLOCK_SEQ_END)
|
||||
break;
|
||||
|
||||
// check for null
|
||||
if(!m_scanner.empty()) {
|
||||
const Token& token = m_scanner.peek();
|
||||
if(token.type == Token::BLOCK_ENTRY || token.type == Token::BLOCK_SEQ_END) {
|
||||
eventHandler.OnNull("", NullAnchor);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
HandleNode(eventHandler);
|
||||
}
|
||||
|
||||
m_pCollectionStack->PopCollectionType(CollectionType::BlockSeq);
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler)
|
||||
{
|
||||
// eat start token
|
||||
m_scanner.pop();
|
||||
m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq);
|
||||
|
||||
while(1) {
|
||||
if(m_scanner.empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_SEQ_FLOW);
|
||||
|
||||
// first check for end
|
||||
if(m_scanner.peek().type == Token::FLOW_SEQ_END) {
|
||||
m_scanner.pop();
|
||||
break;
|
||||
}
|
||||
|
||||
// then read the node
|
||||
HandleNode(eventHandler);
|
||||
|
||||
// now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node)
|
||||
Token& token = m_scanner.peek();
|
||||
if(token.type == Token::FLOW_ENTRY)
|
||||
m_scanner.pop();
|
||||
else if(token.type != Token::FLOW_SEQ_END)
|
||||
throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW);
|
||||
}
|
||||
|
||||
m_pCollectionStack->PopCollectionType(CollectionType::FlowSeq);
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleMap(EventHandler& eventHandler)
|
||||
{
|
||||
// split based on start token
|
||||
switch(m_scanner.peek().type) {
|
||||
case Token::BLOCK_MAP_START: HandleBlockMap(eventHandler); break;
|
||||
case Token::FLOW_MAP_START: HandleFlowMap(eventHandler); break;
|
||||
case Token::KEY: HandleCompactMap(eventHandler); break;
|
||||
case Token::VALUE: HandleCompactMapWithNoKey(eventHandler); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleBlockMap(EventHandler& eventHandler)
|
||||
{
|
||||
// eat start token
|
||||
m_scanner.pop();
|
||||
m_pCollectionStack->PushCollectionType(CollectionType::BlockMap);
|
||||
|
||||
while(1) {
|
||||
if(m_scanner.empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP);
|
||||
|
||||
Token token = m_scanner.peek();
|
||||
if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END)
|
||||
throw ParserException(token.mark, ErrorMsg::END_OF_MAP);
|
||||
|
||||
if(token.type == Token::BLOCK_MAP_END) {
|
||||
m_scanner.pop();
|
||||
break;
|
||||
}
|
||||
|
||||
// grab key (if non-null)
|
||||
if(token.type == Token::KEY) {
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
} else {
|
||||
eventHandler.OnNull("", NullAnchor);
|
||||
}
|
||||
|
||||
// now grab value (optional)
|
||||
if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
} else {
|
||||
eventHandler.OnNull("", NullAnchor);
|
||||
}
|
||||
}
|
||||
|
||||
m_pCollectionStack->PopCollectionType(CollectionType::BlockMap);
|
||||
}
|
||||
|
||||
void SingleDocParser::HandleFlowMap(EventHandler& eventHandler)
|
||||
{
|
||||
// eat start token
|
||||
m_scanner.pop();
|
||||
m_pCollectionStack->PushCollectionType(CollectionType::FlowMap);
|
||||
|
||||
while(1) {
|
||||
if(m_scanner.empty())
|
||||
throw ParserException(Mark::null(), ErrorMsg::END_OF_MAP_FLOW);
|
||||
|
||||
Token& token = m_scanner.peek();
|
||||
// first check for end
|
||||
if(token.type == Token::FLOW_MAP_END) {
|
||||
m_scanner.pop();
|
||||
break;
|
||||
}
|
||||
|
||||
// grab key (if non-null)
|
||||
if(token.type == Token::KEY) {
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
} else {
|
||||
eventHandler.OnNull("", NullAnchor);
|
||||
}
|
||||
|
||||
// now grab value (optional)
|
||||
if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
} else {
|
||||
eventHandler.OnNull("", NullAnchor);
|
||||
}
|
||||
|
||||
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node)
|
||||
Token& nextToken = m_scanner.peek();
|
||||
if(nextToken.type == Token::FLOW_ENTRY)
|
||||
m_scanner.pop();
|
||||
else if(nextToken.type != Token::FLOW_MAP_END)
|
||||
throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
|
||||
}
|
||||
|
||||
m_pCollectionStack->PopCollectionType(CollectionType::FlowMap);
|
||||
}
|
||||
|
||||
// . Single "key: value" pair in a flow sequence
|
||||
void SingleDocParser::HandleCompactMap(EventHandler& eventHandler)
|
||||
{
|
||||
m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
|
||||
|
||||
// grab key
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
|
||||
// now grab value (optional)
|
||||
if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
} else {
|
||||
eventHandler.OnNull("", NullAnchor);
|
||||
}
|
||||
|
||||
m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
|
||||
}
|
||||
|
||||
// . Single ": value" pair in a flow sequence
|
||||
void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler)
|
||||
{
|
||||
m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
|
||||
|
||||
// null key
|
||||
eventHandler.OnNull("", NullAnchor);
|
||||
|
||||
// grab value
|
||||
m_scanner.pop();
|
||||
HandleNode(eventHandler);
|
||||
|
||||
m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
|
||||
}
|
||||
|
||||
// ParseProperties
|
||||
// . Grabs any tag or anchor tokens and deals with them.
|
||||
void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor)
|
||||
{
|
||||
tag.clear();
|
||||
anchor = NullAnchor;
|
||||
|
||||
while(1) {
|
||||
if(m_scanner.empty())
|
||||
return;
|
||||
|
||||
switch(m_scanner.peek().type) {
|
||||
case Token::TAG: ParseTag(tag); break;
|
||||
case Token::ANCHOR: ParseAnchor(anchor); break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SingleDocParser::ParseTag(std::string& tag)
|
||||
{
|
||||
Token& token = m_scanner.peek();
|
||||
if(!tag.empty())
|
||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS);
|
||||
|
||||
Tag tagInfo(token);
|
||||
tag = tagInfo.Translate(m_directives);
|
||||
m_scanner.pop();
|
||||
}
|
||||
|
||||
void SingleDocParser::ParseAnchor(anchor_t& anchor)
|
||||
{
|
||||
Token& token = m_scanner.peek();
|
||||
if(anchor)
|
||||
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
|
||||
|
||||
anchor = RegisterAnchor(token.value);
|
||||
m_scanner.pop();
|
||||
}
|
||||
|
||||
anchor_t SingleDocParser::RegisterAnchor(const std::string& name)
|
||||
{
|
||||
if(name.empty())
|
||||
return NullAnchor;
|
||||
|
||||
return m_anchors[name] = ++m_curAnchor;
|
||||
}
|
||||
|
||||
anchor_t SingleDocParser::LookupAnchor(const Mark& mark, const std::string& name) const
|
||||
{
|
||||
Anchors::const_iterator it = m_anchors.find(name);
|
||||
if(it == m_anchors.end())
|
||||
throw ParserException(mark, ErrorMsg::UNKNOWN_ANCHOR);
|
||||
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
|
||||
#include "anchor.h"
|
||||
#include "noncopyable.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct Directives;
|
||||
struct Mark;
|
||||
struct Token;
|
||||
class CollectionStack;
|
||||
class EventHandler;
|
||||
class Node;
|
||||
class Scanner;
|
||||
|
||||
class SingleDocParser: private noncopyable
|
||||
{
|
||||
public:
|
||||
SingleDocParser(Scanner& scanner, const Directives& directives);
|
||||
~SingleDocParser();
|
||||
|
||||
void HandleDocument(EventHandler& eventHandler);
|
||||
|
||||
private:
|
||||
void HandleNode(EventHandler& eventHandler);
|
||||
|
||||
void HandleSequence(EventHandler& eventHandler);
|
||||
void HandleBlockSequence(EventHandler& eventHandler);
|
||||
void HandleFlowSequence(EventHandler& eventHandler);
|
||||
|
||||
void HandleMap(EventHandler& eventHandler);
|
||||
void HandleBlockMap(EventHandler& eventHandler);
|
||||
void HandleFlowMap(EventHandler& eventHandler);
|
||||
void HandleCompactMap(EventHandler& eventHandler);
|
||||
void HandleCompactMapWithNoKey(EventHandler& eventHandler);
|
||||
|
||||
void ParseProperties(std::string& tag, anchor_t& anchor);
|
||||
void ParseTag(std::string& tag);
|
||||
void ParseAnchor(anchor_t& anchor);
|
||||
|
||||
anchor_t RegisterAnchor(const std::string& name);
|
||||
anchor_t LookupAnchor(const Mark& mark, const std::string& name) const;
|
||||
|
||||
private:
|
||||
Scanner& m_scanner;
|
||||
const Directives& m_directives;
|
||||
std::auto_ptr<CollectionStack> m_pCollectionStack;
|
||||
|
||||
typedef std::map<std::string, anchor_t> Anchors;
|
||||
Anchors m_anchors;
|
||||
|
||||
anchor_t m_curAnchor;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "crt.h"
|
||||
#include "stream.h"
|
||||
#include <iostream>
|
||||
#include "exp.h"
|
||||
|
||||
@@ -30,11 +30,6 @@ namespace YAML
|
||||
++m_offset;
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringCharSource& operator += (std::size_t offset) {
|
||||
m_offset += offset;
|
||||
return *this;
|
||||
}
|
||||
private:
|
||||
const char *m_str;
|
||||
std::size_t m_size;
|
||||
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
#include "tag.h"
|
||||
#include "directives.h"
|
||||
#include "token.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
Tag::Tag(const Token& token): type(static_cast<TYPE>(token.data))
|
||||
{
|
||||
switch(type) {
|
||||
case VERBATIM:
|
||||
value = token.value;
|
||||
break;
|
||||
case PRIMARY_HANDLE:
|
||||
value = token.value;
|
||||
break;
|
||||
case SECONDARY_HANDLE:
|
||||
value = token.value;
|
||||
break;
|
||||
case NAMED_HANDLE:
|
||||
handle = token.value;
|
||||
value = token.params[0];
|
||||
break;
|
||||
case NON_SPECIFIC:
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
const std::string Tag::Translate(const Directives& directives)
|
||||
{
|
||||
switch(type) {
|
||||
case VERBATIM:
|
||||
return value;
|
||||
case PRIMARY_HANDLE:
|
||||
return directives.TranslateTagHandle("!") + value;
|
||||
case SECONDARY_HANDLE:
|
||||
return directives.TranslateTagHandle("!!") + value;
|
||||
case NAMED_HANDLE:
|
||||
return directives.TranslateTagHandle("!" + handle + "!") + value;
|
||||
case NON_SPECIFIC:
|
||||
// TODO:
|
||||
return "!";
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
#define TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
struct Token;
|
||||
struct Directives;
|
||||
|
||||
struct Tag {
|
||||
enum TYPE {
|
||||
VERBATIM, PRIMARY_HANDLE, SECONDARY_HANDLE, NAMED_HANDLE, NON_SPECIFIC
|
||||
};
|
||||
|
||||
Tag(const Token& token);
|
||||
const std::string Translate(const Directives& directives);
|
||||
|
||||
TYPE type;
|
||||
std::string handle, value;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
|
||||
@@ -1,6 +0,0 @@
|
||||
#include "token.h"
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
const std::string Token::PLAIN_SCALAR("pln");
|
||||
}
|
||||
+2
-7
@@ -5,7 +5,7 @@
|
||||
|
||||
|
||||
#include "mark.h"
|
||||
#include <iostream>
|
||||
#include <ios>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -24,7 +24,6 @@ namespace YAML
|
||||
"FLOW_MAP_START",
|
||||
"FLOW_SEQ_END",
|
||||
"FLOW_MAP_END",
|
||||
"FLOW_MAP_COMPACT",
|
||||
"FLOW_ENTRY",
|
||||
"KEY",
|
||||
"VALUE",
|
||||
@@ -50,7 +49,6 @@ namespace YAML
|
||||
FLOW_MAP_START,
|
||||
FLOW_SEQ_END,
|
||||
FLOW_MAP_END,
|
||||
FLOW_MAP_COMPACT,
|
||||
FLOW_ENTRY,
|
||||
KEY,
|
||||
VALUE,
|
||||
@@ -59,11 +57,9 @@ namespace YAML
|
||||
TAG,
|
||||
SCALAR
|
||||
};
|
||||
|
||||
static const std::string PLAIN_SCALAR;
|
||||
|
||||
// data
|
||||
Token(TYPE type_, const Mark& mark_): status(VALID), type(type_), mark(mark_), data(0) {}
|
||||
Token(TYPE type_, const Mark& mark_): status(VALID), type(type_), mark(mark_) {}
|
||||
|
||||
friend std::ostream& operator << (std::ostream& out, const Token& token) {
|
||||
out << TokenNames[token.type] << std::string(": ") << token.value;
|
||||
@@ -77,7 +73,6 @@ namespace YAML
|
||||
Mark mark;
|
||||
std::string value;
|
||||
std::vector <std::string> params;
|
||||
int data;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
-226
@@ -1,226 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="test"
|
||||
ProjectGUID="{D1108F40-6ADF-467E-A95A-236C39A515C5}"
|
||||
RootNamespace="test"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D_SCL_SECURE_NO_WARNINGS"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="include"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
DisableSpecificWarnings="4127;4355"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="yamlcppd.lib"
|
||||
AdditionalLibraryDirectories="lib"
|
||||
GenerateDebugInformation="true"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D_SCL_SECURE_NO_WARNINGS"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="include"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4127;4355"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="yamlcpp.lib"
|
||||
AdditionalLibraryDirectories="lib"
|
||||
GenerateDebugInformation="true"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\test\emittertests.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\main.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\parsertests.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\spectests.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\tests.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\test\emittertests.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\parsertests.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\spectests.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\test\tests.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -1,10 +0,0 @@
|
||||
file(GLOB test_headers [a-z]*.h)
|
||||
file(GLOB test_sources [a-z]*.cpp)
|
||||
|
||||
add_executable(run-tests
|
||||
${test_sources}
|
||||
${test_headers}
|
||||
)
|
||||
target_link_libraries(run-tests yaml-cpp)
|
||||
|
||||
add_test(yaml-reader-test run-tests)
|
||||
@@ -1,7 +0,0 @@
|
||||
#include "tests.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
Test::RunAll();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,25 +1,9 @@
|
||||
#include "yaml.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
struct Params {
|
||||
bool hasFile;
|
||||
std::string fileName;
|
||||
};
|
||||
|
||||
Params ParseArgs(int argc, char **argv) {
|
||||
Params p;
|
||||
|
||||
std::vector<char*> args(argv + 1, argv + argc);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Params p = ParseArgs(argc, argv);
|
||||
|
||||
std::ifstream fin;
|
||||
if(argc > 1)
|
||||
fin.open(argv[1]);
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="parse"
|
||||
ProjectGUID="{CD007B57-7812-4930-A5E2-6E5E56338814}"
|
||||
RootNamespace="parse"
|
||||
Name="yaml-reader"
|
||||
ProjectGUID="{E8CC0D8A-D784-4A6B-B78B-ACEA13F9FB0B}"
|
||||
RootNamespace="yamlreader"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
@@ -39,15 +39,13 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D_SCL_SECURE_NO_WARNINGS"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="include"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
DisableSpecificWarnings="4127;4355"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
@@ -112,15 +110,13 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D_SCL_SECURE_NO_WARNINGS"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="include"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
WarningLevel="3"
|
||||
WarningLevel="4"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4127;4355"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
@@ -172,7 +168,23 @@
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\util\parse.cpp"
|
||||
RelativePath=".\yaml-reader\emittertests.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\yaml-reader\main.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\yaml-reader\parsertests.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\yaml-reader\spectests.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\yaml-reader\tests.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
@@ -181,12 +193,22 @@
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\yaml-reader\emittertests.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\yaml-reader\parsertests.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\yaml-reader\spectests.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\yaml-reader\tests.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
@@ -0,0 +1,10 @@
|
||||
file(GLOB yaml-reader_headers *.h)
|
||||
file(GLOB yaml-reader_sources *.cpp)
|
||||
|
||||
add_executable(yaml-reader
|
||||
${yaml-reader_sources}
|
||||
${yaml-reader_headers}
|
||||
)
|
||||
target_link_libraries(yaml-reader yaml-cpp)
|
||||
|
||||
add_test(yaml-reader-test yaml-reader)
|
||||
@@ -9,7 +9,7 @@ namespace Test
|
||||
|
||||
void SimpleScalar(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
out << "Hello, World!";
|
||||
desiredOutput = "--- Hello, World!";
|
||||
desiredOutput = "Hello, World!";
|
||||
}
|
||||
|
||||
void SimpleSeq(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -19,7 +19,7 @@ namespace Test
|
||||
out << "milk";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- eggs\n- bread\n- milk";
|
||||
desiredOutput = "- eggs\n- bread\n- milk";
|
||||
}
|
||||
|
||||
void SimpleFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -30,7 +30,7 @@ namespace Test
|
||||
out << "Moe";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "--- [Larry, Curly, Moe]";
|
||||
desiredOutput = "[Larry, Curly, Moe]";
|
||||
}
|
||||
|
||||
void EmptyFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -38,7 +38,7 @@ namespace Test
|
||||
out << YAML::BeginSeq;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "--- []";
|
||||
desiredOutput = "[]";
|
||||
}
|
||||
|
||||
void NestedBlockSeq(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -47,7 +47,7 @@ namespace Test
|
||||
out << YAML::BeginSeq << "subitem 1" << "subitem 2" << YAML::EndSeq;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- item 1\n-\n - subitem 1\n - subitem 2";
|
||||
desiredOutput = "- item 1\n-\n - subitem 1\n - subitem 2";
|
||||
}
|
||||
|
||||
void NestedFlowSeq(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -56,7 +56,7 @@ namespace Test
|
||||
out << YAML::Flow << YAML::BeginSeq << "two" << "three" << YAML::EndSeq;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- one\n- [two, three]";
|
||||
desiredOutput = "- one\n- [two, three]";
|
||||
}
|
||||
|
||||
void SimpleMap(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -67,7 +67,7 @@ namespace Test
|
||||
out << YAML::Value << "3B";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nname: Ryan Braun\nposition: 3B";
|
||||
desiredOutput = "name: Ryan Braun\nposition: 3B";
|
||||
}
|
||||
|
||||
void SimpleFlowMap(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -79,7 +79,7 @@ namespace Test
|
||||
out << YAML::Value << "blue";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "--- {shape: square, color: blue}";
|
||||
desiredOutput = "{shape: square, color: blue}";
|
||||
}
|
||||
|
||||
void MapAndList(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -90,7 +90,7 @@ namespace Test
|
||||
out << YAML::Value << YAML::BeginSeq << "Sasha" << "Malia" << YAML::EndSeq;
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nname: Barack Obama\nchildren:\n - Sasha\n - Malia";
|
||||
desiredOutput = "name: Barack Obama\nchildren:\n - Sasha\n - Malia";
|
||||
}
|
||||
|
||||
void ListAndMap(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -103,7 +103,7 @@ namespace Test
|
||||
out << "item 2";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- item 1\n-\n pens: 8\n pencils: 14\n- item 2";
|
||||
desiredOutput = "- item 1\n-\n pens: 8\n pencils: 14\n- item 2";
|
||||
}
|
||||
|
||||
void NestedBlockMap(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -119,7 +119,7 @@ namespace Test
|
||||
out << YAML::EndMap;
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nname: Fred\ngrades:\n algebra: A\n physics: C+\n literature: B";
|
||||
desiredOutput = "name: Fred\ngrades:\n algebra: A\n physics: C+\n literature: B";
|
||||
}
|
||||
|
||||
void NestedFlowMap(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -136,7 +136,7 @@ namespace Test
|
||||
out << YAML::EndMap;
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "--- {name: Fred, grades: {algebra: A, physics: C+, literature: B}}";
|
||||
desiredOutput = "{name: Fred, grades: {algebra: A, physics: C+, literature: B}}";
|
||||
}
|
||||
|
||||
void MapListMix(YAML::Emitter& out, std::string& desiredOutput) {
|
||||
@@ -149,7 +149,7 @@ namespace Test
|
||||
out << YAML::Key << "invincible" << YAML::Value << YAML::OnOffBool << false;
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nname: Bob\nposition: [2, 4]\ninvincible: off";
|
||||
desiredOutput = "name: Bob\nposition: [2, 4]\ninvincible: off";
|
||||
}
|
||||
|
||||
void SimpleLongKey(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -162,7 +162,7 @@ namespace Test
|
||||
out << YAML::Value << 145;
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n? height\n: 5'9\"\n? weight\n: 145";
|
||||
desiredOutput = "? height\n: 5'9\"\n? weight\n: 145";
|
||||
}
|
||||
|
||||
void SingleLongKey(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -176,7 +176,7 @@ namespace Test
|
||||
out << YAML::Value << 145;
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nage: 24\n? height\n: 5'9\"\nweight: 145";
|
||||
desiredOutput = "age: 24\n? height\n: 5'9\"\nweight: 145";
|
||||
}
|
||||
|
||||
void ComplexLongKey(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -189,7 +189,7 @@ namespace Test
|
||||
out << YAML::Value << "demon";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n?\n - 1\n - 3\n: monster\n? [2, 0]\n: demon";
|
||||
desiredOutput = "?\n - 1\n - 3\n: monster\n? [2, 0]\n: demon";
|
||||
}
|
||||
|
||||
void AutoLongKey(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -203,7 +203,7 @@ namespace Test
|
||||
out << YAML::Value << "angel";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n?\n - 1\n - 3\n: monster\n? [2, 0]\n: demon\nthe origin: angel";
|
||||
desiredOutput = "?\n - 1\n - 3\n: monster\n? [2, 0]\n: demon\nthe origin: angel";
|
||||
}
|
||||
|
||||
void ScalarFormat(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -217,7 +217,7 @@ namespace Test
|
||||
out << YAML::Literal << "literal scalar\nthat may span\nmany, many\nlines and have \"whatever\" crazy\tsymbols that we like";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- simple scalar\n- 'explicit single-quoted scalar'\n- \"explicit double-quoted scalar\"\n- \"auto-detected\\x0adouble-quoted scalar\"\n- a non-\"auto-detected\" double-quoted scalar\n- |\n literal scalar\n that may span\n many, many\n lines and have \"whatever\" crazy\tsymbols that we like";
|
||||
desiredOutput = "- simple scalar\n- 'explicit single-quoted scalar'\n- \"explicit double-quoted scalar\"\n- \"auto-detected\\x0adouble-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)
|
||||
@@ -227,7 +227,7 @@ namespace Test
|
||||
out << YAML::Value << "and its value";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n? |\n multi-line\n scalar\n: and its value";
|
||||
desiredOutput = "? |\n multi-line\n scalar\n: and its value";
|
||||
}
|
||||
|
||||
void LongKeyFlowMap(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -240,7 +240,7 @@ namespace Test
|
||||
out << YAML::Value << "and its value";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "--- {simple key: and value, ? long key: and its value}";
|
||||
desiredOutput = "{simple key: and value, ? long key: and its value}";
|
||||
}
|
||||
|
||||
void BlockMapAsKey(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -255,7 +255,7 @@ namespace Test
|
||||
out << "total value";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n?\n key: value\n next key: next value\n: total value";
|
||||
desiredOutput = "?\n key: value\n next key: next value\n: total value";
|
||||
}
|
||||
|
||||
void AliasAndAnchor(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -269,7 +269,7 @@ namespace Test
|
||||
out << YAML::Alias("fred");
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- &fred\n name: Fred\n age: 42\n- *fred";
|
||||
desiredOutput = "- &fred\n name: Fred\n age: 42\n- *fred";
|
||||
}
|
||||
|
||||
void AliasAndAnchorWithNull(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -279,123 +279,7 @@ namespace Test
|
||||
out << YAML::Alias("fred");
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- &fred ~\n- *fred";
|
||||
}
|
||||
|
||||
void SimpleVerbatimTag(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::VerbatimTag("!foo") << "bar";
|
||||
|
||||
desiredOutput = "--- !<!foo> bar";
|
||||
}
|
||||
|
||||
void VerbatimTagInBlockSeq(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::BeginSeq;
|
||||
out << YAML::VerbatimTag("!foo") << "bar";
|
||||
out << "baz";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- !<!foo> 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 = "--- [!<!foo> 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 = "--- [!<!foo> ~, 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 = "---\n!<!foo> bar: !<!waz> 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 = "--- {!<!foo> 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 = "--- {!<!foo> ~: baz}";
|
||||
}
|
||||
|
||||
void VerbatimTagWithEmptySeq(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::VerbatimTag("!foo") << YAML::BeginSeq << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "--- !<!foo>\n[]";
|
||||
}
|
||||
|
||||
void VerbatimTagWithEmptyMap(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
out << YAML::VerbatimTag("!bar") << YAML::BeginMap << YAML::EndMap;
|
||||
|
||||
desiredOutput = "--- !<!bar>\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- !<!foo>\n []\n- !<!bar>\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 = "---\n- \"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";
|
||||
desiredOutput = "- &fred ~\n- *fred";
|
||||
}
|
||||
|
||||
void ComplexDoc(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -451,7 +335,7 @@ namespace Test
|
||||
out << YAML::Value << YAML::Alias("id001");
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nreceipt: Oz-Ware Purchase Invoice\ndate: 2007-08-06\ncustomer:\n given: Dorothy\n family: Gale\nitems:\n -\n part_no: A4786\n descrip: Water Bucket (Filled)\n price: 1.47\n quantity: 4\n -\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";
|
||||
desiredOutput = "receipt: Oz-Ware Purchase Invoice\ndate: 2007-08-06\ncustomer:\n given: Dorothy\n family: Gale\nitems:\n -\n part_no: A4786\n descrip: Water Bucket (Filled)\n price: 1.47\n quantity: 4\n -\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)
|
||||
@@ -471,7 +355,7 @@ namespace Test
|
||||
out << ages;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- [2, 3, 5, 7, 11, 13]\n-\n Daniel: 26\n Jesse: 24";
|
||||
desiredOutput = "- [2, 3, 5, 7, 11, 13]\n-\n Daniel: 26\n Jesse: 24";
|
||||
}
|
||||
|
||||
void SimpleComment(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -481,7 +365,7 @@ namespace Test
|
||||
out << YAML::Value << "least squares" << YAML::Comment("should we change this method?");
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\nmethod: least squares # should we change this method?";
|
||||
desiredOutput = "method: least squares # should we change this method?";
|
||||
}
|
||||
|
||||
void MultiLineComment(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -491,7 +375,7 @@ namespace Test
|
||||
out << "item 2";
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- item 1 # really really long\n # comment that couldn't possibly\n # fit on one line\n- item 2";
|
||||
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)
|
||||
@@ -501,7 +385,7 @@ namespace Test
|
||||
out << YAML::Value << "value";
|
||||
out << YAML::EndMap;
|
||||
|
||||
desiredOutput = "---\n? long key # long key\n: value";
|
||||
desiredOutput = "? long key # long key\n: value";
|
||||
}
|
||||
|
||||
void Indentation(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -514,7 +398,7 @@ namespace Test
|
||||
out << YAML::EndMap;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n-\n key 1: value 1\n key 2:\n - a\n - b\n - c";
|
||||
desiredOutput = "-\n key 1: value 1\n key 2:\n - a\n - b\n - c";
|
||||
}
|
||||
|
||||
void SimpleGlobalSettings(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -529,7 +413,7 @@ namespace Test
|
||||
out << YAML::EndMap;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n-\n ? key 1\n : value 1\n ? key 2\n : [a, b, c]";
|
||||
desiredOutput = "-\n ? key 1\n : value 1\n ? key 2\n : [a, b, c]";
|
||||
}
|
||||
|
||||
void ComplexGlobalSettings(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -548,7 +432,7 @@ namespace Test
|
||||
out << YAML::EndMap;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n-\n key 1: value 1\n key 2: [a, b, c]\n-\n ? [1, 2]\n :\n a: b";
|
||||
desiredOutput = "-\n key 1: value 1\n key 2: [a, b, c]\n-\n ? [1, 2]\n :\n a: b";
|
||||
}
|
||||
|
||||
void Null(YAML::Emitter& out, std::string& desiredOutput)
|
||||
@@ -561,96 +445,28 @@ namespace Test
|
||||
out << YAML::EndMap;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- ~\n-\n null value: ~\n ~: null key";
|
||||
desiredOutput = "- ~\n-\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\"";
|
||||
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";
|
||||
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\"";
|
||||
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 = "---\n-\n x: 5\n bar: hello\n-\n x: 3\n bar: goodbye";
|
||||
}
|
||||
|
||||
void UserTypeInContainer(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
std::vector<Foo> fv;
|
||||
fv.push_back(Foo(5, "hello"));
|
||||
fv.push_back(Foo(3, "goodbye"));
|
||||
out << fv;
|
||||
|
||||
desiredOutput = "---\n-\n x: 5\n bar: hello\n-\n x: 3\n bar: goodbye";
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
YAML::Emitter& operator << (YAML::Emitter& out, const T *v) {
|
||||
if(v)
|
||||
out << *v;
|
||||
else
|
||||
out << YAML::Null;
|
||||
return out;
|
||||
}
|
||||
|
||||
void PointerToInt(YAML::Emitter& out, std::string& desiredOutput)
|
||||
{
|
||||
int foo = 5;
|
||||
int *bar = &foo;
|
||||
int *baz = 0;
|
||||
out << YAML::BeginSeq;
|
||||
out << bar << baz;
|
||||
out << YAML::EndSeq;
|
||||
|
||||
desiredOutput = "---\n- 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 = "---\n-\n x: 5\n bar: hello\n- ~";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// incorrect emitting
|
||||
@@ -804,18 +620,6 @@ namespace Test
|
||||
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::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);
|
||||
@@ -828,10 +632,6 @@ namespace Test
|
||||
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);
|
||||
|
||||
RunEmitterErrorTest(&Emitter::ExtraEndSeq, "extra EndSeq", passed, total);
|
||||
RunEmitterErrorTest(&Emitter::ExtraEndMap, "extra EndMap", passed, total);
|
||||
@@ -842,7 +642,6 @@ namespace Test
|
||||
RunEmitterErrorTest(&Emitter::MissingValue, "missing value", passed, total);
|
||||
RunEmitterErrorTest(&Emitter::UnexpectedKey, "unexpected key", passed, total);
|
||||
RunEmitterErrorTest(&Emitter::UnexpectedValue, "unexpected value", passed, total);
|
||||
RunEmitterErrorTest(&Emitter::BadLocalTag, "bad local tag", passed, total);
|
||||
|
||||
std::cout << "Emitter tests: " << passed << "/" << total << " passed\n";
|
||||
return passed == total;
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "tests.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef WINDOWS
|
||||
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF);
|
||||
#endif // WINDOWS
|
||||
Test::RunAll();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -118,7 +118,7 @@ namespace Test
|
||||
inputScalar = "http://example.com/foo#bar";
|
||||
desiredOutput = "http://example.com/foo#bar";
|
||||
}
|
||||
|
||||
|
||||
bool SimpleSeq()
|
||||
{
|
||||
std::string input =
|
||||
@@ -610,202 +610,6 @@ namespace Test
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BlockKeyWithNullValue()
|
||||
{
|
||||
std::string input =
|
||||
"key:\n"
|
||||
"just a key: value";
|
||||
|
||||
std::stringstream stream(input);
|
||||
YAML::Parser parser(stream);
|
||||
YAML::Node doc;
|
||||
|
||||
parser.GetNextDocument(doc);
|
||||
if(doc.size() != 2)
|
||||
return false;
|
||||
if(!IsNull(doc["key"]))
|
||||
return false;
|
||||
if(doc["just a key"] != "value")
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Bases()
|
||||
{
|
||||
std::string input =
|
||||
"- 15\n"
|
||||
"- 0x10\n"
|
||||
"- 030\n"
|
||||
"- 0xffffffff\n";
|
||||
|
||||
std::stringstream stream(input);
|
||||
YAML::Parser parser(stream);
|
||||
YAML::Node doc;
|
||||
|
||||
parser.GetNextDocument(doc);
|
||||
if(doc.size() != 4)
|
||||
return false;
|
||||
if(doc[0] != 15)
|
||||
return false;
|
||||
if(doc[1] != 0x10)
|
||||
return false;
|
||||
if(doc[2] != 030)
|
||||
return false;
|
||||
if(doc[3] != 0xffffffff)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KeyNotFound()
|
||||
{
|
||||
std::string input = "key: value";
|
||||
std::stringstream stream(input);
|
||||
YAML::Parser parser(stream);
|
||||
YAML::Node doc;
|
||||
parser.GetNextDocument(doc);
|
||||
|
||||
try {
|
||||
doc["bad key"];
|
||||
} catch(const YAML::Exception& e) {
|
||||
if(e.msg != YAML::ErrorMsg::KEY_NOT_FOUND + ": bad key")
|
||||
throw;
|
||||
}
|
||||
|
||||
try {
|
||||
doc[5];
|
||||
} catch(const YAML::Exception& e) {
|
||||
if(e.msg != YAML::ErrorMsg::KEY_NOT_FOUND + ": 5")
|
||||
throw;
|
||||
}
|
||||
|
||||
try {
|
||||
doc[2.5];
|
||||
} catch(const YAML::Exception& e) {
|
||||
if(e.msg != YAML::ErrorMsg::KEY_NOT_FOUND + ": 2.5")
|
||||
throw;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DuplicateKey()
|
||||
{
|
||||
std::string input = "{a: 1, b: 2, c: 3, a: 4}";
|
||||
std::stringstream stream(input);
|
||||
YAML::Parser parser(stream);
|
||||
YAML::Node doc;
|
||||
parser.GetNextDocument(doc);
|
||||
|
||||
if(doc["a"] != 1)
|
||||
return false;
|
||||
if(doc["b"] != 2)
|
||||
return false;
|
||||
if(doc["c"] != 3)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PrepareNodeForTagExam(YAML::Node& doc, const std::string& input)
|
||||
{
|
||||
std::stringstream stream(input);
|
||||
YAML::Parser parser(stream);
|
||||
parser.GetNextDocument(doc);
|
||||
}
|
||||
|
||||
struct TagMismatch: public std::exception {
|
||||
TagMismatch(const std::string& actualTag, const std::string& expectedTag) {
|
||||
std::stringstream output;
|
||||
output << "Tag has value \"" << actualTag << "\" but \"" << expectedTag << "\" was expected";
|
||||
what_ = output.str();
|
||||
}
|
||||
virtual ~TagMismatch() throw() {}
|
||||
virtual const char *what() const throw() { return what_.c_str(); }
|
||||
|
||||
private:
|
||||
std::string what_;
|
||||
};
|
||||
|
||||
bool ExpectedTagValue(YAML::Node& node, const char* tag)
|
||||
{
|
||||
if(node.GetTag() == tag)
|
||||
return true;
|
||||
|
||||
throw TagMismatch(node.GetTag(), tag);
|
||||
}
|
||||
|
||||
bool DefaultPlainScalarTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- 12");
|
||||
|
||||
return ExpectedTagValue(node, "?");
|
||||
}
|
||||
|
||||
bool DefaultSingleQuotedScalarTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- '12'");
|
||||
|
||||
return ExpectedTagValue(node, "!");
|
||||
}
|
||||
|
||||
bool ExplicitNonSpecificPlainScalarTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- ! 12");
|
||||
|
||||
return ExpectedTagValue(node, "!");
|
||||
}
|
||||
|
||||
bool BasicLocalTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- !foo 12");
|
||||
|
||||
return ExpectedTagValue(node, "!foo");
|
||||
}
|
||||
|
||||
bool VerbatimLocalTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- !<!foo> 12");
|
||||
|
||||
return ExpectedTagValue(node, "!foo");
|
||||
}
|
||||
|
||||
bool StandardShortcutTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- !!int 12");
|
||||
|
||||
return ExpectedTagValue(node, "tag:yaml.org,2002:int");
|
||||
}
|
||||
|
||||
bool VerbatimURITag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- !<tag:yaml.org,2002:int> 12");
|
||||
|
||||
return ExpectedTagValue(node, "tag:yaml.org,2002:int");
|
||||
}
|
||||
|
||||
bool DefaultSequenceTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- [12]");
|
||||
|
||||
return ExpectedTagValue(node, "?");
|
||||
}
|
||||
|
||||
bool ExplicitNonSpecificSequenceTag()
|
||||
{
|
||||
YAML::Node node;
|
||||
PrepareNodeForTagExam(node, "--- ! [12]");
|
||||
|
||||
return ExpectedTagValue(node, "!");
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -823,7 +627,7 @@ namespace Test
|
||||
doc >> output;
|
||||
} catch(const YAML::Exception& e) {
|
||||
ok = false;
|
||||
error = e.what();
|
||||
error = e.msg;
|
||||
}
|
||||
if(ok && output == desiredOutput) {
|
||||
passed++;
|
||||
@@ -846,10 +650,7 @@ namespace Test
|
||||
ok = test();
|
||||
} catch(const YAML::Exception& e) {
|
||||
ok = false;
|
||||
error = e.what();
|
||||
} catch(const Parser::TagMismatch& e) {
|
||||
ok = false;
|
||||
error = e.what();
|
||||
error = e.msg;
|
||||
}
|
||||
if(ok) {
|
||||
passed++;
|
||||
@@ -1068,20 +869,6 @@ namespace Test
|
||||
RunParserTest(&Parser::MultipleDocs, "multiple docs", passed, total);
|
||||
RunParserTest(&Parser::ExplicitEndDoc, "explicit end doc", passed, total);
|
||||
RunParserTest(&Parser::MultipleDocsWithSomeExplicitIndicators, "multiple docs with some explicit indicators", passed, total);
|
||||
RunParserTest(&Parser::BlockKeyWithNullValue, "block key with null value", passed, total);
|
||||
RunParserTest(&Parser::Bases, "bases", passed, total);
|
||||
RunParserTest(&Parser::KeyNotFound, "key not found", passed, total);
|
||||
RunParserTest(&Parser::DuplicateKey, "duplicate key", passed, total);
|
||||
RunParserTest(&Parser::DefaultPlainScalarTag, "default plain scalar tag", passed, total);
|
||||
RunParserTest(&Parser::DefaultSingleQuotedScalarTag, "default single-quoted scalar tag", passed, total);
|
||||
RunParserTest(&Parser::ExplicitNonSpecificPlainScalarTag, "explicit, non-specific plain scalar tag", passed, total);
|
||||
RunParserTest(&Parser::BasicLocalTag, "basic local tag", passed, total);
|
||||
RunParserTest(&Parser::VerbatimLocalTag, "verbatim local tag", passed, total);
|
||||
RunParserTest(&Parser::StandardShortcutTag, "standard shortcut tag", passed, total);
|
||||
RunParserTest(&Parser::VerbatimURITag, "verbatim URI tag", passed, total);
|
||||
RunParserTest(&Parser::DefaultPlainScalarTag, "default plain scalar tag", passed, total);
|
||||
RunParserTest(&Parser::DefaultSequenceTag, "default sequence tag", passed, total);
|
||||
RunParserTest(&Parser::ExplicitNonSpecificSequenceTag, "explicit, non-specific sequence tag", passed, total);
|
||||
|
||||
RunEncodingTest(&EncodeToUtf8, false, "UTF-8, no BOM", passed, total);
|
||||
RunEncodingTest(&EncodeToUtf8, true, "UTF-8 with BOM", passed, total);
|
||||
@@ -32,7 +32,7 @@ namespace Test {
|
||||
ret = test();
|
||||
} catch(const YAML::Exception& e) {
|
||||
ret.ok = false;
|
||||
ret.error = std::string(" Exception caught: ") + e.what();
|
||||
ret.error = " Exception caught: " + e.msg;
|
||||
}
|
||||
|
||||
if(!ret.ok) {
|
||||
@@ -459,136 +459,7 @@ namespace Test {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: 2.19 - 2.22 schema tags
|
||||
|
||||
// 2.23
|
||||
TEST VariousExplicitTags()
|
||||
{
|
||||
std::string input =
|
||||
"---\n"
|
||||
"not-date: !!str 2002-04-28\n"
|
||||
"\n"
|
||||
"picture: !!binary |\n"
|
||||
" R0lGODlhDAAMAIQAAP//9/X\n"
|
||||
" 17unp5WZmZgAAAOfn515eXv\n"
|
||||
" Pz7Y6OjuDg4J+fn5OTk6enp\n"
|
||||
" 56enmleECcgggoBADs=\n"
|
||||
"\n"
|
||||
"application specific tag: !something |\n"
|
||||
" The semantics of the tag\n"
|
||||
" above may be different for\n"
|
||||
" different documents.";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 3);
|
||||
YAML_ASSERT(doc["not-date"].GetTag() == "tag:yaml.org,2002:str");
|
||||
YAML_ASSERT(doc["not-date"] == "2002-04-28");
|
||||
YAML_ASSERT(doc["picture"].GetTag() == "tag:yaml.org,2002:binary");
|
||||
YAML_ASSERT(doc["picture"] ==
|
||||
"R0lGODlhDAAMAIQAAP//9/X\n"
|
||||
"17unp5WZmZgAAAOfn515eXv\n"
|
||||
"Pz7Y6OjuDg4J+fn5OTk6enp\n"
|
||||
"56enmleECcgggoBADs=\n"
|
||||
);
|
||||
YAML_ASSERT(doc["application specific tag"].GetTag() == "!something");
|
||||
YAML_ASSERT(doc["application specific tag"] ==
|
||||
"The semantics of the tag\n"
|
||||
"above may be different for\n"
|
||||
"different documents."
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2.24
|
||||
TEST GlobalTags()
|
||||
{
|
||||
std::string input =
|
||||
"%TAG ! tag:clarkevans.com,2002:\n"
|
||||
"--- !shape\n"
|
||||
" # Use the ! handle for presenting\n"
|
||||
" # tag:clarkevans.com,2002:circle\n"
|
||||
"- !circle\n"
|
||||
" center: &ORIGIN {x: 73, y: 129}\n"
|
||||
" radius: 7\n"
|
||||
"- !line\n"
|
||||
" start: *ORIGIN\n"
|
||||
" finish: { x: 89, y: 102 }\n"
|
||||
"- !label\n"
|
||||
" start: *ORIGIN\n"
|
||||
" color: 0xFFEEBB\n"
|
||||
" text: Pretty vector drawing.";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.GetTag() == "tag:clarkevans.com,2002:shape");
|
||||
YAML_ASSERT(doc.size() == 3);
|
||||
YAML_ASSERT(doc[0].GetTag() == "tag:clarkevans.com,2002:circle");
|
||||
YAML_ASSERT(doc[0].size() == 2);
|
||||
YAML_ASSERT(doc[0]["center"].size() == 2);
|
||||
YAML_ASSERT(doc[0]["center"]["x"] == 73);
|
||||
YAML_ASSERT(doc[0]["center"]["y"] == 129);
|
||||
YAML_ASSERT(doc[0]["radius"] == 7);
|
||||
YAML_ASSERT(doc[1].GetTag() == "tag:clarkevans.com,2002:line");
|
||||
YAML_ASSERT(doc[1].size() == 2);
|
||||
YAML_ASSERT(doc[1]["start"].size() == 2);
|
||||
YAML_ASSERT(doc[1]["start"]["x"] == 73);
|
||||
YAML_ASSERT(doc[1]["start"]["y"] == 129);
|
||||
YAML_ASSERT(doc[1]["finish"].size() == 2);
|
||||
YAML_ASSERT(doc[1]["finish"]["x"] == 89);
|
||||
YAML_ASSERT(doc[1]["finish"]["y"] == 102);
|
||||
YAML_ASSERT(doc[2].GetTag() == "tag:clarkevans.com,2002:label");
|
||||
YAML_ASSERT(doc[2].size() == 3);
|
||||
YAML_ASSERT(doc[2]["start"].size() == 2);
|
||||
YAML_ASSERT(doc[2]["start"]["x"] == 73);
|
||||
YAML_ASSERT(doc[2]["start"]["y"] == 129);
|
||||
YAML_ASSERT(doc[2]["color"] == "0xFFEEBB");
|
||||
YAML_ASSERT(doc[2]["text"] == "Pretty vector drawing.");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2.25
|
||||
TEST UnorderedSets()
|
||||
{
|
||||
std::string input =
|
||||
"# Sets are represented as a\n"
|
||||
"# Mapping where each key is\n"
|
||||
"# associated with a null value\n"
|
||||
"--- !!set\n"
|
||||
"? Mark McGwire\n"
|
||||
"? Sammy Sosa\n"
|
||||
"? Ken Griffey";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.GetTag() == "tag:yaml.org,2002:set");
|
||||
YAML_ASSERT(doc.size() == 3);
|
||||
YAML_ASSERT(IsNull(doc["Mark McGwire"]));
|
||||
YAML_ASSERT(IsNull(doc["Sammy Sosa"]));
|
||||
YAML_ASSERT(IsNull(doc["Ken Griffey"]));
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2.26
|
||||
TEST OrderedMappings()
|
||||
{
|
||||
std::string input =
|
||||
"# Ordered maps are represented as\n"
|
||||
"# A sequence of mappings, with\n"
|
||||
"# each mapping having one key\n"
|
||||
"--- !!omap\n"
|
||||
"- Mark McGwire: 65\n"
|
||||
"- Sammy Sosa: 63\n"
|
||||
"- Ken Griffey: 58";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.GetTag() == "tag:yaml.org,2002:omap");
|
||||
YAML_ASSERT(doc.size() == 3);
|
||||
YAML_ASSERT(doc[0].size() == 1);
|
||||
YAML_ASSERT(doc[0]["Mark McGwire"] == 65);
|
||||
YAML_ASSERT(doc[1].size() == 1);
|
||||
YAML_ASSERT(doc[1]["Sammy Sosa"] == 63);
|
||||
YAML_ASSERT(doc[2].size() == 1);
|
||||
YAML_ASSERT(doc[2]["Ken Griffey"] == 58);
|
||||
return true;
|
||||
}
|
||||
// TODO: 2.19 - 2.26 tags
|
||||
|
||||
// 2.27
|
||||
TEST Invoice()
|
||||
@@ -625,7 +496,6 @@ namespace Test {
|
||||
" Billsmer @ 338-4338.";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.GetTag() == "tag:clarkevans.com,2002:invoice");
|
||||
YAML_ASSERT(doc.size() == 8);
|
||||
YAML_ASSERT(doc["invoice"] == 34843);
|
||||
YAML_ASSERT(doc["date"] == "2001-01-23");
|
||||
@@ -765,16 +635,7 @@ namespace Test {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 5.5
|
||||
TEST CommentIndicator()
|
||||
{
|
||||
std::string input =
|
||||
"# Comment only.";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 0);
|
||||
return true;
|
||||
}
|
||||
// TODO: 5.5 comment only
|
||||
|
||||
// 5.6
|
||||
TEST NodePropertyIndicators()
|
||||
@@ -1069,9 +930,10 @@ namespace Test {
|
||||
" # Comment\n"
|
||||
" \n"
|
||||
"\n";
|
||||
std::stringstream stream(input);
|
||||
YAML::Parser parser(stream);
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 0);
|
||||
YAML_ASSERT(!parser);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1121,9 +983,9 @@ namespace Test {
|
||||
" 0.278";
|
||||
|
||||
PARSE(doc, input);
|
||||
std::map<std::string, std::string> key;
|
||||
key["first"] = "Sammy";
|
||||
key["last"] = "Sosa";
|
||||
StringMap key;
|
||||
key._["first"] = "Sammy";
|
||||
key._["last"] = "Sosa";
|
||||
YAML_ASSERT(doc.size() == 1);
|
||||
YAML_ASSERT(doc[key].size() == 2);
|
||||
YAML_ASSERT(doc[key]["hr"] == 65);
|
||||
@@ -1131,291 +993,8 @@ namespace Test {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 6.13
|
||||
TEST ReservedDirectives()
|
||||
{
|
||||
std::string input =
|
||||
"%FOO bar baz # Should be ignored\n"
|
||||
" # with a warning.\n"
|
||||
"--- \"foo\"";
|
||||
|
||||
PARSE(doc, input);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 6.14
|
||||
TEST YAMLDirective()
|
||||
{
|
||||
std::string input =
|
||||
"%YAML 1.3 # Attempt parsing\n"
|
||||
" # with a warning\n"
|
||||
"---\n"
|
||||
"\"foo\"";
|
||||
|
||||
PARSE(doc, input);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 6.15
|
||||
TEST InvalidRepeatedYAMLDirective()
|
||||
{
|
||||
std::string input =
|
||||
"%YAML 1.2\n"
|
||||
"%YAML 1.1\n"
|
||||
"foo";
|
||||
|
||||
try {
|
||||
PARSE(doc, input);
|
||||
} catch(const YAML::ParserException& e) {
|
||||
if(e.msg == YAML::ErrorMsg::REPEATED_YAML_DIRECTIVE)
|
||||
return true;
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
return " No exception was thrown";
|
||||
}
|
||||
|
||||
// 6.16
|
||||
TEST TagDirective()
|
||||
{
|
||||
std::string input =
|
||||
"%TAG !yaml! tag:yaml.org,2002:\n"
|
||||
"---\n"
|
||||
"!yaml!str \"foo\"";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.GetTag() == "tag:yaml.org,2002:str");
|
||||
YAML_ASSERT(doc == "foo");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 6.17
|
||||
TEST InvalidRepeatedTagDirective()
|
||||
{
|
||||
std::string input =
|
||||
"%TAG ! !foo\n"
|
||||
"%TAG ! !foo\n"
|
||||
"bar";
|
||||
|
||||
try {
|
||||
PARSE(doc, input);
|
||||
} 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::string input =
|
||||
"# Private\n"
|
||||
"!foo \"bar\"\n"
|
||||
"...\n"
|
||||
"# Global\n"
|
||||
"%TAG ! tag:example.com,2000:app/\n"
|
||||
"---\n"
|
||||
"!foo \"bar\"";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.GetTag() == "!foo");
|
||||
YAML_ASSERT(doc == "bar");
|
||||
|
||||
PARSE_NEXT(doc);
|
||||
YAML_ASSERT(doc.GetTag() == "tag:example.com,2000:app/foo");
|
||||
YAML_ASSERT(doc == "bar");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 6.19
|
||||
TEST SecondaryTagHandle()
|
||||
{
|
||||
std::string input =
|
||||
"%TAG !! tag:example.com,2000:app/\n"
|
||||
"---\n"
|
||||
"!!int 1 - 3 # Interval, not integer";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.GetTag() == "tag:example.com,2000:app/int");
|
||||
YAML_ASSERT(doc == "1 - 3");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 6.20
|
||||
TEST TagHandles()
|
||||
{
|
||||
std::string input =
|
||||
"%TAG !e! tag:example.com,2000:app/\n"
|
||||
"---\n"
|
||||
"!e!foo \"bar\"";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.GetTag() == "tag:example.com,2000:app/foo");
|
||||
YAML_ASSERT(doc == "bar");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 6.21
|
||||
TEST LocalTagPrefix()
|
||||
{
|
||||
std::string input =
|
||||
"%TAG !m! !my-\n"
|
||||
"--- # Bulb here\n"
|
||||
"!m!light fluorescent\n"
|
||||
"...\n"
|
||||
"%TAG !m! !my-\n"
|
||||
"--- # Color here\n"
|
||||
"!m!light green";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.GetTag() == "!my-light");
|
||||
YAML_ASSERT(doc == "fluorescent");
|
||||
|
||||
PARSE_NEXT(doc);
|
||||
YAML_ASSERT(doc.GetTag() == "!my-light");
|
||||
YAML_ASSERT(doc == "green");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 6.22
|
||||
TEST GlobalTagPrefix()
|
||||
{
|
||||
std::string input =
|
||||
"%TAG !e! tag:example.com,2000:app/\n"
|
||||
"---\n"
|
||||
"- !e!foo \"bar\"";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 1);
|
||||
YAML_ASSERT(doc[0].GetTag() == "tag:example.com,2000:app/foo");
|
||||
YAML_ASSERT(doc[0] == "bar");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 6.23
|
||||
TEST NodeProperties()
|
||||
{
|
||||
std::string input =
|
||||
"!!str &a1 \"foo\":\n"
|
||||
" !!str bar\n"
|
||||
"&a2 baz : *a1";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 2);
|
||||
for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
|
||||
if(it.first() == "foo") {
|
||||
YAML_ASSERT(it.first().GetTag() == "tag:yaml.org,2002:str");
|
||||
YAML_ASSERT(it.second().GetTag() == "tag:yaml.org,2002:str");
|
||||
YAML_ASSERT(it.second() == "bar");
|
||||
} else if(it.first() == "baz") {
|
||||
YAML_ASSERT(it.second() == "foo");
|
||||
} else
|
||||
return " unknown key";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 6.24
|
||||
TEST VerbatimTags()
|
||||
{
|
||||
std::string input =
|
||||
"!<tag:yaml.org,2002:str> foo :\n"
|
||||
" !<!bar> baz";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 1);
|
||||
for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
|
||||
YAML_ASSERT(it.first().GetTag() == "tag:yaml.org,2002:str");
|
||||
YAML_ASSERT(it.first() == "foo");
|
||||
YAML_ASSERT(it.second().GetTag() == "!bar");
|
||||
YAML_ASSERT(it.second() == "baz");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// 6.25
|
||||
TEST InvalidVerbatimTags()
|
||||
{
|
||||
std::string input =
|
||||
"- !<!> foo\n"
|
||||
"- !<$:?> bar\n";
|
||||
|
||||
PARSE(doc, input);
|
||||
return " not implemented yet"; // TODO: check tags (but we probably will say these are valid, I think)
|
||||
}
|
||||
|
||||
// 6.26
|
||||
TEST TagShorthands()
|
||||
{
|
||||
std::string input =
|
||||
"%TAG !e! tag:example.com,2000:app/\n"
|
||||
"---\n"
|
||||
"- !local foo\n"
|
||||
"- !!str bar\n"
|
||||
"- !e!tag%21 baz\n";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 3);
|
||||
YAML_ASSERT(doc[0].GetTag() == "!local");
|
||||
YAML_ASSERT(doc[0] == "foo");
|
||||
YAML_ASSERT(doc[1].GetTag() == "tag:yaml.org,2002:str");
|
||||
YAML_ASSERT(doc[1] == "bar");
|
||||
YAML_ASSERT(doc[2].GetTag() == "tag:example.com,2000:app/tag%21");
|
||||
YAML_ASSERT(doc[2] == "baz");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 6.27
|
||||
TEST InvalidTagShorthands()
|
||||
{
|
||||
std::string input1 =
|
||||
"%TAG !e! tag:example,2000:app/\n"
|
||||
"---\n"
|
||||
"- !e! foo";
|
||||
|
||||
bool threw = false;
|
||||
try {
|
||||
PARSE(doc, input1);
|
||||
} 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";
|
||||
|
||||
std::string input2 =
|
||||
"%TAG !e! tag:example,2000:app/\n"
|
||||
"---\n"
|
||||
"- !h!bar baz";
|
||||
|
||||
PARSE(doc, input2); // TODO: should we reject this one (since !h! is not declared)?
|
||||
return " not implemented yet";
|
||||
}
|
||||
|
||||
// 6.28
|
||||
TEST NonSpecificTags()
|
||||
{
|
||||
std::string input =
|
||||
"# Assuming conventional resolution:\n"
|
||||
"- \"12\"\n"
|
||||
"- 12\n"
|
||||
"- ! 12";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 3);
|
||||
YAML_ASSERT(doc[0] == "12"); // TODO: check tags. How?
|
||||
YAML_ASSERT(doc[1] == 12);
|
||||
YAML_ASSERT(doc[2] == "12");
|
||||
return true;
|
||||
}
|
||||
// TODO: 6.13 - 6.17 directives
|
||||
// TODO: 6.18 - 6.28 tags
|
||||
|
||||
// 6.29
|
||||
TEST NodeAnchors()
|
||||
@@ -1460,16 +1039,8 @@ namespace Test {
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 2);
|
||||
for(YAML::Iterator it=doc.begin();it!=doc.end();++it) {
|
||||
if(it.first() == "foo") {
|
||||
YAML_ASSERT(it.second().GetTag() == "tag:yaml.org,2002:str");
|
||||
YAML_ASSERT(it.second() == "");
|
||||
} else if(it.first() == "") {
|
||||
YAML_ASSERT(it.first().GetTag() == "tag:yaml.org,2002:str");
|
||||
YAML_ASSERT(it.second() == "bar");
|
||||
} else
|
||||
return " unexpected key";
|
||||
}
|
||||
YAML_ASSERT(doc["foo"] == ""); // TODO: check tag
|
||||
YAML_ASSERT(doc[""] == "bar");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1636,424 +1207,6 @@ namespace Test {
|
||||
YAML_ASSERT(doc == "1st non-empty\n2nd non-empty 3rd non-empty");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 7.13
|
||||
TEST FlowSequence()
|
||||
{
|
||||
std::string input =
|
||||
"- [ one, two, ]\n"
|
||||
"- [three ,four]";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 2);
|
||||
YAML_ASSERT(doc[0].size() == 2);
|
||||
YAML_ASSERT(doc[0][0] == "one");
|
||||
YAML_ASSERT(doc[0][1] == "two");
|
||||
YAML_ASSERT(doc[1].size() == 2);
|
||||
YAML_ASSERT(doc[1][0] == "three");
|
||||
YAML_ASSERT(doc[1][1] == "four");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 7.14
|
||||
TEST FlowSequenceEntries()
|
||||
{
|
||||
std::string input =
|
||||
"[\n"
|
||||
"\"double\n"
|
||||
" quoted\", 'single\n"
|
||||
" quoted',\n"
|
||||
"plain\n"
|
||||
" text, [ nested ],\n"
|
||||
"single: pair,\n"
|
||||
"]";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 5);
|
||||
YAML_ASSERT(doc[0] == "double quoted");
|
||||
YAML_ASSERT(doc[1] == "single quoted");
|
||||
YAML_ASSERT(doc[2] == "plain text");
|
||||
YAML_ASSERT(doc[3].size() == 1);
|
||||
YAML_ASSERT(doc[3][0] == "nested");
|
||||
YAML_ASSERT(doc[4].size() == 1);
|
||||
YAML_ASSERT(doc[4]["single"] == "pair");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 7.15
|
||||
TEST FlowMappings()
|
||||
{
|
||||
std::string input =
|
||||
"- { one : two , three: four , }\n"
|
||||
"- {five: six,seven : eight}";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 2);
|
||||
YAML_ASSERT(doc[0].size() == 2);
|
||||
YAML_ASSERT(doc[0]["one"] == "two");
|
||||
YAML_ASSERT(doc[0]["three"] == "four");
|
||||
YAML_ASSERT(doc[1].size() == 2);
|
||||
YAML_ASSERT(doc[1]["five"] == "six");
|
||||
YAML_ASSERT(doc[1]["seven"] == "eight");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 7.16
|
||||
TEST FlowMappingEntries()
|
||||
{
|
||||
std::string input =
|
||||
"{\n"
|
||||
"? explicit: entry,\n"
|
||||
"implicit: entry,\n"
|
||||
"?\n"
|
||||
"}";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 3);
|
||||
YAML_ASSERT(doc["explicit"] == "entry");
|
||||
YAML_ASSERT(doc["implicit"] == "entry");
|
||||
YAML_ASSERT(IsNull(doc[YAML::Null]));
|
||||
return true;
|
||||
}
|
||||
|
||||
// 7.17
|
||||
TEST FlowMappingSeparateValues()
|
||||
{
|
||||
std::string input =
|
||||
"{\n"
|
||||
"unquoted : \"separate\",\n"
|
||||
"http://foo.com,\n"
|
||||
"omitted value:,\n"
|
||||
": omitted key,\n"
|
||||
"}";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 4);
|
||||
YAML_ASSERT(doc["unquoted"] == "separate");
|
||||
YAML_ASSERT(IsNull(doc["http://foo.com"]));
|
||||
YAML_ASSERT(IsNull(doc["omitted value"]));
|
||||
YAML_ASSERT(doc[YAML::Null] == "omitted key");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 7.18
|
||||
TEST FlowMappingAdjacentValues()
|
||||
{
|
||||
std::string input =
|
||||
"{\n"
|
||||
"\"adjacent\":value,\n"
|
||||
"\"readable\":value,\n"
|
||||
"\"empty\":\n"
|
||||
"}";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 3);
|
||||
YAML_ASSERT(doc["adjacent"] == "value");
|
||||
YAML_ASSERT(doc["readable"] == "value");
|
||||
YAML_ASSERT(IsNull(doc["empty"]));
|
||||
return true;
|
||||
}
|
||||
|
||||
// 7.19
|
||||
TEST SinglePairFlowMappings()
|
||||
{
|
||||
std::string input =
|
||||
"[\n"
|
||||
"foo: bar\n"
|
||||
"]";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 1);
|
||||
YAML_ASSERT(doc[0].size() == 1);
|
||||
YAML_ASSERT(doc[0]["foo"] == "bar");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 7.20
|
||||
TEST SinglePairExplicitEntry()
|
||||
{
|
||||
std::string input =
|
||||
"[\n"
|
||||
"? foo\n"
|
||||
" bar : baz\n"
|
||||
"]";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 1);
|
||||
YAML_ASSERT(doc[0].size() == 1);
|
||||
YAML_ASSERT(doc[0]["foo bar"] == "baz");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 7.21
|
||||
TEST SinglePairImplicitEntries()
|
||||
{
|
||||
std::string input =
|
||||
"- [ YAML : separate ]\n"
|
||||
"- [ : empty key entry ]\n"
|
||||
"- [ {JSON: like}:adjacent ]";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 3);
|
||||
YAML_ASSERT(doc[0].size() == 1);
|
||||
YAML_ASSERT(doc[0][0].size() == 1);
|
||||
YAML_ASSERT(doc[0][0]["YAML"] == "separate");
|
||||
YAML_ASSERT(doc[1].size() == 1);
|
||||
YAML_ASSERT(doc[1][0].size() == 1);
|
||||
YAML_ASSERT(doc[1][0][YAML::Null] == "empty key entry");
|
||||
YAML_ASSERT(doc[2].size() == 1);
|
||||
YAML_ASSERT(doc[2][0].size() == 1);
|
||||
StringMap key;
|
||||
key._["JSON"] = "like";
|
||||
YAML_ASSERT(doc[2][0][key] == "adjacent");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 7.22
|
||||
TEST InvalidImplicitKeys()
|
||||
{
|
||||
std::string input =
|
||||
"[ foo\n"
|
||||
" bar: invalid,"; // Note: we don't check (on purpose) the >1K chars for an implicit key
|
||||
|
||||
try {
|
||||
PARSE(doc, input);
|
||||
} 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()
|
||||
{
|
||||
std::string input =
|
||||
"- [ a, b ]\n"
|
||||
"- { a: b }\n"
|
||||
"- \"a\"\n"
|
||||
"- 'b'\n"
|
||||
"- c";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 5);
|
||||
YAML_ASSERT(doc[0].size() == 2);
|
||||
YAML_ASSERT(doc[0][0] == "a");
|
||||
YAML_ASSERT(doc[0][1] == "b");
|
||||
YAML_ASSERT(doc[1].size() == 1);
|
||||
YAML_ASSERT(doc[1]["a"] == "b");
|
||||
YAML_ASSERT(doc[2] == "a");
|
||||
YAML_ASSERT(doc[3] == 'b');
|
||||
YAML_ASSERT(doc[4] == "c");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 7.24
|
||||
TEST FlowNodes()
|
||||
{
|
||||
std::string input =
|
||||
"- !!str \"a\"\n"
|
||||
"- 'b'\n"
|
||||
"- &anchor \"c\"\n"
|
||||
"- *anchor\n"
|
||||
"- !!str";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 5);
|
||||
YAML_ASSERT(doc[0].GetTag() == "tag:yaml.org,2002:str");
|
||||
YAML_ASSERT(doc[0] == "a");
|
||||
YAML_ASSERT(doc[1] == 'b');
|
||||
YAML_ASSERT(doc[2] == "c");
|
||||
YAML_ASSERT(doc[3] == "c");
|
||||
YAML_ASSERT(doc[4].GetTag() == "tag:yaml.org,2002:str");
|
||||
YAML_ASSERT(doc[4] == "");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 8.1
|
||||
TEST BlockScalarHeader()
|
||||
{
|
||||
std::string input =
|
||||
"- | # Empty header\n"
|
||||
" literal\n"
|
||||
"- >1 # Indentation indicator\n"
|
||||
" folded\n"
|
||||
"- |+ # Chomping indicator\n"
|
||||
" keep\n"
|
||||
"\n"
|
||||
"- >1- # Both indicators\n"
|
||||
" strip\n";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 4);
|
||||
YAML_ASSERT(doc[0] == "literal\n");
|
||||
YAML_ASSERT(doc[1] == " folded\n");
|
||||
YAML_ASSERT(doc[2] == "keep\n\n");
|
||||
YAML_ASSERT(doc[3] == " strip");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 8.2
|
||||
TEST BlockIndentationHeader()
|
||||
{
|
||||
std::string input =
|
||||
"- |\n"
|
||||
" detected\n"
|
||||
"- >\n"
|
||||
" \n"
|
||||
" \n"
|
||||
" # detected\n"
|
||||
"- |1\n"
|
||||
" explicit\n"
|
||||
"- >\n"
|
||||
" \t\n"
|
||||
" detected\n";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 4);
|
||||
YAML_ASSERT(doc[0] == "detected\n");
|
||||
YAML_ASSERT(doc[1] == "\n\n# detected\n");
|
||||
YAML_ASSERT(doc[2] == " explicit\n");
|
||||
YAML_ASSERT(doc[3] == "\t detected\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 8.3
|
||||
TEST InvalidBlockScalarIndentationIndicators()
|
||||
{
|
||||
{
|
||||
std::string input =
|
||||
"- |\n"
|
||||
" \n"
|
||||
" text";
|
||||
|
||||
bool threw = false;
|
||||
try {
|
||||
PARSE(doc, input);
|
||||
} 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";
|
||||
}
|
||||
|
||||
{
|
||||
std::string input =
|
||||
"- >\n"
|
||||
" text\n"
|
||||
" text";
|
||||
|
||||
bool threw = false;
|
||||
try {
|
||||
PARSE(doc, input);
|
||||
} 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";
|
||||
}
|
||||
|
||||
{
|
||||
std::string input =
|
||||
"- |2\n"
|
||||
" text";
|
||||
|
||||
bool threw = false;
|
||||
try {
|
||||
PARSE(doc, input);
|
||||
} 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()
|
||||
{
|
||||
std::string input =
|
||||
"strip: |-\n"
|
||||
" text\n"
|
||||
"clip: |\n"
|
||||
" text\n"
|
||||
"keep: |+\n"
|
||||
" text\n";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 3);
|
||||
YAML_ASSERT(doc["strip"] == "text");
|
||||
YAML_ASSERT(doc["clip"] == "text\n");
|
||||
YAML_ASSERT(doc["keep"] == "text\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 8.5
|
||||
TEST ChompingTrailingLines()
|
||||
{
|
||||
std::string input =
|
||||
" # Strip\n"
|
||||
" # Comments:\n"
|
||||
"strip: |-\n"
|
||||
" # text\n"
|
||||
" \n"
|
||||
" # Clip\n"
|
||||
" # comments:\n"
|
||||
"\n"
|
||||
"clip: |\n"
|
||||
" # text\n"
|
||||
" \n"
|
||||
" # Keep\n"
|
||||
" # comments:\n"
|
||||
"\n"
|
||||
"keep: |+\n"
|
||||
" # text\n"
|
||||
"\n"
|
||||
" # Trail\n"
|
||||
" # Comments\n";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 3);
|
||||
YAML_ASSERT(doc["strip"] == "# text");
|
||||
YAML_ASSERT(doc["clip"] == "# text\n");
|
||||
YAML_ASSERT(doc["keep"] == "# text\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 8.6
|
||||
TEST EmptyScalarChomping()
|
||||
{
|
||||
std::string input =
|
||||
"strip: >-\n"
|
||||
"\n"
|
||||
"clip: >\n"
|
||||
"\n"
|
||||
"keep: |+\n"
|
||||
"\n";
|
||||
|
||||
PARSE(doc, input);
|
||||
YAML_ASSERT(doc.size() == 3);
|
||||
YAML_ASSERT(doc["strip"] == "");
|
||||
YAML_ASSERT(doc["clip"] == "");
|
||||
YAML_ASSERT(doc["keep"] == "\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool RunSpecTests()
|
||||
@@ -2079,10 +1232,6 @@ namespace Test {
|
||||
RunSpecTest(&Spec::QuotedScalars, "2.17", "Quoted scalars", passed, total);
|
||||
RunSpecTest(&Spec::MultiLineFlowScalars, "2.18", "Multi-line flow scalars", passed, total);
|
||||
|
||||
RunSpecTest(&Spec::VariousExplicitTags, "2.23", "Various Explicit Tags", passed, total);
|
||||
RunSpecTest(&Spec::GlobalTags, "2.24", "Global Tags", passed, total);
|
||||
RunSpecTest(&Spec::UnorderedSets, "2.25", "Unordered Sets", passed, total);
|
||||
RunSpecTest(&Spec::OrderedMappings, "2.26", "Ordered Mappings", passed, total);
|
||||
RunSpecTest(&Spec::Invoice, "2.27", "Invoice", passed, total);
|
||||
RunSpecTest(&Spec::LogFile, "2.28", "Log File", passed, total);
|
||||
|
||||
@@ -2106,24 +1255,8 @@ namespace Test {
|
||||
RunSpecTest(&Spec::FlowFolding, "6.8", "Flow Folding", passed, total);
|
||||
RunSpecTest(&Spec::SeparatedComment, "6.9", "Separated Comment", passed, total);
|
||||
RunSpecTest(&Spec::CommentLines, "6.10", "Comment Lines", passed, total);
|
||||
RunSpecTest(&Spec::MultiLineComments, "6.11", "Multi-Line Comments", passed, total);
|
||||
RunSpecTest(&Spec::SeparationSpacesII, "6.12", "Separation Spaces", passed, total);
|
||||
RunSpecTest(&Spec::ReservedDirectives, "6.13", "Reserved Directives", passed, total);
|
||||
RunSpecTest(&Spec::YAMLDirective, "6.14", "YAML Directive", passed, total);
|
||||
RunSpecTest(&Spec::InvalidRepeatedYAMLDirective, "6.15", "Invalid Repeated YAML Directive", passed, total);
|
||||
RunSpecTest(&Spec::TagDirective, "6.16", "Tag Directive", passed, total);
|
||||
RunSpecTest(&Spec::InvalidRepeatedTagDirective, "6.17", "Invalid Repeated Tag Directive", passed, total);
|
||||
RunSpecTest(&Spec::PrimaryTagHandle, "6.18", "Primary Tag Handle", passed, total);
|
||||
RunSpecTest(&Spec::SecondaryTagHandle, "6.19", "SecondaryTagHandle", passed, total);
|
||||
RunSpecTest(&Spec::TagHandles, "6.20", "TagHandles", passed, total);
|
||||
RunSpecTest(&Spec::LocalTagPrefix, "6.21", "LocalTagPrefix", passed, total);
|
||||
RunSpecTest(&Spec::GlobalTagPrefix, "6.22", "GlobalTagPrefix", passed, total);
|
||||
RunSpecTest(&Spec::NodeProperties, "6.23", "NodeProperties", passed, total);
|
||||
RunSpecTest(&Spec::VerbatimTags, "6.24", "Verbatim Tags", passed, total);
|
||||
RunSpecTest(&Spec::InvalidVerbatimTags, "6.25", "Invalid Verbatim Tags", passed, total);
|
||||
RunSpecTest(&Spec::TagShorthands, "6.26", "Tag Shorthands", passed, total);
|
||||
RunSpecTest(&Spec::InvalidTagShorthands, "6.27", "Invalid Tag Shorthands", passed, total);
|
||||
RunSpecTest(&Spec::NonSpecificTags, "6.28", "Non Specific Tags", passed, total);
|
||||
RunSpecTest(&Spec::SeparationSpacesII, "6.11", "Separation Spaces", passed, total);
|
||||
|
||||
RunSpecTest(&Spec::NodeAnchors, "6.29", "Node Anchors", passed, total);
|
||||
|
||||
RunSpecTest(&Spec::AliasNodes, "7.1", "Alias Nodes", passed, total);
|
||||
@@ -2138,25 +1271,6 @@ namespace Test {
|
||||
RunSpecTest(&Spec::PlainCharacters, "7.10", "Plain Characters", passed, total);
|
||||
RunSpecTest(&Spec::PlainImplicitKeys, "7.11", "Plain Implicit Keys", passed, total);
|
||||
RunSpecTest(&Spec::PlainLines, "7.12", "Plain Lines", passed, total);
|
||||
RunSpecTest(&Spec::FlowSequence, "7.13", "Flow Sequence", passed, total);
|
||||
RunSpecTest(&Spec::FlowSequenceEntries, "7.14", "Flow Sequence Entries", passed, total);
|
||||
RunSpecTest(&Spec::FlowMappings, "7.15", "Flow Mappings", passed, total);
|
||||
RunSpecTest(&Spec::FlowMappingEntries, "7.16", "Flow Mapping Entries", passed, total);
|
||||
RunSpecTest(&Spec::FlowMappingSeparateValues, "7.17", "Flow Mapping Separate Values", passed, total);
|
||||
RunSpecTest(&Spec::FlowMappingAdjacentValues, "7.18", "Flow Mapping Adjacent Values", passed, total);
|
||||
RunSpecTest(&Spec::SinglePairFlowMappings, "7.19", "Single Pair Flow Mappings", passed, total);
|
||||
RunSpecTest(&Spec::SinglePairExplicitEntry, "7.20", "Single Pair Explicit Entry", passed, total);
|
||||
RunSpecTest(&Spec::SinglePairImplicitEntries, "7.21", "Single Pair Implicit Entries", passed, total);
|
||||
RunSpecTest(&Spec::InvalidImplicitKeys, "7.22", "Invalid Implicit Keys", passed, total);
|
||||
RunSpecTest(&Spec::FlowContent, "7.23", "Flow Content", passed, total);
|
||||
RunSpecTest(&Spec::FlowNodes, "7.24", "FlowNodes", passed, total);
|
||||
|
||||
RunSpecTest(&Spec::BlockScalarHeader, "8.1", "Block Scalar Header", passed, total);
|
||||
RunSpecTest(&Spec::BlockIndentationHeader, "8.2", "Block Indentation Header", passed, total);
|
||||
RunSpecTest(&Spec::InvalidBlockScalarIndentationIndicators, "8.3", "Invalid Block Scalar Indentation Indicators", passed, total);
|
||||
RunSpecTest(&Spec::ChompingFinalLineBreak, "8.4", "Chomping Final Line Break", passed, total);
|
||||
RunSpecTest(&Spec::ChompingTrailingLines, "8.4", "Chomping Trailing Lines", passed, total);
|
||||
RunSpecTest(&Spec::EmptyScalarChomping, "8.4", "Empty Scalar Chomping", passed, total);
|
||||
|
||||
std::cout << "Spec tests: " << passed << "/" << total << " passed\n";
|
||||
return passed == total;
|
||||
@@ -0,0 +1,4 @@
|
||||
--- &list
|
||||
- This document contains a recursive list.
|
||||
- *list
|
||||
...
|
||||
+9
-18
@@ -1,36 +1,27 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml-reader", "yaml-reader.vcproj", "{E8CC0D8A-D784-4A6B-B78B-ACEA13F9FB0B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{3104AB4E-CD31-4F47-95E9-0E8D9374E15D} = {3104AB4E-CD31-4F47-95E9-0E8D9374E15D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yamlcpp", "yamlcpp.vcproj", "{3104AB4E-CD31-4F47-95E9-0E8D9374E15D}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{D1108F40-6ADF-467E-A95A-236C39A515C5}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{3104AB4E-CD31-4F47-95E9-0E8D9374E15D} = {3104AB4E-CD31-4F47-95E9-0E8D9374E15D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "parse", "parse.vcproj", "{CD007B57-7812-4930-A5E2-6E5E56338814}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{3104AB4E-CD31-4F47-95E9-0E8D9374E15D} = {3104AB4E-CD31-4F47-95E9-0E8D9374E15D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E8CC0D8A-D784-4A6B-B78B-ACEA13F9FB0B}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{E8CC0D8A-D784-4A6B-B78B-ACEA13F9FB0B}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{E8CC0D8A-D784-4A6B-B78B-ACEA13F9FB0B}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{E8CC0D8A-D784-4A6B-B78B-ACEA13F9FB0B}.Release|Win32.Build.0 = Release|Win32
|
||||
{3104AB4E-CD31-4F47-95E9-0E8D9374E15D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3104AB4E-CD31-4F47-95E9-0E8D9374E15D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{3104AB4E-CD31-4F47-95E9-0E8D9374E15D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3104AB4E-CD31-4F47-95E9-0E8D9374E15D}.Release|Win32.Build.0 = Release|Win32
|
||||
{D1108F40-6ADF-467E-A95A-236C39A515C5}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D1108F40-6ADF-467E-A95A-236C39A515C5}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D1108F40-6ADF-467E-A95A-236C39A515C5}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{D1108F40-6ADF-467E-A95A-236C39A515C5}.Release|Win32.Build.0 = Release|Win32
|
||||
{CD007B57-7812-4930-A5E2-6E5E56338814}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{CD007B57-7812-4930-A5E2-6E5E56338814}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{CD007B57-7812-4930-A5E2-6E5E56338814}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{CD007B57-7812-4930-A5E2-6E5E56338814}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
+4
-20
@@ -40,7 +40,6 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D_SCL_SECURE_NO_WARNINGS"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
@@ -50,7 +49,6 @@
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4127;4355"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
@@ -106,7 +104,6 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/D_SCL_SECURE_NO_WARNINGS"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalIncludeDirectories="include"
|
||||
@@ -116,7 +113,6 @@
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
DebugInformationFormat="3"
|
||||
DisableSpecificWarnings="4127;4355"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
@@ -175,6 +171,10 @@
|
||||
RelativePath=".\src\aliascontent.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\content.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\conversion.cpp"
|
||||
>
|
||||
@@ -203,10 +203,6 @@
|
||||
RelativePath=".\src\sequence.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\tag.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Scanner"
|
||||
@@ -227,10 +223,6 @@
|
||||
RelativePath=".\src\scanscalar.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\scantag.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\scantoken.cpp"
|
||||
>
|
||||
@@ -345,10 +337,6 @@
|
||||
RelativePath=".\src\sequence.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\tag.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Scanner"
|
||||
@@ -373,10 +361,6 @@
|
||||
RelativePath=".\src\scanscalar.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\scantag.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\stream.h"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user