Merge clang-format from core

This commit is contained in:
Jesse Beder
2014-03-22 13:03:18 -05:00
72 changed files with 20508 additions and 20365 deletions

View File

@@ -1,16 +1,17 @@
#ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <cstddef> #include <cstddef>
namespace YAML namespace YAML {
{ typedef std::size_t anchor_t;
typedef std::size_t anchor_t; const anchor_t NullAnchor = 0;
const anchor_t NullAnchor = 0;
} }
#endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // ANCHOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,29 +1,33 @@
#ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include <vector> #include <vector>
namespace YAML namespace YAML {
{ std::string EncodeBase64(const unsigned char *data, std::size_t size);
std::string EncodeBase64(const unsigned char *data, std::size_t size); std::vector<unsigned char> DecodeBase64(const std::string &input);
std::vector<unsigned char> DecodeBase64(const std::string& input);
class Binary { class Binary {
public: public:
Binary(): m_unownedData(0), m_unownedSize(0) {} Binary() : m_unownedData(0), m_unownedSize(0) {}
Binary(const unsigned char *data_, std::size_t size_): m_unownedData(data_), m_unownedSize(size_) {} Binary(const unsigned char *data_, std::size_t size_)
: m_unownedData(data_), m_unownedSize(size_) {}
bool owned() const { return !m_unownedData; } bool owned() const { return !m_unownedData; }
std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; } std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; }
const unsigned char *data() const { return owned() ? &m_data[0] : m_unownedData; } const unsigned char *data() const {
return owned() ? &m_data[0] : m_unownedData;
}
void swap(std::vector<unsigned char>& rhs) { void swap(std::vector<unsigned char> &rhs) {
if(m_unownedData) { if (m_unownedData) {
m_data.swap(rhs); m_data.swap(rhs);
rhs.clear(); rhs.clear();
rhs.resize(m_unownedSize); rhs.resize(m_unownedSize);
@@ -35,28 +39,26 @@ namespace YAML
} }
} }
bool operator == (const Binary& rhs) const { bool operator==(const Binary &rhs) const {
const std::size_t s = size(); const std::size_t s = size();
if(s != rhs.size()) if (s != rhs.size())
return false; return false;
const unsigned char *d1 = data(); const unsigned char *d1 = data();
const unsigned char *d2 = rhs.data(); const unsigned char *d2 = rhs.data();
for(std::size_t i=0;i<s;i++) { for (std::size_t i = 0; i < s; i++) {
if(*d1++ != *d2++) if (*d1++ != *d2++)
return false; return false;
} }
return true; return true;
} }
bool operator != (const Binary& rhs) const { bool operator!=(const Binary &rhs) const { return !(*this == rhs); }
return !(*this == rhs);
}
private: private:
std::vector<unsigned char> m_data; std::vector<unsigned char> m_data;
const unsigned char *m_unownedData; const unsigned char *m_unownedData;
std::size_t m_unownedSize; std::size_t m_unownedSize;
}; };
} }
#endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // BASE64_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,7 +1,9 @@
#ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
@@ -9,34 +11,27 @@
#include "../anchor.h" #include "../anchor.h"
namespace YAML namespace YAML {
{ /// AnchorDict
/// AnchorDict /// . An object that stores and retrieves values correlating to anchor_t
/// . An object that stores and retrieves values correlating to anchor_t /// values.
/// values. /// . Efficient implementation that can make assumptions about how anchor_t
/// . Efficient implementation that can make assumptions about how anchor_t /// values are assigned by the Parser class.
/// values are assigned by the Parser class. template <class T>
template <class T> class AnchorDict {
class AnchorDict
{
public: public:
void Register(anchor_t anchor, T value) void Register(anchor_t anchor, T value) {
{ if (anchor > m_data.size()) {
if (anchor > m_data.size())
{
m_data.resize(anchor); m_data.resize(anchor);
} }
m_data[anchor - 1] = value; m_data[anchor - 1] = value;
} }
T Get(anchor_t anchor) const T Get(anchor_t anchor) const { return m_data[anchor - 1]; }
{
return m_data[anchor - 1];
}
private: private:
std::vector<T> m_data; std::vector<T> m_data;
}; };
} }
#endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // ANCHORDICT_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,89 +1,101 @@
#ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include <string> #include <string>
namespace YAML namespace YAML {
{ class Parser;
class Parser;
// GraphBuilderInterface // GraphBuilderInterface
// . Abstraction of node creation // . Abstraction of node creation
// . pParentNode is always NULL or the return value of one of the NewXXX() // . pParentNode is always NULL or the return value of one of the NewXXX()
// functions. // functions.
class GraphBuilderInterface class GraphBuilderInterface {
{
public: public:
// Create and return a new node with a null value. // Create and return a new node with a null value.
virtual void *NewNull(const Mark& mark, void *pParentNode) = 0; virtual void *NewNull(const Mark &mark, void *pParentNode) = 0;
// Create and return a new node with the given tag and value. // 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; virtual void *NewScalar(const Mark &mark, const std::string &tag,
void *pParentNode, const std::string &value) = 0;
// Create and return a new sequence node // Create and return a new sequence node
virtual void *NewSequence(const Mark& mark, const std::string& tag, void *pParentNode) = 0; 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() // Add pNode to pSequence. pNode was created with one of the NewXxx()
// functions and pSequence with NewSequence(). // functions and pSequence with NewSequence().
virtual void AppendToSequence(void *pSequence, void *pNode) = 0; virtual void AppendToSequence(void *pSequence, void *pNode) = 0;
// Note that no moew entries will be added to pSequence // Note that no moew entries will be added to pSequence
virtual void SequenceComplete(void *pSequence) {(void)pSequence;} virtual void SequenceComplete(void *pSequence) { (void)pSequence; }
// Create and return a new map node // Create and return a new map node
virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) = 0; virtual void *NewMap(const Mark &mark, const std::string &tag,
void *pParentNode) = 0;
// Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode // Add the pKeyNode => pValueNode mapping to pMap. pKeyNode and pValueNode
// were created with one of the NewXxx() methods and pMap with NewMap(). // were created with one of the NewXxx() methods and pMap with NewMap().
virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0; virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) = 0;
// Note that no more assignments will be made in pMap // Note that no more assignments will be made in pMap
virtual void MapComplete(void *pMap) {(void)pMap;} virtual void MapComplete(void *pMap) { (void)pMap; }
// Return the node that should be used in place of an alias referencing // Return the node that should be used in place of an alias referencing
// pNode (pNode by default) // pNode (pNode by default)
virtual void *AnchorReference(const Mark& mark, void *pNode) {(void)mark; return pNode;} virtual void *AnchorReference(const Mark &mark, void *pNode) {
}; (void)mark;
return pNode;
}
};
// Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines // Typesafe wrapper for GraphBuilderInterface. Assumes that Impl defines
// Node, Sequence, and Map types. Sequence and Map must derive from Node // Node, Sequence, and Map types. Sequence and Map must derive from Node
// (unless Node is defined as void). Impl must also implement function with // (unless Node is defined as void). Impl must also implement function with
// all of the same names as the virtual functions in GraphBuilderInterface // all of the same names as the virtual functions in GraphBuilderInterface
// -- including the ones with default implementations -- but with the // -- including the ones with default implementations -- but with the
// prototypes changed to accept an explicit Node*, Sequence*, or Map* where // prototypes changed to accept an explicit Node*, Sequence*, or Map* where
// appropriate. // appropriate.
template <class Impl> template <class Impl>
class GraphBuilder : public GraphBuilderInterface class GraphBuilder : public GraphBuilderInterface {
{
public: public:
typedef typename Impl::Node Node; typedef typename Impl::Node Node;
typedef typename Impl::Sequence Sequence; typedef typename Impl::Sequence Sequence;
typedef typename Impl::Map Map; typedef typename Impl::Map Map;
GraphBuilder(Impl& impl) : m_impl(impl) GraphBuilder(Impl &impl) : m_impl(impl) {
{ Map *pMap = NULL;
Map* pMap = NULL; Sequence *pSeq = NULL;
Sequence* pSeq = NULL; Node *pNode = NULL;
Node* pNode = NULL;
// Type consistency checks // Type consistency checks
pNode = pMap; pNode = pMap;
pNode = pSeq; pNode = pSeq;
} }
GraphBuilderInterface& AsBuilderInterface() {return *this;} GraphBuilderInterface &AsBuilderInterface() { return *this; }
virtual void *NewNull(const Mark& mark, void* pParentNode) { virtual void *NewNull(const Mark &mark, void *pParentNode) {
return CheckType<Node>(m_impl.NewNull(mark, AsNode(pParentNode))); return CheckType<Node>(m_impl.NewNull(mark, AsNode(pParentNode)));
} }
virtual void *NewScalar(const Mark& mark, const std::string& tag, void *pParentNode, const std::string& value) { virtual void *NewScalar(const Mark &mark, const std::string &tag,
return CheckType<Node>(m_impl.NewScalar(mark, tag, AsNode(pParentNode), value)); 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) { virtual void *NewSequence(const Mark &mark, const std::string &tag,
return CheckType<Sequence>(m_impl.NewSequence(mark, tag, AsNode(pParentNode))); void *pParentNode) {
return CheckType<Sequence>(
m_impl.NewSequence(mark, tag, AsNode(pParentNode)));
} }
virtual void AppendToSequence(void *pSequence, void *pNode) { virtual void AppendToSequence(void *pSequence, void *pNode) {
m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode)); m_impl.AppendToSequence(AsSequence(pSequence), AsNode(pNode));
@@ -92,42 +104,44 @@ namespace YAML
m_impl.SequenceComplete(AsSequence(pSequence)); m_impl.SequenceComplete(AsSequence(pSequence));
} }
virtual void *NewMap(const Mark& mark, const std::string& tag, void *pParentNode) { virtual void *NewMap(const Mark &mark, const std::string &tag,
void *pParentNode) {
return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode))); return CheckType<Map>(m_impl.NewMap(mark, tag, AsNode(pParentNode)));
} }
virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) { virtual void AssignInMap(void *pMap, void *pKeyNode, void *pValueNode) {
m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode)); m_impl.AssignInMap(AsMap(pMap), AsNode(pKeyNode), AsNode(pValueNode));
} }
virtual void MapComplete(void *pMap) { virtual void MapComplete(void *pMap) { m_impl.MapComplete(AsMap(pMap)); }
m_impl.MapComplete(AsMap(pMap));
}
virtual void *AnchorReference(const Mark& mark, void *pNode) { virtual void *AnchorReference(const Mark &mark, void *pNode) {
return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode))); return CheckType<Node>(m_impl.AnchorReference(mark, AsNode(pNode)));
} }
private: private:
Impl& m_impl; Impl &m_impl;
// Static check for pointer to T // Static check for pointer to T
template <class T, class U> template <class T, class U>
static T* CheckType(U* p) {return p;} 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);}
};
void *BuildGraphOfNextDocument(Parser& parser, GraphBuilderInterface& graphBuilder);
template <class Impl>
typename Impl::Node *BuildGraphOfNextDocument(Parser& parser, Impl& impl)
{
GraphBuilder<Impl> graphBuilder(impl);
return static_cast<typename Impl::Node *>(BuildGraphOfNextDocument(
parser, graphBuilder
));
} }
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); }
};
void *BuildGraphOfNextDocument(Parser &parser,
GraphBuilderInterface &graphBuilder);
template <class Impl>
typename Impl::Node *BuildGraphOfNextDocument(Parser &parser, Impl &impl) {
GraphBuilder<Impl> graphBuilder(impl);
return static_cast<typename Impl::Node *>(
BuildGraphOfNextDocument(parser, graphBuilder));
}
} }
#endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // GRAPHBUILDER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,27 +1,36 @@
#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
// The following ifdef block is the standard way of creating macros which make exporting // The following ifdef block is the standard way of creating macros which make
// from a DLL simpler. All files within this DLL are compiled with the yaml_cpp_EXPORTS // exporting
// symbol defined on the command line. this symbol should not be defined on any project // from a DLL simpler. All files within this DLL are compiled with the
// that uses this DLL. This way any other project whose source files include this file see // yaml_cpp_EXPORTS
// YAML_CPP_API functions as being imported from a DLL, whereas this DLL sees symbols // symbol defined on the command line. this symbol should not be defined on any
// project
// that uses this DLL. This way any other project whose source files include
// this file see
// YAML_CPP_API functions as being imported from a DLL, whereas this DLL sees
// symbols
// defined with this macro as being exported. // defined with this macro as being exported.
#undef YAML_CPP_API #undef YAML_CPP_API
#ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined manually) #ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined
#ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake or defined manually) // manually)
// #pragma message( "Defining YAML_CPP_API for DLL export" ) #ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake
#define YAML_CPP_API __declspec(dllexport) // or defined manually)
#else // yaml_cpp_EXPORTS // #pragma message( "Defining YAML_CPP_API for DLL export" )
// #pragma message( "Defining YAML_CPP_API for DLL import" ) #define YAML_CPP_API __declspec(dllexport)
#define YAML_CPP_API __declspec(dllimport) #else // yaml_cpp_EXPORTS
#endif // yaml_cpp_EXPORTS // #pragma message( "Defining YAML_CPP_API for DLL import" )
#else //YAML_CPP_DLL #define YAML_CPP_API __declspec(dllimport)
#endif // yaml_cpp_EXPORTS
#else // YAML_CPP_DLL
#define YAML_CPP_API #define YAML_CPP_API
#endif // YAML_CPP_DLL #endif // YAML_CPP_DLL

View File

@@ -1,19 +1,19 @@
#ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/eventhandler.h" #include "yaml-cpp/eventhandler.h"
#include <stack> #include <stack>
namespace YAML namespace YAML {
{ class Emitter;
class Emitter;
class EmitFromEvents: public EventHandler class EmitFromEvents : public EventHandler {
{
public: public:
EmitFromEvents(Emitter& emitter); EmitFromEvents(Emitter& emitter);
@@ -22,12 +22,15 @@ namespace YAML
virtual void OnNull(const Mark& mark, anchor_t anchor); virtual void OnNull(const Mark& mark, anchor_t anchor);
virtual void OnAlias(const Mark& mark, anchor_t anchor); virtual void OnAlias(const Mark& mark, anchor_t anchor);
virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value); virtual void 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 OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor);
virtual void OnSequenceEnd(); virtual void OnSequenceEnd();
virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor); virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor);
virtual void OnMapEnd(); virtual void OnMapEnd();
private: private:
@@ -37,9 +40,15 @@ namespace YAML
private: private:
Emitter& m_emitter; Emitter& m_emitter;
struct State { enum value { WaitingForSequenceEntry, WaitingForKey, WaitingForValue }; }; struct State {
std::stack<State::value> m_stateStack; enum value {
WaitingForSequenceEntry,
WaitingForKey,
WaitingForValue
}; };
};
std::stack<State::value> m_stateStack;
};
} }
#endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITFROMEVENTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,11 +1,12 @@
#ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/binary.h" #include "yaml-cpp/binary.h"
#include "yaml-cpp/emitterdef.h" #include "yaml-cpp/emitterdef.h"
@@ -17,19 +18,17 @@
#include <string> #include <string>
#include <sstream> #include <sstream>
namespace YAML namespace YAML {
{ class EmitterState;
class EmitterState;
class YAML_CPP_API Emitter: private noncopyable class YAML_CPP_API Emitter : private noncopyable {
{
public: public:
Emitter(); Emitter();
explicit Emitter(std::ostream& stream); explicit Emitter(std::ostream& stream);
~Emitter(); ~Emitter();
// output // output
const char *c_str() const; const char* c_str() const;
std::size_t size() const; std::size_t size() const;
// state checking // state checking
@@ -72,7 +71,8 @@ namespace YAML
Emitter& WriteStreamable(T value); Emitter& WriteStreamable(T value);
private: private:
template<typename T> void SetStreamablePrecision(std::stringstream&) {} template <typename T>
void SetStreamablePrecision(std::stringstream&) {}
unsigned GetFloatPrecision() const; unsigned GetFloatPrecision() const;
unsigned GetDoublePrecision() const; unsigned GetDoublePrecision() const;
@@ -111,18 +111,17 @@ namespace YAML
void SpaceOrIndentTo(bool requireSpace, unsigned indent); void SpaceOrIndentTo(bool requireSpace, unsigned indent);
const char *ComputeFullBoolName(bool b) const; const char* ComputeFullBoolName(bool b) const;
bool CanEmitNewline() const; bool CanEmitNewline() const;
private: private:
std::auto_ptr<EmitterState> m_pState; std::auto_ptr<EmitterState> m_pState;
ostream_wrapper m_stream; ostream_wrapper m_stream;
}; };
template <typename T> template <typename T>
inline Emitter& Emitter::WriteIntegralType(T value) inline Emitter& Emitter::WriteIntegralType(T value) {
{ if (!good())
if(!good())
return *this; return *this;
PrepareNode(EmitterNodeType::Scalar); PrepareNode(EmitterNodeType::Scalar);
@@ -135,12 +134,11 @@ namespace YAML
StartedScalar(); StartedScalar();
return *this; return *this;
} }
template <typename T> template <typename T>
inline Emitter& Emitter::WriteStreamable(T value) inline Emitter& Emitter::WriteStreamable(T value) {
{ if (!good())
if(!good())
return *this; return *this;
PrepareNode(EmitterNodeType::Scalar); PrepareNode(EmitterNodeType::Scalar);
@@ -153,57 +151,97 @@ namespace YAML
StartedScalar(); StartedScalar();
return *this; return *this;
} }
template<> template <>
inline void Emitter::SetStreamablePrecision<float>(std::stringstream& stream) inline void Emitter::SetStreamablePrecision<float>(std::stringstream& stream) {
{
stream.precision(GetFloatPrecision()); stream.precision(GetFloatPrecision());
} }
template<> template <>
inline void Emitter::SetStreamablePrecision<double>(std::stringstream& stream) inline void Emitter::SetStreamablePrecision<double>(std::stringstream& stream) {
{
stream.precision(GetDoublePrecision()); stream.precision(GetDoublePrecision());
} }
// overloads of insertion // overloads of insertion
inline Emitter& operator << (Emitter& emitter, const std::string& v) { return emitter.Write(v); } inline Emitter& operator<<(Emitter& emitter, const std::string& v) {
inline Emitter& operator << (Emitter& emitter, bool v) { return emitter.Write(v); } return emitter.Write(v);
inline Emitter& operator << (Emitter& emitter, char v) { return emitter.Write(v); } }
inline Emitter& operator << (Emitter& emitter, unsigned char v) { return emitter.Write(static_cast<char>(v)); } inline Emitter& operator<<(Emitter& emitter, bool v) {
inline Emitter& operator << (Emitter& emitter, const _Alias& v) { return emitter.Write(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, char v) {
inline Emitter& operator << (Emitter& emitter, const _Comment& v) { return emitter.Write(v); } return emitter.Write(v);
inline Emitter& operator << (Emitter& emitter, const _Null& v) { return emitter.Write(v); } }
inline Emitter& operator << (Emitter& emitter, const Binary& b) { return emitter.Write(b); } inline Emitter& operator<<(Emitter& emitter, unsigned char v) {
return emitter.Write(static_cast<char>(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 Binary& b) {
return emitter.Write(b);
}
inline Emitter& operator << (Emitter& emitter, const char *v) { return emitter.Write(std::string(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, int v) {
inline Emitter& operator << (Emitter& emitter, unsigned int v) { return emitter.WriteIntegralType(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, unsigned int v) {
inline Emitter& operator << (Emitter& emitter, long v) { return emitter.WriteIntegralType(v); } return emitter.WriteIntegralType(v);
inline Emitter& operator << (Emitter& emitter, unsigned long v) { return emitter.WriteIntegralType(v); } }
inline Emitter& operator << (Emitter& emitter, long long v) { return emitter.WriteIntegralType(v); } inline Emitter& operator<<(Emitter& emitter, short v) {
inline Emitter& operator << (Emitter& emitter, unsigned long long v) { return emitter.WriteIntegralType(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, long long v) {
return emitter.WriteIntegralType(v);
}
inline Emitter& operator<<(Emitter& emitter, unsigned long long v) {
return emitter.WriteIntegralType(v);
}
inline Emitter& operator << (Emitter& emitter, float v) { return emitter.WriteStreamable(v); } inline Emitter& operator<<(Emitter& emitter, float v) {
inline Emitter& operator << (Emitter& emitter, double v) { return emitter.WriteStreamable(v); } return emitter.WriteStreamable(v);
}
inline Emitter& operator<<(Emitter& emitter, double v) {
return emitter.WriteStreamable(v);
}
inline Emitter& operator << (Emitter& emitter, EMITTER_MANIP value) { inline Emitter& operator<<(Emitter& emitter, EMITTER_MANIP value) {
return emitter.SetLocalValue(value); return emitter.SetLocalValue(value);
} }
inline Emitter& operator << (Emitter& emitter, _Indent indent) { inline Emitter& operator<<(Emitter& emitter, _Indent indent) {
return emitter.SetLocalIndent(indent); return emitter.SetLocalIndent(indent);
} }
inline Emitter& operator << (Emitter& emitter, _Precision precision) { inline Emitter& operator<<(Emitter& emitter, _Precision precision) {
return emitter.SetLocalPrecision(precision); return emitter.SetLocalPrecision(precision);
} }
} }
#endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,13 +1,24 @@
#ifndef EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
namespace YAML namespace YAML {
{ struct EmitterNodeType {
struct EmitterNodeType { enum value { None, Property, Scalar, FlowSeq, BlockSeq, FlowMap, BlockMap }; }; enum value {
None,
Property,
Scalar,
FlowSeq,
BlockSeq,
FlowMap,
BlockMap
};
};
} }
#endif // EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTERDEF_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,16 +1,16 @@
#ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
namespace YAML namespace YAML {
{ enum EMITTER_MANIP {
enum EMITTER_MANIP {
// general manipulators // general manipulators
Auto, Auto,
TagByKind, TagByKind,
@@ -60,90 +60,82 @@ namespace YAML
// Block, // duplicate // Block, // duplicate
// Auto, // duplicate // Auto, // duplicate
LongKey LongKey
}; };
struct _Indent { struct _Indent {
_Indent(int value_): value(value_) {} _Indent(int value_) : value(value_) {}
int value; int value;
}; };
inline _Indent Indent(int value) { inline _Indent Indent(int value) { return _Indent(value); }
return _Indent(value);
}
struct _Alias { struct _Alias {
_Alias(const std::string& content_): content(content_) {} _Alias(const std::string& content_) : content(content_) {}
std::string content; std::string content;
}; };
inline _Alias Alias(const std::string content) { inline _Alias Alias(const std::string content) { return _Alias(content); }
return _Alias(content);
}
struct _Anchor { struct _Anchor {
_Anchor(const std::string& content_): content(content_) {} _Anchor(const std::string& content_) : content(content_) {}
std::string content; std::string content;
};
inline _Anchor Anchor(const std::string content) { return _Anchor(content); }
struct _Tag {
struct Type {
enum value {
Verbatim,
PrimaryHandle,
NamedHandle
};
}; };
inline _Anchor Anchor(const std::string content) { explicit _Tag(const std::string& prefix_, const std::string& content_,
return _Anchor(content); Type::value type_)
} : prefix(prefix_), content(content_), type(type_) {}
struct _Tag {
struct Type { enum value { Verbatim, PrimaryHandle, NamedHandle }; };
explicit _Tag(const std::string& prefix_, const std::string& content_, Type::value type_)
: prefix(prefix_), content(content_), type(type_)
{
}
std::string prefix; std::string prefix;
std::string content; std::string content;
Type::value type; Type::value type;
}; };
inline _Tag VerbatimTag(const std::string content) { inline _Tag VerbatimTag(const std::string content) {
return _Tag("", content, _Tag::Type::Verbatim); return _Tag("", content, _Tag::Type::Verbatim);
} }
inline _Tag LocalTag(const std::string content) { inline _Tag LocalTag(const std::string content) {
return _Tag("", content, _Tag::Type::PrimaryHandle); return _Tag("", content, _Tag::Type::PrimaryHandle);
} }
inline _Tag LocalTag(const std::string& prefix, const std::string content) { inline _Tag LocalTag(const std::string& prefix, const std::string content) {
return _Tag(prefix, content, _Tag::Type::NamedHandle); return _Tag(prefix, content, _Tag::Type::NamedHandle);
} }
inline _Tag SecondaryTag(const std::string content) { inline _Tag SecondaryTag(const std::string content) {
return _Tag("", content, _Tag::Type::NamedHandle); return _Tag("", content, _Tag::Type::NamedHandle);
} }
struct _Comment { struct _Comment {
_Comment(const std::string& content_): content(content_) {} _Comment(const std::string& content_) : content(content_) {}
std::string content; std::string content;
}; };
inline _Comment Comment(const std::string content) { inline _Comment Comment(const std::string content) { return _Comment(content); }
return _Comment(content);
}
struct _Precision { struct _Precision {
_Precision(int floatPrecision_, int doublePrecision_): floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {} _Precision(int floatPrecision_, int doublePrecision_)
: floatPrecision(floatPrecision_), doublePrecision(doublePrecision_) {}
int floatPrecision; int floatPrecision;
int doublePrecision; int doublePrecision;
}; };
inline _Precision FloatPrecision(int n) { inline _Precision FloatPrecision(int n) { return _Precision(n, -1); }
return _Precision(n, -1);
}
inline _Precision DoublePrecision(int n) { inline _Precision DoublePrecision(int n) { return _Precision(-1, n); }
return _Precision(-1, n);
}
inline _Precision Precision(int n) { inline _Precision Precision(int n) { return _Precision(n, n); }
return _Precision(n, n);
}
} }
#endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTERMANIP_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,19 +1,19 @@
#ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/anchor.h" #include "yaml-cpp/anchor.h"
#include <string> #include <string>
namespace YAML namespace YAML {
{ struct Mark;
struct Mark;
class EventHandler class EventHandler {
{
public: public:
virtual ~EventHandler() {} virtual ~EventHandler() {}
@@ -22,15 +22,17 @@ namespace YAML
virtual void OnNull(const Mark& mark, anchor_t anchor) = 0; virtual void OnNull(const Mark& mark, anchor_t anchor) = 0;
virtual void OnAlias(const Mark& mark, 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 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 OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor) = 0;
virtual void OnSequenceEnd() = 0; virtual void OnSequenceEnd() = 0;
virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor) = 0; virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor) = 0;
virtual void OnMapEnd() = 0; virtual void OnMapEnd() = 0;
}; };
} }
#endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EVENTHANDLER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,17 +1,17 @@
#ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
namespace YAML namespace YAML {
{ struct YAML_CPP_API Mark {
struct YAML_CPP_API Mark { Mark() : pos(0), line(0), column(0) {}
Mark(): pos(0), line(0), column(0) {}
static const Mark null_mark() { return Mark(-1, -1, -1); } static const Mark null_mark() { return Mark(-1, -1, -1); }
@@ -19,8 +19,9 @@ namespace YAML
int line, column; int line, column;
private: private:
Mark(int pos_, int line_, int column_): pos(pos_), line(line_), column(column_) {} Mark(int pos_, int line_, int column_)
}; : pos(pos_), line(line_), column(column_) {}
};
} }
#endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // MARK_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,25 +1,25 @@
#ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
namespace YAML namespace YAML {
{ // this is basically boost::noncopyable
// this is basically boost::noncopyable class YAML_CPP_API noncopyable {
class YAML_CPP_API noncopyable
{
protected: protected:
noncopyable() {} noncopyable() {}
~noncopyable() {} ~noncopyable() {}
private: private:
noncopyable(const noncopyable&); noncopyable(const noncopyable&);
const noncopyable& operator = (const noncopyable&); const noncopyable& operator=(const noncopyable&);
}; };
} }
#endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,25 +1,24 @@
#ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
namespace YAML namespace YAML {
{ class Node;
class Node;
struct YAML_CPP_API _Null {}; struct YAML_CPP_API _Null {};
inline bool operator == (const _Null&, const _Null&) { return true; } inline bool operator==(const _Null&, const _Null&) { return true; }
inline bool operator != (const _Null&, const _Null&) { return false; } inline bool operator!=(const _Null&, const _Null&) { return false; }
YAML_CPP_API bool IsNull(const Node& node); // old API only YAML_CPP_API bool IsNull(const Node& node); // old API only
extern YAML_CPP_API _Null Null; extern YAML_CPP_API _Null Null;
} }
#endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,30 +1,29 @@
#ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include <vector> #include <vector>
namespace YAML namespace YAML {
{ class ostream_wrapper {
class ostream_wrapper
{
public: public:
ostream_wrapper(); ostream_wrapper();
explicit ostream_wrapper(std::ostream& stream); explicit ostream_wrapper(std::ostream& stream);
~ostream_wrapper(); ~ostream_wrapper();
void write(const std::string& str); void write(const std::string& str);
void write(const char *str, std::size_t size); void write(const char* str, std::size_t size);
void set_comment() { m_comment = true; } void set_comment() { m_comment = true; }
const char *str() const { const char* str() const {
if(m_pStream) { if (m_pStream) {
return 0; return 0;
} else { } else {
m_buffer[m_pos] = '\0'; m_buffer[m_pos] = '\0';
@@ -42,28 +41,30 @@ namespace YAML
private: private:
mutable std::vector<char> m_buffer; mutable std::vector<char> m_buffer;
std::ostream *m_pStream; std::ostream* m_pStream;
std::size_t m_pos; std::size_t m_pos;
std::size_t m_row, m_col; std::size_t m_row, m_col;
bool m_comment; bool m_comment;
}; };
template<std::size_t N> template <std::size_t N>
inline ostream_wrapper& operator << (ostream_wrapper& stream, const char (&str)[N]) { inline ostream_wrapper& operator<<(ostream_wrapper& stream,
stream.write(str, N-1); const char (&str)[N]) {
stream.write(str, N - 1);
return stream; return stream;
} }
inline ostream_wrapper& operator << (ostream_wrapper& stream, const std::string& str) { inline ostream_wrapper& operator<<(ostream_wrapper& stream,
const std::string& str) {
stream.write(str); stream.write(str);
return stream; return stream;
} }
inline ostream_wrapper& operator << (ostream_wrapper& stream, char ch) { inline ostream_wrapper& operator<<(ostream_wrapper& stream, char ch) {
stream.write(&ch, 1); stream.write(&ch, 1);
return stream; return stream;
} }
} }
#endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // OSTREAM_WRAPPER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,51 +1,51 @@
#ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <vector> #include <vector>
#include <list> #include <list>
#include <set> #include <set>
#include <map> #include <map>
namespace YAML namespace YAML {
{ template <typename Seq>
template<typename Seq> inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) {
inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) {
emitter << BeginSeq; emitter << BeginSeq;
for(typename Seq::const_iterator it=seq.begin();it!=seq.end();++it) for (typename Seq::const_iterator it = seq.begin(); it != seq.end(); ++it)
emitter << *it; emitter << *it;
emitter << EndSeq; emitter << EndSeq;
return emitter; return emitter;
} }
template<typename T> template <typename T>
inline Emitter& operator << (Emitter& emitter, const std::vector<T>& v) { inline Emitter& operator<<(Emitter& emitter, const std::vector<T>& v) {
return EmitSeq(emitter, v); return EmitSeq(emitter, v);
} }
template<typename T> template <typename T>
inline Emitter& operator << (Emitter& emitter, const std::list<T>& v) { inline Emitter& operator<<(Emitter& emitter, const std::list<T>& v) {
return EmitSeq(emitter, v); return EmitSeq(emitter, v);
} }
template<typename T> template <typename T>
inline Emitter& operator << (Emitter& emitter, const std::set<T>& v) { inline Emitter& operator<<(Emitter& emitter, const std::set<T>& v) {
return EmitSeq(emitter, v); return EmitSeq(emitter, v);
} }
template <typename K, typename V> template <typename K, typename V>
inline Emitter& operator << (Emitter& emitter, const std::map<K, V>& m) { inline Emitter& operator<<(Emitter& emitter, const std::map<K, V>& m) {
typedef typename std::map <K, V> map; typedef typename std::map<K, V> map;
emitter << BeginMap; emitter << BeginMap;
for(typename map::const_iterator it=m.begin();it!=m.end();++it) for (typename map::const_iterator it = m.begin(); it != m.end(); ++it)
emitter << Key << it->first << Value << it->second; emitter << Key << it->first << Value << it->second;
emitter << EndMap; emitter << EndMap;
return emitter; return emitter;
} }
} }
#endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // STLEMITTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,57 +1,135 @@
#ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
namespace YAML {
template <typename>
struct is_numeric {
enum {
value = false
};
};
namespace YAML template <>
{ struct is_numeric<char> {
template <typename> enum {
struct is_numeric { enum { value = false }; }; value = true
};
template <> struct is_numeric <char> { enum { value = true }; }; };
template <> struct is_numeric <unsigned char> { enum { value = true }; }; template <>
template <> struct is_numeric <int> { enum { value = true }; }; struct is_numeric<unsigned char> {
template <> struct is_numeric <unsigned int> { enum { value = true }; }; enum {
template <> struct is_numeric <long int> { enum { value = true }; }; 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<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
};
};
#if defined(_MSC_VER) && (_MSC_VER < 1310) #if defined(_MSC_VER) && (_MSC_VER < 1310)
template <> struct is_numeric <__int64> { enum { value = true }; }; template <>
template <> struct is_numeric <unsigned __int64> { enum { value = true }; }; struct is_numeric<__int64> {
enum {
value = true
};
};
template <>
struct is_numeric<unsigned __int64> {
enum {
value = true
};
};
#else #else
template <> struct is_numeric <long long> { enum { value = true }; }; template <>
template <> struct is_numeric <unsigned long long> { enum { value = true }; }; struct is_numeric<long long> {
enum {
value = true
};
};
template <>
struct is_numeric<unsigned long long> {
enum {
value = true
};
};
#endif #endif
template <> struct is_numeric <float> { enum { value = true }; }; template <>
template <> struct is_numeric <double> { enum { value = true }; }; struct is_numeric<float> {
template <> struct is_numeric <long double> { enum { value = true }; }; enum {
value = true
template <bool, class T = void>
struct enable_if_c {
typedef T type;
}; };
};
template <class T> template <>
struct enable_if_c<false, T> {}; struct is_numeric<double> {
enum {
template <class Cond, class T = void> value = true
struct enable_if : public enable_if_c<Cond::value, T> {};
template <bool, class T = void>
struct disable_if_c {
typedef T type;
}; };
};
template <>
struct is_numeric<long double> {
enum {
value = true
};
};
template <class T> template <bool, class T = void>
struct disable_if_c<true, T> {}; struct enable_if_c {
typedef T type;
};
template <class Cond, class T = void> template <class T>
struct disable_if : public disable_if_c<Cond::value, 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 #endif // TRAITS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,11 +1,10 @@
#include "yaml-cpp/binary.h" #include "yaml-cpp/binary.h"
namespace YAML namespace YAML {
{ static const char encoding[] =
static const char encoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string EncodeBase64(const unsigned char *data, std::size_t size) std::string EncodeBase64(const unsigned char *data, std::size_t size) {
{
const char PAD = '='; const char PAD = '=';
std::string ret; std::string ret;
@@ -15,14 +14,14 @@ namespace YAML
std::size_t chunks = size / 3; std::size_t chunks = size / 3;
std::size_t remainder = size % 3; std::size_t remainder = size % 3;
for(std::size_t i=0;i<chunks;i++, data += 3) { for (std::size_t i = 0; i < chunks; i++, data += 3) {
*out++ = encoding[data[0] >> 2]; *out++ = encoding[data[0] >> 2];
*out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)]; *out++ = encoding[((data[0] & 0x3) << 4) | (data[1] >> 4)];
*out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)]; *out++ = encoding[((data[1] & 0xf) << 2) | (data[2] >> 6)];
*out++ = encoding[data[2] & 0x3f]; *out++ = encoding[data[2] & 0x3f];
} }
switch(remainder) { switch (remainder) {
case 0: case 0:
break; break;
case 1: case 1:
@@ -41,53 +40,53 @@ namespace YAML
ret.resize(out - &ret[0]); ret.resize(out - &ret[0]);
return ret; return ret;
} }
static const unsigned char decoding[] = { static const unsigned char decoding[] = {
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 255, 0, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
}; 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, };
std::vector<unsigned char> DecodeBase64(const std::string& input) std::vector<unsigned char> DecodeBase64(const std::string &input) {
{
typedef std::vector<unsigned char> ret_type; typedef std::vector<unsigned char> ret_type;
if(input.empty()) if (input.empty())
return ret_type(); return ret_type();
ret_type ret(3 * input.size() / 4 + 1); ret_type ret(3 * input.size() / 4 + 1);
unsigned char *out = &ret[0]; unsigned char *out = &ret[0];
unsigned value = 0; unsigned value = 0;
for(std::size_t i=0;i<input.size();i++) { for (std::size_t i = 0; i < input.size(); i++) {
unsigned char d = decoding[static_cast<unsigned>(input[i])]; unsigned char d = decoding[static_cast<unsigned>(input[i])];
if(d == 255) if (d == 255)
return ret_type(); return ret_type();
value = (value << 6) | d; value = (value << 6) | d;
if(i % 4 == 3) { if (i % 4 == 3) {
*out++ = value >> 16; *out++ = value >> 16;
if(i > 0 && input[i - 1] != '=') if (i > 0 && input[i - 1] != '=')
*out++ = value >> 8; *out++ = value >> 8;
if(input[i] != '=') if (input[i] != '=')
*out++ = value; *out++ = value;
} }
} }
ret.resize(out - &ret[0]); ret.resize(out - &ret[0]);
return ret; return ret;
} }
} }

View File

@@ -1,35 +1,46 @@
#ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <stack> #include <stack>
#include <cassert> #include <cassert>
namespace YAML namespace YAML {
{ struct CollectionType {
struct CollectionType { enum value {
enum value { None, BlockMap, BlockSeq, FlowMap, FlowSeq, CompactMap }; None,
BlockMap,
BlockSeq,
FlowMap,
FlowSeq,
CompactMap
}; };
};
class CollectionStack class CollectionStack {
{
public: public:
CollectionType::value GetCurCollectionType() const { CollectionType::value GetCurCollectionType() const {
if(collectionStack.empty()) if (collectionStack.empty())
return CollectionType::None; return CollectionType::None;
return collectionStack.top(); return collectionStack.top();
} }
void PushCollectionType(CollectionType::value type) { collectionStack.push(type); } void PushCollectionType(CollectionType::value type) {
void PopCollectionType(CollectionType::value type) { assert(type == GetCurCollectionType()); collectionStack.pop(); } collectionStack.push(type);
}
void PopCollectionType(CollectionType::value type) {
assert(type == GetCurCollectionType());
collectionStack.pop();
}
private: private:
std::stack<CollectionType::value> collectionStack; std::stack<CollectionType::value> collectionStack;
}; };
} }
#endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // COLLECTIONSTACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -2,15 +2,14 @@
#include "yaml-cpp/contrib/graphbuilder.h" #include "yaml-cpp/contrib/graphbuilder.h"
#include "graphbuilderadapter.h" #include "graphbuilderadapter.h"
namespace YAML namespace YAML {
{ void* BuildGraphOfNextDocument(Parser& parser,
void *BuildGraphOfNextDocument(Parser& parser, GraphBuilderInterface& graphBuilder) GraphBuilderInterface& graphBuilder) {
{
GraphBuilderAdapter eventHandler(graphBuilder); GraphBuilderAdapter eventHandler(graphBuilder);
if (parser.HandleNextDocument(eventHandler)) { if (parser.HandleNextDocument(eventHandler)) {
return eventHandler.RootNode(); return eventHandler.RootNode();
} else { } else {
return NULL; return NULL;
} }
} }
} }

View File

@@ -1,81 +1,74 @@
#include "graphbuilderadapter.h" #include "graphbuilderadapter.h"
namespace YAML namespace YAML {
{ int GraphBuilderAdapter::ContainerFrame::sequenceMarker;
int GraphBuilderAdapter::ContainerFrame::sequenceMarker;
void GraphBuilderAdapter::OnNull(const Mark& mark, anchor_t anchor) void GraphBuilderAdapter::OnNull(const Mark &mark, anchor_t anchor) {
{
void *pParent = GetCurrentParent(); void *pParent = GetCurrentParent();
void *pNode = m_builder.NewNull(mark, pParent); void *pNode = m_builder.NewNull(mark, pParent);
RegisterAnchor(anchor, pNode); RegisterAnchor(anchor, pNode);
DispositionNode(pNode); DispositionNode(pNode);
} }
void GraphBuilderAdapter::OnAlias(const Mark& mark, anchor_t anchor) void GraphBuilderAdapter::OnAlias(const Mark &mark, anchor_t anchor) {
{
void *pReffedNode = m_anchors.Get(anchor); void *pReffedNode = m_anchors.Get(anchor);
DispositionNode(m_builder.AnchorReference(mark, pReffedNode)); DispositionNode(m_builder.AnchorReference(mark, pReffedNode));
} }
void GraphBuilderAdapter::OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value) void GraphBuilderAdapter::OnScalar(const Mark &mark, const std::string &tag,
{ anchor_t anchor, const std::string &value) {
void *pParent = GetCurrentParent(); void *pParent = GetCurrentParent();
void *pNode = m_builder.NewScalar(mark, tag, pParent, value); void *pNode = m_builder.NewScalar(mark, tag, pParent, value);
RegisterAnchor(anchor, pNode); RegisterAnchor(anchor, pNode);
DispositionNode(pNode); DispositionNode(pNode);
} }
void GraphBuilderAdapter::OnSequenceStart(const Mark& mark, const std::string& tag, anchor_t anchor) void GraphBuilderAdapter::OnSequenceStart(const Mark &mark,
{ const std::string &tag,
anchor_t anchor) {
void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent()); void *pNode = m_builder.NewSequence(mark, tag, GetCurrentParent());
m_containers.push(ContainerFrame(pNode)); m_containers.push(ContainerFrame(pNode));
RegisterAnchor(anchor, pNode); RegisterAnchor(anchor, pNode);
} }
void GraphBuilderAdapter::OnSequenceEnd() void GraphBuilderAdapter::OnSequenceEnd() {
{
void *pSequence = m_containers.top().pContainer; void *pSequence = m_containers.top().pContainer;
m_containers.pop(); m_containers.pop();
DispositionNode(pSequence); DispositionNode(pSequence);
} }
void GraphBuilderAdapter::OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor) void GraphBuilderAdapter::OnMapStart(const Mark &mark, const std::string &tag,
{ anchor_t anchor) {
void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent()); void *pNode = m_builder.NewMap(mark, tag, GetCurrentParent());
m_containers.push(ContainerFrame(pNode, m_pKeyNode)); m_containers.push(ContainerFrame(pNode, m_pKeyNode));
m_pKeyNode = NULL; m_pKeyNode = NULL;
RegisterAnchor(anchor, pNode); RegisterAnchor(anchor, pNode);
} }
void GraphBuilderAdapter::OnMapEnd() void GraphBuilderAdapter::OnMapEnd() {
{
void *pMap = m_containers.top().pContainer; void *pMap = m_containers.top().pContainer;
m_pKeyNode = m_containers.top().pPrevKeyNode; m_pKeyNode = m_containers.top().pPrevKeyNode;
m_containers.pop(); m_containers.pop();
DispositionNode(pMap); DispositionNode(pMap);
} }
void *GraphBuilderAdapter::GetCurrentParent() const void *GraphBuilderAdapter::GetCurrentParent() const {
{
if (m_containers.empty()) { if (m_containers.empty()) {
return NULL; return NULL;
} }
return m_containers.top().pContainer; return m_containers.top().pContainer;
} }
void GraphBuilderAdapter::RegisterAnchor(anchor_t anchor, void *pNode) void GraphBuilderAdapter::RegisterAnchor(anchor_t anchor, void *pNode) {
{
if (anchor) { if (anchor) {
m_anchors.Register(anchor, pNode); m_anchors.Register(anchor, pNode);
} }
} }
void GraphBuilderAdapter::DispositionNode(void *pNode) void GraphBuilderAdapter::DispositionNode(void *pNode) {
{
if (m_containers.empty()) { if (m_containers.empty()) {
m_pRootNode = pNode; m_pRootNode = pNode;
return; return;
@@ -92,5 +85,5 @@ namespace YAML
} else { } else {
m_builder.AppendToSequence(pContainer, pNode); m_builder.AppendToSequence(pContainer, pNode);
} }
} }
} }

View File

@@ -1,7 +1,9 @@
#ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
@@ -12,45 +14,41 @@
#include "yaml-cpp/contrib/anchordict.h" #include "yaml-cpp/contrib/anchordict.h"
#include "yaml-cpp/contrib/graphbuilder.h" #include "yaml-cpp/contrib/graphbuilder.h"
namespace YAML namespace YAML {
{ class GraphBuilderAdapter : public EventHandler {
class GraphBuilderAdapter : public EventHandler
{
public: public:
GraphBuilderAdapter(GraphBuilderInterface& builder) GraphBuilderAdapter(GraphBuilderInterface& builder)
: m_builder(builder), m_pRootNode(NULL), m_pKeyNode(NULL) : m_builder(builder), m_pRootNode(NULL), m_pKeyNode(NULL) {}
{
}
virtual void OnDocumentStart(const Mark& mark) {(void)mark;} virtual void OnDocumentStart(const Mark& mark) { (void)mark; }
virtual void OnDocumentEnd() {} virtual void OnDocumentEnd() {}
virtual void OnNull(const Mark& mark, anchor_t anchor); virtual void OnNull(const Mark& mark, anchor_t anchor);
virtual void OnAlias(const Mark& mark, anchor_t anchor); virtual void OnAlias(const Mark& mark, anchor_t anchor);
virtual void OnScalar(const Mark& mark, const std::string& tag, anchor_t anchor, const std::string& value); virtual void 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 OnSequenceStart(const Mark& mark, const std::string& tag,
anchor_t anchor);
virtual void OnSequenceEnd(); virtual void OnSequenceEnd();
virtual void OnMapStart(const Mark& mark, const std::string& tag, anchor_t anchor); virtual void OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor);
virtual void OnMapEnd(); virtual void OnMapEnd();
void *RootNode() const {return m_pRootNode;} void* RootNode() const { return m_pRootNode; }
private: private:
struct ContainerFrame struct ContainerFrame {
{ ContainerFrame(void* pSequence)
ContainerFrame(void *pSequence) : pContainer(pSequence), pPrevKeyNode(&sequenceMarker) {}
: pContainer(pSequence), pPrevKeyNode(&sequenceMarker) ContainerFrame(void* pMap, void* pPrevKeyNode)
{} : pContainer(pMap), pPrevKeyNode(pPrevKeyNode) {}
ContainerFrame(void *pMap, void* pPrevKeyNode)
: pContainer(pMap), pPrevKeyNode(pPrevKeyNode)
{}
void *pContainer; void* pContainer;
void *pPrevKeyNode; void* pPrevKeyNode;
bool isMap() const {return pPrevKeyNode != &sequenceMarker;} bool isMap() const { return pPrevKeyNode != &sequenceMarker; }
private: private:
static int sequenceMarker; static int sequenceMarker;
@@ -61,13 +59,13 @@ namespace YAML
GraphBuilderInterface& m_builder; GraphBuilderInterface& m_builder;
ContainerStack m_containers; ContainerStack m_containers;
AnchorMap m_anchors; AnchorMap m_anchors;
void *m_pRootNode; void* m_pRootNode;
void *m_pKeyNode; void* m_pKeyNode;
void *GetCurrentParent() const; void* GetCurrentParent() const;
void RegisterAnchor(anchor_t anchor, void *pNode); void RegisterAnchor(anchor_t anchor, void* pNode);
void DispositionNode(void *pNode); void DispositionNode(void* pNode);
}; };
} }
#endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // GRAPHBUILDERADAPTER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,24 +1,22 @@
#include "directives.h" #include "directives.h"
namespace YAML namespace YAML {
{ Directives::Directives() {
Directives::Directives()
{
// version // version
version.isDefault = true; version.isDefault = true;
version.major = 1; version.major = 1;
version.minor = 2; version.minor = 2;
} }
const std::string Directives::TranslateTagHandle(const std::string& handle) const const std::string Directives::TranslateTagHandle(const std::string& handle)
{ const {
std::map <std::string, std::string>::const_iterator it = tags.find(handle); std::map<std::string, std::string>::const_iterator it = tags.find(handle);
if(it == tags.end()) { if (it == tags.end()) {
if(handle == "!!") if (handle == "!!")
return "tag:yaml.org,2002:"; return "tag:yaml.org,2002:";
return handle; return handle;
} }
return it->second; return it->second;
} }
} }

View File

@@ -1,29 +1,29 @@
#ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include <map> #include <map>
namespace YAML namespace YAML {
{ struct Version {
struct Version {
bool isDefault; bool isDefault;
int major, minor; int major, minor;
}; };
struct Directives { struct Directives {
Directives(); Directives();
const std::string TranslateTagHandle(const std::string& handle) const; const std::string TranslateTagHandle(const std::string& handle) const;
Version version; Version version;
std::map<std::string, std::string> tags; std::map<std::string, std::string> tags;
}; };
} }
#endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // DIRECTIVES_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -5,83 +5,71 @@
#include <sstream> #include <sstream>
namespace { namespace {
std::string ToString(YAML::anchor_t anchor) { std::string ToString(YAML::anchor_t anchor) {
std::stringstream stream; std::stringstream stream;
stream << anchor; stream << anchor;
return stream.str(); return stream.str();
} }
} }
namespace YAML namespace YAML {
{ EmitFromEvents::EmitFromEvents(Emitter& emitter) : m_emitter(emitter) {}
EmitFromEvents::EmitFromEvents(Emitter& emitter): m_emitter(emitter)
{
}
void EmitFromEvents::OnDocumentStart(const Mark&) void EmitFromEvents::OnDocumentStart(const Mark&) {}
{
}
void EmitFromEvents::OnDocumentEnd() void EmitFromEvents::OnDocumentEnd() {}
{
}
void EmitFromEvents::OnNull(const Mark&, anchor_t anchor) void EmitFromEvents::OnNull(const Mark&, anchor_t anchor) {
{
BeginNode(); BeginNode();
EmitProps("", anchor); EmitProps("", anchor);
m_emitter << Null; m_emitter << Null;
} }
void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor) void EmitFromEvents::OnAlias(const Mark&, anchor_t anchor) {
{
BeginNode(); BeginNode();
m_emitter << Alias(ToString(anchor)); m_emitter << Alias(ToString(anchor));
} }
void EmitFromEvents::OnScalar(const Mark&, const std::string& tag, anchor_t anchor, const std::string& value) void EmitFromEvents::OnScalar(const Mark&, const std::string& tag,
{ anchor_t anchor, const std::string& value) {
BeginNode(); BeginNode();
EmitProps(tag, anchor); EmitProps(tag, anchor);
m_emitter << value; m_emitter << value;
} }
void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag, anchor_t anchor) void EmitFromEvents::OnSequenceStart(const Mark&, const std::string& tag,
{ anchor_t anchor) {
BeginNode(); BeginNode();
EmitProps(tag, anchor); EmitProps(tag, anchor);
m_emitter << BeginSeq; m_emitter << BeginSeq;
m_stateStack.push(State::WaitingForSequenceEntry); m_stateStack.push(State::WaitingForSequenceEntry);
} }
void EmitFromEvents::OnSequenceEnd() void EmitFromEvents::OnSequenceEnd() {
{
m_emitter << EndSeq; m_emitter << EndSeq;
assert(m_stateStack.top() == State::WaitingForSequenceEntry); assert(m_stateStack.top() == State::WaitingForSequenceEntry);
m_stateStack.pop(); m_stateStack.pop();
} }
void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag, anchor_t anchor) void EmitFromEvents::OnMapStart(const Mark&, const std::string& tag,
{ anchor_t anchor) {
BeginNode(); BeginNode();
EmitProps(tag, anchor); EmitProps(tag, anchor);
m_emitter << BeginMap; m_emitter << BeginMap;
m_stateStack.push(State::WaitingForKey); m_stateStack.push(State::WaitingForKey);
} }
void EmitFromEvents::OnMapEnd() void EmitFromEvents::OnMapEnd() {
{
m_emitter << EndMap; m_emitter << EndMap;
assert(m_stateStack.top() == State::WaitingForKey); assert(m_stateStack.top() == State::WaitingForKey);
m_stateStack.pop(); m_stateStack.pop();
} }
void EmitFromEvents::BeginNode() void EmitFromEvents::BeginNode() {
{ if (m_stateStack.empty())
if(m_stateStack.empty())
return; return;
switch(m_stateStack.top()) { switch (m_stateStack.top()) {
case State::WaitingForKey: case State::WaitingForKey:
m_emitter << Key; m_emitter << Key;
m_stateStack.top() = State::WaitingForValue; m_stateStack.top() = State::WaitingForValue;
@@ -93,13 +81,12 @@ namespace YAML
default: default:
break; break;
} }
} }
void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) void EmitFromEvents::EmitProps(const std::string& tag, anchor_t anchor) {
{ if (!tag.empty() && tag != "?")
if(!tag.empty() && tag != "?") m_emitter << VerbatimTag(tag);
m_emitter << VerbatimTag(tag); if (anchor)
if(anchor) m_emitter << Anchor(ToString(anchor));
m_emitter << Anchor(ToString(anchor)); }
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -2,10 +2,14 @@
#include "yaml-cpp/exceptions.h" #include "yaml-cpp/exceptions.h"
#include <limits> #include <limits>
namespace YAML namespace YAML {
{ EmitterState::EmitterState()
EmitterState::EmitterState(): m_isGood(true), m_curIndent(0), m_hasAnchor(false), m_hasTag(false), m_hasNonContent(false), m_docCount(0) : m_isGood(true),
{ m_curIndent(0),
m_hasAnchor(false),
m_hasTag(false),
m_hasNonContent(false),
m_docCount(0) {
// set default global manipulators // set default global manipulators
m_charset.set(EmitNonAscii); m_charset.set(EmitNonAscii);
m_strFmt.set(Auto); m_strFmt.set(Auto);
@@ -21,17 +25,14 @@ namespace YAML
m_mapKeyFmt.set(Auto); m_mapKeyFmt.set(Auto);
m_floatPrecision.set(std::numeric_limits<float>::digits10 + 1); m_floatPrecision.set(std::numeric_limits<float>::digits10 + 1);
m_doublePrecision.set(std::numeric_limits<double>::digits10 + 1); m_doublePrecision.set(std::numeric_limits<double>::digits10 + 1);
} }
EmitterState::~EmitterState() EmitterState::~EmitterState() {}
{
}
// SetLocalValue // SetLocalValue
// . We blindly tries to set all possible formatters to this value // . We blindly tries to set all possible formatters to this value
// . Only the ones that make sense will be accepted // . Only the ones that make sense will be accepted
void EmitterState::SetLocalValue(EMITTER_MANIP value) void EmitterState::SetLocalValue(EMITTER_MANIP value) {
{
SetOutputCharset(value, FmtScope::Local); SetOutputCharset(value, FmtScope::Local);
SetStringFormat(value, FmtScope::Local); SetStringFormat(value, FmtScope::Local);
SetBoolFormat(value, FmtScope::Local); SetBoolFormat(value, FmtScope::Local);
@@ -41,66 +42,54 @@ namespace YAML
SetFlowType(GroupType::Seq, value, FmtScope::Local); SetFlowType(GroupType::Seq, value, FmtScope::Local);
SetFlowType(GroupType::Map, value, FmtScope::Local); SetFlowType(GroupType::Map, value, FmtScope::Local);
SetMapKeyFormat(value, FmtScope::Local); SetMapKeyFormat(value, FmtScope::Local);
} }
void EmitterState::SetAnchor() void EmitterState::SetAnchor() { m_hasAnchor = true; }
{
m_hasAnchor = true;
}
void EmitterState::SetTag() void EmitterState::SetTag() { m_hasTag = true; }
{
m_hasTag = true;
}
void EmitterState::SetNonContent() void EmitterState::SetNonContent() { m_hasNonContent = true; }
{
m_hasNonContent = true;
}
void EmitterState::SetLongKey() void EmitterState::SetLongKey() {
{
assert(!m_groups.empty()); assert(!m_groups.empty());
if(m_groups.empty()) if (m_groups.empty())
return; return;
assert(m_groups.top().type == GroupType::Map); assert(m_groups.top().type == GroupType::Map);
m_groups.top().longKey = true; m_groups.top().longKey = true;
} }
void EmitterState::ForceFlow() void EmitterState::ForceFlow() {
{
assert(!m_groups.empty()); assert(!m_groups.empty());
if(m_groups.empty()) if (m_groups.empty())
return; return;
m_groups.top().flowType = FlowType::Flow; m_groups.top().flowType = FlowType::Flow;
} }
void EmitterState::StartedNode() void EmitterState::StartedNode() {
{ if (m_groups.empty()) {
if(m_groups.empty()) {
m_docCount++; m_docCount++;
} else { } else {
m_groups.top().childCount++; m_groups.top().childCount++;
if(m_groups.top().childCount % 2 == 0) if (m_groups.top().childCount % 2 == 0)
m_groups.top().longKey = false; m_groups.top().longKey = false;
} }
m_hasAnchor = false; m_hasAnchor = false;
m_hasTag = false; m_hasTag = false;
m_hasNonContent = false; m_hasNonContent = false;
} }
EmitterNodeType::value EmitterState::NextGroupType(GroupType::value type) const EmitterNodeType::value EmitterState::NextGroupType(GroupType::value type)
{ const {
if(type == GroupType::Seq) { if (type == GroupType::Seq) {
if(GetFlowType(type) == Block) if (GetFlowType(type) == Block)
return EmitterNodeType::BlockSeq; return EmitterNodeType::BlockSeq;
else else
return EmitterNodeType::FlowSeq; return EmitterNodeType::FlowSeq;
} else { } else {
if(GetFlowType(type) == Block) if (GetFlowType(type) == Block)
return EmitterNodeType::BlockMap; return EmitterNodeType::BlockMap;
else else
return EmitterNodeType::FlowMap; return EmitterNodeType::FlowMap;
@@ -109,30 +98,26 @@ namespace YAML
// can't happen // can't happen
assert(false); assert(false);
return EmitterNodeType::None; return EmitterNodeType::None;
} }
void EmitterState::StartedDoc() void EmitterState::StartedDoc() {
{
m_hasAnchor = false; m_hasAnchor = false;
m_hasTag = false; m_hasTag = false;
m_hasNonContent = false; m_hasNonContent = false;
} }
void EmitterState::EndedDoc() void EmitterState::EndedDoc() {
{
m_hasAnchor = false; m_hasAnchor = false;
m_hasTag = false; m_hasTag = false;
m_hasNonContent = false; m_hasNonContent = false;
} }
void EmitterState::StartedScalar() void EmitterState::StartedScalar() {
{
StartedNode(); StartedNode();
ClearModifiedSettings(); ClearModifiedSettings();
} }
void EmitterState::StartedGroup(GroupType::value type) void EmitterState::StartedGroup(GroupType::value type) {
{
StartedNode(); StartedNode();
const int lastGroupIndent = (m_groups.empty() ? 0 : m_groups.top().indent); const int lastGroupIndent = (m_groups.empty() ? 0 : m_groups.top().indent);
@@ -144,19 +129,18 @@ namespace YAML
pGroup->modifiedSettings = m_modifiedSettings; pGroup->modifiedSettings = m_modifiedSettings;
// set up group // set up group
if(GetFlowType(type) == Block) if (GetFlowType(type) == Block)
pGroup->flowType = FlowType::Block; pGroup->flowType = FlowType::Block;
else else
pGroup->flowType = FlowType::Flow; pGroup->flowType = FlowType::Flow;
pGroup->indent = GetIndent(); pGroup->indent = GetIndent();
m_groups.push(pGroup); m_groups.push(pGroup);
} }
void EmitterState::EndedGroup(GroupType::value type) void EmitterState::EndedGroup(GroupType::value type) {
{ if (m_groups.empty()) {
if(m_groups.empty()) { if (type == GroupType::Seq)
if(type == GroupType::Seq)
return SetError(ErrorMsg::UNEXPECTED_END_SEQ); return SetError(ErrorMsg::UNEXPECTED_END_SEQ);
else else
return SetError(ErrorMsg::UNEXPECTED_END_MAP); return SetError(ErrorMsg::UNEXPECTED_END_MAP);
@@ -165,7 +149,7 @@ namespace YAML
// get rid of the current group // get rid of the current group
{ {
std::auto_ptr<Group> pFinishedGroup = m_groups.pop(); std::auto_ptr<Group> pFinishedGroup = m_groups.pop();
if(pFinishedGroup->type != type) if (pFinishedGroup->type != type)
return SetError(ErrorMsg::UNMATCHED_GROUP_TAG); return SetError(ErrorMsg::UNMATCHED_GROUP_TAG);
} }
@@ -179,57 +163,47 @@ namespace YAML
m_globalModifiedSettings.restore(); m_globalModifiedSettings.restore();
ClearModifiedSettings(); ClearModifiedSettings();
} }
EmitterNodeType::value EmitterState::CurGroupNodeType() const EmitterNodeType::value EmitterState::CurGroupNodeType() const {
{ if (m_groups.empty())
if(m_groups.empty())
return EmitterNodeType::None; return EmitterNodeType::None;
return m_groups.top().NodeType(); return m_groups.top().NodeType();
} }
GroupType::value EmitterState::CurGroupType() const GroupType::value EmitterState::CurGroupType() const {
{
return m_groups.empty() ? GroupType::None : m_groups.top().type; return m_groups.empty() ? GroupType::None : m_groups.top().type;
} }
FlowType::value EmitterState::CurGroupFlowType() const FlowType::value EmitterState::CurGroupFlowType() const {
{
return m_groups.empty() ? FlowType::None : m_groups.top().flowType; return m_groups.empty() ? FlowType::None : m_groups.top().flowType;
} }
int EmitterState::CurGroupIndent() const int EmitterState::CurGroupIndent() const {
{
return m_groups.empty() ? 0 : m_groups.top().indent; return m_groups.empty() ? 0 : m_groups.top().indent;
} }
std::size_t EmitterState::CurGroupChildCount() const std::size_t EmitterState::CurGroupChildCount() const {
{
return m_groups.empty() ? m_docCount : m_groups.top().childCount; return m_groups.empty() ? m_docCount : m_groups.top().childCount;
} }
bool EmitterState::CurGroupLongKey() const bool EmitterState::CurGroupLongKey() const {
{
return m_groups.empty() ? false : m_groups.top().longKey; return m_groups.empty() ? false : m_groups.top().longKey;
} }
int EmitterState::LastIndent() const int EmitterState::LastIndent() const {
{ if (m_groups.size() <= 1)
if(m_groups.size() <= 1)
return 0; return 0;
return m_curIndent - m_groups.top(-1).indent; return m_curIndent - m_groups.top(-1).indent;
} }
void EmitterState::ClearModifiedSettings() void EmitterState::ClearModifiedSettings() { m_modifiedSettings.clear(); }
{
m_modifiedSettings.clear();
}
bool EmitterState::SetOutputCharset(EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetOutputCharset(EMITTER_MANIP value,
{ FmtScope::value scope) {
switch(value) { switch (value) {
case EmitNonAscii: case EmitNonAscii:
case EscapeNonAscii: case EscapeNonAscii:
_Set(m_charset, value, scope); _Set(m_charset, value, scope);
@@ -237,11 +211,10 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetStringFormat(EMITTER_MANIP value, FmtScope::value scope) {
{ switch (value) {
switch(value) {
case Auto: case Auto:
case SingleQuoted: case SingleQuoted:
case DoubleQuoted: case DoubleQuoted:
@@ -251,11 +224,10 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetBoolFormat(EMITTER_MANIP value, FmtScope::value scope) {
{ switch (value) {
switch(value) {
case OnOffBool: case OnOffBool:
case TrueFalseBool: case TrueFalseBool:
case YesNoBool: case YesNoBool:
@@ -264,11 +236,11 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetBoolLengthFormat(EMITTER_MANIP value,
{ FmtScope::value scope) {
switch(value) { switch (value) {
case LongBool: case LongBool:
case ShortBool: case ShortBool:
_Set(m_boolLengthFmt, value, scope); _Set(m_boolLengthFmt, value, scope);
@@ -276,11 +248,11 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetBoolCaseFormat(EMITTER_MANIP value,
{ FmtScope::value scope) {
switch(value) { switch (value) {
case UpperCase: case UpperCase:
case LowerCase: case LowerCase:
case CamelCase: case CamelCase:
@@ -289,11 +261,10 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetIntFormat(EMITTER_MANIP value, FmtScope::value scope) {
{ switch (value) {
switch(value) {
case Dec: case Dec:
case Hex: case Hex:
case Oct: case Oct:
@@ -302,38 +273,35 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetIndent(unsigned value, FmtScope::value scope) bool EmitterState::SetIndent(unsigned value, FmtScope::value scope) {
{ if (value <= 1)
if(value <= 1)
return false; return false;
_Set(m_indent, value, scope); _Set(m_indent, value, scope);
return true; return true;
} }
bool EmitterState::SetPreCommentIndent(unsigned value, FmtScope::value scope) bool EmitterState::SetPreCommentIndent(unsigned value, FmtScope::value scope) {
{ if (value == 0)
if(value == 0)
return false; return false;
_Set(m_preCommentIndent, value, scope); _Set(m_preCommentIndent, value, scope);
return true; return true;
} }
bool EmitterState::SetPostCommentIndent(unsigned value, FmtScope::value scope) bool EmitterState::SetPostCommentIndent(unsigned value, FmtScope::value scope) {
{ if (value == 0)
if(value == 0)
return false; return false;
_Set(m_postCommentIndent, value, scope); _Set(m_postCommentIndent, value, scope);
return true; return true;
} }
bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
{ FmtScope::value scope) {
switch(value) { switch (value) {
case Block: case Block:
case Flow: case Flow:
_Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope); _Set(groupType == GroupType::Seq ? m_seqFmt : m_mapFmt, value, scope);
@@ -341,21 +309,19 @@ namespace YAML
default: default:
return false; return false;
} }
} }
EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const EMITTER_MANIP EmitterState::GetFlowType(GroupType::value groupType) const {
{
// force flow style if we're currently in a flow // force flow style if we're currently in a flow
if(CurGroupFlowType() == FlowType::Flow) if (CurGroupFlowType() == FlowType::Flow)
return Flow; return Flow;
// otherwise, go with what's asked of us // otherwise, go with what's asked of us
return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get()); return (groupType == GroupType::Seq ? m_seqFmt.get() : m_mapFmt.get());
} }
bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope) bool EmitterState::SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope) {
{ switch (value) {
switch(value) {
case Auto: case Auto:
case LongKey: case LongKey:
_Set(m_mapKeyFmt, value, scope); _Set(m_mapKeyFmt, value, scope);
@@ -363,22 +329,19 @@ namespace YAML
default: default:
return false; return false;
} }
} }
bool EmitterState::SetFloatPrecision(int value, FmtScope::value scope) bool EmitterState::SetFloatPrecision(int value, FmtScope::value scope) {
{ if (value < 0 || value > std::numeric_limits<float>::digits10 + 1)
if(value < 0 || value > std::numeric_limits<float>::digits10 + 1)
return false; return false;
_Set(m_floatPrecision, value, scope); _Set(m_floatPrecision, value, scope);
return true; return true;
} }
bool EmitterState::SetDoublePrecision(int value, FmtScope::value scope) bool EmitterState::SetDoublePrecision(int value, FmtScope::value scope) {
{ if (value < 0 || value > std::numeric_limits<double>::digits10 + 1)
if(value < 0 || value > std::numeric_limits<double>::digits10 + 1)
return false; return false;
_Set(m_doublePrecision, value, scope); _Set(m_doublePrecision, value, scope);
return true; return true;
}
} }
}

View File

@@ -1,11 +1,12 @@
#ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "ptr_stack.h" #include "ptr_stack.h"
#include "setting.h" #include "setting.h"
#include "yaml-cpp/emitterdef.h" #include "yaml-cpp/emitterdef.h"
@@ -16,14 +17,29 @@
#include <memory> #include <memory>
#include <stdexcept> #include <stdexcept>
namespace YAML namespace YAML {
{ struct FmtScope {
struct FmtScope { enum value { Local, Global }; }; enum value {
struct GroupType { enum value { None, Seq, Map }; }; Local,
struct FlowType { enum value { None, Flow, Block }; }; Global
};
};
struct GroupType {
enum value {
None,
Seq,
Map
};
};
struct FlowType {
enum value {
None,
Flow,
Block
};
};
class EmitterState class EmitterState {
{
public: public:
EmitterState(); EmitterState();
~EmitterState(); ~EmitterState();
@@ -31,7 +47,10 @@ namespace YAML
// basic state checking // basic state checking
bool good() const { return m_isGood; } bool good() const { return m_isGood; }
const std::string GetLastError() const { return m_lastError; } const std::string GetLastError() const { return m_lastError; }
void SetError(const std::string& error) { m_isGood = false; m_lastError = error; } void SetError(const std::string& error) {
m_isGood = false;
m_lastError = error;
}
// node handling // node handling
void SetAnchor(); void SetAnchor();
@@ -58,7 +77,9 @@ namespace YAML
int CurIndent() const { return m_curIndent; } int CurIndent() const { return m_curIndent; }
bool HasAnchor() const { return m_hasAnchor; } bool HasAnchor() const { return m_hasAnchor; }
bool HasTag() const { return m_hasTag; } bool HasTag() const { return m_hasTag; }
bool HasBegunNode() const { return m_hasAnchor || m_hasTag || m_hasNonContent; } bool HasBegunNode() const {
return m_hasAnchor || m_hasTag || m_hasNonContent;
}
bool HasBegunContent() const { return m_hasAnchor || m_hasTag; } bool HasBegunContent() const { return m_hasAnchor || m_hasTag; }
void ClearModifiedSettings(); void ClearModifiedSettings();
@@ -92,7 +113,8 @@ namespace YAML
bool SetPostCommentIndent(unsigned value, FmtScope::value scope); bool SetPostCommentIndent(unsigned value, FmtScope::value scope);
int GetPostCommentIndent() const { return m_postCommentIndent.get(); } int GetPostCommentIndent() const { return m_postCommentIndent.get(); }
bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value, FmtScope::value scope); bool SetFlowType(GroupType::value groupType, EMITTER_MANIP value,
FmtScope::value scope);
EMITTER_MANIP GetFlowType(GroupType::value groupType) const; EMITTER_MANIP GetFlowType(GroupType::value groupType) const;
bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope); bool SetMapKeyFormat(EMITTER_MANIP value, FmtScope::value scope);
@@ -133,7 +155,8 @@ namespace YAML
SettingChanges m_globalModifiedSettings; SettingChanges m_globalModifiedSettings;
struct Group { struct Group {
explicit Group(GroupType::value type_): type(type_), indent(0), childCount(0), longKey(false) {} explicit Group(GroupType::value type_)
: type(type_), indent(0), childCount(0), longKey(false) {}
GroupType::value type; GroupType::value type;
FlowType::value flowType; FlowType::value flowType;
@@ -144,13 +167,13 @@ namespace YAML
SettingChanges modifiedSettings; SettingChanges modifiedSettings;
EmitterNodeType::value NodeType() const { EmitterNodeType::value NodeType() const {
if(type == GroupType::Seq) { if (type == GroupType::Seq) {
if(flowType == FlowType::Flow) if (flowType == FlowType::Flow)
return EmitterNodeType::FlowSeq; return EmitterNodeType::FlowSeq;
else else
return EmitterNodeType::BlockSeq; return EmitterNodeType::BlockSeq;
} else { } else {
if(flowType == FlowType::Flow) if (flowType == FlowType::Flow)
return EmitterNodeType::FlowMap; return EmitterNodeType::FlowMap;
else else
return EmitterNodeType::BlockMap; return EmitterNodeType::BlockMap;
@@ -168,23 +191,24 @@ namespace YAML
bool m_hasTag; bool m_hasTag;
bool m_hasNonContent; bool m_hasNonContent;
std::size_t m_docCount; std::size_t m_docCount;
}; };
template <typename T> template <typename T>
void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) { void EmitterState::_Set(Setting<T>& fmt, T value, FmtScope::value scope) {
switch(scope) { switch (scope) {
case FmtScope::Local: case FmtScope::Local:
m_modifiedSettings.push(fmt.set(value)); m_modifiedSettings.push(fmt.set(value));
break; break;
case FmtScope::Global: case FmtScope::Global:
fmt.set(value); fmt.set(value);
m_globalModifiedSettings.push(fmt.set(value)); // this pushes an identity set, so when we restore, m_globalModifiedSettings.push(
fmt.set(value)); // this pushes an identity set, so when we restore,
// it restores to the value here, and not the previous one // it restores to the value here, and not the previous one
break; break;
default: default:
assert(false); assert(false);
} }
} }
} }
#endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTERSTATE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -7,19 +7,25 @@
#include <sstream> #include <sstream>
#include <iomanip> #include <iomanip>
namespace YAML namespace YAML {
{ namespace Utils {
namespace Utils namespace {
{ enum {
namespace { REPLACEMENT_CHARACTER = 0xFFFD
enum {REPLACEMENT_CHARACTER = 0xFFFD}; };
bool IsAnchorChar(int ch) { // test for ns-anchor-char bool IsAnchorChar(int ch) { // test for ns-anchor-char
switch (ch) { switch (ch) {
case ',': case '[': case ']': case '{': case '}': // c-flow-indicator case ',':
case ' ': case '\t': // s-white case '[':
case ']':
case '{':
case '}': // c-flow-indicator
case ' ':
case '\t': // s-white
case 0xFEFF: // c-byte-order-mark case 0xFEFF: // c-byte-order-mark
case 0xA: case 0xD: // b-char case 0xA:
case 0xD: // b-char
return false; return false;
case 0x85: case 0x85:
return true; return true;
@@ -43,14 +49,22 @@ namespace YAML
return false; return false;
return true; return true;
} }
int Utf8BytesIndicated(char ch) { int Utf8BytesIndicated(char ch) {
int byteVal = static_cast<unsigned char>(ch); int byteVal = static_cast<unsigned char>(ch);
switch (byteVal >> 4) { switch (byteVal >> 4) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
return 1; return 1;
case 12: case 13: case 12:
case 13:
return 2; return 2;
case 14: case 14:
return 3; return 3;
@@ -59,13 +73,13 @@ namespace YAML
default: default:
return -1; return -1;
} }
} }
bool IsTrailingByte(char ch) { bool IsTrailingByte(char ch) { return (ch & 0xC0) == 0x80; }
return (ch & 0xC0) == 0x80;
}
bool GetNextCodePointAndAdvance(int& codePoint, std::string::const_iterator& first, std::string::const_iterator last) { bool GetNextCodePointAndAdvance(int& codePoint,
std::string::const_iterator& first,
std::string::const_iterator last) {
if (first == last) if (first == last)
return false; return false;
@@ -105,9 +119,9 @@ namespace YAML
else if (codePoint >= 0xFDD0 && codePoint <= 0xFDEF) else if (codePoint >= 0xFDD0 && codePoint <= 0xFDEF)
codePoint = REPLACEMENT_CHARACTER; codePoint = REPLACEMENT_CHARACTER;
return true; return true;
} }
void WriteCodePoint(ostream_wrapper& out, int codePoint) { void WriteCodePoint(ostream_wrapper& out, int codePoint) {
if (codePoint < 0 || codePoint > 0x10FFFF) { if (codePoint < 0 || codePoint > 0x10FFFF) {
codePoint = REPLACEMENT_CHARACTER; codePoint = REPLACEMENT_CHARACTER;
} }
@@ -126,74 +140,75 @@ namespace YAML
<< static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F)) << static_cast<char>(0x80 | ((codePoint >> 6) & 0x3F))
<< static_cast<char>(0x80 | (codePoint & 0x3F)); << static_cast<char>(0x80 | (codePoint & 0x3F));
} }
} }
bool IsValidPlainScalar(const std::string& str, FlowType::value flowType, bool allowOnlyAscii) { bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
if(str.empty()) bool allowOnlyAscii) {
if (str.empty())
return false; return false;
// first check the start // first check the start
const RegEx& start = (flowType == FlowType::Flow ? Exp::PlainScalarInFlow() : Exp::PlainScalar()); const RegEx& start = (flowType == FlowType::Flow ? Exp::PlainScalarInFlow()
if(!start.Matches(str)) : Exp::PlainScalar());
if (!start.Matches(str))
return false; return false;
// and check the end for plain whitespace (which can't be faithfully kept in a plain scalar) // and check the end for plain whitespace (which can't be faithfully kept in a
if(!str.empty() && *str.rbegin() == ' ') // plain scalar)
if (!str.empty() && *str.rbegin() == ' ')
return false; return false;
// then check until something is disallowed // then check until something is disallowed
const RegEx& disallowed = (flowType == FlowType::Flow ? Exp::EndScalarInFlow() : Exp::EndScalar()) const RegEx& disallowed = (flowType == FlowType::Flow ? Exp::EndScalarInFlow()
|| (Exp::BlankOrBreak() + Exp::Comment()) : Exp::EndScalar()) ||
|| Exp::NotPrintable() (Exp::BlankOrBreak() + Exp::Comment()) ||
|| Exp::Utf8_ByteOrderMark() Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() ||
|| Exp::Break() Exp::Break() || Exp::Tab();
|| Exp::Tab();
StringCharSource buffer(str.c_str(), str.size()); StringCharSource buffer(str.c_str(), str.size());
while(buffer) { while (buffer) {
if(disallowed.Matches(buffer)) if (disallowed.Matches(buffer))
return false; return false;
if(allowOnlyAscii && (0x80 <= static_cast<unsigned char>(buffer[0]))) if (allowOnlyAscii && (0x80 <= static_cast<unsigned char>(buffer[0])))
return false; return false;
++buffer; ++buffer;
} }
return true; return true;
} }
bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii) bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii) {
{
// TODO: check for non-printable characters? // TODO: check for non-printable characters?
for(std::size_t i=0;i<str.size();i++) { for (std::size_t i = 0; i < str.size(); i++) {
if(escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i])))
return false; return false;
if(str[i] == '\n') if (str[i] == '\n')
return false; return false;
} }
return true; return true;
} }
bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType, bool escapeNonAscii) bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType,
{ bool escapeNonAscii) {
if(flowType == FlowType::Flow) if (flowType == FlowType::Flow)
return false; return false;
// TODO: check for non-printable characters? // TODO: check for non-printable characters?
for(std::size_t i=0;i<str.size();i++) { for (std::size_t i = 0; i < str.size(); i++) {
if(escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i]))) if (escapeNonAscii && (0x80 <= static_cast<unsigned char>(str[i])))
return false; return false;
} }
return true; return true;
} }
void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint) { void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint) {
static const char hexDigits[] = "0123456789abcdef"; static const char hexDigits[] = "0123456789abcdef";
out << "\\"; out << "\\";
int digits = 8; int digits = 8;
if(codePoint < 0xFF) { if (codePoint < 0xFF) {
out << "x"; out << "x";
digits = 2; digits = 2;
} else if(codePoint < 0xFFFF) { } else if (codePoint < 0xFFFF) {
out << "u"; out << "u";
digits = 4; digits = 4;
} else { } else {
@@ -204,38 +219,38 @@ namespace YAML
// Write digits into the escape sequence // Write digits into the escape sequence
for (; digits > 0; --digits) for (; digits > 0; --digits)
out << hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF]; out << hexDigits[(codePoint >> (4 * (digits - 1))) & 0xF];
} }
bool WriteAliasName(ostream_wrapper& out, const std::string& str) { bool WriteAliasName(ostream_wrapper& out, const std::string& str) {
int codePoint; int codePoint;
for(std::string::const_iterator i = str.begin(); for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end()); GetNextCodePointAndAdvance(codePoint, i, str.end());) {
)
{
if (!IsAnchorChar(codePoint)) if (!IsAnchorChar(codePoint))
return false; return false;
WriteCodePoint(out, codePoint); WriteCodePoint(out, codePoint);
} }
return true; return true;
} }
} }
StringFormat::value ComputeStringFormat(const std::string& str, EMITTER_MANIP strFormat, FlowType::value flowType, bool escapeNonAscii) StringFormat::value ComputeStringFormat(const std::string& str,
{ EMITTER_MANIP strFormat,
switch(strFormat) { FlowType::value flowType,
bool escapeNonAscii) {
switch (strFormat) {
case Auto: case Auto:
if(IsValidPlainScalar(str, flowType, escapeNonAscii)) if (IsValidPlainScalar(str, flowType, escapeNonAscii))
return StringFormat::Plain; return StringFormat::Plain;
return StringFormat::DoubleQuoted; return StringFormat::DoubleQuoted;
case SingleQuoted: case SingleQuoted:
if(IsValidSingleQuotedScalar(str, escapeNonAscii)) if (IsValidSingleQuotedScalar(str, escapeNonAscii))
return StringFormat::SingleQuoted; return StringFormat::SingleQuoted;
return StringFormat::DoubleQuoted; return StringFormat::DoubleQuoted;
case DoubleQuoted: case DoubleQuoted:
return StringFormat::DoubleQuoted; return StringFormat::DoubleQuoted;
case Literal: case Literal:
if(IsValidLiteralScalar(str, flowType, escapeNonAscii)) if (IsValidLiteralScalar(str, flowType, escapeNonAscii))
return StringFormat::Literal; return StringFormat::Literal;
return StringFormat::DoubleQuoted; return StringFormat::DoubleQuoted;
default: default:
@@ -243,18 +258,16 @@ namespace YAML
} }
return StringFormat::DoubleQuoted; return StringFormat::DoubleQuoted;
} }
bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str) {
{
out << "'"; out << "'";
int codePoint; int codePoint;
for(std::string::const_iterator i = str.begin(); for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end()); GetNextCodePointAndAdvance(codePoint, i, str.end());) {
)
{
if (codePoint == '\n') if (codePoint == '\n')
return false; // We can't handle a new line and the attendant indentation yet return false; // We can't handle a new line and the attendant indentation
// yet
if (codePoint == '\'') if (codePoint == '\'')
out << "''"; out << "''";
@@ -263,27 +276,40 @@ namespace YAML
} }
out << "'"; out << "'";
return true; return true;
} }
bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str, bool escapeNonAscii) bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
{ bool escapeNonAscii) {
out << "\""; out << "\"";
int codePoint; int codePoint;
for(std::string::const_iterator i = str.begin(); for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end()); GetNextCodePointAndAdvance(codePoint, i, str.end());) {
) switch (codePoint) {
{ case '\"':
switch(codePoint) { out << "\\\"";
case '\"': out << "\\\""; break; break;
case '\\': out << "\\\\"; break; case '\\':
case '\n': out << "\\n"; break; out << "\\\\";
case '\t': out << "\\t"; break; break;
case '\r': out << "\\r"; break; case '\n':
case '\b': out << "\\b"; break; out << "\\n";
break;
case '\t':
out << "\\t";
break;
case '\r':
out << "\\r";
break;
case '\b':
out << "\\b";
break;
default: default:
if(codePoint < 0x20 || (codePoint >= 0x80 && codePoint <= 0xA0)) // Control characters and non-breaking space if (codePoint < 0x20 ||
(codePoint >= 0x80 &&
codePoint <= 0xA0)) // Control characters and non-breaking space
WriteDoubleQuoteEscapeSequence(out, codePoint); WriteDoubleQuoteEscapeSequence(out, codePoint);
else if (codePoint == 0xFEFF) // Byte order marks (ZWNS) should be escaped (YAML 1.2, sec. 5.2) else if (codePoint == 0xFEFF) // Byte order marks (ZWNS) should be
// escaped (YAML 1.2, sec. 5.2)
WriteDoubleQuoteEscapeSequence(out, codePoint); WriteDoubleQuoteEscapeSequence(out, codePoint);
else if (escapeNonAscii && codePoint > 0x7E) else if (escapeNonAscii && codePoint > 0x7E)
WriteDoubleQuoteEscapeSequence(out, codePoint); WriteDoubleQuoteEscapeSequence(out, codePoint);
@@ -293,36 +319,33 @@ namespace YAML
} }
out << "\""; out << "\"";
return true; return true;
} }
bool WriteLiteralString(ostream_wrapper& out, const std::string& str, int indent) bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
{ int indent) {
out << "|\n"; out << "|\n";
out << IndentTo(indent); out << IndentTo(indent);
int codePoint; int codePoint;
for(std::string::const_iterator i = str.begin(); for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end()); GetNextCodePointAndAdvance(codePoint, i, str.end());) {
)
{
if (codePoint == '\n') if (codePoint == '\n')
out << "\n" << IndentTo(indent); out << "\n" << IndentTo(indent);
else else
WriteCodePoint(out, codePoint); WriteCodePoint(out, codePoint);
} }
return true; return true;
} }
bool WriteChar(ostream_wrapper& out, char ch) bool WriteChar(ostream_wrapper& out, char ch) {
{ if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z'))
if(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z'))
out << ch; out << ch;
else if((0x20 <= ch && ch <= 0x7e) || ch == ' ') else if ((0x20 <= ch && ch <= 0x7e) || ch == ' ')
out << "\"" << ch << "\""; out << "\"" << ch << "\"";
else if(ch == '\t') else if (ch == '\t')
out << "\"\\t\""; out << "\"\\t\"";
else if(ch == '\n') else if (ch == '\n')
out << "\"\\n\""; out << "\"\\n\"";
else if(ch == '\b') else if (ch == '\b')
out << "\"\\b\""; out << "\"\\b\"";
else { else {
out << "\""; out << "\"";
@@ -330,51 +353,47 @@ namespace YAML
out << "\""; out << "\"";
} }
return true; return true;
} }
bool WriteComment(ostream_wrapper& out, const std::string& str, int postCommentIndent) bool WriteComment(ostream_wrapper& out, const std::string& str,
{ int postCommentIndent) {
const unsigned curIndent = out.col(); const unsigned curIndent = out.col();
out << "#" << Indentation(postCommentIndent); out << "#" << Indentation(postCommentIndent);
out.set_comment(); out.set_comment();
int codePoint; int codePoint;
for(std::string::const_iterator i = str.begin(); for (std::string::const_iterator i = str.begin();
GetNextCodePointAndAdvance(codePoint, i, str.end()); GetNextCodePointAndAdvance(codePoint, i, str.end());) {
) if (codePoint == '\n') {
{ out << "\n" << IndentTo(curIndent) << "#"
if(codePoint == '\n') { << Indentation(postCommentIndent);
out << "\n" << IndentTo(curIndent) << "#" << Indentation(postCommentIndent);
out.set_comment(); out.set_comment();
} else { } else {
WriteCodePoint(out, codePoint); WriteCodePoint(out, codePoint);
} }
} }
return true; return true;
} }
bool WriteAlias(ostream_wrapper& out, const std::string& str) bool WriteAlias(ostream_wrapper& out, const std::string& str) {
{
out << "*"; out << "*";
return WriteAliasName(out, str); return WriteAliasName(out, str);
} }
bool WriteAnchor(ostream_wrapper& out, const std::string& str) bool WriteAnchor(ostream_wrapper& out, const std::string& str) {
{
out << "&"; out << "&";
return WriteAliasName(out, str); return WriteAliasName(out, str);
} }
bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) {
{
out << (verbatim ? "!<" : "!"); out << (verbatim ? "!<" : "!");
StringCharSource buffer(str.c_str(), str.size()); StringCharSource buffer(str.c_str(), str.size());
const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag(); const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag();
while(buffer) { while (buffer) {
int n = reValid.Match(buffer); int n = reValid.Match(buffer);
if(n <= 0) if (n <= 0)
return false; return false;
while(--n >= 0) { while (--n >= 0) {
out << buffer[0]; out << buffer[0];
++buffer; ++buffer;
} }
@@ -382,18 +401,18 @@ namespace YAML
if (verbatim) if (verbatim)
out << ">"; out << ">";
return true; return true;
} }
bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix, const std::string& tag) bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
{ const std::string& tag) {
out << "!"; out << "!";
StringCharSource prefixBuffer(prefix.c_str(), prefix.size()); StringCharSource prefixBuffer(prefix.c_str(), prefix.size());
while(prefixBuffer) { while (prefixBuffer) {
int n = Exp::URI().Match(prefixBuffer); int n = Exp::URI().Match(prefixBuffer);
if(n <= 0) if (n <= 0)
return false; return false;
while(--n >= 0) { while (--n >= 0) {
out << prefixBuffer[0]; out << prefixBuffer[0];
++prefixBuffer; ++prefixBuffer;
} }
@@ -401,24 +420,23 @@ namespace YAML
out << "!"; out << "!";
StringCharSource tagBuffer(tag.c_str(), tag.size()); StringCharSource tagBuffer(tag.c_str(), tag.size());
while(tagBuffer) { while (tagBuffer) {
int n = Exp::Tag().Match(tagBuffer); int n = Exp::Tag().Match(tagBuffer);
if(n <= 0) if (n <= 0)
return false; return false;
while(--n >= 0) { while (--n >= 0) {
out << tagBuffer[0]; out << tagBuffer[0];
++tagBuffer; ++tagBuffer;
} }
} }
return true; return true;
}
bool WriteBinary(ostream_wrapper& out, const Binary& binary)
{
WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()), false);
return true;
}
}
} }
bool WriteBinary(ostream_wrapper& out, const Binary& binary) {
WriteDoubleQuotedString(out, EncodeBase64(binary.data(), binary.size()),
false);
return true;
}
}
}

View File

@@ -1,36 +1,49 @@
#ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "emitterstate.h" #include "emitterstate.h"
#include "yaml-cpp/ostream_wrapper.h" #include "yaml-cpp/ostream_wrapper.h"
#include <string> #include <string>
namespace YAML namespace YAML {
{ class Binary;
class Binary;
struct StringFormat { enum value { Plain, SingleQuoted, DoubleQuoted, Literal }; }; struct StringFormat {
enum value {
Plain,
SingleQuoted,
DoubleQuoted,
Literal
};
};
namespace Utils namespace Utils {
{ StringFormat::value ComputeStringFormat(const std::string& str,
StringFormat::value ComputeStringFormat(const std::string& str, EMITTER_MANIP strFormat, FlowType::value flowType, bool escapeNonAscii); EMITTER_MANIP strFormat,
FlowType::value flowType,
bool escapeNonAscii);
bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str); bool WriteSingleQuotedString(ostream_wrapper& out, const std::string& str);
bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str, bool escapeNonAscii); bool WriteDoubleQuotedString(ostream_wrapper& out, const std::string& str,
bool WriteLiteralString(ostream_wrapper& out, const std::string& str, int indent); bool escapeNonAscii);
bool WriteChar(ostream_wrapper& out, char ch); bool WriteLiteralString(ostream_wrapper& out, const std::string& str,
bool WriteComment(ostream_wrapper& out, const std::string& str, int postCommentIndent); int indent);
bool WriteAlias(ostream_wrapper& out, const std::string& str); bool WriteChar(ostream_wrapper& out, char ch);
bool WriteAnchor(ostream_wrapper& out, const std::string& str); bool WriteComment(ostream_wrapper& out, const std::string& str,
bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim); int postCommentIndent);
bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix, const std::string& tag); bool WriteAlias(ostream_wrapper& out, const std::string& str);
bool WriteBinary(ostream_wrapper& out, const Binary& binary); bool WriteAnchor(ostream_wrapper& out, const std::string& str);
} bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim);
bool WriteTagWithPrefix(ostream_wrapper& out, const std::string& prefix,
const std::string& tag);
bool WriteBinary(ostream_wrapper& out, const Binary& binary);
}
} }
#endif // EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTERUTILS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -2,21 +2,18 @@
#include "yaml-cpp/exceptions.h" #include "yaml-cpp/exceptions.h"
#include <sstream> #include <sstream>
namespace YAML namespace YAML {
{ namespace Exp {
namespace Exp unsigned ParseHex(const std::string& str, const Mark& mark) {
{
unsigned ParseHex(const std::string& str, const Mark& mark)
{
unsigned value = 0; unsigned value = 0;
for(std::size_t i=0;i<str.size();i++) { for (std::size_t i = 0; i < str.size(); i++) {
char ch = str[i]; char ch = str[i];
int digit = 0; int digit = 0;
if('a' <= ch && ch <= 'f') if ('a' <= ch && ch <= 'f')
digit = ch - 'a' + 10; digit = ch - 'a' + 10;
else if('A' <= ch && ch <= 'F') else if ('A' <= ch && ch <= 'F')
digit = ch - 'A' + 10; digit = ch - 'A' + 10;
else if('0' <= ch && ch <= '9') else if ('0' <= ch && ch <= '9')
digit = ch - '0'; digit = ch - '0';
else else
throw ParserException(mark, ErrorMsg::INVALID_HEX); throw ParserException(mark, ErrorMsg::INVALID_HEX);
@@ -25,51 +22,49 @@ namespace YAML
} }
return value; return value;
} }
std::string Str(unsigned ch) std::string Str(unsigned ch) { return std::string(1, static_cast<char>(ch)); }
{
return std::string(1, static_cast<char>(ch));
}
// Escape // Escape
// . Translates the next 'codeLength' characters into a hex number and returns the result. // . Translates the next 'codeLength' characters into a hex number and returns
// . Throws if it's not actually hex. // the result.
std::string Escape(Stream& in, int codeLength) // . Throws if it's not actually hex.
{ std::string Escape(Stream& in, int codeLength) {
// grab string // grab string
std::string str; std::string str;
for(int i=0;i<codeLength;i++) for (int i = 0; i < codeLength; i++)
str += in.get(); str += in.get();
// get the value // get the value
unsigned value = ParseHex(str, in.mark()); unsigned value = ParseHex(str, in.mark());
// legal unicode? // legal unicode?
if((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) { if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
std::stringstream msg; std::stringstream msg;
msg << ErrorMsg::INVALID_UNICODE << value; msg << ErrorMsg::INVALID_UNICODE << value;
throw ParserException(in.mark(), msg.str()); throw ParserException(in.mark(), msg.str());
} }
// now break it up into chars // now break it up into chars
if(value <= 0x7F) if (value <= 0x7F)
return Str(value); return Str(value);
else if(value <= 0x7FF) else if (value <= 0x7FF)
return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F)); return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F));
else if(value <= 0xFFFF) else if (value <= 0xFFFF)
return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F)); return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) +
Str(0x80 + (value & 0x3F));
else else
return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) + return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) +
Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F)); Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F));
} }
// Escape // Escape
// . Escapes the sequence starting 'in' (it must begin with a '\' or single quote) // . Escapes the sequence starting 'in' (it must begin with a '\' or single
// and returns the result. // quote)
// . Throws if it's an unknown escape character. // and returns the result.
std::string Escape(Stream& in) // . Throws if it's an unknown escape character.
{ std::string Escape(Stream& in) {
// eat slash // eat slash
char escape = in.get(); char escape = in.get();
@@ -77,37 +72,59 @@ namespace YAML
char ch = in.get(); char ch = in.get();
// first do single quote, since it's easier // first do single quote, since it's easier
if(escape == '\'' && ch == '\'') if (escape == '\'' && ch == '\'')
return "\'"; return "\'";
// now do the slash (we're not gonna check if it's a slash - you better pass one!) // now do the slash (we're not gonna check if it's a slash - you better pass
switch(ch) { // one!)
case '0': return std::string(1, '\x00'); switch (ch) {
case 'a': return "\x07"; case '0':
case 'b': return "\x08"; return std::string(1, '\x00');
case 'a':
return "\x07";
case 'b':
return "\x08";
case 't': case 't':
case '\t': return "\x09"; case '\t':
case 'n': return "\x0A"; return "\x09";
case 'v': return "\x0B"; case 'n':
case 'f': return "\x0C"; return "\x0A";
case 'r': return "\x0D"; case 'v':
case 'e': return "\x1B"; return "\x0B";
case ' ': return "\x20"; case 'f':
case '\"': return "\""; return "\x0C";
case '\'': return "\'"; case 'r':
case '\\': return "\\"; return "\x0D";
case '/': return "/"; case 'e':
case 'N': return "\x85"; return "\x1B";
case '_': return "\xA0"; case ' ':
case 'L': return "\xE2\x80\xA8"; // LS (#x2028) return "\x20";
case 'P': return "\xE2\x80\xA9"; // PS (#x2029) case '\"':
case 'x': return Escape(in, 2); return "\"";
case 'u': return Escape(in, 4); case '\'':
case 'U': return Escape(in, 8); return "\'";
case '\\':
return "\\";
case '/':
return "/";
case 'N':
return "\x85";
case '_':
return "\xA0";
case 'L':
return "\xE2\x80\xA8"; // LS (#x2028)
case 'P':
return "\xE2\x80\xA9"; // PS (#x2029)
case 'x':
return Escape(in, 2);
case 'u':
return Escape(in, 4);
case 'U':
return Escape(in, 8);
} }
std::stringstream msg; std::stringstream msg;
throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch); throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);
} }
} }
} }

232
src/exp.h
View File

@@ -1,196 +1,208 @@
#ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "regex.h" #include "regex.h"
#include <string> #include <string>
#include <ios> #include <ios>
#include "stream.h" #include "stream.h"
namespace YAML namespace YAML {
{ ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// // Here we store a bunch of expressions for matching different parts of the
// Here we store a bunch of expressions for matching different parts of the file. // file.
namespace Exp namespace Exp {
{ // misc
// misc inline const RegEx& Space() {
inline const RegEx& Space() {
static const RegEx e = RegEx(' '); static const RegEx e = RegEx(' ');
return e; return e;
} }
inline const RegEx& Tab() { inline const RegEx& Tab() {
static const RegEx e = RegEx('\t'); static const RegEx e = RegEx('\t');
return e; return e;
} }
inline const RegEx& Blank() { inline const RegEx& Blank() {
static const RegEx e = Space() || Tab(); static const RegEx e = Space() || Tab();
return e; return e;
} }
inline const RegEx& Break() { inline const RegEx& Break() {
static const RegEx e = RegEx('\n') || RegEx("\r\n"); static const RegEx e = RegEx('\n') || RegEx("\r\n");
return e; return e;
} }
inline const RegEx& BlankOrBreak() { inline const RegEx& BlankOrBreak() {
static const RegEx e = Blank() || Break(); static const RegEx e = Blank() || Break();
return e; return e;
} }
inline const RegEx& Digit() { inline const RegEx& Digit() {
static const RegEx e = RegEx('0', '9'); static const RegEx e = RegEx('0', '9');
return e; return e;
} }
inline const RegEx& Alpha() { inline const RegEx& Alpha() {
static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z'); static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z');
return e; return e;
} }
inline const RegEx& AlphaNumeric() { inline const RegEx& AlphaNumeric() {
static const RegEx e = Alpha() || Digit(); static const RegEx e = Alpha() || Digit();
return e; return e;
} }
inline const RegEx& Word() { inline const RegEx& Word() {
static const RegEx e = AlphaNumeric() || RegEx('-'); static const RegEx e = AlphaNumeric() || RegEx('-');
return e; return e;
} }
inline const RegEx& Hex() { inline const RegEx& Hex() {
static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f'); static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f');
return e; return e;
} }
// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec. 5.1) // Valid Unicode code points that are not part of c-printable (YAML 1.2, sec.
inline const RegEx& NotPrintable() { // 5.1)
static const RegEx e = RegEx(0) || 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("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) ||
RegEx(0x0E, 0x1F) || RegEx(0x0E, 0x1F) ||
(RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F'))); (RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F')));
return e; return e;
} }
inline const RegEx& Utf8_ByteOrderMark() { inline const RegEx& Utf8_ByteOrderMark() {
static const RegEx e = RegEx("\xEF\xBB\xBF"); static const RegEx e = RegEx("\xEF\xBB\xBF");
return e; return e;
} }
// actual tags // actual tags
inline const RegEx& DocStart() { inline const RegEx& DocStart() {
static const RegEx e = RegEx("---") + (BlankOrBreak() || RegEx()); static const RegEx e = RegEx("---") + (BlankOrBreak() || RegEx());
return e; return e;
} }
inline const RegEx& DocEnd() { inline const RegEx& DocEnd() {
static const RegEx e = RegEx("...") + (BlankOrBreak() || RegEx()); static const RegEx e = RegEx("...") + (BlankOrBreak() || RegEx());
return e; return e;
} }
inline const RegEx& DocIndicator() { inline const RegEx& DocIndicator() {
static const RegEx e = DocStart() || DocEnd(); static const RegEx e = DocStart() || DocEnd();
return e; return e;
} }
inline const RegEx& BlockEntry() { inline const RegEx& BlockEntry() {
static const RegEx e = RegEx('-') + (BlankOrBreak() || RegEx()); static const RegEx e = RegEx('-') + (BlankOrBreak() || RegEx());
return e; return e;
} }
inline const RegEx& Key() { inline const RegEx& Key() {
static const RegEx e = RegEx('?') + BlankOrBreak(); static const RegEx e = RegEx('?') + BlankOrBreak();
return e; return e;
} }
inline const RegEx& KeyInFlow() { inline const RegEx& KeyInFlow() {
static const RegEx e = RegEx('?') + BlankOrBreak(); static const RegEx e = RegEx('?') + BlankOrBreak();
return e; return e;
} }
inline const RegEx& Value() { inline const RegEx& Value() {
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx()); static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
return e; return e;
} }
inline const RegEx& ValueInFlow() { inline const RegEx& ValueInFlow() {
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx(",}", REGEX_OR)); static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx(",}", REGEX_OR));
return e; return e;
} }
inline const RegEx& ValueInJSONFlow() { inline const RegEx& ValueInJSONFlow() {
static const RegEx e = RegEx(':'); static const RegEx e = RegEx(':');
return e; return e;
} }
inline const RegEx Comment() { inline const RegEx Comment() {
static const RegEx e = RegEx('#'); static const RegEx e = RegEx('#');
return e; return e;
} }
inline const RegEx& Anchor() { inline const RegEx& Anchor() {
static const RegEx e = !(RegEx("[]{},", REGEX_OR) || BlankOrBreak()); static const RegEx e = !(RegEx("[]{},", REGEX_OR) || BlankOrBreak());
return e; return e;
} }
inline const RegEx& AnchorEnd() { inline const RegEx& AnchorEnd() {
static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak(); static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak();
return e; return e;
} }
inline const RegEx& URI() { inline const RegEx& URI() {
static const RegEx e = Word() || RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) || (RegEx('%') + Hex() + Hex()); static const RegEx e = Word() || RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) ||
(RegEx('%') + Hex() + Hex());
return e; return e;
} }
inline const RegEx& Tag() { inline const RegEx& Tag() {
static const RegEx e = Word() || RegEx("#;/?:@&=+$_.~*'", REGEX_OR) || (RegEx('%') + Hex() + Hex()); static const RegEx e = Word() || RegEx("#;/?:@&=+$_.~*'", REGEX_OR) ||
(RegEx('%') + Hex() + Hex());
return e; return e;
} }
// Plain scalar rules: // Plain scalar rules:
// . Cannot start with a blank. // . Cannot start with a blank.
// . Can never start with any of , [ ] { } # & * ! | > \' \" % @ ` // . Can never start with any of , [ ] { } # & * ! | > \' \" % @ `
// . In the block context - ? : must be not be followed with a space. // . 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. // . In the flow context ? is illegal and : and - must not be followed with a
inline const RegEx& PlainScalar() { // space.
static const RegEx e = !(BlankOrBreak() || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-?:", REGEX_OR) + (BlankOrBreak() || RegEx()))); inline const RegEx& PlainScalar() {
static const RegEx e =
!(BlankOrBreak() || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) ||
(RegEx("-?:", REGEX_OR) + (BlankOrBreak() || RegEx())));
return e; return e;
} }
inline const RegEx& PlainScalarInFlow() { inline const RegEx& PlainScalarInFlow() {
static const RegEx e = !(BlankOrBreak() || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) || (RegEx("-:", REGEX_OR) + Blank())); static const RegEx e =
!(BlankOrBreak() || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) ||
(RegEx("-:", REGEX_OR) + Blank()));
return e; return e;
} }
inline const RegEx& EndScalar() { inline const RegEx& EndScalar() {
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx()); static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
return e; return e;
} }
inline const RegEx& EndScalarInFlow() { inline const RegEx& EndScalarInFlow() {
static const RegEx e = (RegEx(':') + (BlankOrBreak() || RegEx() || RegEx(",]}", REGEX_OR))) || RegEx(",?[]{}", REGEX_OR); static const RegEx e =
(RegEx(':') + (BlankOrBreak() || RegEx() || RegEx(",]}", REGEX_OR))) ||
RegEx(",?[]{}", REGEX_OR);
return e; return e;
} }
inline const RegEx& EscSingleQuote() { inline const RegEx& EscSingleQuote() {
static const RegEx e = RegEx("\'\'"); static const RegEx e = RegEx("\'\'");
return e; return e;
} }
inline const RegEx& EscBreak() { inline const RegEx& EscBreak() {
static const RegEx e = RegEx('\\') + Break(); static const RegEx e = RegEx('\\') + Break();
return e; return e;
} }
inline const RegEx& ChompIndicator() { inline const RegEx& ChompIndicator() {
static const RegEx e = RegEx("+-", REGEX_OR); static const RegEx e = RegEx("+-", REGEX_OR);
return e; return e;
} }
inline const RegEx& Chomp() { inline const RegEx& Chomp() {
static const RegEx e = (ChompIndicator() + Digit()) || (Digit() + ChompIndicator()) || ChompIndicator() || Digit(); static const RegEx e = (ChompIndicator() + Digit()) ||
(Digit() + ChompIndicator()) || ChompIndicator() ||
Digit();
return e; return e;
} }
// and some functions // and some functions
std::string Escape(Stream& in); std::string Escape(Stream& in);
} }
namespace Keys namespace Keys {
{ const char Directive = '%';
const char Directive = '%'; const char FlowSeqStart = '[';
const char FlowSeqStart = '['; const char FlowSeqEnd = ']';
const char FlowSeqEnd = ']'; const char FlowMapStart = '{';
const char FlowMapStart = '{'; const char FlowMapEnd = '}';
const char FlowMapEnd = '}'; const char FlowEntry = ',';
const char FlowEntry = ','; const char Alias = '*';
const char Alias = '*'; const char Anchor = '&';
const char Anchor = '&'; const char Tag = '!';
const char Tag = '!'; const char LiteralScalar = '|';
const char LiteralScalar = '|'; const char FoldedScalar = '>';
const char FoldedScalar = '>'; const char VerbatimTagStart = '<';
const char VerbatimTagStart = '<'; const char VerbatimTagEnd = '>';
const char VerbatimTagEnd = '>'; }
}
} }
#endif // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EXP_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,38 +1,39 @@
#ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/ostream_wrapper.h" #include "yaml-cpp/ostream_wrapper.h"
#include <iostream> #include <iostream>
namespace YAML namespace YAML {
{ struct Indentation {
struct Indentation { Indentation(unsigned n_) : n(n_) {}
Indentation(unsigned n_): n(n_) {}
unsigned n; unsigned n;
}; };
inline ostream_wrapper& operator << (ostream_wrapper& out, const Indentation& indent) { inline ostream_wrapper& operator<<(ostream_wrapper& out,
for(unsigned i=0;i<indent.n;i++) const Indentation& indent) {
for (unsigned i = 0; i < indent.n; i++)
out << ' '; out << ' ';
return out; return out;
}
struct IndentTo {
IndentTo(unsigned n_): n(n_) {}
unsigned n;
};
inline ostream_wrapper& operator << (ostream_wrapper& out, const IndentTo& indent) {
while(out.col() < indent.n)
out << ' ';
return out;
}
} }
struct IndentTo {
IndentTo(unsigned n_) : n(n_) {}
unsigned n;
};
inline ostream_wrapper& operator<<(ostream_wrapper& out,
const IndentTo& indent) {
while (out.col() < indent.n)
out << ' ';
return out;
}
}
#endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // INDENTATION_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,6 +1,5 @@
#include "yaml-cpp/null.h" #include "yaml-cpp/null.h"
namespace YAML namespace YAML {
{ _Null Null;
_Null Null;
} }

View File

@@ -9,133 +9,119 @@
#include <sstream> #include <sstream>
#include <cstdio> #include <cstdio>
namespace YAML namespace YAML {
{ Parser::Parser() {}
Parser::Parser()
{
}
Parser::Parser(std::istream& in) Parser::Parser(std::istream& in) { Load(in); }
{
Load(in);
}
Parser::~Parser() Parser::~Parser() {}
{
}
Parser::operator bool() const Parser::operator bool() const {
{
return m_pScanner.get() && !m_pScanner->empty(); return m_pScanner.get() && !m_pScanner->empty();
} }
void Parser::Load(std::istream& in) void Parser::Load(std::istream& in) {
{
m_pScanner.reset(new Scanner(in)); m_pScanner.reset(new Scanner(in));
m_pDirectives.reset(new Directives); m_pDirectives.reset(new Directives);
} }
// HandleNextDocument // HandleNextDocument
// . Handles the next document // . Handles the next document
// . Throws a ParserException on error. // . Throws a ParserException on error.
// . Returns false if there are no more documents // . Returns false if there are no more documents
bool Parser::HandleNextDocument(EventHandler& eventHandler) bool Parser::HandleNextDocument(EventHandler& eventHandler) {
{ if (!m_pScanner.get())
if(!m_pScanner.get())
return false; return false;
ParseDirectives(); ParseDirectives();
if(m_pScanner->empty()) if (m_pScanner->empty())
return false; return false;
SingleDocParser sdp(*m_pScanner, *m_pDirectives); SingleDocParser sdp(*m_pScanner, *m_pDirectives);
sdp.HandleDocument(eventHandler); sdp.HandleDocument(eventHandler);
return true; return true;
} }
// ParseDirectives // ParseDirectives
// . Reads any directives that are next in the queue. // . Reads any directives that are next in the queue.
void Parser::ParseDirectives() void Parser::ParseDirectives() {
{
bool readDirective = false; bool readDirective = false;
while(1) { while (1) {
if(m_pScanner->empty()) if (m_pScanner->empty())
break; break;
Token& token = m_pScanner->peek(); Token& token = m_pScanner->peek();
if(token.type != Token::DIRECTIVE) if (token.type != Token::DIRECTIVE)
break; break;
// we keep the directives from the last document if none are specified; // we keep the directives from the last document if none are specified;
// but if any directives are specific, then we reset them // but if any directives are specific, then we reset them
if(!readDirective) if (!readDirective)
m_pDirectives.reset(new Directives); m_pDirectives.reset(new Directives);
readDirective = true; readDirective = true;
HandleDirective(token); HandleDirective(token);
m_pScanner->pop(); m_pScanner->pop();
} }
} }
void Parser::HandleDirective(const Token& token) void Parser::HandleDirective(const Token& token) {
{ if (token.value == "YAML")
if(token.value == "YAML")
HandleYamlDirective(token); HandleYamlDirective(token);
else if(token.value == "TAG") else if (token.value == "TAG")
HandleTagDirective(token); HandleTagDirective(token);
} }
// HandleYamlDirective // HandleYamlDirective
// . Should be of the form 'major.minor' (like a version number) // . Should be of the form 'major.minor' (like a version number)
void Parser::HandleYamlDirective(const Token& token) void Parser::HandleYamlDirective(const Token& token) {
{ if (token.params.size() != 1)
if(token.params.size() != 1)
throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS); throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
if(!m_pDirectives->version.isDefault) if (!m_pDirectives->version.isDefault)
throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE); throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE);
std::stringstream str(token.params[0]); std::stringstream str(token.params[0]);
str >> m_pDirectives->version.major; str >> m_pDirectives->version.major;
str.get(); str.get();
str >> m_pDirectives->version.minor; str >> m_pDirectives->version.minor;
if(!str || str.peek() != EOF) if (!str || str.peek() != EOF)
throw ParserException(token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]); throw ParserException(
token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]);
if(m_pDirectives->version.major > 1) if (m_pDirectives->version.major > 1)
throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION); throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION);
m_pDirectives->version.isDefault = false; m_pDirectives->version.isDefault = false;
// TODO: warning on major == 1, minor > 2? // TODO: warning on major == 1, minor > 2?
} }
// HandleTagDirective // HandleTagDirective
// . Should be of the form 'handle prefix', where 'handle' is converted to 'prefix' in the file. // . Should be of the form 'handle prefix', where 'handle' is converted to
void Parser::HandleTagDirective(const Token& token) // 'prefix' in the file.
{ void Parser::HandleTagDirective(const Token& token) {
if(token.params.size() != 2) if (token.params.size() != 2)
throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS); throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS);
const std::string& handle = token.params[0]; const std::string& handle = token.params[0];
const std::string& prefix = token.params[1]; const std::string& prefix = token.params[1];
if(m_pDirectives->tags.find(handle) != m_pDirectives->tags.end()) if (m_pDirectives->tags.find(handle) != m_pDirectives->tags.end())
throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE); throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE);
m_pDirectives->tags[handle] = prefix; m_pDirectives->tags[handle] = prefix;
} }
void Parser::PrintTokens(std::ostream& out) void Parser::PrintTokens(std::ostream& out) {
{ if (!m_pScanner.get())
if(!m_pScanner.get())
return; return;
while(1) { while (1) {
if(m_pScanner->empty()) if (m_pScanner->empty())
break; break;
out << m_pScanner->peek() << "\n"; out << m_pScanner->peek() << "\n";
m_pScanner->pop(); m_pScanner->pop();
} }
} }
} }

View File

@@ -1,7 +1,9 @@
#ifndef PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define PTR_STACK_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
@@ -12,14 +14,13 @@
#include <vector> #include <vector>
template <typename T> template <typename T>
class ptr_stack: private YAML::noncopyable class ptr_stack : private YAML::noncopyable {
{ public:
public:
ptr_stack() {} ptr_stack() {}
~ptr_stack() { clear(); } ~ptr_stack() { clear(); }
void clear() { void clear() {
for(unsigned i=0;i<m_data.size();i++) for (unsigned i = 0; i < m_data.size(); i++)
delete m_data[i]; delete m_data[i];
m_data.clear(); m_data.clear();
} }
@@ -40,9 +41,11 @@ public:
const T& top() const { return *m_data.back(); } const T& top() const { return *m_data.back(); }
T& top(std::ptrdiff_t diff) { return **(m_data.end() - 1 + diff); } T& top(std::ptrdiff_t diff) { return **(m_data.end() - 1 + diff); }
const T& top(std::ptrdiff_t diff) const { return **(m_data.end() - 1 + diff); } const T& top(std::ptrdiff_t diff) const {
return **(m_data.end() - 1 + diff);
}
private: private:
std::vector<T*> m_data; std::vector<T*> m_data;
}; };

View File

@@ -1,7 +1,9 @@
#ifndef PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
@@ -13,15 +15,14 @@
namespace YAML { namespace YAML {
template <typename T> template <typename T>
class ptr_vector: private YAML::noncopyable class ptr_vector : private YAML::noncopyable {
{
public: public:
ptr_vector() {} ptr_vector() {}
~ptr_vector() { clear(); } ~ptr_vector() { clear(); }
void clear() { void clear() {
for(unsigned i=0;i<m_data.size();i++) for (unsigned i = 0; i < m_data.size(); i++)
delete m_data[i]; delete m_data[i];
m_data.clear(); m_data.clear();
} }
@@ -41,7 +42,7 @@ namespace YAML {
private: private:
std::vector<T*> m_data; std::vector<T*> m_data;
}; };
} }
#endif // PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // PTR_VECTOR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,60 +1,45 @@
#include "regex.h" #include "regex.h"
namespace YAML namespace YAML {
{ // constructors
// constructors RegEx::RegEx() : m_op(REGEX_EMPTY) {}
RegEx::RegEx(): m_op(REGEX_EMPTY)
{
}
RegEx::RegEx(REGEX_OP op): m_op(op) RegEx::RegEx(REGEX_OP op) : m_op(op) {}
{
}
RegEx::RegEx(char ch): m_op(REGEX_MATCH), m_a(ch) RegEx::RegEx(char ch) : m_op(REGEX_MATCH), m_a(ch) {}
{
}
RegEx::RegEx(char a, char z): m_op(REGEX_RANGE), m_a(a), m_z(z) RegEx::RegEx(char a, char z) : m_op(REGEX_RANGE), m_a(a), m_z(z) {}
{
}
RegEx::RegEx(const std::string& str, REGEX_OP op): m_op(op) RegEx::RegEx(const std::string& str, REGEX_OP op) : m_op(op) {
{ for (std::size_t i = 0; i < str.size(); i++)
for(std::size_t i=0;i<str.size();i++)
m_params.push_back(RegEx(str[i])); m_params.push_back(RegEx(str[i]));
} }
// combination constructors // combination constructors
RegEx operator ! (const RegEx& ex) RegEx operator!(const RegEx & ex) {
{
RegEx ret(REGEX_NOT); RegEx ret(REGEX_NOT);
ret.m_params.push_back(ex); ret.m_params.push_back(ex);
return ret; return ret;
} }
RegEx operator || (const RegEx& ex1, const RegEx& ex2) RegEx operator||(const RegEx& ex1, const RegEx& ex2) {
{
RegEx ret(REGEX_OR); RegEx ret(REGEX_OR);
ret.m_params.push_back(ex1); ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2); ret.m_params.push_back(ex2);
return ret; return ret;
} }
RegEx operator && (const RegEx& ex1, const RegEx& ex2) RegEx operator&&(const RegEx& ex1, const RegEx& ex2) {
{
RegEx ret(REGEX_AND); RegEx ret(REGEX_AND);
ret.m_params.push_back(ex1); ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2); ret.m_params.push_back(ex2);
return ret; return ret;
} }
RegEx operator + (const RegEx& ex1, const RegEx& ex2) RegEx operator+(const RegEx& ex1, const RegEx& ex2) {
{
RegEx ret(REGEX_SEQ); RegEx ret(REGEX_SEQ);
ret.m_params.push_back(ex1); ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2); ret.m_params.push_back(ex2);
return ret; return ret;
}
} }
}

View File

@@ -1,25 +1,32 @@
#ifndef REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define REGEX_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <vector> #include <vector>
#include <string> #include <string>
namespace YAML namespace YAML {
{ class Stream;
class Stream;
enum REGEX_OP { REGEX_EMPTY, REGEX_MATCH, REGEX_RANGE, REGEX_OR, REGEX_AND, REGEX_NOT, REGEX_SEQ }; enum REGEX_OP {
REGEX_EMPTY,
REGEX_MATCH,
REGEX_RANGE,
REGEX_OR,
REGEX_AND,
REGEX_NOT,
REGEX_SEQ
};
// simplified regular expressions // simplified regular expressions
// . Only straightforward matches (no repeated characters) // . Only straightforward matches (no repeated characters)
// . Only matches from start of string // . Only matches from start of string
class RegEx class RegEx {
{
public: public:
RegEx(); RegEx();
RegEx(char ch); RegEx(char ch);
@@ -27,39 +34,50 @@ namespace YAML
RegEx(const std::string& str, REGEX_OP op = REGEX_SEQ); RegEx(const std::string& str, REGEX_OP op = REGEX_SEQ);
~RegEx() {} ~RegEx() {}
friend RegEx operator ! (const RegEx& ex); friend RegEx operator!(const RegEx & ex);
friend RegEx operator || (const RegEx& ex1, const RegEx& ex2); friend RegEx operator||(const RegEx& ex1, const RegEx& ex2);
friend RegEx operator && (const RegEx& ex1, const RegEx& ex2); friend RegEx operator&&(const RegEx& ex1, const RegEx& ex2);
friend RegEx operator + (const RegEx& ex1, const RegEx& ex2); friend RegEx operator+(const RegEx& ex1, const RegEx& ex2);
bool Matches(char ch) const; bool Matches(char ch) const;
bool Matches(const std::string& str) const; bool Matches(const std::string& str) const;
bool Matches(const Stream& in) const; bool Matches(const Stream& in) const;
template <typename Source> bool Matches(const Source& source) const; template <typename Source>
bool Matches(const Source& source) const;
int Match(const std::string& str) const; int Match(const std::string& str) const;
int Match(const Stream& in) const; int Match(const Stream& in) const;
template <typename Source> int Match(const Source& source) const; template <typename Source>
int Match(const Source& source) const;
private: private:
RegEx(REGEX_OP op); RegEx(REGEX_OP op);
template <typename Source> bool IsValidSource(const Source& source) const; template <typename Source>
template <typename Source> int MatchUnchecked(const Source& source) const; bool IsValidSource(const Source& source) const;
template <typename Source>
int MatchUnchecked(const Source& source) const;
template <typename Source> int MatchOpEmpty(const Source& source) const; template <typename Source>
template <typename Source> int MatchOpMatch(const Source& source) const; int MatchOpEmpty(const Source& source) const;
template <typename Source> int MatchOpRange(const Source& source) const; template <typename Source>
template <typename Source> int MatchOpOr(const Source& source) const; int MatchOpMatch(const Source& source) const;
template <typename Source> int MatchOpAnd(const Source& source) const; template <typename Source>
template <typename Source> int MatchOpNot(const Source& source) const; int MatchOpRange(const Source& source) const;
template <typename Source> int MatchOpSeq(const Source& source) const; template <typename Source>
int MatchOpOr(const Source& source) const;
template <typename Source>
int MatchOpAnd(const Source& source) const;
template <typename Source>
int MatchOpNot(const Source& source) const;
template <typename Source>
int MatchOpSeq(const Source& source) const;
private: private:
REGEX_OP m_op; REGEX_OP m_op;
char m_a, m_z; char m_a, m_z;
std::vector <RegEx> m_params; std::vector<RegEx> m_params;
}; };
} }
#include "regeximpl.h" #include "regeximpl.h"

View File

@@ -1,84 +1,77 @@
#ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "stream.h" #include "stream.h"
#include "stringsource.h" #include "stringsource.h"
#include "streamcharsource.h" #include "streamcharsource.h"
namespace YAML namespace YAML {
{ // query matches
// query matches inline bool RegEx::Matches(char ch) const {
inline bool RegEx::Matches(char ch) const {
std::string str; std::string str;
str += ch; str += ch;
return Matches(str); return Matches(str);
} }
inline bool RegEx::Matches(const std::string& str) const { inline bool RegEx::Matches(const std::string& str) const {
return Match(str) >= 0; return Match(str) >= 0;
} }
inline bool RegEx::Matches(const Stream& in) const { inline bool RegEx::Matches(const Stream& in) const { return Match(in) >= 0; }
return Match(in) >= 0;
}
template <typename Source> template <typename Source>
inline bool RegEx::Matches(const Source& source) const { inline bool RegEx::Matches(const Source& source) const {
return Match(source) >= 0; return Match(source) >= 0;
} }
// Match // Match
// . Matches the given string against this regular expression. // . Matches the given string against this regular expression.
// . Returns the number of characters matched. // . Returns the number of characters matched.
// . Returns -1 if no characters were matched (the reason for // . Returns -1 if no characters were matched (the reason for
// not returning zero is that we may have an empty regex // not returning zero is that we may have an empty regex
// which is ALWAYS successful at matching zero characters). // which is ALWAYS successful at matching zero characters).
// . REMEMBER that we only match from the start of the buffer! // . REMEMBER that we only match from the start of the buffer!
inline int RegEx::Match(const std::string& str) const inline int RegEx::Match(const std::string& str) const {
{
StringCharSource source(str.c_str(), str.size()); StringCharSource source(str.c_str(), str.size());
return Match(source); return Match(source);
} }
inline int RegEx::Match(const Stream& in) const inline int RegEx::Match(const Stream& in) const {
{
StreamCharSource source(in); StreamCharSource source(in);
return Match(source); return Match(source);
} }
template <typename Source> template <typename Source>
inline bool RegEx::IsValidSource(const Source& source) const inline bool RegEx::IsValidSource(const Source& source) const {
{
return source; return source;
} }
template<> template <>
inline bool RegEx::IsValidSource<StringCharSource>(const StringCharSource&source) const inline bool RegEx::IsValidSource<StringCharSource>(
{ const StringCharSource& source) const {
switch(m_op) { switch (m_op) {
case REGEX_MATCH: case REGEX_MATCH:
case REGEX_RANGE: case REGEX_RANGE:
return source; return source;
default: default:
return true; return true;
} }
} }
template <typename Source> template <typename Source>
inline int RegEx::Match(const Source& source) const inline int RegEx::Match(const Source& source) const {
{
return IsValidSource(source) ? MatchUnchecked(source) : -1; return IsValidSource(source) ? MatchUnchecked(source) : -1;
} }
template <typename Source> template <typename Source>
inline int RegEx::MatchUnchecked(const Source& source) const inline int RegEx::MatchUnchecked(const Source& source) const {
{ switch (m_op) {
switch(m_op) {
case REGEX_EMPTY: case REGEX_EMPTY:
return MatchOpEmpty(source); return MatchOpEmpty(source);
case REGEX_MATCH: case REGEX_MATCH:
@@ -96,91 +89,98 @@ namespace YAML
} }
return -1; return -1;
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Operators // Operators
// Note: the convention MatchOp*<Source> is that we can assume IsSourceValid(source). // Note: the convention MatchOp*<Source> is that we can assume
// So we do all our checks *before* we call these functions // IsSourceValid(source).
// So we do all our checks *before* we call these functions
// EmptyOperator // EmptyOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpEmpty(const Source& source) const { inline int RegEx::MatchOpEmpty(const Source& source) const {
return source[0] == Stream::eof() ? 0 : -1; return source[0] == Stream::eof() ? 0 : -1;
} }
template <> template <>
inline int RegEx::MatchOpEmpty<StringCharSource>(const StringCharSource& source) const { inline int RegEx::MatchOpEmpty<StringCharSource>(const StringCharSource& source)
return !source ? 0 : -1; // the empty regex only is successful on the empty string const {
} return !source
? 0
: -1; // the empty regex only is successful on the empty string
}
// MatchOperator // MatchOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpMatch(const Source& source) const { inline int RegEx::MatchOpMatch(const Source& source) const {
if(source[0] != m_a) if (source[0] != m_a)
return -1; return -1;
return 1; return 1;
} }
// RangeOperator // RangeOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpRange(const Source& source) const { inline int RegEx::MatchOpRange(const Source& source) const {
if(m_a > source[0] || m_z < source[0]) if (m_a > source[0] || m_z < source[0])
return -1; return -1;
return 1; return 1;
} }
// OrOperator // OrOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpOr(const Source& source) const { inline int RegEx::MatchOpOr(const Source& source) const {
for(std::size_t i=0;i<m_params.size();i++) { for (std::size_t i = 0; i < m_params.size(); i++) {
int n = m_params[i].MatchUnchecked(source); int n = m_params[i].MatchUnchecked(source);
if(n >= 0) if (n >= 0)
return n; return n;
} }
return -1; return -1;
} }
// AndOperator // AndOperator
// Note: 'AND' is a little funny, since we may be required to match things // Note: 'AND' is a little funny, since we may be required to match things
// of different lengths. If we find a match, we return the length of // of different lengths. If we find a match, we return the length of
// the FIRST entry on the list. // the FIRST entry on the list.
template <typename Source> template <typename Source>
inline int RegEx::MatchOpAnd(const Source& source) const { inline int RegEx::MatchOpAnd(const Source& source) const {
int first = -1; int first = -1;
for(std::size_t i=0;i<m_params.size();i++) { for (std::size_t i = 0; i < m_params.size(); i++) {
int n = m_params[i].MatchUnchecked(source); int n = m_params[i].MatchUnchecked(source);
if(n == -1) if (n == -1)
return -1; return -1;
if(i == 0) if (i == 0)
first = n; first = n;
} }
return first; return first;
} }
// NotOperator // NotOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpNot(const Source& source) const { inline int RegEx::MatchOpNot(const Source& source) const {
if(m_params.empty()) if (m_params.empty())
return -1; return -1;
if(m_params[0].MatchUnchecked(source) >= 0) if (m_params[0].MatchUnchecked(source) >= 0)
return -1; return -1;
return 1; return 1;
} }
// SeqOperator // SeqOperator
template <typename Source> template <typename Source>
inline int RegEx::MatchOpSeq(const Source& source) const { inline int RegEx::MatchOpSeq(const Source& source) const {
int offset = 0; int offset = 0;
for(std::size_t i=0;i<m_params.size();i++) { for (std::size_t i = 0; i < m_params.size(); i++) {
int n = m_params[i].Match(source + offset); // note Match, not MatchUnchecked because we need to check validity after the offset int n = m_params[i].Match(source + offset); // note Match, not
if(n == -1) // MatchUnchecked because we
// need to check validity after
// the offset
if (n == -1)
return -1; return -1;
offset += n; offset += n;
} }
return offset; return offset;
} }
} }
#endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // REGEXIMPL_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -5,40 +5,37 @@
#include <cassert> #include <cassert>
#include <memory> #include <memory>
namespace YAML namespace YAML {
{ Scanner::Scanner(std::istream& in)
Scanner::Scanner(std::istream& in) : INPUT(in),
: INPUT(in), m_startedStream(false), m_endedStream(false), m_simpleKeyAllowed(false), m_canBeJSONFlow(false) m_startedStream(false),
{ m_endedStream(false),
} m_simpleKeyAllowed(false),
m_canBeJSONFlow(false) {}
Scanner::~Scanner() Scanner::~Scanner() {}
{
}
// empty // empty
// . Returns true if there are no more tokens to be read // . Returns true if there are no more tokens to be read
bool Scanner::empty() bool Scanner::empty() {
{
EnsureTokensInQueue(); EnsureTokensInQueue();
return m_tokens.empty(); return m_tokens.empty();
} }
// pop // pop
// . Simply removes the next token on the queue. // . Simply removes the next token on the queue.
void Scanner::pop() void Scanner::pop() {
{
EnsureTokensInQueue(); EnsureTokensInQueue();
if(!m_tokens.empty()) if (!m_tokens.empty())
m_tokens.pop(); m_tokens.pop();
} }
// peek // peek
// . Returns (but does not remove) the next token on the queue. // . Returns (but does not remove) the next token on the queue.
Token& Scanner::peek() Token& Scanner::peek() {
{
EnsureTokensInQueue(); EnsureTokensInQueue();
assert(!m_tokens.empty()); // should we be asserting here? I mean, we really just be checking assert(!m_tokens.empty()); // should we be asserting here? I mean, we really
// just be checking
// if it's empty before peeking. // if it's empty before peeking.
#if 0 #if 0
@@ -49,30 +46,26 @@ namespace YAML
#endif #endif
return m_tokens.front(); return m_tokens.front();
} }
// mark // mark
// . Returns the current mark in the stream // . Returns the current mark in the stream
Mark Scanner::mark() const Mark Scanner::mark() const { return INPUT.mark(); }
{
return INPUT.mark();
}
// EnsureTokensInQueue // EnsureTokensInQueue
// . Scan until there's a valid token at the front of the queue, // . Scan until there's a valid token at the front of the queue,
// or we're sure the queue is empty. // or we're sure the queue is empty.
void Scanner::EnsureTokensInQueue() void Scanner::EnsureTokensInQueue() {
{ while (1) {
while(1) { if (!m_tokens.empty()) {
if(!m_tokens.empty()) {
Token& token = m_tokens.front(); Token& token = m_tokens.front();
// if this guy's valid, then we're done // if this guy's valid, then we're done
if(token.status == Token::VALID) if (token.status == Token::VALID)
return; return;
// here's where we clean up the impossible tokens // here's where we clean up the impossible tokens
if(token.status == Token::INVALID) { if (token.status == Token::INVALID) {
m_tokens.pop(); m_tokens.pop();
continue; continue;
} }
@@ -81,23 +74,22 @@ namespace YAML
} }
// no token? maybe we've actually finished // no token? maybe we've actually finished
if(m_endedStream) if (m_endedStream)
return; return;
// no? then scan... // no? then scan...
ScanNextToken(); ScanNextToken();
} }
} }
// ScanNextToken // ScanNextToken
// . The main scanning function; here we branch out and // . The main scanning function; here we branch out and
// scan whatever the next token should be. // scan whatever the next token should be.
void Scanner::ScanNextToken() void Scanner::ScanNextToken() {
{ if (m_endedStream)
if(m_endedStream)
return; return;
if(!m_startedStream) if (!m_startedStream)
return StartStream(); return StartStream();
// get rid of whitespace, etc. (in between tokens it should be irrelevent) // get rid of whitespace, etc. (in between tokens it should be irrelevent)
@@ -111,83 +103,84 @@ namespace YAML
// ***** // *****
// end of stream // end of stream
if(!INPUT) if (!INPUT)
return EndStream(); return EndStream();
if(INPUT.column() == 0 && INPUT.peek() == Keys::Directive) if (INPUT.column() == 0 && INPUT.peek() == Keys::Directive)
return ScanDirective(); return ScanDirective();
// document token // document token
if(INPUT.column() == 0 && Exp::DocStart().Matches(INPUT)) if (INPUT.column() == 0 && Exp::DocStart().Matches(INPUT))
return ScanDocStart(); return ScanDocStart();
if(INPUT.column() == 0 && Exp::DocEnd().Matches(INPUT)) if (INPUT.column() == 0 && Exp::DocEnd().Matches(INPUT))
return ScanDocEnd(); return ScanDocEnd();
// flow start/end/entry // flow start/end/entry
if(INPUT.peek() == Keys::FlowSeqStart || INPUT.peek() == Keys::FlowMapStart) if (INPUT.peek() == Keys::FlowSeqStart || INPUT.peek() == Keys::FlowMapStart)
return ScanFlowStart(); return ScanFlowStart();
if(INPUT.peek() == Keys::FlowSeqEnd || INPUT.peek() == Keys::FlowMapEnd) if (INPUT.peek() == Keys::FlowSeqEnd || INPUT.peek() == Keys::FlowMapEnd)
return ScanFlowEnd(); return ScanFlowEnd();
if(INPUT.peek() == Keys::FlowEntry) if (INPUT.peek() == Keys::FlowEntry)
return ScanFlowEntry(); return ScanFlowEntry();
// block/map stuff // block/map stuff
if(Exp::BlockEntry().Matches(INPUT)) if (Exp::BlockEntry().Matches(INPUT))
return ScanBlockEntry(); return ScanBlockEntry();
if((InBlockContext() ? Exp::Key() : Exp::KeyInFlow()).Matches(INPUT)) if ((InBlockContext() ? Exp::Key() : Exp::KeyInFlow()).Matches(INPUT))
return ScanKey(); return ScanKey();
if(GetValueRegex().Matches(INPUT)) if (GetValueRegex().Matches(INPUT))
return ScanValue(); return ScanValue();
// alias/anchor // alias/anchor
if(INPUT.peek() == Keys::Alias || INPUT.peek() == Keys::Anchor) if (INPUT.peek() == Keys::Alias || INPUT.peek() == Keys::Anchor)
return ScanAnchorOrAlias(); return ScanAnchorOrAlias();
// tag // tag
if(INPUT.peek() == Keys::Tag) if (INPUT.peek() == Keys::Tag)
return ScanTag(); return ScanTag();
// special scalars // special scalars
if(InBlockContext() && (INPUT.peek() == Keys::LiteralScalar || INPUT.peek() == Keys::FoldedScalar)) if (InBlockContext() && (INPUT.peek() == Keys::LiteralScalar ||
INPUT.peek() == Keys::FoldedScalar))
return ScanBlockScalar(); return ScanBlockScalar();
if(INPUT.peek() == '\'' || INPUT.peek() == '\"') if (INPUT.peek() == '\'' || INPUT.peek() == '\"')
return ScanQuotedScalar(); return ScanQuotedScalar();
// plain scalars // plain scalars
if((InBlockContext() ? Exp::PlainScalar() : Exp::PlainScalarInFlow()).Matches(INPUT)) if ((InBlockContext() ? Exp::PlainScalar() : Exp::PlainScalarInFlow())
.Matches(INPUT))
return ScanPlainScalar(); return ScanPlainScalar();
// don't know what it is! // don't know what it is!
throw ParserException(INPUT.mark(), ErrorMsg::UNKNOWN_TOKEN); throw ParserException(INPUT.mark(), ErrorMsg::UNKNOWN_TOKEN);
} }
// ScanToNextToken // ScanToNextToken
// . Eats input until we reach the next token-like thing. // . Eats input until we reach the next token-like thing.
void Scanner::ScanToNextToken() void Scanner::ScanToNextToken() {
{ while (1) {
while(1) {
// first eat whitespace // first eat whitespace
while(INPUT && IsWhitespaceToBeEaten(INPUT.peek())) { while (INPUT && IsWhitespaceToBeEaten(INPUT.peek())) {
if(InBlockContext() && Exp::Tab().Matches(INPUT)) if (InBlockContext() && Exp::Tab().Matches(INPUT))
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
INPUT.eat(1); INPUT.eat(1);
} }
// then eat a comment // then eat a comment
if(Exp::Comment().Matches(INPUT)) { if (Exp::Comment().Matches(INPUT)) {
// eat until line break // eat until line break
while(INPUT && !Exp::Break().Matches(INPUT)) while (INPUT && !Exp::Break().Matches(INPUT))
INPUT.eat(1); INPUT.eat(1);
} }
// if it's NOT a line break, then we're done! // if it's NOT a line break, then we're done!
if(!Exp::Break().Matches(INPUT)) if (!Exp::Break().Matches(INPUT))
break; break;
// otherwise, let's eat the line break and keep going // otherwise, let's eat the line break and keep going
@@ -198,60 +191,57 @@ namespace YAML
InvalidateSimpleKey(); InvalidateSimpleKey();
// new line - we may be able to accept a simple key now // new line - we may be able to accept a simple key now
if(InBlockContext()) if (InBlockContext())
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
} }
} }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// Misc. helpers // Misc. helpers
// IsWhitespaceToBeEaten // IsWhitespaceToBeEaten
// . We can eat whitespace if it's a space or tab // . We can eat whitespace if it's a space or tab
// . Note: originally tabs in block context couldn't be eaten // . Note: originally tabs in block context couldn't be eaten
// "where a simple key could be allowed // "where a simple key could be allowed
// (i.e., not at the beginning of a line, or following '-', '?', or ':')" // (i.e., not at the beginning of a line, or following '-', '?', or
// I think this is wrong, since tabs can be non-content whitespace; it's just // ':')"
// that they can't contribute to indentation, so once you've seen a tab in a // I think this is wrong, since tabs can be non-content whitespace; it's just
// line, you can't start a simple key // that they can't contribute to indentation, so once you've seen a tab in a
bool Scanner::IsWhitespaceToBeEaten(char ch) // line, you can't start a simple key
{ bool Scanner::IsWhitespaceToBeEaten(char ch) {
if(ch == ' ') if (ch == ' ')
return true; return true;
if(ch == '\t') if (ch == '\t')
return true; return true;
return false; return false;
} }
// GetValueRegex // GetValueRegex
// . Get the appropriate regex to check if it's a value token // . Get the appropriate regex to check if it's a value token
const RegEx& Scanner::GetValueRegex() const const RegEx& Scanner::GetValueRegex() const {
{ if (InBlockContext())
if(InBlockContext())
return Exp::Value(); return Exp::Value();
return m_canBeJSONFlow ? Exp::ValueInJSONFlow() : Exp::ValueInFlow(); return m_canBeJSONFlow ? Exp::ValueInJSONFlow() : Exp::ValueInFlow();
} }
// StartStream // StartStream
// . Set the initial conditions for starting a stream. // . Set the initial conditions for starting a stream.
void Scanner::StartStream() void Scanner::StartStream() {
{
m_startedStream = true; m_startedStream = true;
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
std::auto_ptr<IndentMarker> pIndent(new IndentMarker(-1, IndentMarker::NONE)); std::auto_ptr<IndentMarker> pIndent(new IndentMarker(-1, IndentMarker::NONE));
m_indentRefs.push_back(pIndent); m_indentRefs.push_back(pIndent);
m_indents.push(&m_indentRefs.back()); m_indents.push(&m_indentRefs.back());
} }
// EndStream // EndStream
// . Close out the stream, finish up, etc. // . Close out the stream, finish up, etc.
void Scanner::EndStream() void Scanner::EndStream() {
{
// force newline // force newline
if(INPUT.column() > 0) if (INPUT.column() > 0)
INPUT.ResetColumn(); INPUT.ResetColumn();
PopAllIndents(); PopAllIndents();
@@ -259,33 +249,35 @@ namespace YAML
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
m_endedStream = true; m_endedStream = true;
} }
Token *Scanner::PushToken(Token::TYPE type) Token* Scanner::PushToken(Token::TYPE type) {
{
m_tokens.push(Token(type, INPUT.mark())); m_tokens.push(Token(type, INPUT.mark()));
return &m_tokens.back(); return &m_tokens.back();
} }
Token::TYPE Scanner::GetStartTokenFor(IndentMarker::INDENT_TYPE type) const Token::TYPE Scanner::GetStartTokenFor(IndentMarker::INDENT_TYPE type) const {
{ switch (type) {
switch(type) { case IndentMarker::SEQ:
case IndentMarker::SEQ: return Token::BLOCK_SEQ_START; return Token::BLOCK_SEQ_START;
case IndentMarker::MAP: return Token::BLOCK_MAP_START; case IndentMarker::MAP:
case IndentMarker::NONE: assert(false); break; return Token::BLOCK_MAP_START;
case IndentMarker::NONE:
assert(false);
break;
} }
assert(false); assert(false);
throw std::runtime_error("yaml-cpp: internal error, invalid indent type"); throw std::runtime_error("yaml-cpp: internal error, invalid indent type");
} }
// PushIndentTo // PushIndentTo
// . Pushes an indentation onto the stack, and enqueues the // . Pushes an indentation onto the stack, and enqueues the
// proper token (sequence start or mapping start). // proper token (sequence start or mapping start).
// . Returns the indent marker it generates (if any). // . Returns the indent marker it generates (if any).
Scanner::IndentMarker *Scanner::PushIndentTo(int column, IndentMarker::INDENT_TYPE type) Scanner::IndentMarker* Scanner::PushIndentTo(int column,
{ IndentMarker::INDENT_TYPE type) {
// are we in flow? // are we in flow?
if(InFlowContext()) if (InFlowContext())
return 0; return 0;
std::auto_ptr<IndentMarker> pIndent(new IndentMarker(column, type)); std::auto_ptr<IndentMarker> pIndent(new IndentMarker(column, type));
@@ -293,9 +285,11 @@ namespace YAML
const IndentMarker& lastIndent = *m_indents.top(); const IndentMarker& lastIndent = *m_indents.top();
// is this actually an indentation? // is this actually an indentation?
if(indent.column < lastIndent.column) if (indent.column < lastIndent.column)
return 0; return 0;
if(indent.column == lastIndent.column && !(indent.type == IndentMarker::SEQ && lastIndent.type == IndentMarker::MAP)) if (indent.column == lastIndent.column &&
!(indent.type == IndentMarker::SEQ &&
lastIndent.type == IndentMarker::MAP))
return 0; return 0;
// push a start token // push a start token
@@ -305,90 +299,86 @@ namespace YAML
m_indents.push(&indent); m_indents.push(&indent);
m_indentRefs.push_back(pIndent); m_indentRefs.push_back(pIndent);
return &m_indentRefs.back(); return &m_indentRefs.back();
} }
// PopIndentToHere // PopIndentToHere
// . Pops indentations off the stack until we reach the current indentation level, // . Pops indentations off the stack until we reach the current indentation
// and enqueues the proper token each time. // level,
// . Then pops all invalid indentations off. // and enqueues the proper token each time.
void Scanner::PopIndentToHere() // . Then pops all invalid indentations off.
{ void Scanner::PopIndentToHere() {
// are we in flow? // are we in flow?
if(InFlowContext()) if (InFlowContext())
return; return;
// now pop away // now pop away
while(!m_indents.empty()) { while (!m_indents.empty()) {
const IndentMarker& indent = *m_indents.top(); const IndentMarker& indent = *m_indents.top();
if(indent.column < INPUT.column()) if (indent.column < INPUT.column())
break; 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; break;
PopIndent(); PopIndent();
} }
while(!m_indents.empty() && m_indents.top()->status == IndentMarker::INVALID) while (!m_indents.empty() && m_indents.top()->status == IndentMarker::INVALID)
PopIndent(); PopIndent();
} }
// PopAllIndents // PopAllIndents
// . Pops all indentations (except for the base empty one) off the stack, // . Pops all indentations (except for the base empty one) off the stack,
// and enqueues the proper token each time. // and enqueues the proper token each time.
void Scanner::PopAllIndents() void Scanner::PopAllIndents() {
{
// are we in flow? // are we in flow?
if(InFlowContext()) if (InFlowContext())
return; return;
// now pop away // now pop away
while(!m_indents.empty()) { while (!m_indents.empty()) {
const IndentMarker& indent = *m_indents.top(); const IndentMarker& indent = *m_indents.top();
if(indent.type == IndentMarker::NONE) if (indent.type == IndentMarker::NONE)
break; break;
PopIndent(); PopIndent();
} }
} }
// PopIndent // PopIndent
// . Pops a single indent, pushing the proper token // . Pops a single indent, pushing the proper token
void Scanner::PopIndent() void Scanner::PopIndent() {
{
const IndentMarker& indent = *m_indents.top(); const IndentMarker& indent = *m_indents.top();
m_indents.pop(); m_indents.pop();
if(indent.status != IndentMarker::VALID) { if (indent.status != IndentMarker::VALID) {
InvalidateSimpleKey(); InvalidateSimpleKey();
return; return;
} }
if(indent.type == IndentMarker::SEQ) if (indent.type == IndentMarker::SEQ)
m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark())); m_tokens.push(Token(Token::BLOCK_SEQ_END, INPUT.mark()));
else if(indent.type == IndentMarker::MAP) else if (indent.type == IndentMarker::MAP)
m_tokens.push(Token(Token::BLOCK_MAP_END, INPUT.mark())); m_tokens.push(Token(Token::BLOCK_MAP_END, INPUT.mark()));
} }
// GetTopIndent // GetTopIndent
int Scanner::GetTopIndent() const int Scanner::GetTopIndent() const {
{ if (m_indents.empty())
if(m_indents.empty())
return 0; return 0;
return m_indents.top()->column; return m_indents.top()->column;
} }
// ThrowParserException // ThrowParserException
// . Throws a ParserException with the current token location // . Throws a ParserException with the current token location
// (if available). // (if available).
// . Does not parse any more tokens. // . Does not parse any more tokens.
void Scanner::ThrowParserException(const std::string& msg) const void Scanner::ThrowParserException(const std::string& msg) const {
{
Mark mark = Mark::null_mark(); Mark mark = Mark::null_mark();
if(!m_tokens.empty()) { if (!m_tokens.empty()) {
const Token& token = m_tokens.front(); const Token& token = m_tokens.front();
mark = token.mark; mark = token.mark;
} }
throw ParserException(mark, msg); throw ParserException(mark, msg);
}
} }
}

View File

@@ -1,11 +1,12 @@
#ifndef SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <ios> #include <ios>
#include <string> #include <string>
#include <queue> #include <queue>
@@ -16,28 +17,35 @@
#include "stream.h" #include "stream.h"
#include "token.h" #include "token.h"
namespace YAML namespace YAML {
{ class Node;
class Node; class RegEx;
class RegEx;
class Scanner class Scanner {
{
public: public:
Scanner(std::istream& in); Scanner(std::istream &in);
~Scanner(); ~Scanner();
// token queue management (hopefully this looks kinda stl-ish) // token queue management (hopefully this looks kinda stl-ish)
bool empty(); bool empty();
void pop(); void pop();
Token& peek(); Token &peek();
Mark mark() const; Mark mark() const;
private: private:
struct IndentMarker { struct IndentMarker {
enum INDENT_TYPE { MAP, SEQ, NONE }; enum INDENT_TYPE {
enum STATUS { VALID, INVALID, UNKNOWN }; MAP,
IndentMarker(int column_, INDENT_TYPE type_): column(column_), type(type_), status(VALID), pStartToken(0) {} SEQ,
NONE
};
enum STATUS {
VALID,
INVALID,
UNKNOWN
};
IndentMarker(int column_, INDENT_TYPE type_)
: column(column_), type(type_), status(VALID), pStartToken(0) {}
int column; int column;
INDENT_TYPE type; INDENT_TYPE type;
@@ -45,7 +53,10 @@ namespace YAML
Token *pStartToken; Token *pStartToken;
}; };
enum FLOW_MARKER { FLOW_MAP, FLOW_SEQ }; enum FLOW_MARKER {
FLOW_MAP,
FLOW_SEQ
};
private: private:
// scanning // scanning
@@ -75,13 +86,13 @@ namespace YAML
bool VerifySimpleKey(); bool VerifySimpleKey();
void PopAllSimpleKeys(); void PopAllSimpleKeys();
void ThrowParserException(const std::string& msg) const; void ThrowParserException(const std::string &msg) const;
bool IsWhitespaceToBeEaten(char ch); bool IsWhitespaceToBeEaten(char ch);
const RegEx& GetValueRegex() const; const RegEx &GetValueRegex() const;
struct SimpleKey { struct SimpleKey {
SimpleKey(const Mark& mark_, int flowLevel_); SimpleKey(const Mark &mark_, int flowLevel_);
void Validate(); void Validate();
void Invalidate(); void Invalidate();
@@ -126,8 +137,7 @@ namespace YAML
std::stack<IndentMarker *> m_indents; std::stack<IndentMarker *> m_indents;
ptr_vector<IndentMarker> m_indentRefs; // for "garbage collection" ptr_vector<IndentMarker> m_indentRefs; // for "garbage collection"
std::stack<FLOW_MARKER> m_flows; std::stack<FLOW_MARKER> m_flows;
}; };
} }
#endif // SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // SCANNER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -4,20 +4,18 @@
#include "yaml-cpp/exceptions.h" #include "yaml-cpp/exceptions.h"
#include "token.h" #include "token.h"
namespace YAML namespace YAML {
{ // ScanScalar
// ScanScalar // . This is where the scalar magic happens.
// . This is where the scalar magic happens. //
// // . We do the scanning in three phases:
// . We do the scanning in three phases: // 1. Scan until newline
// 1. Scan until newline // 2. Eat newline
// 2. Eat newline // 3. Scan leading blanks.
// 3. Scan leading blanks. //
// // . Depending on the parameters given, we store or stop
// . Depending on the parameters given, we store or stop // and different places in the above flow.
// and different places in the above flow. std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) {
std::string ScanScalar(Stream& INPUT, ScanScalarParams& params)
{
bool foundNonEmptyLine = false; bool foundNonEmptyLine = false;
bool pastOpeningBreak = (params.fold == FOLD_FLOW); bool pastOpeningBreak = (params.fold == FOLD_FLOW);
bool emptyLine = false, moreIndented = false; bool emptyLine = false, moreIndented = false;
@@ -27,21 +25,21 @@ namespace YAML
std::string scalar; std::string scalar;
params.leadingSpaces = false; params.leadingSpaces = false;
while(INPUT) { while (INPUT) {
// ******************************** // ********************************
// Phase #1: scan until line ending // Phase #1: scan until line ending
std::size_t lastNonWhitespaceChar = scalar.size(); std::size_t lastNonWhitespaceChar = scalar.size();
bool escapedNewline = false; bool escapedNewline = false;
while(!params.end.Matches(INPUT) && !Exp::Break().Matches(INPUT)) { while (!params.end.Matches(INPUT) && !Exp::Break().Matches(INPUT)) {
if(!INPUT) if (!INPUT)
break; break;
// document indicator? // document indicator?
if(INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT)) { if (INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT)) {
if(params.onDocIndicator == BREAK) if (params.onDocIndicator == BREAK)
break; break;
else if(params.onDocIndicator == THROW) else if (params.onDocIndicator == THROW)
throw ParserException(INPUT.mark(), ErrorMsg::DOC_IN_SCALAR); throw ParserException(INPUT.mark(), ErrorMsg::DOC_IN_SCALAR);
} }
@@ -49,7 +47,7 @@ namespace YAML
pastOpeningBreak = true; pastOpeningBreak = true;
// escaped newline? (only if we're escaping on slash) // escaped newline? (only if we're escaping on slash)
if(params.escape == '\\' && Exp::EscBreak().Matches(INPUT)) { if (params.escape == '\\' && Exp::EscBreak().Matches(INPUT)) {
// eat escape character and get out (but preserve trailing whitespace!) // eat escape character and get out (but preserve trailing whitespace!)
INPUT.get(); INPUT.get();
lastNonWhitespaceChar = scalar.size(); lastNonWhitespaceChar = scalar.size();
@@ -59,7 +57,7 @@ namespace YAML
} }
// escape this? // escape this?
if(INPUT.peek() == params.escape) { if (INPUT.peek() == params.escape) {
scalar += Exp::Escape(INPUT); scalar += Exp::Escape(INPUT);
lastNonWhitespaceChar = scalar.size(); lastNonWhitespaceChar = scalar.size();
lastEscapedChar = scalar.size(); lastEscapedChar = scalar.size();
@@ -69,31 +67,32 @@ namespace YAML
// otherwise, just add the damn character // otherwise, just add the damn character
char ch = INPUT.get(); char ch = INPUT.get();
scalar += ch; scalar += ch;
if(ch != ' ' && ch != '\t') if (ch != ' ' && ch != '\t')
lastNonWhitespaceChar = scalar.size(); lastNonWhitespaceChar = scalar.size();
} }
// eof? if we're looking to eat something, then we throw // eof? if we're looking to eat something, then we throw
if(!INPUT) { if (!INPUT) {
if(params.eatEnd) if (params.eatEnd)
throw ParserException(INPUT.mark(), ErrorMsg::EOF_IN_SCALAR); throw ParserException(INPUT.mark(), ErrorMsg::EOF_IN_SCALAR);
break; break;
} }
// doc indicator? // 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; break;
// are we done via character match? // are we done via character match?
int n = params.end.Match(INPUT); int n = params.end.Match(INPUT);
if(n >= 0) { if (n >= 0) {
if(params.eatEnd) if (params.eatEnd)
INPUT.eat(n); INPUT.eat(n);
break; break;
} }
// do we remove trailing whitespace? // do we remove trailing whitespace?
if(params.fold == FOLD_FLOW) if (params.fold == FOLD_FLOW)
scalar.erase(lastNonWhitespaceChar); scalar.erase(lastNonWhitespaceChar);
// ******************************** // ********************************
@@ -105,20 +104,22 @@ namespace YAML
// Phase #3: scan initial spaces // Phase #3: scan initial spaces
// first the required indentation // first the required indentation
while(INPUT.peek() == ' ' && (INPUT.column() < params.indent || (params.detectIndent && !foundNonEmptyLine))) while (INPUT.peek() == ' ' && (INPUT.column() < params.indent ||
(params.detectIndent && !foundNonEmptyLine)))
INPUT.eat(1); INPUT.eat(1);
// update indent if we're auto-detecting // update indent if we're auto-detecting
if(params.detectIndent && !foundNonEmptyLine) if (params.detectIndent && !foundNonEmptyLine)
params.indent = std::max(params.indent, INPUT.column()); params.indent = std::max(params.indent, INPUT.column());
// and then the rest of the whitespace // 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 // we check for tabs that masquerade as indentation
if(INPUT.peek() == '\t'&& INPUT.column() < params.indent && params.onTabInIndentation == THROW) if (INPUT.peek() == '\t' && INPUT.column() < params.indent &&
params.onTabInIndentation == THROW)
throw ParserException(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION); throw ParserException(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION);
if(!params.eatLeadingWhitespace) if (!params.eatLeadingWhitespace)
break; break;
INPUT.eat(1); INPUT.eat(1);
@@ -127,34 +128,37 @@ namespace YAML
// was this an empty line? // was this an empty line?
bool nextEmptyLine = Exp::Break().Matches(INPUT); bool nextEmptyLine = Exp::Break().Matches(INPUT);
bool nextMoreIndented = Exp::Blank().Matches(INPUT); bool nextMoreIndented = Exp::Blank().Matches(INPUT);
if(params.fold == FOLD_BLOCK && foldedNewlineCount == 0 && nextEmptyLine) if (params.fold == FOLD_BLOCK && foldedNewlineCount == 0 && nextEmptyLine)
foldedNewlineStartedMoreIndented = moreIndented; foldedNewlineStartedMoreIndented = moreIndented;
// for block scalars, we always start with a newline, so we should ignore it (not fold or keep) // for block scalars, we always start with a newline, so we should ignore it
if(pastOpeningBreak) { // (not fold or keep)
switch(params.fold) { if (pastOpeningBreak) {
switch (params.fold) {
case DONT_FOLD: case DONT_FOLD:
scalar += "\n"; scalar += "\n";
break; break;
case FOLD_BLOCK: case FOLD_BLOCK:
if(!emptyLine && !nextEmptyLine && !moreIndented && !nextMoreIndented && INPUT.column() >= params.indent) if (!emptyLine && !nextEmptyLine && !moreIndented &&
!nextMoreIndented && INPUT.column() >= params.indent)
scalar += " "; scalar += " ";
else if(nextEmptyLine) else if (nextEmptyLine)
foldedNewlineCount++; foldedNewlineCount++;
else else
scalar += "\n"; scalar += "\n";
if(!nextEmptyLine && foldedNewlineCount > 0) { if (!nextEmptyLine && foldedNewlineCount > 0) {
scalar += std::string(foldedNewlineCount - 1, '\n'); scalar += std::string(foldedNewlineCount - 1, '\n');
if(foldedNewlineStartedMoreIndented || nextMoreIndented | !foundNonEmptyLine) if (foldedNewlineStartedMoreIndented ||
nextMoreIndented | !foundNonEmptyLine)
scalar += "\n"; scalar += "\n";
foldedNewlineCount = 0; foldedNewlineCount = 0;
} }
break; break;
case FOLD_FLOW: case FOLD_FLOW:
if(nextEmptyLine) if (nextEmptyLine)
scalar += "\n"; scalar += "\n";
else if(!emptyLine && !nextEmptyLine && !escapedNewline) else if (!emptyLine && !nextEmptyLine && !escapedNewline)
scalar += " "; scalar += " ";
break; break;
} }
@@ -165,44 +169,44 @@ namespace YAML
pastOpeningBreak = true; pastOpeningBreak = true;
// are we done via indentation? // are we done via indentation?
if(!emptyLine && INPUT.column() < params.indent) { if (!emptyLine && INPUT.column() < params.indent) {
params.leadingSpaces = true; params.leadingSpaces = true;
break; break;
} }
} }
// post-processing // post-processing
if(params.trimTrailingSpaces) { if (params.trimTrailingSpaces) {
std::size_t pos = scalar.find_last_not_of(' '); std::size_t pos = scalar.find_last_not_of(' ');
if(lastEscapedChar != std::string::npos) { if (lastEscapedChar != std::string::npos) {
if(pos < lastEscapedChar || pos == std::string::npos) if (pos < lastEscapedChar || pos == std::string::npos)
pos = lastEscapedChar; pos = lastEscapedChar;
} }
if(pos < scalar.size()) if (pos < scalar.size())
scalar.erase(pos + 1); scalar.erase(pos + 1);
} }
switch(params.chomp) { switch (params.chomp) {
case CLIP: { case CLIP: {
std::size_t pos = scalar.find_last_not_of('\n'); std::size_t pos = scalar.find_last_not_of('\n');
if(lastEscapedChar != std::string::npos) { if (lastEscapedChar != std::string::npos) {
if(pos < lastEscapedChar || pos == std::string::npos) if (pos < lastEscapedChar || pos == std::string::npos)
pos = lastEscapedChar; pos = lastEscapedChar;
} }
if(pos == std::string::npos) if (pos == std::string::npos)
scalar.erase(); scalar.erase();
else if(pos + 1 < scalar.size()) else if (pos + 1 < scalar.size())
scalar.erase(pos + 2); scalar.erase(pos + 2);
} break; } break;
case STRIP: { case STRIP: {
std::size_t pos = scalar.find_last_not_of('\n'); std::size_t pos = scalar.find_last_not_of('\n');
if(lastEscapedChar != std::string::npos) { if (lastEscapedChar != std::string::npos) {
if(pos < lastEscapedChar || pos == std::string::npos) if (pos < lastEscapedChar || pos == std::string::npos)
pos = lastEscapedChar; pos = lastEscapedChar;
} }
if(pos == std::string::npos) if (pos == std::string::npos)
scalar.erase(); scalar.erase();
else if(pos < scalar.size()) else if (pos < scalar.size())
scalar.erase(pos + 1); scalar.erase(pos + 1);
} break; } break;
default: default:
@@ -210,5 +214,5 @@ namespace YAML
} }
return scalar; return scalar;
} }
} }

View File

@@ -1,45 +1,72 @@
#ifndef SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include "regex.h" #include "regex.h"
#include "stream.h" #include "stream.h"
namespace YAML namespace YAML {
{ enum CHOMP {
enum CHOMP { STRIP = -1, CLIP, KEEP }; STRIP = -1,
enum ACTION { NONE, BREAK, THROW }; CLIP,
enum FOLD { DONT_FOLD, FOLD_BLOCK, FOLD_FLOW }; KEEP
};
enum ACTION {
NONE,
BREAK,
THROW
};
enum FOLD {
DONT_FOLD,
FOLD_BLOCK,
FOLD_FLOW
};
struct ScanScalarParams { struct ScanScalarParams {
ScanScalarParams(): eatEnd(false), indent(0), detectIndent(false), eatLeadingWhitespace(0), escape(0), fold(DONT_FOLD), ScanScalarParams()
trimTrailingSpaces(0), chomp(CLIP), onDocIndicator(NONE), onTabInIndentation(NONE), leadingSpaces(false) {} : eatEnd(false),
indent(0),
detectIndent(false),
eatLeadingWhitespace(0),
escape(0),
fold(DONT_FOLD),
trimTrailingSpaces(0),
chomp(CLIP),
onDocIndicator(NONE),
onTabInIndentation(NONE),
leadingSpaces(false) {}
// input: // input:
RegEx end; // what condition ends this scalar? RegEx end; // what condition ends this scalar?
bool eatEnd; // should we eat that condition when we see it? bool eatEnd; // should we eat that condition when we see it?
int indent; // what level of indentation should be eaten and ignored? int indent; // what level of indentation should be eaten and ignored?
bool detectIndent; // should we try to autodetect the indent? bool detectIndent; // should we try to autodetect the indent?
bool eatLeadingWhitespace; // should we continue eating this delicious indentation after 'indent' spaces? bool eatLeadingWhitespace; // should we continue eating this delicious
char escape; // what character do we escape on (i.e., slash or single quote) (0 for none) // indentation after 'indent' spaces?
char escape; // what character do we escape on (i.e., slash or single quote)
// (0 for none)
FOLD fold; // how do we fold line ends? FOLD fold; // how do we fold line ends?
bool trimTrailingSpaces; // do we remove all trailing spaces (at the very end) bool trimTrailingSpaces; // do we remove all trailing spaces (at the very
CHOMP chomp; // do we strip, clip, or keep trailing newlines (at the very end) // end)
// Note: strip means kill all, clip means keep at most one, keep means keep all CHOMP chomp; // do we strip, clip, or keep trailing newlines (at the very
// end)
// Note: strip means kill all, clip means keep at most one, keep means keep
// all
ACTION onDocIndicator; // what do we do if we see a document indicator? ACTION onDocIndicator; // what do we do if we see a document indicator?
ACTION onTabInIndentation; // what do we do if we see a tab where we should be seeing indentation spaces ACTION onTabInIndentation; // what do we do if we see a tab where we should
// be seeing indentation spaces
// output: // output:
bool leadingSpaces; bool leadingSpaces;
}; };
std::string ScanScalar(Stream& INPUT, ScanScalarParams& info); std::string ScanScalar(Stream& INPUT, ScanScalarParams& info);
} }
#endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -3,82 +3,77 @@
#include "exp.h" #include "exp.h"
#include "yaml-cpp/exceptions.h" #include "yaml-cpp/exceptions.h"
namespace YAML namespace YAML {
{ const std::string ScanVerbatimTag(Stream& INPUT) {
const std::string ScanVerbatimTag(Stream& INPUT)
{
std::string tag; std::string tag;
// eat the start character // eat the start character
INPUT.get(); INPUT.get();
while(INPUT) { while (INPUT) {
if(INPUT.peek() == Keys::VerbatimTagEnd) { if (INPUT.peek() == Keys::VerbatimTagEnd) {
// eat the end character // eat the end character
INPUT.get(); INPUT.get();
return tag; return tag;
} }
int n = Exp::URI().Match(INPUT); int n = Exp::URI().Match(INPUT);
if(n <= 0) if (n <= 0)
break; break;
tag += INPUT.get(n); tag += INPUT.get(n);
} }
throw ParserException(INPUT.mark(), ErrorMsg::END_OF_VERBATIM_TAG); throw ParserException(INPUT.mark(), ErrorMsg::END_OF_VERBATIM_TAG);
} }
const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle) const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle) {
{
std::string tag; std::string tag;
canBeHandle = true; canBeHandle = true;
Mark firstNonWordChar; Mark firstNonWordChar;
while(INPUT) { while (INPUT) {
if(INPUT.peek() == Keys::Tag) { if (INPUT.peek() == Keys::Tag) {
if(!canBeHandle) if (!canBeHandle)
throw ParserException(firstNonWordChar, ErrorMsg::CHAR_IN_TAG_HANDLE); throw ParserException(firstNonWordChar, ErrorMsg::CHAR_IN_TAG_HANDLE);
break; break;
} }
int n = 0; int n = 0;
if(canBeHandle) { if (canBeHandle) {
n = Exp::Word().Match(INPUT); n = Exp::Word().Match(INPUT);
if(n <= 0) { if (n <= 0) {
canBeHandle = false; canBeHandle = false;
firstNonWordChar = INPUT.mark(); firstNonWordChar = INPUT.mark();
} }
} }
if(!canBeHandle) if (!canBeHandle)
n = Exp::Tag().Match(INPUT); n = Exp::Tag().Match(INPUT);
if(n <= 0) if (n <= 0)
break; break;
tag += INPUT.get(n); tag += INPUT.get(n);
} }
return tag; return tag;
} }
const std::string ScanTagSuffix(Stream& INPUT) const std::string ScanTagSuffix(Stream& INPUT) {
{
std::string tag; std::string tag;
while(INPUT) { while (INPUT) {
int n = Exp::Tag().Match(INPUT); int n = Exp::Tag().Match(INPUT);
if(n <= 0) if (n <= 0)
break; break;
tag += INPUT.get(n); tag += INPUT.get(n);
} }
if(tag.empty()) if (tag.empty())
throw ParserException(INPUT.mark(), ErrorMsg::TAG_WITH_NO_SUFFIX); throw ParserException(INPUT.mark(), ErrorMsg::TAG_WITH_NO_SUFFIX);
return tag; return tag;
}
} }
}

View File

@@ -1,20 +1,19 @@
#ifndef SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
#include "stream.h" #include "stream.h"
namespace YAML namespace YAML {
{ const std::string ScanVerbatimTag(Stream& INPUT);
const std::string ScanVerbatimTag(Stream& INPUT); const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle);
const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle); const std::string ScanTagSuffix(Stream& INPUT);
const std::string ScanTagSuffix(Stream& INPUT);
} }
#endif // SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // SCANTAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -7,17 +7,15 @@
#include "tag.h" #include "tag.h"
#include <sstream> #include <sstream>
namespace YAML namespace YAML {
{ ///////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////// // Specialization for scanning specific tokens
// Specialization for scanning specific tokens
// Directive // Directive
// . Note: no semantic checking is done here (that's for the parser to do) // . Note: no semantic checking is done here (that's for the parser to do)
void Scanner::ScanDirective() void Scanner::ScanDirective() {
{
std::string name; std::string name;
std::vector <std::string> params; std::vector<std::string> params;
// pop indents and simple keys // pop indents and simple keys
PopAllIndents(); PopAllIndents();
@@ -31,33 +29,32 @@ namespace YAML
INPUT.eat(1); INPUT.eat(1);
// read name // read name
while(INPUT && !Exp::BlankOrBreak().Matches(INPUT)) while (INPUT && !Exp::BlankOrBreak().Matches(INPUT))
token.value += INPUT.get(); token.value += INPUT.get();
// read parameters // read parameters
while(1) { while (1) {
// first get rid of whitespace // first get rid of whitespace
while(Exp::Blank().Matches(INPUT)) while (Exp::Blank().Matches(INPUT))
INPUT.eat(1); INPUT.eat(1);
// break on newline or comment // 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; break;
// now read parameter // now read parameter
std::string param; std::string param;
while(INPUT && !Exp::BlankOrBreak().Matches(INPUT)) while (INPUT && !Exp::BlankOrBreak().Matches(INPUT))
param += INPUT.get(); param += INPUT.get();
token.params.push_back(param); token.params.push_back(param);
} }
m_tokens.push(token); m_tokens.push(token);
} }
// DocStart // DocStart
void Scanner::ScanDocStart() void Scanner::ScanDocStart() {
{
PopAllIndents(); PopAllIndents();
PopAllSimpleKeys(); PopAllSimpleKeys();
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
@@ -67,11 +64,10 @@ namespace YAML
Mark mark = INPUT.mark(); Mark mark = INPUT.mark();
INPUT.eat(3); INPUT.eat(3);
m_tokens.push(Token(Token::DOC_START, mark)); m_tokens.push(Token(Token::DOC_START, mark));
} }
// DocEnd // DocEnd
void Scanner::ScanDocEnd() void Scanner::ScanDocEnd() {
{
PopAllIndents(); PopAllIndents();
PopAllSimpleKeys(); PopAllSimpleKeys();
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
@@ -81,11 +77,10 @@ namespace YAML
Mark mark = INPUT.mark(); Mark mark = INPUT.mark();
INPUT.eat(3); INPUT.eat(3);
m_tokens.push(Token(Token::DOC_END, mark)); m_tokens.push(Token(Token::DOC_END, mark));
} }
// FlowStart // FlowStart
void Scanner::ScanFlowStart() void Scanner::ScanFlowStart() {
{
// flows can be simple keys // flows can be simple keys
InsertPotentialSimpleKey(); InsertPotentialSimpleKey();
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
@@ -96,21 +91,21 @@ namespace YAML
char ch = INPUT.get(); char ch = INPUT.get();
FLOW_MARKER flowType = (ch == Keys::FlowSeqStart ? FLOW_SEQ : FLOW_MAP); FLOW_MARKER flowType = (ch == Keys::FlowSeqStart ? FLOW_SEQ : FLOW_MAP);
m_flows.push(flowType); m_flows.push(flowType);
Token::TYPE type = (flowType == FLOW_SEQ ? Token::FLOW_SEQ_START : Token::FLOW_MAP_START); Token::TYPE type =
(flowType == FLOW_SEQ ? Token::FLOW_SEQ_START : Token::FLOW_MAP_START);
m_tokens.push(Token(type, mark)); m_tokens.push(Token(type, mark));
} }
// FlowEnd // FlowEnd
void Scanner::ScanFlowEnd() void Scanner::ScanFlowEnd() {
{ if (InBlockContext())
if(InBlockContext())
throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END); throw ParserException(INPUT.mark(), ErrorMsg::FLOW_END);
// we might have a solo entry in the flow context // we might have a solo entry in the flow context
if(InFlowContext()) { if (InFlowContext()) {
if(m_flows.top() == FLOW_MAP && VerifySimpleKey()) if (m_flows.top() == FLOW_MAP && VerifySimpleKey())
m_tokens.push(Token(Token::VALUE, INPUT.mark())); m_tokens.push(Token(Token::VALUE, INPUT.mark()));
else if(m_flows.top() == FLOW_SEQ) else if (m_flows.top() == FLOW_SEQ)
InvalidateSimpleKey(); InvalidateSimpleKey();
} }
@@ -123,22 +118,21 @@ namespace YAML
// check that it matches the start // check that it matches the start
FLOW_MARKER flowType = (ch == Keys::FlowSeqEnd ? FLOW_SEQ : FLOW_MAP); FLOW_MARKER flowType = (ch == Keys::FlowSeqEnd ? FLOW_SEQ : FLOW_MAP);
if(m_flows.top() != flowType) if (m_flows.top() != flowType)
throw ParserException(mark, ErrorMsg::FLOW_END); throw ParserException(mark, ErrorMsg::FLOW_END);
m_flows.pop(); m_flows.pop();
Token::TYPE type = (flowType ? Token::FLOW_SEQ_END : Token::FLOW_MAP_END); Token::TYPE type = (flowType ? Token::FLOW_SEQ_END : Token::FLOW_MAP_END);
m_tokens.push(Token(type, mark)); m_tokens.push(Token(type, mark));
} }
// FlowEntry // FlowEntry
void Scanner::ScanFlowEntry() void Scanner::ScanFlowEntry() {
{
// we might have a solo entry in the flow context // we might have a solo entry in the flow context
if(InFlowContext()) { if (InFlowContext()) {
if(m_flows.top() == FLOW_MAP && VerifySimpleKey()) if (m_flows.top() == FLOW_MAP && VerifySimpleKey())
m_tokens.push(Token(Token::VALUE, INPUT.mark())); m_tokens.push(Token(Token::VALUE, INPUT.mark()));
else if(m_flows.top() == FLOW_SEQ) else if (m_flows.top() == FLOW_SEQ)
InvalidateSimpleKey(); InvalidateSimpleKey();
} }
@@ -149,17 +143,16 @@ namespace YAML
Mark mark = INPUT.mark(); Mark mark = INPUT.mark();
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(Token(Token::FLOW_ENTRY, mark)); m_tokens.push(Token(Token::FLOW_ENTRY, mark));
} }
// BlockEntry // BlockEntry
void Scanner::ScanBlockEntry() void Scanner::ScanBlockEntry() {
{
// we better be in the block context! // we better be in the block context!
if(InFlowContext()) if (InFlowContext())
throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY); throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY);
// can we put it here? // can we put it here?
if(!m_simpleKeyAllowed) if (!m_simpleKeyAllowed)
throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY); throw ParserException(INPUT.mark(), ErrorMsg::BLOCK_ENTRY);
PushIndentTo(INPUT.column(), IndentMarker::SEQ); PushIndentTo(INPUT.column(), IndentMarker::SEQ);
@@ -170,14 +163,13 @@ namespace YAML
Mark mark = INPUT.mark(); Mark mark = INPUT.mark();
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(Token(Token::BLOCK_ENTRY, mark)); m_tokens.push(Token(Token::BLOCK_ENTRY, mark));
} }
// Key // Key
void Scanner::ScanKey() void Scanner::ScanKey() {
{
// handle keys diffently in the block context (and manage indents) // handle keys diffently in the block context (and manage indents)
if(InBlockContext()) { if (InBlockContext()) {
if(!m_simpleKeyAllowed) if (!m_simpleKeyAllowed)
throw ParserException(INPUT.mark(), ErrorMsg::MAP_KEY); throw ParserException(INPUT.mark(), ErrorMsg::MAP_KEY);
PushIndentTo(INPUT.column(), IndentMarker::MAP); PushIndentTo(INPUT.column(), IndentMarker::MAP);
@@ -190,22 +182,22 @@ namespace YAML
Mark mark = INPUT.mark(); Mark mark = INPUT.mark();
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(Token(Token::KEY, mark)); m_tokens.push(Token(Token::KEY, mark));
} }
// Value // Value
void Scanner::ScanValue() void Scanner::ScanValue() {
{
// and check that simple key // and check that simple key
bool isSimpleKey = VerifySimpleKey(); bool isSimpleKey = VerifySimpleKey();
m_canBeJSONFlow = false; m_canBeJSONFlow = false;
if(isSimpleKey) { if (isSimpleKey) {
// can't follow a simple key with another simple key (dunno why, though - it seems fine) // can't follow a simple key with another simple key (dunno why, though - it
// seems fine)
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
} else { } else {
// handle values diffently in the block context (and manage indents) // handle values diffently in the block context (and manage indents)
if(InBlockContext()) { if (InBlockContext()) {
if(!m_simpleKeyAllowed) if (!m_simpleKeyAllowed)
throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE); throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE);
PushIndentTo(INPUT.column(), IndentMarker::MAP); PushIndentTo(INPUT.column(), IndentMarker::MAP);
@@ -219,11 +211,10 @@ namespace YAML
Mark mark = INPUT.mark(); Mark mark = INPUT.mark();
INPUT.eat(1); INPUT.eat(1);
m_tokens.push(Token(Token::VALUE, mark)); m_tokens.push(Token(Token::VALUE, mark));
} }
// AnchorOrAlias // AnchorOrAlias
void Scanner::ScanAnchorOrAlias() void Scanner::ScanAnchorOrAlias() {
{
bool alias; bool alias;
std::string name; std::string name;
@@ -238,26 +229,27 @@ namespace YAML
alias = (indicator == Keys::Alias); alias = (indicator == Keys::Alias);
// now eat the content // now eat the content
while(INPUT && Exp::Anchor().Matches(INPUT)) while (INPUT && Exp::Anchor().Matches(INPUT))
name += INPUT.get(); name += INPUT.get();
// we need to have read SOMETHING! // we need to have read SOMETHING!
if(name.empty()) if (name.empty())
throw ParserException(INPUT.mark(), alias ? ErrorMsg::ALIAS_NOT_FOUND : ErrorMsg::ANCHOR_NOT_FOUND); throw ParserException(INPUT.mark(), alias ? ErrorMsg::ALIAS_NOT_FOUND
: ErrorMsg::ANCHOR_NOT_FOUND);
// and needs to end correctly // 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); throw ParserException(INPUT.mark(), alias ? ErrorMsg::CHAR_IN_ALIAS
: ErrorMsg::CHAR_IN_ANCHOR);
// and we're done // and we're done
Token token(alias ? Token::ALIAS : Token::ANCHOR, mark); Token token(alias ? Token::ALIAS : Token::ANCHOR, mark);
token.value = name; token.value = name;
m_tokens.push(token); m_tokens.push(token);
} }
// Tag // Tag
void Scanner::ScanTag() void Scanner::ScanTag() {
{
// insert a potential simple key // insert a potential simple key
InsertPotentialSimpleKey(); InsertPotentialSimpleKey();
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
@@ -268,7 +260,7 @@ namespace YAML
// eat the indicator // eat the indicator
INPUT.get(); INPUT.get();
if(INPUT && INPUT.peek() == Keys::VerbatimTagStart){ if (INPUT && INPUT.peek() == Keys::VerbatimTagStart) {
std::string tag = ScanVerbatimTag(INPUT); std::string tag = ScanVerbatimTag(INPUT);
token.value = tag; token.value = tag;
@@ -276,15 +268,15 @@ namespace YAML
} else { } else {
bool canBeHandle; bool canBeHandle;
token.value = ScanTagHandle(INPUT, canBeHandle); token.value = ScanTagHandle(INPUT, canBeHandle);
if(!canBeHandle && token.value.empty()) if (!canBeHandle && token.value.empty())
token.data = Tag::NON_SPECIFIC; token.data = Tag::NON_SPECIFIC;
else if(token.value.empty()) else if (token.value.empty())
token.data = Tag::SECONDARY_HANDLE; token.data = Tag::SECONDARY_HANDLE;
else else
token.data = Tag::PRIMARY_HANDLE; token.data = Tag::PRIMARY_HANDLE;
// is there a suffix? // is there a suffix?
if(canBeHandle && INPUT.peek() == Keys::Tag) { if (canBeHandle && INPUT.peek() == Keys::Tag) {
// eat the indicator // eat the indicator
INPUT.get(); INPUT.get();
token.params.push_back(ScanTagSuffix(INPUT)); token.params.push_back(ScanTagSuffix(INPUT));
@@ -293,16 +285,16 @@ namespace YAML
} }
m_tokens.push(token); m_tokens.push(token);
} }
// PlainScalar // PlainScalar
void Scanner::ScanPlainScalar() void Scanner::ScanPlainScalar() {
{
std::string scalar; std::string scalar;
// set up the scanning parameters // set up the scanning parameters
ScanScalarParams params; 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.eatEnd = false;
params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1); params.indent = (InFlowContext() ? 0 : GetTopIndent() + 1);
params.fold = FOLD_FLOW; params.fold = FOLD_FLOW;
@@ -323,20 +315,20 @@ namespace YAML
m_canBeJSONFlow = false; m_canBeJSONFlow = false;
// finally, check and see if we ended on an illegal character // finally, check and see if we ended on an illegal character
//if(Exp::IllegalCharInScalar.Matches(INPUT)) // if(Exp::IllegalCharInScalar.Matches(INPUT))
// throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR); // throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR);
Token token(Token::PLAIN_SCALAR, mark); Token token(Token::PLAIN_SCALAR, mark);
token.value = scalar; token.value = scalar;
m_tokens.push(token); m_tokens.push(token);
} }
// QuotedScalar // QuotedScalar
void Scanner::ScanQuotedScalar() void Scanner::ScanQuotedScalar() {
{
std::string scalar; std::string scalar;
// peek at single or double quote (don't eat because we need to preserve (for the time being) the input position) // peek at single or double quote (don't eat because we need to preserve (for
// the time being) the input position)
char quote = INPUT.peek(); char quote = INPUT.peek();
bool single = (quote == '\''); bool single = (quote == '\'');
@@ -368,14 +360,14 @@ namespace YAML
Token token(Token::NON_PLAIN_SCALAR, mark); Token token(Token::NON_PLAIN_SCALAR, mark);
token.value = scalar; token.value = scalar;
m_tokens.push(token); m_tokens.push(token);
} }
// BlockScalarToken // BlockScalarToken
// . These need a little extra processing beforehand. // . These need a little extra processing beforehand.
// . We need to scan the line where the indicator is (this doesn't count as part of the scalar), // . We need to scan the line where the indicator is (this doesn't count as part
// and then we need to figure out what level of indentation we'll be using. // of the scalar),
void Scanner::ScanBlockScalar() // and then we need to figure out what level of indentation we'll be using.
{ void Scanner::ScanBlockScalar() {
std::string scalar; std::string scalar;
ScanScalarParams params; ScanScalarParams params;
@@ -390,14 +382,14 @@ namespace YAML
// eat chomping/indentation indicators // eat chomping/indentation indicators
params.chomp = CLIP; params.chomp = CLIP;
int n = Exp::Chomp().Match(INPUT); int n = Exp::Chomp().Match(INPUT);
for(int i=0;i<n;i++) { for (int i = 0; i < n; i++) {
char ch = INPUT.get(); char ch = INPUT.get();
if(ch == '+') if (ch == '+')
params.chomp = KEEP; params.chomp = KEEP;
else if(ch == '-') else if (ch == '-')
params.chomp = STRIP; params.chomp = STRIP;
else if(Exp::Digit().Matches(ch)) { else if (Exp::Digit().Matches(ch)) {
if(ch == '0') if (ch == '0')
throw ParserException(INPUT.mark(), ErrorMsg::ZERO_INDENT_IN_BLOCK); throw ParserException(INPUT.mark(), ErrorMsg::ZERO_INDENT_IN_BLOCK);
params.indent = ch - '0'; params.indent = ch - '0';
@@ -406,20 +398,20 @@ namespace YAML
} }
// now eat whitespace // now eat whitespace
while(Exp::Blank().Matches(INPUT)) while (Exp::Blank().Matches(INPUT))
INPUT.eat(1); INPUT.eat(1);
// and comments to the end of the line // and comments to the end of the line
if(Exp::Comment().Matches(INPUT)) if (Exp::Comment().Matches(INPUT))
while(INPUT && !Exp::Break().Matches(INPUT)) while (INPUT && !Exp::Break().Matches(INPUT))
INPUT.eat(1); INPUT.eat(1);
// if it's not a line break, then we ran into a bad character inline // 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); throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_BLOCK);
// set the initial indentation // set the initial indentation
if(GetTopIndent() >= 0) if (GetTopIndent() >= 0)
params.indent += GetTopIndent(); params.indent += GetTopIndent();
params.eatLeadingWhitespace = false; params.eatLeadingWhitespace = false;
@@ -428,12 +420,13 @@ namespace YAML
scalar = ScanScalar(INPUT, params); scalar = ScanScalar(INPUT, params);
// simple keys always ok after block scalars (since we're gonna start a new line anyways) // simple keys always ok after block scalars (since we're gonna start a new
// line anyways)
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
m_canBeJSONFlow = false; m_canBeJSONFlow = false;
Token token(Token::NON_PLAIN_SCALAR, mark); Token token(Token::NON_PLAIN_SCALAR, mark);
token.value = scalar; token.value = scalar;
m_tokens.push(token); m_tokens.push(token);
} }
} }

View File

@@ -1,69 +1,61 @@
#ifndef SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "yaml-cpp/noncopyable.h" #include "yaml-cpp/noncopyable.h"
namespace YAML namespace YAML {
{ class SettingChangeBase;
class SettingChangeBase;
template <typename T> template <typename T>
class Setting class Setting {
{
public: public:
Setting(): m_value() {} Setting() : m_value() {}
const T get() const { return m_value; } const T get() const { return m_value; }
std::auto_ptr <SettingChangeBase> set(const T& value); std::auto_ptr<SettingChangeBase> set(const T& value);
void restore(const Setting<T>& oldSetting) { void restore(const Setting<T>& oldSetting) { m_value = oldSetting.get(); }
m_value = oldSetting.get();
}
private: private:
T m_value; T m_value;
}; };
class SettingChangeBase class SettingChangeBase {
{
public: public:
virtual ~SettingChangeBase() {} virtual ~SettingChangeBase() {}
virtual void pop() = 0; virtual void pop() = 0;
}; };
template <typename T> template <typename T>
class SettingChange: public SettingChangeBase class SettingChange : public SettingChangeBase {
{
public: public:
SettingChange(Setting<T> *pSetting): m_pCurSetting(pSetting) { SettingChange(Setting<T>* pSetting) : m_pCurSetting(pSetting) {
// copy old setting to save its state // copy old setting to save its state
m_oldSetting = *pSetting; m_oldSetting = *pSetting;
} }
virtual void pop() { virtual void pop() { m_pCurSetting->restore(m_oldSetting); }
m_pCurSetting->restore(m_oldSetting);
}
private: private:
Setting<T> *m_pCurSetting; Setting<T>* m_pCurSetting;
Setting<T> m_oldSetting; Setting<T> m_oldSetting;
}; };
template <typename T> template <typename T>
inline std::auto_ptr <SettingChangeBase> Setting<T>::set(const T& value) { inline std::auto_ptr<SettingChangeBase> Setting<T>::set(const T& value) {
std::auto_ptr <SettingChangeBase> pChange(new SettingChange<T> (this)); std::auto_ptr<SettingChangeBase> pChange(new SettingChange<T>(this));
m_value = value; m_value = value;
return pChange; return pChange;
} }
class SettingChanges: private noncopyable class SettingChanges : private noncopyable {
{
public: public:
SettingChanges() {} SettingChanges() {}
~SettingChanges() { clear(); } ~SettingChanges() { clear(); }
@@ -71,23 +63,25 @@ namespace YAML
void clear() { void clear() {
restore(); restore();
for(setting_changes::const_iterator it=m_settingChanges.begin();it!=m_settingChanges.end();++it) for (setting_changes::const_iterator it = m_settingChanges.begin();
it != m_settingChanges.end(); ++it)
delete *it; delete *it;
m_settingChanges.clear(); m_settingChanges.clear();
} }
void restore() { void restore() {
for(setting_changes::const_iterator it=m_settingChanges.begin();it!=m_settingChanges.end();++it) for (setting_changes::const_iterator it = m_settingChanges.begin();
it != m_settingChanges.end(); ++it)
(*it)->pop(); (*it)->pop();
} }
void push(std::auto_ptr <SettingChangeBase> pSettingChange) { void push(std::auto_ptr<SettingChangeBase> pSettingChange) {
m_settingChanges.push_back(pSettingChange.release()); m_settingChanges.push_back(pSettingChange.release());
} }
// like std::auto_ptr - assignment is transfer of ownership // like std::auto_ptr - assignment is transfer of ownership
SettingChanges& operator = (SettingChanges& rhs) { SettingChanges& operator=(SettingChanges& rhs) {
if(this == &rhs) if (this == &rhs)
return *this; return *this;
clear(); clear();
@@ -97,9 +91,9 @@ namespace YAML
} }
private: private:
typedef std::vector <SettingChangeBase *> setting_changes; typedef std::vector<SettingChangeBase*> setting_changes;
setting_changes m_settingChanges; setting_changes m_settingChanges;
}; };
} }
#endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // SETTING_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -3,71 +3,64 @@
#include "yaml-cpp/exceptions.h" #include "yaml-cpp/exceptions.h"
#include "exp.h" #include "exp.h"
namespace YAML namespace YAML {
{ Scanner::SimpleKey::SimpleKey(const Mark& mark_, int flowLevel_)
Scanner::SimpleKey::SimpleKey(const Mark& mark_, int flowLevel_) : mark(mark_), flowLevel(flowLevel_), pIndent(0), pMapStart(0), pKey(0) {}
: mark(mark_), flowLevel(flowLevel_), pIndent(0), pMapStart(0), pKey(0)
{
}
void Scanner::SimpleKey::Validate() void Scanner::SimpleKey::Validate() {
{
// Note: pIndent will *not* be garbage here; // Note: pIndent will *not* be garbage here;
// we "garbage collect" them so we can // we "garbage collect" them so we can
// always refer to them // always refer to them
if(pIndent) if (pIndent)
pIndent->status = IndentMarker::VALID; pIndent->status = IndentMarker::VALID;
if(pMapStart) if (pMapStart)
pMapStart->status = Token::VALID; pMapStart->status = Token::VALID;
if(pKey) if (pKey)
pKey->status = Token::VALID; pKey->status = Token::VALID;
} }
void Scanner::SimpleKey::Invalidate() void Scanner::SimpleKey::Invalidate() {
{ if (pIndent)
if(pIndent)
pIndent->status = IndentMarker::INVALID; pIndent->status = IndentMarker::INVALID;
if(pMapStart) if (pMapStart)
pMapStart->status = Token::INVALID; pMapStart->status = Token::INVALID;
if(pKey) if (pKey)
pKey->status = Token::INVALID; pKey->status = Token::INVALID;
} }
// CanInsertPotentialSimpleKey // CanInsertPotentialSimpleKey
bool Scanner::CanInsertPotentialSimpleKey() const bool Scanner::CanInsertPotentialSimpleKey() const {
{ if (!m_simpleKeyAllowed)
if(!m_simpleKeyAllowed)
return false; return false;
return !ExistsActiveSimpleKey(); return !ExistsActiveSimpleKey();
} }
// ExistsActiveSimpleKey // ExistsActiveSimpleKey
// . Returns true if there's a potential simple key at our flow level // . Returns true if there's a potential simple key at our flow level
// (there's allowed at most one per flow level, i.e., at the start of the flow start token) // (there's allowed at most one per flow level, i.e., at the start of the flow
bool Scanner::ExistsActiveSimpleKey() const // start token)
{ bool Scanner::ExistsActiveSimpleKey() const {
if(m_simpleKeys.empty()) if (m_simpleKeys.empty())
return false; return false;
const SimpleKey& key = m_simpleKeys.top(); const SimpleKey& key = m_simpleKeys.top();
return key.flowLevel == GetFlowLevel(); return key.flowLevel == GetFlowLevel();
} }
// InsertPotentialSimpleKey // InsertPotentialSimpleKey
// . If we can, add a potential simple key to the queue, // . If we can, add a potential simple key to the queue,
// and save it on a stack. // and save it on a stack.
void Scanner::InsertPotentialSimpleKey() void Scanner::InsertPotentialSimpleKey() {
{ if (!CanInsertPotentialSimpleKey())
if(!CanInsertPotentialSimpleKey())
return; return;
SimpleKey key(INPUT.mark(), GetFlowLevel()); SimpleKey key(INPUT.mark(), GetFlowLevel());
// first add a map start, if necessary // first add a map start, if necessary
if(InBlockContext()) { if (InBlockContext()) {
key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP); key.pIndent = PushIndentTo(INPUT.column(), IndentMarker::MAP);
if(key.pIndent) { if (key.pIndent) {
key.pIndent->status = IndentMarker::UNKNOWN; key.pIndent->status = IndentMarker::UNKNOWN;
key.pMapStart = key.pIndent->pStartToken; key.pMapStart = key.pIndent->pStartToken;
key.pMapStart->status = Token::UNVERIFIED; key.pMapStart->status = Token::UNVERIFIED;
@@ -80,37 +73,35 @@ namespace YAML
key.pKey->status = Token::UNVERIFIED; key.pKey->status = Token::UNVERIFIED;
m_simpleKeys.push(key); m_simpleKeys.push(key);
} }
// InvalidateSimpleKey // InvalidateSimpleKey
// . Automatically invalidate the simple key in our flow level // . Automatically invalidate the simple key in our flow level
void Scanner::InvalidateSimpleKey() void Scanner::InvalidateSimpleKey() {
{ if (m_simpleKeys.empty())
if(m_simpleKeys.empty())
return; return;
// grab top key // grab top key
SimpleKey& key = m_simpleKeys.top(); SimpleKey& key = m_simpleKeys.top();
if(key.flowLevel != GetFlowLevel()) if (key.flowLevel != GetFlowLevel())
return; return;
key.Invalidate(); key.Invalidate();
m_simpleKeys.pop(); m_simpleKeys.pop();
} }
// VerifySimpleKey // VerifySimpleKey
// . Determines whether the latest simple key to be added is valid, // . Determines whether the latest simple key to be added is valid,
// and if so, makes it valid. // and if so, makes it valid.
bool Scanner::VerifySimpleKey() bool Scanner::VerifySimpleKey() {
{ if (m_simpleKeys.empty())
if(m_simpleKeys.empty())
return false; return false;
// grab top key // grab top key
SimpleKey key = m_simpleKeys.top(); SimpleKey key = m_simpleKeys.top();
// only validate if we're in the correct flow level // only validate if we're in the correct flow level
if(key.flowLevel != GetFlowLevel()) if (key.flowLevel != GetFlowLevel())
return false; return false;
m_simpleKeys.pop(); m_simpleKeys.pop();
@@ -118,22 +109,20 @@ namespace YAML
bool isValid = true; bool isValid = true;
// needs to be less than 1024 characters and inline // needs to be less than 1024 characters and inline
if(INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024) if (INPUT.line() != key.mark.line || INPUT.pos() - key.mark.pos > 1024)
isValid = false; isValid = false;
// invalidate key // invalidate key
if(isValid) if (isValid)
key.Validate(); key.Validate();
else else
key.Invalidate(); key.Invalidate();
return isValid; return isValid;
}
void Scanner::PopAllSimpleKeys()
{
while(!m_simpleKeys.empty())
m_simpleKeys.pop();
}
} }
void Scanner::PopAllSimpleKeys() {
while (!m_simpleKeys.empty())
m_simpleKeys.pop();
}
}

View File

@@ -10,28 +10,26 @@
#include <cstdio> #include <cstdio>
#include <algorithm> #include <algorithm>
namespace YAML namespace YAML {
{ SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives)
SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives): m_scanner(scanner), m_directives(directives), m_pCollectionStack(new CollectionStack), m_curAnchor(0) : m_scanner(scanner),
{ m_directives(directives),
} m_pCollectionStack(new CollectionStack),
m_curAnchor(0) {}
SingleDocParser::~SingleDocParser() SingleDocParser::~SingleDocParser() {}
{
}
// HandleDocument // HandleDocument
// . Handles the next document // . Handles the next document
// . Throws a ParserException on error. // . Throws a ParserException on error.
void SingleDocParser::HandleDocument(EventHandler& eventHandler) void SingleDocParser::HandleDocument(EventHandler& eventHandler) {
{
assert(!m_scanner.empty()); // guaranteed that there are tokens assert(!m_scanner.empty()); // guaranteed that there are tokens
assert(!m_curAnchor); assert(!m_curAnchor);
eventHandler.OnDocumentStart(m_scanner.peek().mark); eventHandler.OnDocumentStart(m_scanner.peek().mark);
// eat doc start // eat doc start
if(m_scanner.peek().type == Token::DOC_START) if (m_scanner.peek().type == Token::DOC_START)
m_scanner.pop(); m_scanner.pop();
// recurse! // recurse!
@@ -40,14 +38,13 @@ namespace YAML
eventHandler.OnDocumentEnd(); eventHandler.OnDocumentEnd();
// and finally eat any doc ends we see // and finally eat any doc ends we see
while(!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END) while (!m_scanner.empty() && m_scanner.peek().type == Token::DOC_END)
m_scanner.pop(); m_scanner.pop();
} }
void SingleDocParser::HandleNode(EventHandler& eventHandler) void SingleDocParser::HandleNode(EventHandler& eventHandler) {
{
// an empty node *is* a possibility // an empty node *is* a possibility
if(m_scanner.empty()) { if (m_scanner.empty()) {
eventHandler.OnNull(m_scanner.mark(), NullAnchor); eventHandler.OnNull(m_scanner.mark(), NullAnchor);
return; return;
} }
@@ -56,7 +53,7 @@ namespace YAML
Mark mark = m_scanner.peek().mark; Mark mark = m_scanner.peek().mark;
// special case: a value node by itself must be a map, with no header // special case: a value node by itself must be a map, with no header
if(m_scanner.peek().type == Token::VALUE) { if (m_scanner.peek().type == Token::VALUE) {
eventHandler.OnMapStart(mark, "?", NullAnchor); eventHandler.OnMapStart(mark, "?", NullAnchor);
HandleMap(eventHandler); HandleMap(eventHandler);
eventHandler.OnMapEnd(); eventHandler.OnMapEnd();
@@ -64,7 +61,7 @@ namespace YAML
} }
// special case: an alias node // special case: an alias node
if(m_scanner.peek().type == Token::ALIAS) { if (m_scanner.peek().type == Token::ALIAS) {
eventHandler.OnAlias(mark, LookupAnchor(mark, m_scanner.peek().value)); eventHandler.OnAlias(mark, LookupAnchor(mark, m_scanner.peek().value));
m_scanner.pop(); m_scanner.pop();
return; return;
@@ -76,18 +73,18 @@ namespace YAML
const Token& token = m_scanner.peek(); const Token& token = m_scanner.peek();
if(token.type == Token::PLAIN_SCALAR && token.value == "null") { if (token.type == Token::PLAIN_SCALAR && token.value == "null") {
eventHandler.OnNull(mark, anchor); eventHandler.OnNull(mark, anchor);
m_scanner.pop(); m_scanner.pop();
return; return;
} }
// add non-specific tags // add non-specific tags
if(tag.empty()) if (tag.empty())
tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?"); tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?");
// now split based on what kind of node we should be // now split based on what kind of node we should be
switch(token.type) { switch (token.type) {
case Token::PLAIN_SCALAR: case Token::PLAIN_SCALAR:
case Token::NON_PLAIN_SCALAR: case Token::NON_PLAIN_SCALAR:
eventHandler.OnScalar(mark, tag, anchor, token.value); eventHandler.OnScalar(mark, tag, anchor, token.value);
@@ -107,7 +104,8 @@ namespace YAML
return; return;
case Token::KEY: case Token::KEY:
// compact maps can only go in a flow sequence // compact maps can only go in a flow sequence
if(m_pCollectionStack->GetCurCollectionType() == CollectionType::FlowSeq) { if (m_pCollectionStack->GetCurCollectionType() ==
CollectionType::FlowSeq) {
eventHandler.OnMapStart(mark, tag, anchor); eventHandler.OnMapStart(mark, tag, anchor);
HandleMap(eventHandler); HandleMap(eventHandler);
eventHandler.OnMapEnd(); eventHandler.OnMapEnd();
@@ -118,44 +116,48 @@ namespace YAML
break; break;
} }
if(tag == "?") if (tag == "?")
eventHandler.OnNull(mark, anchor); eventHandler.OnNull(mark, anchor);
else else
eventHandler.OnScalar(mark, tag, anchor, ""); eventHandler.OnScalar(mark, tag, anchor, "");
} }
void SingleDocParser::HandleSequence(EventHandler& eventHandler) void SingleDocParser::HandleSequence(EventHandler& eventHandler) {
{
// split based on start token // split based on start token
switch(m_scanner.peek().type) { switch (m_scanner.peek().type) {
case Token::BLOCK_SEQ_START: HandleBlockSequence(eventHandler); break; case Token::BLOCK_SEQ_START:
case Token::FLOW_SEQ_START: HandleFlowSequence(eventHandler); break; HandleBlockSequence(eventHandler);
default: break; break;
} case Token::FLOW_SEQ_START:
HandleFlowSequence(eventHandler);
break;
default:
break;
} }
}
void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler) void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler) {
{
// eat start token // eat start token
m_scanner.pop(); m_scanner.pop();
m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq); m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq);
while(1) { while (1) {
if(m_scanner.empty()) if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ); throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ);
Token token = m_scanner.peek(); Token token = m_scanner.peek();
if(token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END) if (token.type != Token::BLOCK_ENTRY && token.type != Token::BLOCK_SEQ_END)
throw ParserException(token.mark, ErrorMsg::END_OF_SEQ); throw ParserException(token.mark, ErrorMsg::END_OF_SEQ);
m_scanner.pop(); m_scanner.pop();
if(token.type == Token::BLOCK_SEQ_END) if (token.type == Token::BLOCK_SEQ_END)
break; break;
// check for null // check for null
if(!m_scanner.empty()) { if (!m_scanner.empty()) {
const Token& token = m_scanner.peek(); const Token& token = m_scanner.peek();
if(token.type == Token::BLOCK_ENTRY || token.type == Token::BLOCK_SEQ_END) { if (token.type == Token::BLOCK_ENTRY ||
token.type == Token::BLOCK_SEQ_END) {
eventHandler.OnNull(token.mark, NullAnchor); eventHandler.OnNull(token.mark, NullAnchor);
continue; continue;
} }
@@ -165,20 +167,19 @@ namespace YAML
} }
m_pCollectionStack->PopCollectionType(CollectionType::BlockSeq); m_pCollectionStack->PopCollectionType(CollectionType::BlockSeq);
} }
void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler) void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler) {
{
// eat start token // eat start token
m_scanner.pop(); m_scanner.pop();
m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq); m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq);
while(1) { while (1) {
if(m_scanner.empty()) if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW); throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW);
// first check for end // first check for end
if(m_scanner.peek().type == Token::FLOW_SEQ_END) { if (m_scanner.peek().type == Token::FLOW_SEQ_END) {
m_scanner.pop(); m_scanner.pop();
break; break;
} }
@@ -186,53 +187,62 @@ namespace YAML
// then read the node // then read the node
HandleNode(eventHandler); HandleNode(eventHandler);
if(m_scanner.empty()) if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW); throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW);
// now eat the separator (or could be a sequence end, which we ignore - but if it's neither, then it's a bad node) // 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(); Token& token = m_scanner.peek();
if(token.type == Token::FLOW_ENTRY) if (token.type == Token::FLOW_ENTRY)
m_scanner.pop(); m_scanner.pop();
else if(token.type != Token::FLOW_SEQ_END) else if (token.type != Token::FLOW_SEQ_END)
throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW); throw ParserException(token.mark, ErrorMsg::END_OF_SEQ_FLOW);
} }
m_pCollectionStack->PopCollectionType(CollectionType::FlowSeq); m_pCollectionStack->PopCollectionType(CollectionType::FlowSeq);
} }
void SingleDocParser::HandleMap(EventHandler& eventHandler) void SingleDocParser::HandleMap(EventHandler& eventHandler) {
{
// split based on start token // split based on start token
switch(m_scanner.peek().type) { switch (m_scanner.peek().type) {
case Token::BLOCK_MAP_START: HandleBlockMap(eventHandler); break; case Token::BLOCK_MAP_START:
case Token::FLOW_MAP_START: HandleFlowMap(eventHandler); break; HandleBlockMap(eventHandler);
case Token::KEY: HandleCompactMap(eventHandler); break; break;
case Token::VALUE: HandleCompactMapWithNoKey(eventHandler); break; case Token::FLOW_MAP_START:
default: break; HandleFlowMap(eventHandler);
} break;
case Token::KEY:
HandleCompactMap(eventHandler);
break;
case Token::VALUE:
HandleCompactMapWithNoKey(eventHandler);
break;
default:
break;
} }
}
void SingleDocParser::HandleBlockMap(EventHandler& eventHandler) void SingleDocParser::HandleBlockMap(EventHandler& eventHandler) {
{
// eat start token // eat start token
m_scanner.pop(); m_scanner.pop();
m_pCollectionStack->PushCollectionType(CollectionType::BlockMap); m_pCollectionStack->PushCollectionType(CollectionType::BlockMap);
while(1) { while (1) {
if(m_scanner.empty()) if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP); throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP);
Token token = m_scanner.peek(); Token token = m_scanner.peek();
if(token.type != Token::KEY && token.type != Token::VALUE && token.type != Token::BLOCK_MAP_END) if (token.type != Token::KEY && token.type != Token::VALUE &&
token.type != Token::BLOCK_MAP_END)
throw ParserException(token.mark, ErrorMsg::END_OF_MAP); throw ParserException(token.mark, ErrorMsg::END_OF_MAP);
if(token.type == Token::BLOCK_MAP_END) { if (token.type == Token::BLOCK_MAP_END) {
m_scanner.pop(); m_scanner.pop();
break; break;
} }
// grab key (if non-null) // grab key (if non-null)
if(token.type == Token::KEY) { if (token.type == Token::KEY) {
m_scanner.pop(); m_scanner.pop();
HandleNode(eventHandler); HandleNode(eventHandler);
} else { } else {
@@ -240,7 +250,7 @@ namespace YAML
} }
// now grab value (optional) // now grab value (optional)
if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) { if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
m_scanner.pop(); m_scanner.pop();
HandleNode(eventHandler); HandleNode(eventHandler);
} else { } else {
@@ -249,28 +259,27 @@ namespace YAML
} }
m_pCollectionStack->PopCollectionType(CollectionType::BlockMap); m_pCollectionStack->PopCollectionType(CollectionType::BlockMap);
} }
void SingleDocParser::HandleFlowMap(EventHandler& eventHandler) void SingleDocParser::HandleFlowMap(EventHandler& eventHandler) {
{
// eat start token // eat start token
m_scanner.pop(); m_scanner.pop();
m_pCollectionStack->PushCollectionType(CollectionType::FlowMap); m_pCollectionStack->PushCollectionType(CollectionType::FlowMap);
while(1) { while (1) {
if(m_scanner.empty()) if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW); throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW);
Token& token = m_scanner.peek(); Token& token = m_scanner.peek();
const Mark mark = token.mark; const Mark mark = token.mark;
// first check for end // first check for end
if(token.type == Token::FLOW_MAP_END) { if (token.type == Token::FLOW_MAP_END) {
m_scanner.pop(); m_scanner.pop();
break; break;
} }
// grab key (if non-null) // grab key (if non-null)
if(token.type == Token::KEY) { if (token.type == Token::KEY) {
m_scanner.pop(); m_scanner.pop();
HandleNode(eventHandler); HandleNode(eventHandler);
} else { } else {
@@ -278,30 +287,30 @@ namespace YAML
} }
// now grab value (optional) // now grab value (optional)
if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) { if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
m_scanner.pop(); m_scanner.pop();
HandleNode(eventHandler); HandleNode(eventHandler);
} else { } else {
eventHandler.OnNull(mark, NullAnchor); eventHandler.OnNull(mark, NullAnchor);
} }
if(m_scanner.empty()) if (m_scanner.empty())
throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW); throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW);
// now eat the separator (or could be a map end, which we ignore - but if it's neither, then it's a bad node) // 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(); Token& nextToken = m_scanner.peek();
if(nextToken.type == Token::FLOW_ENTRY) if (nextToken.type == Token::FLOW_ENTRY)
m_scanner.pop(); m_scanner.pop();
else if(nextToken.type != Token::FLOW_MAP_END) else if (nextToken.type != Token::FLOW_MAP_END)
throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW); throw ParserException(nextToken.mark, ErrorMsg::END_OF_MAP_FLOW);
} }
m_pCollectionStack->PopCollectionType(CollectionType::FlowMap); m_pCollectionStack->PopCollectionType(CollectionType::FlowMap);
} }
// . Single "key: value" pair in a flow sequence // . Single "key: value" pair in a flow sequence
void SingleDocParser::HandleCompactMap(EventHandler& eventHandler) void SingleDocParser::HandleCompactMap(EventHandler& eventHandler) {
{
m_pCollectionStack->PushCollectionType(CollectionType::CompactMap); m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
// grab key // grab key
@@ -310,7 +319,7 @@ namespace YAML
HandleNode(eventHandler); HandleNode(eventHandler);
// now grab value (optional) // now grab value (optional)
if(!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) { if (!m_scanner.empty() && m_scanner.peek().type == Token::VALUE) {
m_scanner.pop(); m_scanner.pop();
HandleNode(eventHandler); HandleNode(eventHandler);
} else { } else {
@@ -318,11 +327,10 @@ namespace YAML
} }
m_pCollectionStack->PopCollectionType(CollectionType::CompactMap); m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
} }
// . Single ": value" pair in a flow sequence // . Single ": value" pair in a flow sequence
void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler) void SingleDocParser::HandleCompactMapWithNoKey(EventHandler& eventHandler) {
{
m_pCollectionStack->PushCollectionType(CollectionType::CompactMap); m_pCollectionStack->PushCollectionType(CollectionType::CompactMap);
// null key // null key
@@ -333,62 +341,63 @@ namespace YAML
HandleNode(eventHandler); HandleNode(eventHandler);
m_pCollectionStack->PopCollectionType(CollectionType::CompactMap); m_pCollectionStack->PopCollectionType(CollectionType::CompactMap);
} }
// ParseProperties // ParseProperties
// . Grabs any tag or anchor tokens and deals with them. // . Grabs any tag or anchor tokens and deals with them.
void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor) void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor) {
{
tag.clear(); tag.clear();
anchor = NullAnchor; anchor = NullAnchor;
while(1) { while (1) {
if(m_scanner.empty()) if (m_scanner.empty())
return; return;
switch(m_scanner.peek().type) { switch (m_scanner.peek().type) {
case Token::TAG: ParseTag(tag); break; case Token::TAG:
case Token::ANCHOR: ParseAnchor(anchor); break; ParseTag(tag);
default: return; break;
} case Token::ANCHOR:
ParseAnchor(anchor);
break;
default:
return;
} }
} }
}
void SingleDocParser::ParseTag(std::string& tag) void SingleDocParser::ParseTag(std::string& tag) {
{
Token& token = m_scanner.peek(); Token& token = m_scanner.peek();
if(!tag.empty()) if (!tag.empty())
throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS); throw ParserException(token.mark, ErrorMsg::MULTIPLE_TAGS);
Tag tagInfo(token); Tag tagInfo(token);
tag = tagInfo.Translate(m_directives); tag = tagInfo.Translate(m_directives);
m_scanner.pop(); m_scanner.pop();
} }
void SingleDocParser::ParseAnchor(anchor_t& anchor) void SingleDocParser::ParseAnchor(anchor_t& anchor) {
{
Token& token = m_scanner.peek(); Token& token = m_scanner.peek();
if(anchor) if (anchor)
throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS); throw ParserException(token.mark, ErrorMsg::MULTIPLE_ANCHORS);
anchor = RegisterAnchor(token.value); anchor = RegisterAnchor(token.value);
m_scanner.pop(); m_scanner.pop();
} }
anchor_t SingleDocParser::RegisterAnchor(const std::string& name) anchor_t SingleDocParser::RegisterAnchor(const std::string& name) {
{ if (name.empty())
if(name.empty())
return NullAnchor; return NullAnchor;
return m_anchors[name] = ++m_curAnchor; return m_anchors[name] = ++m_curAnchor;
} }
anchor_t SingleDocParser::LookupAnchor(const Mark& mark, const std::string& name) const anchor_t SingleDocParser::LookupAnchor(const Mark& mark,
{ const std::string& name) const {
Anchors::const_iterator it = m_anchors.find(name); Anchors::const_iterator it = m_anchors.find(name);
if(it == m_anchors.end()) if (it == m_anchors.end())
throw ParserException(mark, ErrorMsg::UNKNOWN_ANCHOR); throw ParserException(mark, ErrorMsg::UNKNOWN_ANCHOR);
return it->second; return it->second;
} }
} }

View File

@@ -1,29 +1,28 @@
#ifndef SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/anchor.h" #include "yaml-cpp/anchor.h"
#include "yaml-cpp/noncopyable.h" #include "yaml-cpp/noncopyable.h"
#include <string> #include <string>
#include <map> #include <map>
#include <memory> #include <memory>
namespace YAML namespace YAML {
{ struct Directives;
struct Directives; struct Mark;
struct Mark; struct Token;
struct Token; class CollectionStack;
class CollectionStack; class EventHandler;
class EventHandler; class Node;
class Node; class Scanner;
class Scanner;
class SingleDocParser: private noncopyable class SingleDocParser : private noncopyable {
{
public: public:
SingleDocParser(Scanner& scanner, const Directives& directives); SingleDocParser(Scanner& scanner, const Directives& directives);
~SingleDocParser(); ~SingleDocParser();
@@ -59,7 +58,7 @@ namespace YAML
Anchors m_anchors; Anchors m_anchors;
anchor_t m_curAnchor; anchor_t m_curAnchor;
}; };
} }
#endif // SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // SINGLEDOCPARSER_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -6,14 +6,13 @@
#define YAML_PREFETCH_SIZE 2048 #define YAML_PREFETCH_SIZE 2048
#endif #endif
#define S_ARRAY_SIZE( A ) (sizeof(A)/sizeof(*(A))) #define S_ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A)))
#define S_ARRAY_END( A ) ((A) + S_ARRAY_SIZE(A)) #define S_ARRAY_END(A) ((A) + S_ARRAY_SIZE(A))
#define CP_REPLACEMENT_CHARACTER (0xFFFD) #define CP_REPLACEMENT_CHARACTER (0xFFFD)
namespace YAML namespace YAML {
{ enum UtfIntroState {
enum UtfIntroState {
uis_start, uis_start,
uis_utfbe_b1, uis_utfbe_b1,
uis_utf32be_b2, uis_utf32be_b2,
@@ -33,9 +32,9 @@ namespace YAML
uis_utf8_bom2, uis_utf8_bom2,
uis_utf8, uis_utf8,
uis_error uis_error
}; };
enum UtfIntroCharType { enum UtfIntroCharType {
uict00, uict00,
uictBB, uictBB,
uictBF, uictBF,
@@ -45,53 +44,70 @@ namespace YAML
uictAscii, uictAscii,
uictOther, uictOther,
uictMax uictMax
}; };
static bool s_introFinalState[] = { static bool s_introFinalState[] = {false, // uis_start
false, //uis_start false, // uis_utfbe_b1
false, //uis_utfbe_b1 false, // uis_utf32be_b2
false, //uis_utf32be_b2 false, // uis_utf32be_bom3
false, //uis_utf32be_bom3 true, // uis_utf32be
true, //uis_utf32be true, // uis_utf16be
true, //uis_utf16be false, // uis_utf16be_bom1
false, //uis_utf16be_bom1 false, // uis_utfle_bom1
false, //uis_utfle_bom1 false, // uis_utf16le_bom2
false, //uis_utf16le_bom2 false, // uis_utf32le_bom3
false, //uis_utf32le_bom3 true, // uis_utf16le
true, //uis_utf16le true, // uis_utf32le
true, //uis_utf32le false, // uis_utf8_imp
false, //uis_utf8_imp false, // uis_utf16le_imp
false, //uis_utf16le_imp false, // uis_utf32le_imp3
false, //uis_utf32le_imp3 false, // uis_utf8_bom1
false, //uis_utf8_bom1 false, // uis_utf8_bom2
false, //uis_utf8_bom2 true, // uis_utf8
true, //uis_utf8 true, // uis_error
true, //uis_error };
};
static UtfIntroState s_introTransitions[][uictMax] = { static UtfIntroState s_introTransitions[][uictMax] = {
// uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther // uict00, uictBB, uictBF, uictEF,
{uis_utfbe_b1, uis_utf8, uis_utf8, uis_utf8_bom1, uis_utf16be_bom1, uis_utfle_bom1, uis_utf8_imp, uis_utf8}, // uictFE, uictFF, uictAscii, uictOther
{uis_utf32be_b2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16be, uis_utf8}, {uis_utfbe_b1, uis_utf8, uis_utf8, uis_utf8_bom1,
{uis_utf32be, uis_utf8, uis_utf8, uis_utf8, uis_utf32be_bom3, uis_utf8, uis_utf8, uis_utf8}, uis_utf16be_bom1, uis_utfle_bom1, uis_utf8_imp, uis_utf8},
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf32be, uis_utf8, uis_utf8}, {uis_utf32be_b2, uis_utf8, uis_utf8, uis_utf8,
{uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be}, uis_utf8, uis_utf8, uis_utf16be, uis_utf8},
{uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be}, {uis_utf32be, uis_utf8, uis_utf8, uis_utf8,
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16be, uis_utf8, uis_utf8}, uis_utf32be_bom3, uis_utf8, uis_utf8, uis_utf8},
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf16le_bom2, uis_utf8, uis_utf8, uis_utf8}, {uis_utf8, uis_utf8, uis_utf8, uis_utf8,
{uis_utf32le_bom3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le}, uis_utf8, uis_utf32be, uis_utf8, uis_utf8},
{uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le}, {uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be,
{uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le}, uis_utf32be, uis_utf32be, uis_utf32be, uis_utf32be},
{uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le}, {uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be,
{uis_utf16le_imp, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8}, uis_utf16be, uis_utf16be, uis_utf16be, uis_utf16be},
{uis_utf32le_imp3, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le}, {uis_utf8, uis_utf8, uis_utf8, uis_utf8,
{uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le}, uis_utf8, uis_utf16be, uis_utf8, uis_utf8},
{uis_utf8, uis_utf8_bom2, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8}, {uis_utf8, uis_utf8, uis_utf8, uis_utf8,
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8}, uis_utf16le_bom2, uis_utf8, uis_utf8, uis_utf8},
{uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8, uis_utf8}, {uis_utf32le_bom3, uis_utf16le, uis_utf16le, uis_utf16le,
}; uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le},
{uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le,
uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le},
{uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le,
uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le},
{uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le,
uis_utf32le, uis_utf32le, uis_utf32le, uis_utf32le},
{uis_utf16le_imp, uis_utf8, uis_utf8, uis_utf8,
uis_utf8, uis_utf8, uis_utf8, uis_utf8},
{uis_utf32le_imp3, uis_utf16le, uis_utf16le, uis_utf16le,
uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le},
{uis_utf32le, uis_utf16le, uis_utf16le, uis_utf16le,
uis_utf16le, uis_utf16le, uis_utf16le, uis_utf16le},
{uis_utf8, uis_utf8_bom2, uis_utf8, uis_utf8,
uis_utf8, uis_utf8, uis_utf8, uis_utf8},
{uis_utf8, uis_utf8, uis_utf8, uis_utf8,
uis_utf8, uis_utf8, uis_utf8, uis_utf8},
{uis_utf8, uis_utf8, uis_utf8, uis_utf8,
uis_utf8, uis_utf8, uis_utf8, uis_utf8}, };
static char s_introUngetCount[][uictMax] = { static char s_introUngetCount[][uictMax] = {
// uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther // uict00, uictBB, uictBF, uictEF, uictFE, uictFF, uictAscii, uictOther
{0, 1, 1, 0, 0, 0, 0, 1}, {0, 1, 1, 0, 0, 0, 0, 1},
{0, 2, 2, 2, 2, 2, 2, 2}, {0, 2, 2, 2, 2, 2, 2, 2},
@@ -110,22 +126,26 @@ namespace YAML
{4, 4, 4, 4, 4, 4, 4, 4}, {4, 4, 4, 4, 4, 4, 4, 4},
{2, 0, 2, 2, 2, 2, 2, 2}, {2, 0, 2, 2, 2, 2, 2, 2},
{3, 3, 0, 3, 3, 3, 3, 3}, {3, 3, 0, 3, 3, 3, 3, 3},
{1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, };
};
inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) inline UtfIntroCharType IntroCharTypeOf(std::istream::int_type ch) {
{
if (std::istream::traits_type::eof() == ch) { if (std::istream::traits_type::eof() == ch) {
return uictOther; return uictOther;
} }
switch (ch) { switch (ch) {
case 0: return uict00; case 0:
case 0xBB: return uictBB; return uict00;
case 0xBF: return uictBF; case 0xBB:
case 0xEF: return uictEF; return uictBB;
case 0xFE: return uictFE; case 0xBF:
case 0xFF: return uictFF; return uictBF;
case 0xEF:
return uictEF;
case 0xFE:
return uictFE;
case 0xFF:
return uictFF;
} }
if ((ch > 0) && (ch < 0xFF)) { if ((ch > 0) && (ch < 0xFF)) {
@@ -133,58 +153,48 @@ namespace YAML
} }
return uictOther; return uictOther;
} }
inline char Utf8Adjust(unsigned long ch, unsigned char lead_bits, unsigned char rshift) inline char Utf8Adjust(unsigned long ch, unsigned char lead_bits,
{ unsigned char rshift) {
const unsigned char header = ((1 << lead_bits) - 1) << (8 - lead_bits); const unsigned char header = ((1 << lead_bits) - 1) << (8 - lead_bits);
const unsigned char mask = (0xFF >> (lead_bits + 1)); const unsigned char mask = (0xFF >> (lead_bits + 1));
return static_cast<char>(static_cast<unsigned char>( return static_cast<char>(
header | ((ch >> rshift) & mask) static_cast<unsigned char>(header | ((ch >> rshift) & mask)));
)); }
}
inline void QueueUnicodeCodepoint(std::deque<char>& q, unsigned long ch) inline void QueueUnicodeCodepoint(std::deque<char>& q, unsigned long ch) {
{
// We are not allowed to queue the Stream::eof() codepoint, so // We are not allowed to queue the Stream::eof() codepoint, so
// replace it with CP_REPLACEMENT_CHARACTER // replace it with CP_REPLACEMENT_CHARACTER
if (static_cast<unsigned long>(Stream::eof()) == ch) if (static_cast<unsigned long>(Stream::eof()) == ch) {
{
ch = CP_REPLACEMENT_CHARACTER; ch = CP_REPLACEMENT_CHARACTER;
} }
if (ch < 0x80) if (ch < 0x80) {
{
q.push_back(Utf8Adjust(ch, 0, 0)); q.push_back(Utf8Adjust(ch, 0, 0));
} } else if (ch < 0x800) {
else if (ch < 0x800)
{
q.push_back(Utf8Adjust(ch, 2, 6)); q.push_back(Utf8Adjust(ch, 2, 6));
q.push_back(Utf8Adjust(ch, 1, 0)); q.push_back(Utf8Adjust(ch, 1, 0));
} } else if (ch < 0x10000) {
else if (ch < 0x10000)
{
q.push_back(Utf8Adjust(ch, 3, 12)); q.push_back(Utf8Adjust(ch, 3, 12));
q.push_back(Utf8Adjust(ch, 1, 6)); q.push_back(Utf8Adjust(ch, 1, 6));
q.push_back(Utf8Adjust(ch, 1, 0)); q.push_back(Utf8Adjust(ch, 1, 0));
} } else {
else
{
q.push_back(Utf8Adjust(ch, 4, 18)); q.push_back(Utf8Adjust(ch, 4, 18));
q.push_back(Utf8Adjust(ch, 1, 12)); q.push_back(Utf8Adjust(ch, 1, 12));
q.push_back(Utf8Adjust(ch, 1, 6)); q.push_back(Utf8Adjust(ch, 1, 6));
q.push_back(Utf8Adjust(ch, 1, 0)); q.push_back(Utf8Adjust(ch, 1, 0));
} }
} }
Stream::Stream(std::istream& input) Stream::Stream(std::istream& input)
: m_input(input), : m_input(input),
m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]), m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]),
m_nPrefetchedAvailable(0), m_nPrefetchedUsed(0) m_nPrefetchedAvailable(0),
{ m_nPrefetchedUsed(0) {
typedef std::istream::traits_type char_traits; typedef std::istream::traits_type char_traits;
if(!input) if (!input)
return; return;
// Determine (or guess) the character-set by reading the BOM, if any. See // Determine (or guess) the character-set by reading the BOM, if any. See
@@ -192,16 +202,16 @@ namespace YAML
char_traits::int_type intro[4]; char_traits::int_type intro[4];
int nIntroUsed = 0; int nIntroUsed = 0;
UtfIntroState state = uis_start; UtfIntroState state = uis_start;
for(; !s_introFinalState[state]; ) { for (; !s_introFinalState[state];) {
std::istream::int_type ch = input.get(); std::istream::int_type ch = input.get();
intro[nIntroUsed++] = ch; intro[nIntroUsed++] = ch;
UtfIntroCharType charType = IntroCharTypeOf(ch); UtfIntroCharType charType = IntroCharTypeOf(ch);
UtfIntroState newState = s_introTransitions[state][charType]; UtfIntroState newState = s_introTransitions[state][charType];
int nUngets = s_introUngetCount[state][charType]; int nUngets = s_introUngetCount[state][charType];
if(nUngets > 0) { if (nUngets > 0) {
input.clear(); input.clear();
for(; nUngets > 0; --nUngets) { for (; nUngets > 0; --nUngets) {
if(char_traits::eof() != intro[--nIntroUsed]) if (char_traits::eof() != intro[--nIntroUsed])
input.putback(char_traits::to_char_type(intro[nIntroUsed])); input.putback(char_traits::to_char_type(intro[nIntroUsed]));
} }
} }
@@ -209,166 +219,163 @@ namespace YAML
} }
switch (state) { switch (state) {
case uis_utf8: m_charSet = utf8; break; case uis_utf8:
case uis_utf16le: m_charSet = utf16le; break; m_charSet = utf8;
case uis_utf16be: m_charSet = utf16be; break; break;
case uis_utf32le: m_charSet = utf32le; break; case uis_utf16le:
case uis_utf32be: m_charSet = utf32be; break; m_charSet = utf16le;
default: m_charSet = utf8; break; break;
case uis_utf16be:
m_charSet = utf16be;
break;
case uis_utf32le:
m_charSet = utf32le;
break;
case uis_utf32be:
m_charSet = utf32be;
break;
default:
m_charSet = utf8;
break;
} }
ReadAheadTo(0); ReadAheadTo(0);
} }
Stream::~Stream() Stream::~Stream() { delete[] m_pPrefetched; }
{
delete[] m_pPrefetched;
}
char Stream::peek() const char Stream::peek() const {
{ if (m_readahead.empty()) {
if (m_readahead.empty())
{
return Stream::eof(); return Stream::eof();
} }
return m_readahead[0]; return m_readahead[0];
} }
Stream::operator bool() const Stream::operator bool() const {
{ return m_input.good() ||
return m_input.good() || (!m_readahead.empty() && m_readahead[0] != Stream::eof()); (!m_readahead.empty() && m_readahead[0] != Stream::eof());
} }
// get // get
// . Extracts a character from the stream and updates our position // . Extracts a character from the stream and updates our position
char Stream::get() char Stream::get() {
{
char ch = peek(); char ch = peek();
AdvanceCurrent(); AdvanceCurrent();
m_mark.column++; m_mark.column++;
if(ch == '\n') { if (ch == '\n') {
m_mark.column = 0; m_mark.column = 0;
m_mark.line++; m_mark.line++;
} }
return ch; return ch;
} }
// get // get
// . Extracts 'n' characters from the stream and updates our position // . Extracts 'n' characters from the stream and updates our position
std::string Stream::get(int n) std::string Stream::get(int n) {
{
std::string ret; std::string ret;
ret.reserve(n); ret.reserve(n);
for(int i=0;i<n;i++) for (int i = 0; i < n; i++)
ret += get(); ret += get();
return ret; return ret;
} }
// eat // eat
// . Eats 'n' characters and updates our position. // . Eats 'n' characters and updates our position.
void Stream::eat(int n) void Stream::eat(int n) {
{ for (int i = 0; i < n; i++)
for(int i=0;i<n;i++)
get(); get();
} }
void Stream::AdvanceCurrent() void Stream::AdvanceCurrent() {
{ if (!m_readahead.empty()) {
if (!m_readahead.empty())
{
m_readahead.pop_front(); m_readahead.pop_front();
m_mark.pos++; m_mark.pos++;
} }
ReadAheadTo(0); ReadAheadTo(0);
} }
bool Stream::_ReadAheadTo(size_t i) const bool Stream::_ReadAheadTo(size_t i) const {
{ while (m_input.good() && (m_readahead.size() <= i)) {
while (m_input.good() && (m_readahead.size() <= i)) switch (m_charSet) {
{ case utf8:
switch (m_charSet) StreamInUtf8();
{ break;
case utf8: StreamInUtf8(); break; case utf16le:
case utf16le: StreamInUtf16(); break; StreamInUtf16();
case utf16be: StreamInUtf16(); break; break;
case utf32le: StreamInUtf32(); break; case utf16be:
case utf32be: StreamInUtf32(); break; StreamInUtf16();
break;
case utf32le:
StreamInUtf32();
break;
case utf32be:
StreamInUtf32();
break;
} }
} }
// signal end of stream // signal end of stream
if(!m_input.good()) if (!m_input.good())
m_readahead.push_back(Stream::eof()); m_readahead.push_back(Stream::eof());
return m_readahead.size() > i; return m_readahead.size() > i;
} }
void Stream::StreamInUtf8() const void Stream::StreamInUtf8() const {
{
unsigned char b = GetNextByte(); unsigned char b = GetNextByte();
if (m_input.good()) if (m_input.good()) {
{
m_readahead.push_back(b); m_readahead.push_back(b);
} }
} }
void Stream::StreamInUtf16() const void Stream::StreamInUtf16() const {
{
unsigned long ch = 0; unsigned long ch = 0;
unsigned char bytes[2]; unsigned char bytes[2];
int nBigEnd = (m_charSet == utf16be) ? 0 : 1; int nBigEnd = (m_charSet == utf16be) ? 0 : 1;
bytes[0] = GetNextByte(); bytes[0] = GetNextByte();
bytes[1] = GetNextByte(); bytes[1] = GetNextByte();
if (!m_input.good()) if (!m_input.good()) {
{
return; return;
} }
ch = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) | ch = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) |
static_cast<unsigned long>(bytes[1 ^ nBigEnd]); static_cast<unsigned long>(bytes[1 ^ nBigEnd]);
if (ch >= 0xDC00 && ch < 0xE000) if (ch >= 0xDC00 && ch < 0xE000) {
{
// Trailing (low) surrogate...ugh, wrong order // Trailing (low) surrogate...ugh, wrong order
QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER);
return; return;
} } else if (ch >= 0xD800 && ch < 0xDC00) {
else if (ch >= 0xD800 && ch < 0xDC00)
{
// ch is a leading (high) surrogate // ch is a leading (high) surrogate
// Four byte UTF-8 code point // Four byte UTF-8 code point
// Read the trailing (low) surrogate // Read the trailing (low) surrogate
for (;;) for (;;) {
{
bytes[0] = GetNextByte(); bytes[0] = GetNextByte();
bytes[1] = GetNextByte(); bytes[1] = GetNextByte();
if (!m_input.good()) if (!m_input.good()) {
{
QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER);
return; return;
} }
unsigned long chLow = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) | unsigned long chLow = (static_cast<unsigned long>(bytes[nBigEnd]) << 8) |
static_cast<unsigned long>(bytes[1 ^ nBigEnd]); static_cast<unsigned long>(bytes[1 ^ nBigEnd]);
if (chLow < 0xDC00 || ch >= 0xE000) if (chLow < 0xDC00 || ch >= 0xE000) {
{ // Trouble...not a low surrogate. Dump a REPLACEMENT CHARACTER into the
// Trouble...not a low surrogate. Dump a REPLACEMENT CHARACTER into the stream. // stream.
QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER);
// Deal with the next UTF-16 unit // Deal with the next UTF-16 unit
if (chLow < 0xD800 || ch >= 0xE000) if (chLow < 0xD800 || ch >= 0xE000) {
{
// Easiest case: queue the codepoint and return // Easiest case: queue the codepoint and return
QueueUnicodeCodepoint(m_readahead, ch); QueueUnicodeCodepoint(m_readahead, ch);
return; return;
} } else {
else
{
// Start the loop over with the new high surrogate // Start the loop over with the new high surrogate
ch = chLow; ch = chLow;
continue; continue;
@@ -388,40 +395,32 @@ namespace YAML
} }
QueueUnicodeCodepoint(m_readahead, ch); QueueUnicodeCodepoint(m_readahead, ch);
} }
inline char* ReadBuffer(unsigned char* pBuffer) inline char* ReadBuffer(unsigned char* pBuffer) {
{
return reinterpret_cast<char*>(pBuffer); return reinterpret_cast<char*>(pBuffer);
} }
unsigned char Stream::GetNextByte() const unsigned char Stream::GetNextByte() const {
{ if (m_nPrefetchedUsed >= m_nPrefetchedAvailable) {
if (m_nPrefetchedUsed >= m_nPrefetchedAvailable) std::streambuf* pBuf = m_input.rdbuf();
{ m_nPrefetchedAvailable = static_cast<std::size_t>(
std::streambuf *pBuf = m_input.rdbuf(); pBuf->sgetn(ReadBuffer(m_pPrefetched), YAML_PREFETCH_SIZE));
m_nPrefetchedAvailable = static_cast<std::size_t>(pBuf->sgetn(ReadBuffer(m_pPrefetched), YAML_PREFETCH_SIZE));
m_nPrefetchedUsed = 0; m_nPrefetchedUsed = 0;
if (!m_nPrefetchedAvailable) if (!m_nPrefetchedAvailable) {
{
m_input.setstate(std::ios_base::eofbit); m_input.setstate(std::ios_base::eofbit);
} }
if (0 == m_nPrefetchedAvailable) if (0 == m_nPrefetchedAvailable) {
{
return 0; return 0;
} }
} }
return m_pPrefetched[m_nPrefetchedUsed++]; return m_pPrefetched[m_nPrefetchedUsed++];
} }
void Stream::StreamInUtf32() const void Stream::StreamInUtf32() const {
{ static int indexes[2][4] = {{3, 2, 1, 0}, {0, 1, 2, 3}};
static int indexes[2][4] = {
{3, 2, 1, 0},
{0, 1, 2, 3}
};
unsigned long ch = 0; unsigned long ch = 0;
unsigned char bytes[4]; unsigned char bytes[4];
@@ -431,17 +430,15 @@ namespace YAML
bytes[1] = GetNextByte(); bytes[1] = GetNextByte();
bytes[2] = GetNextByte(); bytes[2] = GetNextByte();
bytes[3] = GetNextByte(); bytes[3] = GetNextByte();
if (!m_input.good()) if (!m_input.good()) {
{
return; return;
} }
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i) {
{
ch <<= 8; ch <<= 8;
ch |= bytes[pIndexes[i]]; ch |= bytes[pIndexes[i]];
} }
QueueUnicodeCodepoint(m_readahead, ch); QueueUnicodeCodepoint(m_readahead, ch);
} }
} }

View File

@@ -1,11 +1,12 @@
#ifndef STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/noncopyable.h" #include "yaml-cpp/noncopyable.h"
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include <cstddef> #include <cstddef>
@@ -15,10 +16,8 @@
#include <set> #include <set>
#include <string> #include <string>
namespace YAML namespace YAML {
{ class Stream : private noncopyable {
class Stream: private noncopyable
{
public: public:
friend class StreamCharSource; friend class StreamCharSource;
@@ -26,7 +25,7 @@ namespace YAML
~Stream(); ~Stream();
operator bool() const; operator bool() const;
bool operator !() const { return !static_cast <bool>(*this); } bool operator!() const { return !static_cast<bool>(*this); }
char peek() const; char peek() const;
char get(); char get();
@@ -42,7 +41,13 @@ namespace YAML
void ResetColumn() { m_mark.column = 0; } void ResetColumn() { m_mark.column = 0; }
private: private:
enum CharacterSet {utf8, utf16le, utf16be, utf32le, utf32be}; enum CharacterSet {
utf8,
utf16le,
utf16be,
utf32le,
utf32be
};
std::istream& m_input; std::istream& m_input;
Mark m_mark; Mark m_mark;
@@ -61,19 +66,17 @@ namespace YAML
void StreamInUtf16() const; void StreamInUtf16() const;
void StreamInUtf32() const; void StreamInUtf32() const;
unsigned char GetNextByte() const; unsigned char GetNextByte() const;
}; };
// CharAt // CharAt
// . Unchecked access // . Unchecked access
inline char Stream::CharAt(size_t i) const { inline char Stream::CharAt(size_t i) const { return m_readahead[i]; }
return m_readahead[i];
}
inline bool Stream::ReadAheadTo(size_t i) const { inline bool Stream::ReadAheadTo(size_t i) const {
if(m_readahead.size() > i) if (m_readahead.size() > i)
return true; return true;
return _ReadAheadTo(i); return _ReadAheadTo(i);
} }
} }
#endif // STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // STREAM_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,48 +1,48 @@
#ifndef STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/noncopyable.h" #include "yaml-cpp/noncopyable.h"
#include <cstddef> #include <cstddef>
namespace YAML namespace YAML {
{ class StreamCharSource {
class StreamCharSource
{
public: public:
StreamCharSource(const Stream& stream): m_offset(0), m_stream(stream) {} StreamCharSource(const Stream& stream) : m_offset(0), m_stream(stream) {}
StreamCharSource(const StreamCharSource& source): m_offset(source.m_offset), m_stream(source.m_stream) {} StreamCharSource(const StreamCharSource& source)
: m_offset(source.m_offset), m_stream(source.m_stream) {}
~StreamCharSource() {} ~StreamCharSource() {}
operator bool() const; operator bool() const;
char operator [] (std::size_t i) const { return m_stream.CharAt(m_offset + i); } char operator[](std::size_t i) const { return m_stream.CharAt(m_offset + i); }
bool operator !() const { return !static_cast<bool>(*this); } bool operator!() const { return !static_cast<bool>(*this); }
const StreamCharSource operator + (int i) const; const StreamCharSource operator+(int i) const;
private: private:
std::size_t m_offset; std::size_t m_offset;
const Stream& m_stream; const Stream& m_stream;
StreamCharSource& operator = (const StreamCharSource&); // non-assignable StreamCharSource& operator=(const StreamCharSource&); // non-assignable
}; };
inline StreamCharSource::operator bool() const { inline StreamCharSource::operator bool() const {
return m_stream.ReadAheadTo(m_offset); return m_stream.ReadAheadTo(m_offset);
} }
inline const StreamCharSource StreamCharSource::operator + (int i) const { inline const StreamCharSource StreamCharSource::operator+(int i) const {
StreamCharSource source(*this); StreamCharSource source(*this);
if(static_cast<int> (source.m_offset) + i >= 0) if (static_cast<int>(source.m_offset) + i >= 0)
source.m_offset += i; source.m_offset += i;
else else
source.m_offset = 0; source.m_offset = 0;
return source; return source;
} }
} }
#endif // STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // STREAMCHARSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,47 +1,48 @@
#ifndef STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <cstddef> #include <cstddef>
namespace YAML namespace YAML {
{ class StringCharSource {
class StringCharSource
{
public: public:
StringCharSource(const char *str, std::size_t size): m_str(str), m_size(size), m_offset(0) {} StringCharSource(const char* str, std::size_t size)
: m_str(str), m_size(size), m_offset(0) {}
operator bool() const { return m_offset < m_size; } operator bool() const { return m_offset < m_size; }
char operator [] (std::size_t i) const { return m_str[m_offset + i]; } char operator[](std::size_t i) const { return m_str[m_offset + i]; }
bool operator !() const { return !static_cast<bool>(*this); } bool operator!() const { return !static_cast<bool>(*this); }
const StringCharSource operator + (int i) const { const StringCharSource operator+(int i) const {
StringCharSource source(*this); StringCharSource source(*this);
if(static_cast<int> (source.m_offset) + i >= 0) if (static_cast<int>(source.m_offset) + i >= 0)
source.m_offset += i; source.m_offset += i;
else else
source.m_offset = 0; source.m_offset = 0;
return source; return source;
} }
StringCharSource& operator ++ () { StringCharSource& operator++() {
++m_offset; ++m_offset;
return *this; return *this;
} }
StringCharSource& operator += (std::size_t offset) { StringCharSource& operator+=(std::size_t offset) {
m_offset += offset; m_offset += offset;
return *this; return *this;
} }
private: private:
const char *m_str; const char* m_str;
std::size_t m_size; std::size_t m_size;
std::size_t m_offset; std::size_t m_offset;
}; };
} }
#endif // STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // STRINGSOURCE_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -4,11 +4,9 @@
#include <cassert> #include <cassert>
#include <stdexcept> #include <stdexcept>
namespace YAML namespace YAML {
{ Tag::Tag(const Token& token) : type(static_cast<TYPE>(token.data)) {
Tag::Tag(const Token& token): type(static_cast<TYPE>(token.data)) switch (type) {
{
switch(type) {
case VERBATIM: case VERBATIM:
value = token.value; value = token.value;
break; break;
@@ -27,11 +25,10 @@ namespace YAML
default: default:
assert(false); assert(false);
} }
} }
const std::string Tag::Translate(const Directives& directives) const std::string Tag::Translate(const Directives& directives) {
{ switch (type) {
switch(type) {
case VERBATIM: case VERBATIM:
return value; return value;
case PRIMARY_HANDLE: case PRIMARY_HANDLE:
@@ -47,6 +44,5 @@ namespace YAML
assert(false); assert(false);
} }
throw std::runtime_error("yaml-cpp: internal error, bad tag type"); throw std::runtime_error("yaml-cpp: internal error, bad tag type");
}
} }
}

View File

@@ -1,20 +1,25 @@
#ifndef TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
namespace YAML namespace YAML {
{ struct Token;
struct Token; struct Directives;
struct Directives;
struct Tag { struct Tag {
enum TYPE { enum TYPE {
VERBATIM, PRIMARY_HANDLE, SECONDARY_HANDLE, NAMED_HANDLE, NON_SPECIFIC VERBATIM,
PRIMARY_HANDLE,
SECONDARY_HANDLE,
NAMED_HANDLE,
NON_SPECIFIC
}; };
Tag(const Token& token); Tag(const Token& token);
@@ -22,7 +27,7 @@ namespace YAML
TYPE type; TYPE type;
std::string handle, value; std::string handle, value;
}; };
} }
#endif // TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // TAG_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,44 +1,32 @@
#ifndef TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "yaml-cpp/mark.h" #include "yaml-cpp/mark.h"
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <vector> #include <vector>
namespace YAML namespace YAML {
{ const std::string TokenNames[] = {
const std::string TokenNames[] = { "DIRECTIVE", "DOC_START", "DOC_END", "BLOCK_SEQ_START",
"DIRECTIVE", "BLOCK_MAP_START", "BLOCK_SEQ_END", "BLOCK_MAP_END", "BLOCK_ENTRY",
"DOC_START", "FLOW_SEQ_START", "FLOW_MAP_START", "FLOW_SEQ_END", "FLOW_MAP_END",
"DOC_END", "FLOW_MAP_COMPACT", "FLOW_ENTRY", "KEY", "VALUE",
"BLOCK_SEQ_START", "ANCHOR", "ALIAS", "TAG", "SCALAR"};
"BLOCK_MAP_START",
"BLOCK_SEQ_END",
"BLOCK_MAP_END",
"BLOCK_ENTRY",
"FLOW_SEQ_START",
"FLOW_MAP_START",
"FLOW_SEQ_END",
"FLOW_MAP_END",
"FLOW_MAP_COMPACT",
"FLOW_ENTRY",
"KEY",
"VALUE",
"ANCHOR",
"ALIAS",
"TAG",
"SCALAR"
};
struct Token { struct Token {
// enums // enums
enum STATUS { VALID, INVALID, UNVERIFIED }; enum STATUS {
VALID,
INVALID,
UNVERIFIED
};
enum TYPE { enum TYPE {
DIRECTIVE, DIRECTIVE,
DOC_START, DOC_START,
@@ -64,11 +52,12 @@ namespace YAML
}; };
// data // 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_), data(0) {}
friend std::ostream& operator << (std::ostream& out, const Token& token) { friend std::ostream& operator<<(std::ostream& out, const Token& token) {
out << TokenNames[token.type] << std::string(": ") << token.value; out << TokenNames[token.type] << std::string(": ") << token.value;
for(std::size_t i=0;i<token.params.size();i++) for (std::size_t i = 0; i < token.params.size(); i++)
out << std::string(" ") << token.params[i]; out << std::string(" ") << token.params[i];
return out; return out;
} }
@@ -77,9 +66,9 @@ namespace YAML
TYPE type; TYPE type;
Mark mark; Mark mark;
std::string value; std::string value;
std::vector <std::string> params; std::vector<std::string> params;
int data; int data;
}; };
} }
#endif // TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // TOKEN_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -3,22 +3,20 @@
#include "yaml-cpp/yaml.h" #include "yaml-cpp/yaml.h"
#include <iostream> #include <iostream>
namespace Test namespace Test {
{ namespace Parser {
namespace Parser { TEST NoEndOfMapFlow() {
TEST NoEndOfMapFlow()
{
try { try {
HANDLE("---{header: {id: 1"); HANDLE("---{header: {id: 1");
} catch(const YAML::ParserException& e) { }
catch (const YAML::ParserException& e) {
YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::END_OF_MAP_FLOW)); YAML_ASSERT(e.msg == std::string(YAML::ErrorMsg::END_OF_MAP_FLOW));
return true; return true;
} }
return " no exception caught"; return " no exception caught";
} }
TEST PlainScalarStartingWithQuestionMark() TEST PlainScalarStartingWithQuestionMark() {
{
HANDLE("foo: ?bar"); HANDLE("foo: ?bar");
EXPECT_DOC_START(); EXPECT_DOC_START();
EXPECT_MAP_START("?", 0); EXPECT_MAP_START("?", 0);
@@ -27,10 +25,9 @@ namespace Test
EXPECT_MAP_END(); EXPECT_MAP_END();
EXPECT_DOC_END(); EXPECT_DOC_END();
DONE(); DONE();
} }
TEST NullStringScalar() TEST NullStringScalar() {
{
HANDLE("foo: null"); HANDLE("foo: null");
EXPECT_DOC_START(); EXPECT_DOC_START();
EXPECT_MAP_START("?", 0); EXPECT_MAP_START("?", 0);
@@ -39,39 +36,41 @@ namespace Test
EXPECT_MAP_END(); EXPECT_MAP_END();
EXPECT_DOC_END(); EXPECT_DOC_END();
DONE(); DONE();
} }
} }
namespace { namespace {
void RunParserTest(TEST (*test)(), const std::string& name, int& passed, int& total) { void RunParserTest(TEST (*test)(), const std::string& name, int& passed,
int& total) {
TEST ret; TEST ret;
try { try {
ret = test(); ret = test();
} catch(const YAML::Exception& e) { }
catch (const YAML::Exception& e) {
ret.ok = false; ret.ok = false;
ret.error = std::string(" Exception caught: ") + e.what(); ret.error = std::string(" Exception caught: ") + e.what();
} }
if(!ret.ok) { if (!ret.ok) {
std::cout << "Parser test failed: " << name << "\n"; std::cout << "Parser test failed: " << name << "\n";
std::cout << ret.error << "\n"; std::cout << ret.error << "\n";
} }
if(ret.ok) if (ret.ok)
passed++; passed++;
total++; total++;
} }
} }
bool RunParserTests() bool RunParserTests() {
{
int passed = 0; int passed = 0;
int total = 0; int total = 0;
RunParserTest(&Parser::NoEndOfMapFlow, "No end of map flow", passed, total); RunParserTest(&Parser::NoEndOfMapFlow, "No end of map flow", passed, total);
RunParserTest(&Parser::PlainScalarStartingWithQuestionMark, "Plain scalar starting with question mark", passed, total); RunParserTest(&Parser::PlainScalarStartingWithQuestionMark,
"Plain scalar starting with question mark", passed, total);
RunParserTest(&Parser::NullStringScalar, "Null string scalar", passed, total); RunParserTest(&Parser::NullStringScalar, "Null string scalar", passed, total);
std::cout << "Parser tests: " << passed << "/" << total << " passed\n"; std::cout << "Parser tests: " << passed << "/" << total << " passed\n";
return passed == total; return passed == total;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,14 @@
#ifndef EMITTERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef EMITTERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EMITTERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define EMITTERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
namespace Test { namespace Test {
bool RunEmitterTests(); bool RunEmitterTests();
} }
#endif // EMITTERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // EMITTERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

File diff suppressed because it is too large Load Diff

View File

@@ -7,19 +7,31 @@
#include <cassert> #include <cassert>
namespace Test { namespace Test {
inline std::string Quote(const std::string& text) { inline std::string Quote(const std::string& text) {
YAML::Emitter out; YAML::Emitter out;
out << YAML::DoubleQuoted << text; out << YAML::DoubleQuoted << text;
return out.c_str(); return out.c_str();
} }
struct Event { struct Event {
enum Type { DocStart, DocEnd, Null, Alias, Scalar, SeqStart, SeqEnd, MapStart, MapEnd }; enum Type {
DocStart,
DocEnd,
Null,
Alias,
Scalar,
SeqStart,
SeqEnd,
MapStart,
MapEnd
};
typedef YAML::Mark Mark; typedef YAML::Mark Mark;
typedef YAML::anchor_t anchor_t; typedef YAML::anchor_t anchor_t;
Event(Type type_, const std::string& tag_, anchor_t anchor_, const std::string& scalar_): type(type_), tag(tag_), anchor(anchor_), scalar(scalar_) {} Event(Type type_, const std::string& tag_, anchor_t anchor_,
const std::string& scalar_)
: type(type_), tag(tag_), anchor(anchor_), scalar(scalar_) {}
Type type; Type type;
std::string tag; std::string tag;
@@ -27,7 +39,7 @@ namespace Test {
std::string scalar; std::string scalar;
std::ostream& write(std::ostream& out) const { std::ostream& write(std::ostream& out) const {
switch(type) { switch (type) {
case DocStart: case DocStart:
return out << "DocStart"; return out << "DocStart";
case DocEnd: case DocEnd:
@@ -37,7 +49,8 @@ namespace Test {
case Alias: case Alias:
return out << "Alias(" << anchor << ")"; return out << "Alias(" << anchor << ")";
case Scalar: case Scalar:
return out << "Scalar(" << Quote(tag) << ", " << anchor << ", " << Quote(scalar) << ")"; return out << "Scalar(" << Quote(tag) << ", " << anchor << ", "
<< Quote(scalar) << ")";
case SeqStart: case SeqStart:
return out << "SeqStart(" << Quote(tag) << ", " << anchor << ")"; return out << "SeqStart(" << Quote(tag) << ", " << anchor << ")";
case SeqEnd: case SeqEnd:
@@ -50,22 +63,20 @@ namespace Test {
assert(false); assert(false);
return out; return out;
} }
}; };
inline std::ostream& operator << (std::ostream& out, const Event& event) { inline std::ostream& operator<<(std::ostream& out, const Event& event) {
return event.write(out); return event.write(out);
} }
inline bool operator == (const Event& a, const Event& b) { inline bool operator==(const Event& a, const Event& b) {
return a.type == b.type && a.tag == b.tag && a.anchor == b.anchor && a.scalar == b.scalar; return a.type == b.type && a.tag == b.tag && a.anchor == b.anchor &&
} a.scalar == b.scalar;
}
inline bool operator != (const Event& a, const Event& b) { inline bool operator!=(const Event& a, const Event& b) { return !(a == b); }
return !(a == b);
}
class MockEventHandler: public YAML::EventHandler class MockEventHandler : public YAML::EventHandler {
{
public: public:
typedef YAML::Mark Mark; typedef YAML::Mark Mark;
typedef YAML::anchor_t anchor_t; typedef YAML::anchor_t anchor_t;
@@ -88,11 +99,13 @@ namespace Test {
m_actualEvents.push_back(Event(Event::Alias, "", anchor, "")); m_actualEvents.push_back(Event(Event::Alias, "", anchor, ""));
} }
virtual void OnScalar(const Mark&, const std::string& tag, anchor_t anchor, const std::string& value) { virtual void OnScalar(const Mark&, const std::string& tag, anchor_t anchor,
const std::string& value) {
m_actualEvents.push_back(Event(Event::Scalar, tag, anchor, value)); m_actualEvents.push_back(Event(Event::Scalar, tag, anchor, value));
} }
virtual void OnSequenceStart(const Mark&, const std::string& tag, anchor_t anchor) { virtual void OnSequenceStart(const Mark&, const std::string& tag,
anchor_t anchor) {
m_actualEvents.push_back(Event(Event::SeqStart, tag, anchor, "")); m_actualEvents.push_back(Event(Event::SeqStart, tag, anchor, ""));
} }
@@ -100,7 +113,8 @@ namespace Test {
m_actualEvents.push_back(Event(Event::SeqEnd, "", 0, "")); m_actualEvents.push_back(Event(Event::SeqEnd, "", 0, ""));
} }
virtual void OnMapStart(const Mark&, const std::string& tag, anchor_t anchor) { virtual void OnMapStart(const Mark&, const std::string& tag,
anchor_t anchor) {
m_actualEvents.push_back(Event(Event::MapStart, tag, anchor, "")); m_actualEvents.push_back(Event(Event::MapStart, tag, anchor, ""));
} }
@@ -112,10 +126,10 @@ namespace Test {
Test::TEST Check() const { Test::TEST Check() const {
std::size_t N = std::max(m_expectedEvents.size(), m_actualEvents.size()); std::size_t N = std::max(m_expectedEvents.size(), m_actualEvents.size());
for(std::size_t i=0;i<N;i++) { for (std::size_t i = 0; i < N; i++) {
if(i >= m_expectedEvents.size()) { if (i >= m_expectedEvents.size()) {
std::stringstream out; std::stringstream out;
for(std::size_t j=0;j<i;j++) { for (std::size_t j = 0; j < i; j++) {
out << " " << m_expectedEvents[j] << "\n"; out << " " << m_expectedEvents[j] << "\n";
} }
out << " EXPECTED: (no event expected)\n"; out << " EXPECTED: (no event expected)\n";
@@ -123,9 +137,9 @@ namespace Test {
return out.str().c_str(); return out.str().c_str();
} }
if(i >= m_actualEvents.size()) { if (i >= m_actualEvents.size()) {
std::stringstream out; std::stringstream out;
for(std::size_t j=0;j<i;j++) { for (std::size_t j = 0; j < i; j++) {
out << " " << m_expectedEvents[j] << "\n"; out << " " << m_expectedEvents[j] << "\n";
} }
out << " EXPECTED: " << m_expectedEvents[i] << "\n"; out << " EXPECTED: " << m_expectedEvents[i] << "\n";
@@ -133,9 +147,9 @@ namespace Test {
return out.str().c_str(); return out.str().c_str();
} }
if(m_expectedEvents[i] != m_actualEvents[i]) { if (m_expectedEvents[i] != m_actualEvents[i]) {
std::stringstream out; std::stringstream out;
for(std::size_t j=0;j<i;j++) { for (std::size_t j = 0; j < i; j++) {
out << " " << m_expectedEvents[j] << "\n"; out << " " << m_expectedEvents[j] << "\n";
} }
out << " EXPECTED: " << m_expectedEvents[i] << "\n"; out << " EXPECTED: " << m_expectedEvents[i] << "\n";
@@ -149,42 +163,35 @@ namespace Test {
std::vector<Event> m_expectedEvents; std::vector<Event> m_expectedEvents;
std::vector<Event> m_actualEvents; std::vector<Event> m_actualEvents;
}; };
#define HANDLE(ex)\ #define HANDLE(ex) \
MockEventHandler handler;\ MockEventHandler handler; \
std::stringstream stream(ex);\ std::stringstream stream(ex); \
YAML::Parser parser(stream);\ YAML::Parser parser(stream); \
while(parser.HandleNextDocument(handler)) {} while (parser.HandleNextDocument(handler)) { \
}
#define EXPECT_DOC_START()\ #define EXPECT_DOC_START() handler.Expect(Event(Event::DocStart, "", 0, ""))
handler.Expect(Event(Event::DocStart, "", 0, ""))
#define EXPECT_DOC_END()\ #define EXPECT_DOC_END() handler.Expect(Event(Event::DocEnd, "", 0, ""))
handler.Expect(Event(Event::DocEnd, "", 0, ""))
#define EXPECT_NULL(anchor)\ #define EXPECT_NULL(anchor) handler.Expect(Event(Event::Null, "", anchor, ""))
handler.Expect(Event(Event::Null, "", anchor, ""))
#define EXPECT_ALIAS(anchor)\ #define EXPECT_ALIAS(anchor) handler.Expect(Event(Event::Alias, "", anchor, ""))
handler.Expect(Event(Event::Alias, "", anchor, ""))
#define EXPECT_SCALAR(tag, anchor, value)\ #define EXPECT_SCALAR(tag, anchor, value) \
handler.Expect(Event(Event::Scalar, tag, anchor, value)) handler.Expect(Event(Event::Scalar, tag, anchor, value))
#define EXPECT_SEQ_START(tag, anchor)\ #define EXPECT_SEQ_START(tag, anchor) \
handler.Expect(Event(Event::SeqStart, tag, anchor, "")) handler.Expect(Event(Event::SeqStart, tag, anchor, ""))
#define EXPECT_SEQ_END()\ #define EXPECT_SEQ_END() handler.Expect(Event(Event::SeqEnd, "", 0, ""))
handler.Expect(Event(Event::SeqEnd, "", 0, ""))
#define EXPECT_MAP_START(tag, anchor)\ #define EXPECT_MAP_START(tag, anchor) \
handler.Expect(Event(Event::MapStart, tag, anchor, "")) handler.Expect(Event(Event::MapStart, tag, anchor, ""))
#define EXPECT_MAP_END()\ #define EXPECT_MAP_END() handler.Expect(Event(Event::MapEnd, "", 0, ""))
handler.Expect(Event(Event::MapEnd, "", 0, ""))
#define DONE()\
return handler.Check()
#define DONE() return handler.Check()
} }

View File

@@ -1,7 +1,6 @@
#include "tests.h" #include "tests.h"
int main() int main() {
{
Test::RunAll(); Test::RunAll();
return 0; return 0;
} }

View File

@@ -1,13 +1,14 @@
#ifndef PARSERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef PARSERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define PARSERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define PARSERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
namespace Test { namespace Test {
bool RunParserTests(); bool RunParserTests();
} }
#endif // PARSERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // PARSERTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,16 +1,16 @@
namespace Test { namespace Test {
namespace Spec { namespace Spec {
const char *ex2_1 = const char *ex2_1 =
"- Mark McGwire\n" "- Mark McGwire\n"
"- Sammy Sosa\n" "- Sammy Sosa\n"
"- Ken Griffey"; "- Ken Griffey";
const char *ex2_2 = const char *ex2_2 =
"hr: 65 # Home runs\n" "hr: 65 # Home runs\n"
"avg: 0.278 # Batting average\n" "avg: 0.278 # Batting average\n"
"rbi: 147 # Runs Batted In"; "rbi: 147 # Runs Batted In";
const char *ex2_3 = const char *ex2_3 =
"american:\n" "american:\n"
"- Boston Red Sox\n" "- Boston Red Sox\n"
"- Detroit Tigers\n" "- Detroit Tigers\n"
@@ -20,7 +20,7 @@ namespace Test {
"- Chicago Cubs\n" "- Chicago Cubs\n"
"- Atlanta Braves"; "- Atlanta Braves";
const char *ex2_4 = const char *ex2_4 =
"-\n" "-\n"
" name: Mark McGwire\n" " name: Mark McGwire\n"
" hr: 65\n" " hr: 65\n"
@@ -30,19 +30,19 @@ namespace Test {
" hr: 63\n" " hr: 63\n"
" avg: 0.288"; " avg: 0.288";
const char *ex2_5 = const char *ex2_5 =
"- [name , hr, avg ]\n" "- [name , hr, avg ]\n"
"- [Mark McGwire, 65, 0.278]\n" "- [Mark McGwire, 65, 0.278]\n"
"- [Sammy Sosa , 63, 0.288]"; "- [Sammy Sosa , 63, 0.288]";
const char *ex2_6 = const char *ex2_6 =
"Mark McGwire: {hr: 65, avg: 0.278}\n" "Mark McGwire: {hr: 65, avg: 0.278}\n"
"Sammy Sosa: {\n" "Sammy Sosa: {\n"
" hr: 63,\n" " hr: 63,\n"
" avg: 0.288\n" " avg: 0.288\n"
" }"; " }";
const char *ex2_7 = const char *ex2_7 =
"# Ranking of 1998 home runs\n" "# Ranking of 1998 home runs\n"
"---\n" "---\n"
"- Mark McGwire\n" "- Mark McGwire\n"
@@ -54,7 +54,7 @@ namespace Test {
"- Chicago Cubs\n" "- Chicago Cubs\n"
"- St Louis Cardinals"; "- St Louis Cardinals";
const char *ex2_8 = const char *ex2_8 =
"---\n" "---\n"
"time: 20:03:20\n" "time: 20:03:20\n"
"player: Sammy Sosa\n" "player: Sammy Sosa\n"
@@ -66,7 +66,7 @@ namespace Test {
"action: grand slam\n" "action: grand slam\n"
"..."; "...";
const char *ex2_9 = const char *ex2_9 =
"---\n" "---\n"
"hr: # 1998 hr ranking\n" "hr: # 1998 hr ranking\n"
" - Mark McGwire\n" " - Mark McGwire\n"
@@ -76,7 +76,7 @@ namespace Test {
" - Sammy Sosa\n" " - Sammy Sosa\n"
" - Ken Griffey"; " - Ken Griffey";
const char *ex2_10 = const char *ex2_10 =
"---\n" "---\n"
"hr:\n" "hr:\n"
" - Mark McGwire\n" " - Mark McGwire\n"
@@ -86,7 +86,7 @@ namespace Test {
" - *SS # Subsequent occurrence\n" " - *SS # Subsequent occurrence\n"
" - Ken Griffey"; " - Ken Griffey";
const char *ex2_11 = const char *ex2_11 =
"? - Detroit Tigers\n" "? - Detroit Tigers\n"
" - Chicago cubs\n" " - Chicago cubs\n"
":\n" ":\n"
@@ -97,7 +97,7 @@ namespace Test {
": [ 2001-07-02, 2001-08-12,\n" ": [ 2001-07-02, 2001-08-12,\n"
" 2001-08-14 ]"; " 2001-08-14 ]";
const char *ex2_12 = const char *ex2_12 =
"---\n" "---\n"
"# Products purchased\n" "# Products purchased\n"
"- item : Super Hoop\n" "- item : Super Hoop\n"
@@ -107,19 +107,19 @@ namespace Test {
"- item : Big Shoes\n" "- item : Big Shoes\n"
" quantity: 1"; " quantity: 1";
const char *ex2_13 = const char *ex2_13 =
"# ASCII Art\n" "# ASCII Art\n"
"--- |\n" "--- |\n"
" \\//||\\/||\n" " \\//||\\/||\n"
" // || ||__"; " // || ||__";
const char *ex2_14 = const char *ex2_14 =
"--- >\n" "--- >\n"
" Mark McGwire's\n" " Mark McGwire's\n"
" year was crippled\n" " year was crippled\n"
" by a knee injury."; " by a knee injury.";
const char *ex2_15 = const char *ex2_15 =
">\n" ">\n"
" Sammy Sosa completed another\n" " Sammy Sosa completed another\n"
" fine season with great stats.\n" " fine season with great stats.\n"
@@ -129,7 +129,7 @@ namespace Test {
" \n" " \n"
" What a year!"; " What a year!";
const char *ex2_16 = const char *ex2_16 =
"name: Mark McGwire\n" "name: Mark McGwire\n"
"accomplishment: >\n" "accomplishment: >\n"
" Mark set a major league\n" " Mark set a major league\n"
@@ -138,7 +138,7 @@ namespace Test {
" 65 Home Runs\n" " 65 Home Runs\n"
" 0.278 Batting Average\n"; " 0.278 Batting Average\n";
const char *ex2_17 = const char *ex2_17 =
"unicode: \"Sosa did fine.\\u263A\"\n" "unicode: \"Sosa did fine.\\u263A\"\n"
"control: \"\\b1998\\t1999\\t2000\\n\"\n" "control: \"\\b1998\\t1999\\t2000\\n\"\n"
"hex esc: \"\\x0d\\x0a is \\r\\n\"\n" "hex esc: \"\\x0d\\x0a is \\r\\n\"\n"
@@ -147,7 +147,7 @@ namespace Test {
"quoted: ' # Not a ''comment''.'\n" "quoted: ' # Not a ''comment''.'\n"
"tie-fighter: '|\\-*-/|'"; "tie-fighter: '|\\-*-/|'";
const char *ex2_18 = const char *ex2_18 =
"plain:\n" "plain:\n"
" This unquoted scalar\n" " This unquoted scalar\n"
" spans many lines.\n" " spans many lines.\n"
@@ -155,9 +155,9 @@ namespace Test {
"quoted: \"So does this\n" "quoted: \"So does this\n"
" quoted scalar.\\n\""; " quoted scalar.\\n\"";
// TODO: 2.19 - 2.22 schema tags // TODO: 2.19 - 2.22 schema tags
const char *ex2_23 = const char *ex2_23 =
"---\n" "---\n"
"not-date: !!str 2002-04-28\n" "not-date: !!str 2002-04-28\n"
"\n" "\n"
@@ -172,7 +172,7 @@ namespace Test {
" above may be different for\n" " above may be different for\n"
" different documents."; " different documents.";
const char *ex2_24 = const char *ex2_24 =
"%TAG ! tag:clarkevans.com,2002:\n" "%TAG ! tag:clarkevans.com,2002:\n"
"--- !shape\n" "--- !shape\n"
" # Use the ! handle for presenting\n" " # Use the ! handle for presenting\n"
@@ -188,7 +188,7 @@ namespace Test {
" color: 0xFFEEBB\n" " color: 0xFFEEBB\n"
" text: Pretty vector drawing."; " text: Pretty vector drawing.";
const char *ex2_25 = const char *ex2_25 =
"# Sets are represented as a\n" "# Sets are represented as a\n"
"# Mapping where each key is\n" "# Mapping where each key is\n"
"# associated with a null value\n" "# associated with a null value\n"
@@ -197,7 +197,7 @@ namespace Test {
"? Sammy Sosa\n" "? Sammy Sosa\n"
"? Ken Griffey"; "? Ken Griffey";
const char *ex2_26 = const char *ex2_26 =
"# Ordered maps are represented as\n" "# Ordered maps are represented as\n"
"# A sequence of mappings, with\n" "# A sequence of mappings, with\n"
"# each mapping having one key\n" "# each mapping having one key\n"
@@ -206,7 +206,7 @@ namespace Test {
"- Sammy Sosa: 63\n" "- Sammy Sosa: 63\n"
"- Ken Griffey: 58"; "- Ken Griffey: 58";
const char *ex2_27 = const char *ex2_27 =
"--- !<tag:clarkevans.com,2002:invoice>\n" "--- !<tag:clarkevans.com,2002:invoice>\n"
"invoice: 34843\n" "invoice: 34843\n"
"date : 2001-01-23\n" "date : 2001-01-23\n"
@@ -237,7 +237,7 @@ namespace Test {
" Backup contact is Nancy\n" " Backup contact is Nancy\n"
" Billsmer @ 338-4338."; " Billsmer @ 338-4338.";
const char *ex2_28 = const char *ex2_28 =
"---\n" "---\n"
"Time: 2001-11-23 15:01:42 -5\n" "Time: 2001-11-23 15:01:42 -5\n"
"User: ed\n" "User: ed\n"
@@ -265,9 +265,9 @@ namespace Test {
" code: |-\n" " code: |-\n"
" foo = bar"; " foo = bar";
// TODO: 5.1 - 5.2 BOM // TODO: 5.1 - 5.2 BOM
const char *ex5_3 = const char *ex5_3 =
"sequence:\n" "sequence:\n"
"- one\n" "- one\n"
"- two\n" "- two\n"
@@ -276,18 +276,17 @@ namespace Test {
" : blue\n" " : blue\n"
" sea : green"; " sea : green";
const char *ex5_4 = const char *ex5_4 =
"sequence: [ one, two, ]\n" "sequence: [ one, two, ]\n"
"mapping: { sky: blue, sea: green }"; "mapping: { sky: blue, sea: green }";
const char *ex5_5 = const char *ex5_5 = "# Comment only.";
"# Comment only.";
const char *ex5_6 = const char *ex5_6 =
"anchored: !local &anchor value\n" "anchored: !local &anchor value\n"
"alias: *anchor"; "alias: *anchor";
const char *ex5_7 = const char *ex5_7 =
"literal: |\n" "literal: |\n"
" some\n" " some\n"
" text\n" " text\n"
@@ -295,19 +294,19 @@ namespace Test {
" some\n" " some\n"
" text\n"; " text\n";
const char *ex5_8 = const char *ex5_8 =
"single: 'text'\n" "single: 'text'\n"
"double: \"text\""; "double: \"text\"";
// TODO: 5.9 directive // TODO: 5.9 directive
// TODO: 5.10 reserved indicator // TODO: 5.10 reserved indicator
const char *ex5_11 = const char *ex5_11 =
"|\n" "|\n"
" Line break (no glyph)\n" " Line break (no glyph)\n"
" Line break (glyphed)\n"; " Line break (glyphed)\n";
const char *ex5_12 = const char *ex5_12 =
"# Tabs and spaces\n" "# Tabs and spaces\n"
"quoted: \"Quoted\t\"\n" "quoted: \"Quoted\t\"\n"
"block: |\n" "block: |\n"
@@ -315,19 +314,19 @@ namespace Test {
" \tprintf(\"Hello, world!\\n\");\n" " \tprintf(\"Hello, world!\\n\");\n"
" }"; " }";
const char *ex5_13 = const char *ex5_13 =
"\"Fun with \\\\\n" "\"Fun with \\\\\n"
"\\\" \\a \\b \\e \\f \\\n" "\\\" \\a \\b \\e \\f \\\n"
"\\n \\r \\t \\v \\0 \\\n" "\\n \\r \\t \\v \\0 \\\n"
"\\ \\_ \\N \\L \\P \\\n" "\\ \\_ \\N \\L \\P \\\n"
"\\x41 \\u0041 \\U00000041\""; "\\x41 \\u0041 \\U00000041\"";
const char *ex5_14 = const char *ex5_14 =
"Bad escapes:\n" "Bad escapes:\n"
" \"\\c\n" " \"\\c\n"
" \\xq-\""; " \\xq-\"";
const char *ex6_1 = const char *ex6_1 =
" # Leading comment line spaces are\n" " # Leading comment line spaces are\n"
" # neither content nor indentation.\n" " # neither content nor indentation.\n"
" \n" " \n"
@@ -341,18 +340,18 @@ namespace Test {
" \tStill by two # content nor\n" " \tStill by two # content nor\n"
" ] # indentation."; " ] # indentation.";
const char *ex6_2 = const char *ex6_2 =
"? a\n" "? a\n"
": -\tb\n" ": -\tb\n"
" - -\tc\n" " - -\tc\n"
" - d"; " - d";
const char *ex6_3 = const char *ex6_3 =
"- foo:\t bar\n" "- foo:\t bar\n"
"- - baz\n" "- - baz\n"
" -\tbaz"; " -\tbaz";
const char *ex6_4 = const char *ex6_4 =
"plain: text\n" "plain: text\n"
" lines\n" " lines\n"
"quoted: \"text\n" "quoted: \"text\n"
@@ -361,7 +360,7 @@ namespace Test {
" text\n" " text\n"
" \tlines\n"; " \tlines\n";
const char *ex6_5 = const char *ex6_5 =
"Folding:\n" "Folding:\n"
" \"Empty line\n" " \"Empty line\n"
" \t\n" " \t\n"
@@ -370,7 +369,7 @@ namespace Test {
" Clipped empty lines\n" " Clipped empty lines\n"
" "; " ";
const char *ex6_6 = const char *ex6_6 =
">-\n" ">-\n"
" trimmed\n" " trimmed\n"
" \n" " \n"
@@ -379,7 +378,7 @@ namespace Test {
" as\n" " as\n"
" space"; " space";
const char *ex6_7 = const char *ex6_7 =
">\n" ">\n"
" foo \n" " foo \n"
" \n" " \n"
@@ -387,7 +386,7 @@ namespace Test {
"\n" "\n"
" baz\n"; " baz\n";
const char *ex6_8 = const char *ex6_8 =
"\"\n" "\"\n"
" foo \n" " foo \n"
" \n" " \n"
@@ -396,22 +395,22 @@ namespace Test {
" baz\n" " baz\n"
"\""; "\"";
const char *ex6_9 = const char *ex6_9 =
"key: # Comment\n" "key: # Comment\n"
" value"; " value";
const char *ex6_10 = const char *ex6_10 =
" # Comment\n" " # Comment\n"
" \n" " \n"
"\n"; "\n";
const char *ex6_11 = const char *ex6_11 =
"key: # Comment\n" "key: # Comment\n"
" # lines\n" " # lines\n"
" value\n" " value\n"
"\n"; "\n";
const char *ex6_12 = const char *ex6_12 =
"{ first: Sammy, last: Sosa }:\n" "{ first: Sammy, last: Sosa }:\n"
"# Statistics:\n" "# Statistics:\n"
" hr: # Home runs\n" " hr: # Home runs\n"
@@ -419,33 +418,33 @@ namespace Test {
" avg: # Average\n" " avg: # Average\n"
" 0.278"; " 0.278";
const char *ex6_13 = const char *ex6_13 =
"%FOO bar baz # Should be ignored\n" "%FOO bar baz # Should be ignored\n"
" # with a warning.\n" " # with a warning.\n"
"--- \"foo\""; "--- \"foo\"";
const char *ex6_14 = const char *ex6_14 =
"%YAML 1.3 # Attempt parsing\n" "%YAML 1.3 # Attempt parsing\n"
" # with a warning\n" " # with a warning\n"
"---\n" "---\n"
"\"foo\""; "\"foo\"";
const char *ex6_15 = const char *ex6_15 =
"%YAML 1.2\n" "%YAML 1.2\n"
"%YAML 1.1\n" "%YAML 1.1\n"
"foo"; "foo";
const char *ex6_16 = const char *ex6_16 =
"%TAG !yaml! tag:yaml.org,2002:\n" "%TAG !yaml! tag:yaml.org,2002:\n"
"---\n" "---\n"
"!yaml!str \"foo\""; "!yaml!str \"foo\"";
const char *ex6_17 = const char *ex6_17 =
"%TAG ! !foo\n" "%TAG ! !foo\n"
"%TAG ! !foo\n" "%TAG ! !foo\n"
"bar"; "bar";
const char *ex6_18 = const char *ex6_18 =
"# Private\n" "# Private\n"
"!foo \"bar\"\n" "!foo \"bar\"\n"
"...\n" "...\n"
@@ -454,17 +453,17 @@ namespace Test {
"---\n" "---\n"
"!foo \"bar\""; "!foo \"bar\"";
const char *ex6_19 = const char *ex6_19 =
"%TAG !! tag:example.com,2000:app/\n" "%TAG !! tag:example.com,2000:app/\n"
"---\n" "---\n"
"!!int 1 - 3 # Interval, not integer"; "!!int 1 - 3 # Interval, not integer";
const char *ex6_20 = const char *ex6_20 =
"%TAG !e! tag:example.com,2000:app/\n" "%TAG !e! tag:example.com,2000:app/\n"
"---\n" "---\n"
"!e!foo \"bar\""; "!e!foo \"bar\"";
const char *ex6_21 = const char *ex6_21 =
"%TAG !m! !my-\n" "%TAG !m! !my-\n"
"--- # Bulb here\n" "--- # Bulb here\n"
"!m!light fluorescent\n" "!m!light fluorescent\n"
@@ -473,102 +472,101 @@ namespace Test {
"--- # Color here\n" "--- # Color here\n"
"!m!light green"; "!m!light green";
const char *ex6_22 = const char *ex6_22 =
"%TAG !e! tag:example.com,2000:app/\n" "%TAG !e! tag:example.com,2000:app/\n"
"---\n" "---\n"
"- !e!foo \"bar\""; "- !e!foo \"bar\"";
const char *ex6_23 = const char *ex6_23 =
"!!str &a1 \"foo\":\n" "!!str &a1 \"foo\":\n"
" !!str bar\n" " !!str bar\n"
"&a2 baz : *a1"; "&a2 baz : *a1";
const char *ex6_24 = const char *ex6_24 =
"!<tag:yaml.org,2002:str> foo :\n" "!<tag:yaml.org,2002:str> foo :\n"
" !<!bar> baz"; " !<!bar> baz";
const char *ex6_25 = const char *ex6_25 =
"- !<!> foo\n" "- !<!> foo\n"
"- !<$:?> bar\n"; "- !<$:?> bar\n";
const char *ex6_26 = const char *ex6_26 =
"%TAG !e! tag:example.com,2000:app/\n" "%TAG !e! tag:example.com,2000:app/\n"
"---\n" "---\n"
"- !local foo\n" "- !local foo\n"
"- !!str bar\n" "- !!str bar\n"
"- !e!tag%21 baz\n"; "- !e!tag%21 baz\n";
const char *ex6_27a = const char *ex6_27a =
"%TAG !e! tag:example,2000:app/\n" "%TAG !e! tag:example,2000:app/\n"
"---\n" "---\n"
"- !e! foo"; "- !e! foo";
const char *ex6_27b = const char *ex6_27b =
"%TAG !e! tag:example,2000:app/\n" "%TAG !e! tag:example,2000:app/\n"
"---\n" "---\n"
"- !h!bar baz"; "- !h!bar baz";
const char *ex6_28 = const char *ex6_28 =
"# Assuming conventional resolution:\n" "# Assuming conventional resolution:\n"
"- \"12\"\n" "- \"12\"\n"
"- 12\n" "- 12\n"
"- ! 12"; "- ! 12";
const char *ex6_29 = const char *ex6_29 =
"First occurrence: &anchor Value\n" "First occurrence: &anchor Value\n"
"Second occurrence: *anchor"; "Second occurrence: *anchor";
const char *ex7_1 = const char *ex7_1 =
"First occurrence: &anchor Foo\n" "First occurrence: &anchor Foo\n"
"Second occurrence: *anchor\n" "Second occurrence: *anchor\n"
"Override anchor: &anchor Bar\n" "Override anchor: &anchor Bar\n"
"Reuse anchor: *anchor"; "Reuse anchor: *anchor";
const char *ex7_2 = const char *ex7_2 =
"{\n" "{\n"
" foo : !!str,\n" " foo : !!str,\n"
" !!str : bar,\n" " !!str : bar,\n"
"}"; "}";
const char *ex7_3 = const char *ex7_3 =
"{\n" "{\n"
" ? foo :,\n" " ? foo :,\n"
" : bar,\n" " : bar,\n"
"}\n"; "}\n";
const char *ex7_4 = const char *ex7_4 =
"\"implicit block key\" : [\n" "\"implicit block key\" : [\n"
" \"implicit flow key\" : value,\n" " \"implicit flow key\" : value,\n"
" ]"; " ]";
const char *ex7_5 = const char *ex7_5 =
"\"folded \n" "\"folded \n"
"to a space,\t\n" "to a space,\t\n"
" \n" " \n"
"to a line feed, or \t\\\n" "to a line feed, or \t\\\n"
" \\ \tnon-content\""; " \\ \tnon-content\"";
const char *ex7_6 = const char *ex7_6 =
"\" 1st non-empty\n" "\" 1st non-empty\n"
"\n" "\n"
" 2nd non-empty \n" " 2nd non-empty \n"
"\t3rd non-empty \""; "\t3rd non-empty \"";
const char *ex7_7 = const char *ex7_7 = " 'here''s to \"quotes\"'";
" 'here''s to \"quotes\"'";
const char *ex7_8 = const char *ex7_8 =
"'implicit block key' : [\n" "'implicit block key' : [\n"
" 'implicit flow key' : value,\n" " 'implicit flow key' : value,\n"
" ]"; " ]";
const char *ex7_9 = const char *ex7_9 =
"' 1st non-empty\n" "' 1st non-empty\n"
"\n" "\n"
" 2nd non-empty \n" " 2nd non-empty \n"
"\t3rd non-empty '"; "\t3rd non-empty '";
const char *ex7_10 = const char *ex7_10 =
"# Outside flow collection:\n" "# Outside flow collection:\n"
"- ::vector\n" "- ::vector\n"
"- \": - ()\"\n" "- \": - ()\"\n"
@@ -582,22 +580,22 @@ namespace Test {
" -123,\n" " -123,\n"
" http://example.com/foo#bar ]"; " http://example.com/foo#bar ]";
const char *ex7_11 = const char *ex7_11 =
"implicit block key : [\n" "implicit block key : [\n"
" implicit flow key : value,\n" " implicit flow key : value,\n"
" ]"; " ]";
const char *ex7_12 = const char *ex7_12 =
"1st non-empty\n" "1st non-empty\n"
"\n" "\n"
" 2nd non-empty \n" " 2nd non-empty \n"
"\t3rd non-empty"; "\t3rd non-empty";
const char *ex7_13 = const char *ex7_13 =
"- [ one, two, ]\n" "- [ one, two, ]\n"
"- [three ,four]"; "- [three ,four]";
const char *ex7_14 = const char *ex7_14 =
"[\n" "[\n"
"\"double\n" "\"double\n"
" quoted\", 'single\n" " quoted\", 'single\n"
@@ -607,18 +605,18 @@ namespace Test {
"single: pair,\n" "single: pair,\n"
"]"; "]";
const char *ex7_15 = const char *ex7_15 =
"- { one : two , three: four , }\n" "- { one : two , three: four , }\n"
"- {five: six,seven : eight}"; "- {five: six,seven : eight}";
const char *ex7_16 = const char *ex7_16 =
"{\n" "{\n"
"? explicit: entry,\n" "? explicit: entry,\n"
"implicit: entry,\n" "implicit: entry,\n"
"?\n" "?\n"
"}"; "}";
const char *ex7_17 = const char *ex7_17 =
"{\n" "{\n"
"unquoted : \"separate\",\n" "unquoted : \"separate\",\n"
"http://foo.com,\n" "http://foo.com,\n"
@@ -626,48 +624,49 @@ namespace Test {
": omitted key,\n" ": omitted key,\n"
"}"; "}";
const char *ex7_18 = const char *ex7_18 =
"{\n" "{\n"
"\"adjacent\":value,\n" "\"adjacent\":value,\n"
"\"readable\":value,\n" "\"readable\":value,\n"
"\"empty\":\n" "\"empty\":\n"
"}"; "}";
const char *ex7_19 = const char *ex7_19 =
"[\n" "[\n"
"foo: bar\n" "foo: bar\n"
"]"; "]";
const char *ex7_20 = const char *ex7_20 =
"[\n" "[\n"
"? foo\n" "? foo\n"
" bar : baz\n" " bar : baz\n"
"]"; "]";
const char *ex7_21 = const char *ex7_21 =
"- [ YAML : separate ]\n" "- [ YAML : separate ]\n"
"- [ : empty key entry ]\n" "- [ : empty key entry ]\n"
"- [ {JSON: like}:adjacent ]"; "- [ {JSON: like}:adjacent ]";
const char *ex7_22 = const char *ex7_22 =
"[ foo\n" "[ foo\n"
" bar: invalid,"; // Note: we don't check (on purpose) the >1K chars for an implicit key " bar: invalid,"; // Note: we don't check (on purpose) the >1K chars for an
// implicit key
const char *ex7_23 = const char *ex7_23 =
"- [ a, b ]\n" "- [ a, b ]\n"
"- { a: b }\n" "- { a: b }\n"
"- \"a\"\n" "- \"a\"\n"
"- 'b'\n" "- 'b'\n"
"- c"; "- c";
const char *ex7_24 = const char *ex7_24 =
"- !!str \"a\"\n" "- !!str \"a\"\n"
"- 'b'\n" "- 'b'\n"
"- &anchor \"c\"\n" "- &anchor \"c\"\n"
"- *anchor\n" "- *anchor\n"
"- !!str"; "- !!str";
const char *ex8_1 = const char *ex8_1 =
"- | # Empty header\n" "- | # Empty header\n"
" literal\n" " literal\n"
"- >1 # Indentation indicator\n" "- >1 # Indentation indicator\n"
@@ -678,7 +677,7 @@ namespace Test {
"- >1- # Both indicators\n" "- >1- # Both indicators\n"
" strip\n"; " strip\n";
const char *ex8_2 = const char *ex8_2 =
"- |\n" "- |\n"
" detected\n" " detected\n"
"- >\n" "- >\n"
@@ -691,21 +690,21 @@ namespace Test {
" \t\n" " \t\n"
" detected\n"; " detected\n";
const char *ex8_3a = const char *ex8_3a =
"- |\n" "- |\n"
" \n" " \n"
" text"; " text";
const char *ex8_3b = const char *ex8_3b =
"- >\n" "- >\n"
" text\n" " text\n"
" text"; " text";
const char *ex8_3c = const char *ex8_3c =
"- |2\n" "- |2\n"
" text"; " text";
const char *ex8_4 = const char *ex8_4 =
"strip: |-\n" "strip: |-\n"
" text\n" " text\n"
"clip: |\n" "clip: |\n"
@@ -713,7 +712,7 @@ namespace Test {
"keep: |+\n" "keep: |+\n"
" text\n"; " text\n";
const char *ex8_5 = const char *ex8_5 =
" # Strip\n" " # Strip\n"
" # Comments:\n" " # Comments:\n"
"strip: |-\n" "strip: |-\n"
@@ -734,7 +733,7 @@ namespace Test {
" # Trail\n" " # Trail\n"
" # Comments\n"; " # Comments\n";
const char *ex8_6 = const char *ex8_6 =
"strip: >-\n" "strip: >-\n"
"\n" "\n"
"clip: >\n" "clip: >\n"
@@ -742,13 +741,13 @@ namespace Test {
"keep: |+\n" "keep: |+\n"
"\n"; "\n";
const char *ex8_7 = const char *ex8_7 =
"|\n" "|\n"
" literal\n" " literal\n"
" \ttext\n" " \ttext\n"
"\n"; "\n";
const char *ex8_8 = const char *ex8_8 =
"|\n" "|\n"
" \n" " \n"
" \n" " \n"
@@ -759,13 +758,13 @@ namespace Test {
"\n" "\n"
" # Comment\n"; " # Comment\n";
const char *ex8_9 = const char *ex8_9 =
">\n" ">\n"
" folded\n" " folded\n"
" text\n" " text\n"
"\n"; "\n";
const char *ex8_10 = const char *ex8_10 =
">\n" ">\n"
"\n" "\n"
" folded\n" " folded\n"
@@ -783,16 +782,16 @@ namespace Test {
"\n" "\n"
"# Comment\n"; "# Comment\n";
const char *ex8_11 = ex8_10; const char *ex8_11 = ex8_10;
const char *ex8_12 = ex8_10; const char *ex8_12 = ex8_10;
const char *ex8_13 = ex8_10; const char *ex8_13 = ex8_10;
const char *ex8_14 = const char *ex8_14 =
"block sequence:\n" "block sequence:\n"
" - one\n" " - one\n"
" - two : three\n"; " - two : three\n";
const char *ex8_15 = const char *ex8_15 =
"- # Empty\n" "- # Empty\n"
"- |\n" "- |\n"
" block node\n" " block node\n"
@@ -800,29 +799,29 @@ namespace Test {
" - two # sequence\n" " - two # sequence\n"
"- one: two # Compact mapping\n"; "- one: two # Compact mapping\n";
const char *ex8_16 = const char *ex8_16 =
"block mapping:\n" "block mapping:\n"
" key: value\n"; " key: value\n";
const char *ex8_17 = const char *ex8_17 =
"? explicit key # Empty value\n" "? explicit key # Empty value\n"
"? |\n" "? |\n"
" block key\n" " block key\n"
": - one # Explicit compact\n" ": - one # Explicit compact\n"
" - two # block value\n"; " - two # block value\n";
const char *ex8_18 = const char *ex8_18 =
"plain key: in-line value\n" "plain key: in-line value\n"
": # Both empty\n" ": # Both empty\n"
"\"quoted key\":\n" "\"quoted key\":\n"
"- entry\n"; "- entry\n";
const char *ex8_19 = const char *ex8_19 =
"- sun: yellow\n" "- sun: yellow\n"
"- ? earth: blue\n" "- ? earth: blue\n"
" : moon: white\n"; " : moon: white\n";
const char *ex8_20 = const char *ex8_20 =
"-\n" "-\n"
" \"flow in block\"\n" " \"flow in block\"\n"
"- >\n" "- >\n"
@@ -830,7 +829,7 @@ namespace Test {
"- !!map # Block collection\n" "- !!map # Block collection\n"
" foo : bar\n"; " foo : bar\n";
const char *ex8_21 = const char *ex8_21 =
"literal: |2\n" "literal: |2\n"
" value\n" " value\n"
"folded:\n" "folded:\n"
@@ -838,13 +837,12 @@ namespace Test {
" >1\n" " >1\n"
" value\n"; " value\n";
const char *ex8_22 = const char *ex8_22 =
"sequence: !!seq\n" "sequence: !!seq\n"
"- entry\n" "- entry\n"
"- !!seq\n" "- !!seq\n"
" - nested\n" " - nested\n"
"mapping: !!map\n" "mapping: !!map\n"
" foo: bar\n"; " foo: bar\n";
}
} }
}

View File

@@ -2,148 +2,223 @@
#include "yaml-cpp/yaml.h" #include "yaml-cpp/yaml.h"
#include <iostream> #include <iostream>
namespace Test namespace Test {
{ namespace {
namespace { void RunSpecTest(TEST (*test)(), const std::string& index,
void RunSpecTest(TEST (*test)(), const std::string& index, const std::string& name, int& passed, int& total) { const std::string& name, int& passed, int& total) {
TEST ret; TEST ret;
try { try {
ret = test(); ret = test();
} catch(const YAML::Exception& e) { }
catch (const YAML::Exception& e) {
ret.ok = false; ret.ok = false;
ret.error = std::string(" Exception caught: ") + e.what(); ret.error = std::string(" Exception caught: ") + e.what();
} }
if(!ret.ok) { if (!ret.ok) {
std::cout << "Spec test " << index << " failed: " << name << "\n"; std::cout << "Spec test " << index << " failed: " << name << "\n";
std::cout << ret.error << "\n"; std::cout << ret.error << "\n";
} }
if(ret.ok) if (ret.ok)
passed++; passed++;
total++; total++;
} }
} }
bool RunSpecTests() bool RunSpecTests() {
{
int passed = 0; int passed = 0;
int total = 0; int total = 0;
RunSpecTest(&Spec::SeqScalars, "2.1", "Sequence of Scalars", passed, total); RunSpecTest(&Spec::SeqScalars, "2.1", "Sequence of Scalars", passed, total);
RunSpecTest(&Spec::MappingScalarsToScalars, "2.2", "Mapping Scalars to Scalars", passed, total); RunSpecTest(&Spec::MappingScalarsToScalars, "2.2",
RunSpecTest(&Spec::MappingScalarsToSequences, "2.3", "Mapping Scalars to Sequences", passed, total); "Mapping Scalars to Scalars", passed, total);
RunSpecTest(&Spec::SequenceOfMappings, "2.4", "Sequence of Mappings", passed, total); RunSpecTest(&Spec::MappingScalarsToSequences, "2.3",
RunSpecTest(&Spec::SequenceOfSequences, "2.5", "Sequence of Sequences", passed, total); "Mapping Scalars to Sequences", passed, total);
RunSpecTest(&Spec::MappingOfMappings, "2.6", "Mapping of Mappings", passed, total); RunSpecTest(&Spec::SequenceOfMappings, "2.4", "Sequence of Mappings", passed,
RunSpecTest(&Spec::TwoDocumentsInAStream, "2.7", "Two Documents in a Stream", passed, total); total);
RunSpecTest(&Spec::PlayByPlayFeed, "2.8", "Play by Play Feed from a Game", passed, total); RunSpecTest(&Spec::SequenceOfSequences, "2.5", "Sequence of Sequences",
RunSpecTest(&Spec::SingleDocumentWithTwoComments, "2.9", "Single Document with Two Comments", passed, total); passed, total);
RunSpecTest(&Spec::SimpleAnchor, "2.10", "Node for \"Sammy Sosa\" appears twice in this document", passed, total); RunSpecTest(&Spec::MappingOfMappings, "2.6", "Mapping of Mappings", passed,
RunSpecTest(&Spec::MappingBetweenSequences, "2.11", "Mapping between Sequences", passed, total); total);
RunSpecTest(&Spec::CompactNestedMapping, "2.12", "Compact Nested Mapping", passed, total); RunSpecTest(&Spec::TwoDocumentsInAStream, "2.7", "Two Documents in a Stream",
RunSpecTest(&Spec::InLiteralsNewlinesArePreserved, "2.13", "In literals, newlines are preserved", passed, total); passed, total);
RunSpecTest(&Spec::InFoldedScalarsNewlinesBecomeSpaces, "2.14", "In folded scalars, newlines become spaces", passed, total); RunSpecTest(&Spec::PlayByPlayFeed, "2.8", "Play by Play Feed from a Game",
RunSpecTest(&Spec::FoldedNewlinesArePreservedForMoreIndentedAndBlankLines, "2.15", "Folded newlines are preserved for \"more indented\" and blank lines", passed, total); passed, total);
RunSpecTest(&Spec::IndentationDeterminesScope, "2.16", "Indentation determines scope", passed, total); RunSpecTest(&Spec::SingleDocumentWithTwoComments, "2.9",
"Single Document with Two Comments", passed, total);
RunSpecTest(&Spec::SimpleAnchor, "2.10",
"Node for \"Sammy Sosa\" appears twice in this document", passed,
total);
RunSpecTest(&Spec::MappingBetweenSequences, "2.11",
"Mapping between Sequences", passed, total);
RunSpecTest(&Spec::CompactNestedMapping, "2.12", "Compact Nested Mapping",
passed, total);
RunSpecTest(&Spec::InLiteralsNewlinesArePreserved, "2.13",
"In literals, newlines are preserved", passed, total);
RunSpecTest(&Spec::InFoldedScalarsNewlinesBecomeSpaces, "2.14",
"In folded scalars, newlines become spaces", passed, total);
RunSpecTest(
&Spec::FoldedNewlinesArePreservedForMoreIndentedAndBlankLines, "2.15",
"Folded newlines are preserved for \"more indented\" and blank lines",
passed, total);
RunSpecTest(&Spec::IndentationDeterminesScope, "2.16",
"Indentation determines scope", passed, total);
RunSpecTest(&Spec::QuotedScalars, "2.17", "Quoted scalars", passed, total); RunSpecTest(&Spec::QuotedScalars, "2.17", "Quoted scalars", passed, total);
RunSpecTest(&Spec::MultiLineFlowScalars, "2.18", "Multi-line flow 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::VariousExplicitTags, "2.23", "Various Explicit Tags",
passed, total);
RunSpecTest(&Spec::GlobalTags, "2.24", "Global Tags", passed, total); RunSpecTest(&Spec::GlobalTags, "2.24", "Global Tags", passed, total);
RunSpecTest(&Spec::UnorderedSets, "2.25", "Unordered Sets", passed, total); RunSpecTest(&Spec::UnorderedSets, "2.25", "Unordered Sets", passed, total);
RunSpecTest(&Spec::OrderedMappings, "2.26", "Ordered Mappings", passed, total); RunSpecTest(&Spec::OrderedMappings, "2.26", "Ordered Mappings", passed,
total);
RunSpecTest(&Spec::Invoice, "2.27", "Invoice", passed, total); RunSpecTest(&Spec::Invoice, "2.27", "Invoice", passed, total);
RunSpecTest(&Spec::LogFile, "2.28", "Log File", passed, total); RunSpecTest(&Spec::LogFile, "2.28", "Log File", passed, total);
RunSpecTest(&Spec::BlockStructureIndicators, "5.3", "Block Structure Indicators", passed, total); RunSpecTest(&Spec::BlockStructureIndicators, "5.3",
RunSpecTest(&Spec::FlowStructureIndicators, "5.4", "Flow Structure Indicators", passed, total); "Block Structure Indicators", passed, total);
RunSpecTest(&Spec::NodePropertyIndicators, "5.6", "Node Property Indicators", passed, total); RunSpecTest(&Spec::FlowStructureIndicators, "5.4",
RunSpecTest(&Spec::BlockScalarIndicators, "5.7", "Block Scalar Indicators", passed, total); "Flow Structure Indicators", passed, total);
RunSpecTest(&Spec::QuotedScalarIndicators, "5.8", "Quoted Scalar Indicators", passed, total); RunSpecTest(&Spec::NodePropertyIndicators, "5.6", "Node Property Indicators",
RunSpecTest(&Spec::LineBreakCharacters, "5.11", "Line Break Characters", passed, total); passed, total);
RunSpecTest(&Spec::BlockScalarIndicators, "5.7", "Block Scalar Indicators",
passed, total);
RunSpecTest(&Spec::QuotedScalarIndicators, "5.8", "Quoted Scalar Indicators",
passed, total);
RunSpecTest(&Spec::LineBreakCharacters, "5.11", "Line Break Characters",
passed, total);
RunSpecTest(&Spec::TabsAndSpaces, "5.12", "Tabs and Spaces", passed, total); RunSpecTest(&Spec::TabsAndSpaces, "5.12", "Tabs and Spaces", passed, total);
RunSpecTest(&Spec::EscapedCharacters, "5.13", "Escaped Characters", passed, total); RunSpecTest(&Spec::EscapedCharacters, "5.13", "Escaped Characters", passed,
RunSpecTest(&Spec::InvalidEscapedCharacters, "5.14", "Invalid Escaped Characters", passed, total); total);
RunSpecTest(&Spec::InvalidEscapedCharacters, "5.14",
"Invalid Escaped Characters", passed, total);
RunSpecTest(&Spec::IndentationSpaces, "6.1", "Indentation Spaces", passed, total); RunSpecTest(&Spec::IndentationSpaces, "6.1", "Indentation Spaces", passed,
RunSpecTest(&Spec::IndentationIndicators, "6.2", "Indentation Indicators", passed, total); total);
RunSpecTest(&Spec::SeparationSpaces, "6.3", "Separation Spaces", passed, total); RunSpecTest(&Spec::IndentationIndicators, "6.2", "Indentation Indicators",
passed, total);
RunSpecTest(&Spec::SeparationSpaces, "6.3", "Separation Spaces", passed,
total);
RunSpecTest(&Spec::LinePrefixes, "6.4", "Line Prefixes", passed, total); RunSpecTest(&Spec::LinePrefixes, "6.4", "Line Prefixes", passed, total);
RunSpecTest(&Spec::EmptyLines, "6.5", "Empty Lines", passed, total); RunSpecTest(&Spec::EmptyLines, "6.5", "Empty Lines", passed, total);
RunSpecTest(&Spec::LineFolding, "6.6", "Line Folding", passed, total); RunSpecTest(&Spec::LineFolding, "6.6", "Line Folding", passed, total);
RunSpecTest(&Spec::BlockFolding, "6.7", "Block Folding", passed, total); RunSpecTest(&Spec::BlockFolding, "6.7", "Block Folding", passed, total);
RunSpecTest(&Spec::FlowFolding, "6.8", "Flow Folding", passed, total); RunSpecTest(&Spec::FlowFolding, "6.8", "Flow Folding", passed, total);
RunSpecTest(&Spec::SeparatedComment, "6.9", "Separated Comment", passed, total); RunSpecTest(&Spec::SeparatedComment, "6.9", "Separated Comment", passed,
total);
RunSpecTest(&Spec::CommentLines, "6.10", "Comment Lines", passed, total); RunSpecTest(&Spec::CommentLines, "6.10", "Comment Lines", passed, total);
RunSpecTest(&Spec::MultiLineComments, "6.11", "Multi-Line Comments", passed, total); RunSpecTest(&Spec::MultiLineComments, "6.11", "Multi-Line Comments", passed,
RunSpecTest(&Spec::SeparationSpacesII, "6.12", "Separation Spaces", passed, total); total);
RunSpecTest(&Spec::ReservedDirectives, "6.13", "Reserved Directives", 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::YAMLDirective, "6.14", "YAML Directive", passed, total);
RunSpecTest(&Spec::InvalidRepeatedYAMLDirective, "6.15", "Invalid Repeated 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::TagDirective, "6.16", "Tag Directive", passed, total);
RunSpecTest(&Spec::InvalidRepeatedTagDirective, "6.17", "Invalid Repeated Tag Directive", passed, total); RunSpecTest(&Spec::InvalidRepeatedTagDirective, "6.17",
RunSpecTest(&Spec::PrimaryTagHandle, "6.18", "Primary Tag Handle", passed, total); "Invalid Repeated Tag Directive", passed, total);
RunSpecTest(&Spec::SecondaryTagHandle, "6.19", "SecondaryTagHandle", 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::TagHandles, "6.20", "TagHandles", passed, total);
RunSpecTest(&Spec::LocalTagPrefix, "6.21", "LocalTagPrefix", passed, total); RunSpecTest(&Spec::LocalTagPrefix, "6.21", "LocalTagPrefix", passed, total);
RunSpecTest(&Spec::GlobalTagPrefix, "6.22", "GlobalTagPrefix", passed, total); RunSpecTest(&Spec::GlobalTagPrefix, "6.22", "GlobalTagPrefix", passed, total);
RunSpecTest(&Spec::NodeProperties, "6.23", "NodeProperties", passed, total); RunSpecTest(&Spec::NodeProperties, "6.23", "NodeProperties", passed, total);
RunSpecTest(&Spec::VerbatimTags, "6.24", "Verbatim Tags", passed, total); RunSpecTest(&Spec::VerbatimTags, "6.24", "Verbatim Tags", passed, total);
RunSpecTest(&Spec::InvalidVerbatimTags, "6.25", "Invalid 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::TagShorthands, "6.26", "Tag Shorthands", passed, total);
RunSpecTest(&Spec::InvalidTagShorthands, "6.27", "Invalid Tag Shorthands", passed, total); RunSpecTest(&Spec::InvalidTagShorthands, "6.27", "Invalid Tag Shorthands",
RunSpecTest(&Spec::NonSpecificTags, "6.28", "Non Specific Tags", passed, total); passed, total);
RunSpecTest(&Spec::NonSpecificTags, "6.28", "Non Specific Tags", passed,
total);
RunSpecTest(&Spec::NodeAnchors, "6.29", "Node Anchors", passed, total); RunSpecTest(&Spec::NodeAnchors, "6.29", "Node Anchors", passed, total);
RunSpecTest(&Spec::AliasNodes, "7.1", "Alias Nodes", passed, total); RunSpecTest(&Spec::AliasNodes, "7.1", "Alias Nodes", passed, total);
RunSpecTest(&Spec::EmptyNodes, "7.2", "Empty Nodes", passed, total); RunSpecTest(&Spec::EmptyNodes, "7.2", "Empty Nodes", passed, total);
RunSpecTest(&Spec::CompletelyEmptyNodes, "7.3", "Completely Empty Nodes", passed, total); RunSpecTest(&Spec::CompletelyEmptyNodes, "7.3", "Completely Empty Nodes",
RunSpecTest(&Spec::DoubleQuotedImplicitKeys, "7.4", "Double Quoted Implicit Keys", passed, total); passed, total);
RunSpecTest(&Spec::DoubleQuotedLineBreaks, "7.5", "Double Quoted Line Breaks", passed, total); RunSpecTest(&Spec::DoubleQuotedImplicitKeys, "7.4",
RunSpecTest(&Spec::DoubleQuotedLines, "7.6", "Double Quoted Lines", passed, total); "Double Quoted Implicit Keys", passed, total);
RunSpecTest(&Spec::SingleQuotedCharacters, "7.7", "Single Quoted Characters", passed, total); RunSpecTest(&Spec::DoubleQuotedLineBreaks, "7.5", "Double Quoted Line Breaks",
RunSpecTest(&Spec::SingleQuotedImplicitKeys, "7.8", "Single Quoted Implicit Keys", passed, total); passed, total);
RunSpecTest(&Spec::SingleQuotedLines, "7.9", "Single Quoted Lines", passed, total); RunSpecTest(&Spec::DoubleQuotedLines, "7.6", "Double Quoted Lines", passed,
RunSpecTest(&Spec::PlainCharacters, "7.10", "Plain Characters", passed, total); total);
RunSpecTest(&Spec::PlainImplicitKeys, "7.11", "Plain Implicit Keys", passed, total); RunSpecTest(&Spec::SingleQuotedCharacters, "7.7", "Single Quoted Characters",
passed, total);
RunSpecTest(&Spec::SingleQuotedImplicitKeys, "7.8",
"Single Quoted Implicit Keys", passed, total);
RunSpecTest(&Spec::SingleQuotedLines, "7.9", "Single Quoted Lines", passed,
total);
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::PlainLines, "7.12", "Plain Lines", passed, total);
RunSpecTest(&Spec::FlowSequence, "7.13", "Flow Sequence", passed, total); RunSpecTest(&Spec::FlowSequence, "7.13", "Flow Sequence", passed, total);
RunSpecTest(&Spec::FlowSequenceEntries, "7.14", "Flow Sequence Entries", passed, total); RunSpecTest(&Spec::FlowSequenceEntries, "7.14", "Flow Sequence Entries",
passed, total);
RunSpecTest(&Spec::FlowMappings, "7.15", "Flow Mappings", passed, total); RunSpecTest(&Spec::FlowMappings, "7.15", "Flow Mappings", passed, total);
RunSpecTest(&Spec::FlowMappingEntries, "7.16", "Flow Mapping Entries", passed, total); RunSpecTest(&Spec::FlowMappingEntries, "7.16", "Flow Mapping Entries", passed,
RunSpecTest(&Spec::FlowMappingSeparateValues, "7.17", "Flow Mapping Separate Values", passed, total); total);
RunSpecTest(&Spec::FlowMappingAdjacentValues, "7.18", "Flow Mapping Adjacent Values", passed, total); RunSpecTest(&Spec::FlowMappingSeparateValues, "7.17",
RunSpecTest(&Spec::SinglePairFlowMappings, "7.19", "Single Pair Flow Mappings", passed, total); "Flow Mapping Separate Values", passed, total);
RunSpecTest(&Spec::SinglePairExplicitEntry, "7.20", "Single Pair Explicit Entry", passed, total); RunSpecTest(&Spec::FlowMappingAdjacentValues, "7.18",
RunSpecTest(&Spec::SinglePairImplicitEntries, "7.21", "Single Pair Implicit Entries", passed, total); "Flow Mapping Adjacent Values", passed, total);
RunSpecTest(&Spec::InvalidImplicitKeys, "7.22", "Invalid Implicit Keys", 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::FlowContent, "7.23", "Flow Content", passed, total);
RunSpecTest(&Spec::FlowNodes, "7.24", "FlowNodes", passed, total); RunSpecTest(&Spec::FlowNodes, "7.24", "FlowNodes", passed, total);
RunSpecTest(&Spec::BlockScalarHeader, "8.1", "Block Scalar Header", passed, total); RunSpecTest(&Spec::BlockScalarHeader, "8.1", "Block Scalar Header", passed,
RunSpecTest(&Spec::BlockIndentationHeader, "8.2", "Block Indentation Header", passed, total); total);
RunSpecTest(&Spec::InvalidBlockScalarIndentationIndicators, "8.3", "Invalid Block Scalar Indentation Indicators", passed, total); RunSpecTest(&Spec::BlockIndentationHeader, "8.2", "Block Indentation Header",
RunSpecTest(&Spec::ChompingFinalLineBreak, "8.4", "Chomping Final Line Break", passed, total); passed, total);
RunSpecTest(&Spec::ChompingTrailingLines, "8.5", "Chomping Trailing Lines", passed, total); RunSpecTest(&Spec::InvalidBlockScalarIndentationIndicators, "8.3",
RunSpecTest(&Spec::EmptyScalarChomping, "8.6", "Empty Scalar Chomping", passed, total); "Invalid Block Scalar Indentation Indicators", passed, total);
RunSpecTest(&Spec::ChompingFinalLineBreak, "8.4", "Chomping Final Line Break",
passed, total);
RunSpecTest(&Spec::ChompingTrailingLines, "8.5", "Chomping Trailing Lines",
passed, total);
RunSpecTest(&Spec::EmptyScalarChomping, "8.6", "Empty Scalar Chomping",
passed, total);
RunSpecTest(&Spec::LiteralScalar, "8.7", "Literal Scalar", passed, total); RunSpecTest(&Spec::LiteralScalar, "8.7", "Literal Scalar", passed, total);
RunSpecTest(&Spec::LiteralContent, "8.8", "Literal Content", passed, total); RunSpecTest(&Spec::LiteralContent, "8.8", "Literal Content", passed, total);
RunSpecTest(&Spec::FoldedScalar, "8.9", "Folded Scalar", passed, total); RunSpecTest(&Spec::FoldedScalar, "8.9", "Folded Scalar", passed, total);
RunSpecTest(&Spec::FoldedLines, "8.10", "Folded Lines", passed, total); RunSpecTest(&Spec::FoldedLines, "8.10", "Folded Lines", passed, total);
RunSpecTest(&Spec::MoreIndentedLines, "8.11", "More Indented Lines", passed, total); RunSpecTest(&Spec::MoreIndentedLines, "8.11", "More Indented Lines", passed,
RunSpecTest(&Spec::EmptySeparationLines, "8.12", "Empty Separation Lines", passed, total); total);
RunSpecTest(&Spec::FinalEmptyLines, "8.13", "Final Empty Lines", passed, total); RunSpecTest(&Spec::EmptySeparationLines, "8.12", "Empty Separation Lines",
passed, total);
RunSpecTest(&Spec::FinalEmptyLines, "8.13", "Final Empty Lines", passed,
total);
RunSpecTest(&Spec::BlockSequence, "8.14", "Block Sequence", passed, total); RunSpecTest(&Spec::BlockSequence, "8.14", "Block Sequence", passed, total);
RunSpecTest(&Spec::BlockSequenceEntryTypes, "8.15", "Block Sequence Entry Types", passed, total); RunSpecTest(&Spec::BlockSequenceEntryTypes, "8.15",
"Block Sequence Entry Types", passed, total);
RunSpecTest(&Spec::BlockMappings, "8.16", "Block Mappings", passed, total); RunSpecTest(&Spec::BlockMappings, "8.16", "Block Mappings", passed, total);
RunSpecTest(&Spec::ExplicitBlockMappingEntries, "8.17", "Explicit Block Mapping Entries", passed, total); RunSpecTest(&Spec::ExplicitBlockMappingEntries, "8.17",
RunSpecTest(&Spec::ImplicitBlockMappingEntries, "8.18", "Implicit Block Mapping Entries", passed, total); "Explicit Block Mapping Entries", passed, total);
RunSpecTest(&Spec::CompactBlockMappings, "8.19", "Compact Block Mappings", passed, total); RunSpecTest(&Spec::ImplicitBlockMappingEntries, "8.18",
"Implicit Block Mapping Entries", passed, total);
RunSpecTest(&Spec::CompactBlockMappings, "8.19", "Compact Block Mappings",
passed, total);
RunSpecTest(&Spec::BlockNodeTypes, "8.20", "Block Node Types", passed, total); RunSpecTest(&Spec::BlockNodeTypes, "8.20", "Block Node Types", passed, total);
RunSpecTest(&Spec::BlockScalarNodes, "8.21", "Block Scalar Nodes", passed, total); RunSpecTest(&Spec::BlockScalarNodes, "8.21", "Block Scalar Nodes", passed,
RunSpecTest(&Spec::BlockCollectionNodes, "8.22", "Block Collection Nodes", passed, total); total);
RunSpecTest(&Spec::BlockCollectionNodes, "8.22", "Block Collection Nodes",
passed, total);
std::cout << "Spec tests: " << passed << "/" << total << " passed\n"; std::cout << "Spec tests: " << passed << "/" << total << " passed\n";
return passed == total; return passed == total;
} }
} }

View File

@@ -1,351 +1,352 @@
#ifndef SPECTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef SPECTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define SPECTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define SPECTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include "teststruct.h" #include "teststruct.h"
namespace Test { namespace Test {
namespace Spec { namespace Spec {
// 2.1 // 2.1
TEST SeqScalars(); TEST SeqScalars();
// 2.2 // 2.2
TEST MappingScalarsToScalars(); TEST MappingScalarsToScalars();
// 2.3 // 2.3
TEST MappingScalarsToSequences(); TEST MappingScalarsToSequences();
// 2.4 // 2.4
TEST SequenceOfMappings(); TEST SequenceOfMappings();
// 2.5 // 2.5
TEST SequenceOfSequences(); TEST SequenceOfSequences();
// 2.6 // 2.6
TEST MappingOfMappings(); TEST MappingOfMappings();
// 2.7 // 2.7
TEST TwoDocumentsInAStream(); TEST TwoDocumentsInAStream();
// 2.8 // 2.8
TEST PlayByPlayFeed(); TEST PlayByPlayFeed();
// 2.9 // 2.9
TEST SingleDocumentWithTwoComments(); TEST SingleDocumentWithTwoComments();
// 2.10 // 2.10
TEST SimpleAnchor(); TEST SimpleAnchor();
// 2.11 // 2.11
TEST MappingBetweenSequences(); TEST MappingBetweenSequences();
// 2.12 // 2.12
TEST CompactNestedMapping(); TEST CompactNestedMapping();
// 2.13 // 2.13
TEST InLiteralsNewlinesArePreserved(); TEST InLiteralsNewlinesArePreserved();
// 2.14 // 2.14
TEST InFoldedScalarsNewlinesBecomeSpaces(); TEST InFoldedScalarsNewlinesBecomeSpaces();
// 2.15 // 2.15
TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines(); TEST FoldedNewlinesArePreservedForMoreIndentedAndBlankLines();
// 2.16 // 2.16
TEST IndentationDeterminesScope(); TEST IndentationDeterminesScope();
// 2.17 // 2.17
TEST QuotedScalars(); TEST QuotedScalars();
// 2.18 // 2.18
TEST MultiLineFlowScalars(); TEST MultiLineFlowScalars();
// TODO: 2.19 - 2.22 schema tags // TODO: 2.19 - 2.22 schema tags
// 2.23 // 2.23
TEST VariousExplicitTags(); TEST VariousExplicitTags();
// 2.24 // 2.24
TEST GlobalTags(); TEST GlobalTags();
// 2.25 // 2.25
TEST UnorderedSets(); TEST UnorderedSets();
// 2.26 // 2.26
TEST OrderedMappings(); TEST OrderedMappings();
// 2.27 // 2.27
TEST Invoice(); TEST Invoice();
// 2.28 // 2.28
TEST LogFile(); TEST LogFile();
// TODO: 5.1 - 5.2 BOM // TODO: 5.1 - 5.2 BOM
// 5.3 // 5.3
TEST BlockStructureIndicators(); TEST BlockStructureIndicators();
// 5.4 // 5.4
TEST FlowStructureIndicators(); TEST FlowStructureIndicators();
// 5.5 // 5.5
TEST CommentIndicator(); TEST CommentIndicator();
// 5.6 // 5.6
TEST NodePropertyIndicators(); TEST NodePropertyIndicators();
// 5.7 // 5.7
TEST BlockScalarIndicators(); TEST BlockScalarIndicators();
// 5.8 // 5.8
TEST QuotedScalarIndicators(); TEST QuotedScalarIndicators();
// TODO: 5.9 directive // TODO: 5.9 directive
// TODO: 5.10 reserved indicator // TODO: 5.10 reserved indicator
// 5.11 // 5.11
TEST LineBreakCharacters(); TEST LineBreakCharacters();
// 5.12 // 5.12
TEST TabsAndSpaces(); TEST TabsAndSpaces();
// 5.13 // 5.13
TEST EscapedCharacters(); TEST EscapedCharacters();
// 5.14 // 5.14
TEST InvalidEscapedCharacters(); TEST InvalidEscapedCharacters();
// 6.1 // 6.1
TEST IndentationSpaces(); TEST IndentationSpaces();
// 6.2 // 6.2
TEST IndentationIndicators(); TEST IndentationIndicators();
// 6.3 // 6.3
TEST SeparationSpaces(); TEST SeparationSpaces();
// 6.4 // 6.4
TEST LinePrefixes(); TEST LinePrefixes();
// 6.5 // 6.5
TEST EmptyLines(); TEST EmptyLines();
// 6.6 // 6.6
TEST LineFolding(); TEST LineFolding();
// 6.7 // 6.7
TEST BlockFolding(); TEST BlockFolding();
// 6.8 // 6.8
TEST FlowFolding(); TEST FlowFolding();
// 6.9 // 6.9
TEST SeparatedComment(); TEST SeparatedComment();
// 6.10 // 6.10
TEST CommentLines(); TEST CommentLines();
// 6.11 // 6.11
TEST MultiLineComments(); TEST MultiLineComments();
// 6.12 // 6.12
TEST SeparationSpacesII(); TEST SeparationSpacesII();
// 6.13 // 6.13
TEST ReservedDirectives(); TEST ReservedDirectives();
// 6.14 // 6.14
TEST YAMLDirective(); TEST YAMLDirective();
// 6.15 // 6.15
TEST InvalidRepeatedYAMLDirective(); TEST InvalidRepeatedYAMLDirective();
// 6.16 // 6.16
TEST TagDirective(); TEST TagDirective();
// 6.17 // 6.17
TEST InvalidRepeatedTagDirective(); TEST InvalidRepeatedTagDirective();
// 6.18 // 6.18
TEST PrimaryTagHandle(); TEST PrimaryTagHandle();
// 6.19 // 6.19
TEST SecondaryTagHandle(); TEST SecondaryTagHandle();
// 6.20 // 6.20
TEST TagHandles(); TEST TagHandles();
// 6.21 // 6.21
TEST LocalTagPrefix(); TEST LocalTagPrefix();
// 6.22 // 6.22
TEST GlobalTagPrefix(); TEST GlobalTagPrefix();
// 6.23 // 6.23
TEST NodeProperties(); TEST NodeProperties();
// 6.24 // 6.24
TEST VerbatimTags(); TEST VerbatimTags();
// 6.25 // 6.25
TEST InvalidVerbatimTags(); TEST InvalidVerbatimTags();
// 6.26 // 6.26
TEST TagShorthands(); TEST TagShorthands();
// 6.27 // 6.27
TEST InvalidTagShorthands(); TEST InvalidTagShorthands();
// 6.28 // 6.28
TEST NonSpecificTags(); TEST NonSpecificTags();
// 6.29 // 6.29
TEST NodeAnchors(); TEST NodeAnchors();
// 7.1 // 7.1
TEST AliasNodes(); TEST AliasNodes();
// 7.2 // 7.2
TEST EmptyNodes(); TEST EmptyNodes();
// 7.3 // 7.3
TEST CompletelyEmptyNodes(); TEST CompletelyEmptyNodes();
// 7.4 // 7.4
TEST DoubleQuotedImplicitKeys(); TEST DoubleQuotedImplicitKeys();
// 7.5 // 7.5
TEST DoubleQuotedLineBreaks(); TEST DoubleQuotedLineBreaks();
// 7.6 // 7.6
TEST DoubleQuotedLines(); TEST DoubleQuotedLines();
// 7.7 // 7.7
TEST SingleQuotedCharacters(); TEST SingleQuotedCharacters();
// 7.8 // 7.8
TEST SingleQuotedImplicitKeys(); TEST SingleQuotedImplicitKeys();
// 7.9 // 7.9
TEST SingleQuotedLines(); TEST SingleQuotedLines();
// 7.10 // 7.10
TEST PlainCharacters(); TEST PlainCharacters();
// 7.11 // 7.11
TEST PlainImplicitKeys(); TEST PlainImplicitKeys();
// 7.12 // 7.12
TEST PlainLines(); TEST PlainLines();
// 7.13 // 7.13
TEST FlowSequence(); TEST FlowSequence();
// 7.14 // 7.14
TEST FlowSequenceEntries(); TEST FlowSequenceEntries();
// 7.15 // 7.15
TEST FlowMappings(); TEST FlowMappings();
// 7.16 // 7.16
TEST FlowMappingEntries(); TEST FlowMappingEntries();
// 7.17 // 7.17
TEST FlowMappingSeparateValues(); TEST FlowMappingSeparateValues();
// 7.18 // 7.18
TEST FlowMappingAdjacentValues(); TEST FlowMappingAdjacentValues();
// 7.19 // 7.19
TEST SinglePairFlowMappings(); TEST SinglePairFlowMappings();
// 7.20 // 7.20
TEST SinglePairExplicitEntry(); TEST SinglePairExplicitEntry();
// 7.21 // 7.21
TEST SinglePairImplicitEntries(); TEST SinglePairImplicitEntries();
// 7.22 // 7.22
TEST InvalidImplicitKeys(); TEST InvalidImplicitKeys();
// 7.23 // 7.23
TEST FlowContent(); TEST FlowContent();
// 7.24 // 7.24
TEST FlowNodes(); TEST FlowNodes();
// 8.1 // 8.1
TEST BlockScalarHeader(); TEST BlockScalarHeader();
// 8.2 // 8.2
TEST BlockIndentationHeader(); TEST BlockIndentationHeader();
// 8.3 // 8.3
TEST InvalidBlockScalarIndentationIndicators(); TEST InvalidBlockScalarIndentationIndicators();
// 8.4 // 8.4
TEST ChompingFinalLineBreak(); TEST ChompingFinalLineBreak();
// 8.5 // 8.5
TEST ChompingTrailingLines(); TEST ChompingTrailingLines();
// 8.6 // 8.6
TEST EmptyScalarChomping(); TEST EmptyScalarChomping();
// 8.7 // 8.7
TEST LiteralScalar(); TEST LiteralScalar();
// 8.8 // 8.8
TEST LiteralContent(); TEST LiteralContent();
// 8.9 // 8.9
TEST FoldedScalar(); TEST FoldedScalar();
// 8.10 // 8.10
TEST FoldedLines(); TEST FoldedLines();
// 8.11 // 8.11
TEST MoreIndentedLines(); TEST MoreIndentedLines();
// 8.12 // 8.12
TEST EmptySeparationLines(); TEST EmptySeparationLines();
// 8.13 // 8.13
TEST FinalEmptyLines(); TEST FinalEmptyLines();
// 8.14 // 8.14
TEST BlockSequence(); TEST BlockSequence();
// 8.15 // 8.15
TEST BlockSequenceEntryTypes(); TEST BlockSequenceEntryTypes();
// 8.16 // 8.16
TEST BlockMappings(); TEST BlockMappings();
// 8.17 // 8.17
TEST ExplicitBlockMappingEntries(); TEST ExplicitBlockMappingEntries();
// 8.18 // 8.18
TEST ImplicitBlockMappingEntries(); TEST ImplicitBlockMappingEntries();
// 8.19 // 8.19
TEST CompactBlockMappings(); TEST CompactBlockMappings();
// 8.20 // 8.20
TEST BlockNodeTypes(); TEST BlockNodeTypes();
// 8.21 // 8.21
TEST BlockScalarNodes(); TEST BlockScalarNodes();
// 8.22 // 8.22
TEST BlockCollectionNodes(); TEST BlockCollectionNodes();
} }
bool RunSpecTests(); bool RunSpecTests();
} }
#endif // SPECTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // SPECTESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -1,53 +1,56 @@
#ifndef TESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #ifndef TESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define TESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #define TESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#if defined(_MSC_VER) || (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 #if defined(_MSC_VER) || \
(defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \
(__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4
#pragma once #pragma once
#endif #endif
#include <string> #include <string>
namespace Test { namespace Test {
void RunAll(); void RunAll();
namespace Parser { namespace Parser {
// scalar tests // scalar tests
void SimpleScalar(std::string& inputScalar, std::string& desiredOutput); void SimpleScalar(std::string& inputScalar, std::string& desiredOutput);
void MultiLineScalar(std::string& inputScalar, std::string& desiredOutput); void MultiLineScalar(std::string& inputScalar, std::string& desiredOutput);
void LiteralScalar(std::string& inputScalar, std::string& desiredOutput); void LiteralScalar(std::string& inputScalar, std::string& desiredOutput);
void FoldedScalar(std::string& inputScalar, std::string& desiredOutput); void FoldedScalar(std::string& inputScalar, std::string& desiredOutput);
void ChompedFoldedScalar(std::string& inputScalar, std::string& desiredOutput); void ChompedFoldedScalar(std::string& inputScalar, std::string& desiredOutput);
void ChompedLiteralScalar(std::string& inputScalar, std::string& desiredOutput); void ChompedLiteralScalar(std::string& inputScalar, std::string& desiredOutput);
void FoldedScalarWithIndent(std::string& inputScalar, std::string& desiredOutput); void FoldedScalarWithIndent(std::string& inputScalar,
void ColonScalar(std::string& inputScalar, std::string& desiredOutput); std::string& desiredOutput);
void QuotedScalar(std::string& inputScalar, std::string& desiredOutput); void ColonScalar(std::string& inputScalar, std::string& desiredOutput);
void CommaScalar(std::string& inputScalar, std::string& desiredOutput); void QuotedScalar(std::string& inputScalar, std::string& desiredOutput);
void DashScalar(std::string& inputScalar, std::string& desiredOutput); void CommaScalar(std::string& inputScalar, std::string& desiredOutput);
void URLScalar(std::string& inputScalar, std::string& desiredOutput); void DashScalar(std::string& inputScalar, std::string& desiredOutput);
void URLScalar(std::string& inputScalar, std::string& desiredOutput);
// misc tests // misc tests
bool SimpleSeq(); bool SimpleSeq();
bool SimpleMap(); bool SimpleMap();
bool FlowSeq(); bool FlowSeq();
bool FlowMap(); bool FlowMap();
bool FlowMapWithOmittedKey(); bool FlowMapWithOmittedKey();
bool FlowMapWithOmittedValue(); bool FlowMapWithOmittedValue();
bool FlowMapWithSoloEntry(); bool FlowMapWithSoloEntry();
bool FlowMapEndingWithSoloEntry(); bool FlowMapEndingWithSoloEntry();
bool QuotedSimpleKeys(); bool QuotedSimpleKeys();
bool CompressedMapAndSeq(); bool CompressedMapAndSeq();
bool NullBlockSeqEntry(); bool NullBlockSeqEntry();
bool NullBlockMapKey(); bool NullBlockMapKey();
bool NullBlockMapValue(); bool NullBlockMapValue();
bool SimpleAlias(); bool SimpleAlias();
bool AliasWithNull(); bool AliasWithNull();
bool AnchorInSimpleKey(); bool AnchorInSimpleKey();
bool AliasAsSimpleKey(); bool AliasAsSimpleKey();
bool ExplicitDoc(); bool ExplicitDoc();
bool MultipleDocs(); bool MultipleDocs();
bool ExplicitEndDoc(); bool ExplicitEndDoc();
bool MultipleDocsWithSomeExplicitIndicators(); bool MultipleDocsWithSomeExplicitIndicators();
} }
} }
#endif // TESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 #endif // TESTS_H_62B23520_7C8E_11DE_8A39_0800200C9A66

View File

@@ -2,17 +2,19 @@
#include <string> #include <string>
#define YAML_ASSERT(cond) do { if(!(cond)) return " Assert failed: " #cond; } while(false) #define YAML_ASSERT(cond) \
do { \
if (!(cond)) \
return " Assert failed: " #cond; \
} while (false)
namespace Test namespace Test {
{ struct TEST {
struct TEST { TEST() : ok(false) {}
TEST(): ok(false) {} TEST(bool ok_) : ok(ok_) {}
TEST(bool ok_): ok(ok_) {} TEST(const char *error_) : ok(false), error(error_) {}
TEST(const char *error_): ok(false), error(error_) {}
bool ok; bool ok;
std::string error; std::string error;
}; };
} }

View File

@@ -3,8 +3,7 @@
#include "yaml-cpp/yaml.h" #include "yaml-cpp/yaml.h"
#include <iostream> #include <iostream>
int main() int main() {
{
{ {
// test.yaml // test.yaml
// - foo // - foo
@@ -46,7 +45,8 @@ int main()
other.push_back(root); // &1 [5, ~, two, *1] other.push_back(root); // &1 [5, ~, two, *1]
other[3][0] = 0; // &1 [0, ~, two, *1] # since it's a true alias other[3][0] = 0; // &1 [0, ~, two, *1] # since it's a true alias
other.push_back(Copy(root)); // &1 [0, ~, two, *1, &2 [0, ~, two, *2]] other.push_back(Copy(root)); // &1 [0, ~, two, *1, &2 [0, ~, two, *2]]
other[4][0] = 5; // &1 [0, ~, two, *1, &2 [5, ~, two, *2]] # they're really different other[4][0] = 5; // &1 [0, ~, two, *1, &2 [5, ~, two, *2]] # they're
// really different
} }
{ {
@@ -54,8 +54,10 @@ int main()
node[0] = 1; // [1] # auto-construct a sequence node[0] = 1; // [1] # auto-construct a sequence
node["key"] = 5; // {0: 1, key: 5} # auto-turn it into a map node["key"] = 5; // {0: 1, key: 5} # auto-turn it into a map
node.push_back(10); // error, can't turn a map into a sequence node.push_back(10); // error, can't turn a map into a sequence
node.erase("key"); // {0: 1} # still a map, even if we remove the key that caused the problem node.erase("key"); // {0: 1} # still a map, even if we remove the key that
node = "Hello"; // Hello # assignment overwrites everything, so it's now just a plain scalar // caused the problem
node = "Hello"; // Hello # assignment overwrites everything, so it's now
// just a plain scalar
} }
{ {
@@ -74,18 +76,22 @@ int main()
{ {
YAML::Value node; YAML::Value node;
YAML::Value subnode = node["key"]; // 'subnode' is not instantiated ('node' is still null) YAML::Value subnode =
node["key"]; // 'subnode' is not instantiated ('node' is still null)
subnode = "value"; // {key: value} # now it is subnode = "value"; // {key: value} # now it is
YAML::Value subnode2 = node["key2"]; YAML::Value subnode2 = node["key2"];
node["key3"] = subnode2; // subnode2 is still not instantiated, but node["key3"] is "pseudo" aliased to it node["key3"] = subnode2; // subnode2 is still not instantiated, but
subnode2 = "monkey"; // {key: value, key2: &1 monkey, key3: *1} # bam! it instantiates both // node["key3"] is "pseudo" aliased to it
subnode2 = "monkey"; // {key: value, key2: &1 monkey, key3: *1} # bam! it
// instantiates both
} }
{ {
YAML::Value seq = YAML::Sequence(); YAML::Value seq = YAML::Sequence();
seq[0] = "zero"; // [zero] seq[0] = "zero"; // [zero]
seq[1] = seq[0]; // [&1 zero, *1] seq[1] = seq[0]; // [&1 zero, *1]
seq[0] = seq[1]; // [&1 zero, *1] # no-op (they both alias the same thing, so setting them equal is nothing) seq[0] = seq[1]; // [&1 zero, *1] # no-op (they both alias the same thing,
// so setting them equal is nothing)
Is(seq[0], seq[1]); // true Is(seq[0], seq[1]); // true
seq[1] = "one"; // [&1 one, *1] seq[1] = "one"; // [&1 one, *1]
UnAlias(seq[1]); // [one, one] UnAlias(seq[1]); // [one, one]
@@ -98,9 +104,11 @@ int main()
root.push_back("one"); root.push_back("one");
root.push_back("two"); root.push_back("two");
YAML::Value two = root[2]; YAML::Value two = root[2];
root = "scalar"; // 'two' is still "two", even though 'root' is "scalar" (the sequence effectively no longer exists) root = "scalar"; // 'two' is still "two", even though 'root' is "scalar"
// (the sequence effectively no longer exists)
// Note: in all likelihood, the memory for nodes "zero" and "one" is still allocated. How can it go away? Weak pointers? // Note: in all likelihood, the memory for nodes "zero" and "one" is still
// allocated. How can it go away? Weak pointers?
} }
{ {

View File

@@ -2,9 +2,8 @@
#include "yaml-cpp/eventhandler.h" #include "yaml-cpp/eventhandler.h"
#include <iostream> #include <iostream>
class NullEventHandler: public YAML::EventHandler class NullEventHandler : public YAML::EventHandler {
{ public:
public:
typedef YAML::Mark Mark; typedef YAML::Mark Mark;
typedef YAML::anchor_t anchor_t; typedef YAML::anchor_t anchor_t;
@@ -14,15 +13,15 @@ public:
virtual void OnDocumentEnd() {} virtual void OnDocumentEnd() {}
virtual void OnNull(const Mark&, anchor_t) {} virtual void OnNull(const Mark&, anchor_t) {}
virtual void OnAlias(const Mark&, anchor_t) {} virtual void OnAlias(const Mark&, anchor_t) {}
virtual void OnScalar(const Mark&, const std::string&, anchor_t, const std::string&) {} virtual void OnScalar(const Mark&, const std::string&, anchor_t,
const std::string&) {}
virtual void OnSequenceStart(const Mark&, const std::string&, anchor_t) {} virtual void OnSequenceStart(const Mark&, const std::string&, anchor_t) {}
virtual void OnSequenceEnd() {} virtual void OnSequenceEnd() {}
virtual void OnMapStart(const Mark&, const std::string&, anchor_t) {} virtual void OnMapStart(const Mark&, const std::string&, anchor_t) {}
virtual void OnMapEnd() {} virtual void OnMapEnd() {}
}; };
int main() int main() {
{
YAML::Parser parser(std::cin); YAML::Parser parser(std::cin);
NullEventHandler handler; NullEventHandler handler;
parser.HandleNextDocument(handler); parser.HandleNextDocument(handler);

View File

@@ -2,9 +2,8 @@
#include "yaml-cpp/eventhandler.h" #include "yaml-cpp/eventhandler.h"
#include <iostream> #include <iostream>
class NullEventHandler: public YAML::EventHandler class NullEventHandler : public YAML::EventHandler {
{ public:
public:
typedef YAML::Mark Mark; typedef YAML::Mark Mark;
typedef YAML::anchor_t anchor_t; typedef YAML::anchor_t anchor_t;
@@ -14,18 +13,18 @@ public:
virtual void OnDocumentEnd() {} virtual void OnDocumentEnd() {}
virtual void OnNull(const Mark&, anchor_t) {} virtual void OnNull(const Mark&, anchor_t) {}
virtual void OnAlias(const Mark&, anchor_t) {} virtual void OnAlias(const Mark&, anchor_t) {}
virtual void OnScalar(const Mark&, const std::string&, anchor_t, const std::string&) {} virtual void OnScalar(const Mark&, const std::string&, anchor_t,
const std::string&) {}
virtual void OnSequenceStart(const Mark&, const std::string&, anchor_t) {} virtual void OnSequenceStart(const Mark&, const std::string&, anchor_t) {}
virtual void OnSequenceEnd() {} virtual void OnSequenceEnd() {}
virtual void OnMapStart(const Mark&, const std::string&, anchor_t) {} virtual void OnMapStart(const Mark&, const std::string&, anchor_t) {}
virtual void OnMapEnd() {} virtual void OnMapEnd() {}
}; };
int main() int main() {
{
std::stringstream stream("---{header: {id: 1"); std::stringstream stream("---{header: {id: 1");
YAML::Parser parser(stream); YAML::Parser parser(stream);
// parser.PrintTokens(std::cout); // parser.PrintTokens(std::cout);
NullEventHandler handler; NullEventHandler handler;
parser.HandleNextDocument(handler); parser.HandleNextDocument(handler);
return 0; return 0;