From c67b41c966f82eb5819570860dc586f5ad38e358 Mon Sep 17 00:00:00 2001 From: Jesse Beder Date: Wed, 16 Mar 2011 02:31:30 +0000 Subject: [PATCH] Marked Parser, Emitter, Node, Iterator, Mark, and Null for exporting to a DLL. It appears to work properly, although VS gives me lots of warning C4251 since I didn't export all data members of each of the above classes. It seems that it's not necessary to export those members (as long as you can't access them), and most of them are STL instances, which apparently cause lots of problems for DLLs. (For example, you simply can't export instances of std::map; see http://support.microsoft.com/kb/168958.) --- include/yaml-cpp/conversion.h | 4 ++-- include/yaml-cpp/dll.h | 28 ++++++++++++++++++++++++++++ include/yaml-cpp/emitter.h | 14 ++++++-------- include/yaml-cpp/iterator.h | 7 ++++--- include/yaml-cpp/mark.h | 4 +++- include/yaml-cpp/node.h | 7 ++++--- include/yaml-cpp/noncopyable.h | 19 ++++++++++--------- include/yaml-cpp/null.h | 8 +++++--- include/yaml-cpp/parser.h | 3 ++- src/emitter.cpp | 13 +++++++++++++ 10 files changed, 77 insertions(+), 30 deletions(-) create mode 100644 include/yaml-cpp/dll.h diff --git a/include/yaml-cpp/conversion.h b/include/yaml-cpp/conversion.h index 1036182..327f88d 100644 --- a/include/yaml-cpp/conversion.h +++ b/include/yaml-cpp/conversion.h @@ -18,8 +18,8 @@ namespace YAML return true; } - bool Convert(const std::string& input, bool& output); - bool Convert(const std::string& input, _Null& output); + YAML_CPP_API bool Convert(const std::string& input, bool& output); + YAML_CPP_API bool Convert(const std::string& input, _Null& output); template inline bool Convert(const std::string& input, T& output, typename enable_if >::type * = 0) { diff --git a/include/yaml-cpp/dll.h b/include/yaml-cpp/dll.h new file mode 100644 index 0000000..3c82c1a --- /dev/null +++ b/include/yaml-cpp/dll.h @@ -0,0 +1,28 @@ +#ifndef DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 +#define DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 + +#if !defined(__GNUC__) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || (__GNUC__ >= 4) // GCC supports "pragma once" correctly since 3.4 +#pragma once +#endif + +// The following ifdef block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the yaml_cpp_EXPORTS +// 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. +#undef YAML_CPP_API + +#ifdef YAML_CPP_DLL // Using or Building YAML-CPP DLL (definition defined manually) + #ifdef yaml_cpp_EXPORTS // Building YAML-CPP DLL (definition created by CMake or defined manually) + // #pragma message( "Defining YAML_CPP_API for DLL export" ) + #define YAML_CPP_API __declspec(dllexport) + #else // yaml_cpp_EXPORTS + // #pragma message( "Defining YAML_CPP_API for DLL import" ) + #define YAML_CPP_API __declspec(dllimport) + #endif // yaml_cpp_EXPORTS +#else //YAML_CPP_DLL +#define YAML_CPP_API +#endif // YAML_CPP_DLL + +#endif // DLL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/emitter.h b/include/yaml-cpp/emitter.h index 0e1ca26..86d3ed8 100644 --- a/include/yaml-cpp/emitter.h +++ b/include/yaml-cpp/emitter.h @@ -6,6 +6,7 @@ #endif +#include "yaml-cpp/dll.h" #include "yaml-cpp/emittermanip.h" #include "yaml-cpp/ostream.h" #include "yaml-cpp/noncopyable.h" @@ -18,7 +19,7 @@ namespace YAML { class EmitterState; - class Emitter: private noncopyable + class YAML_CPP_API Emitter: private noncopyable { public: Emitter(); @@ -65,7 +66,9 @@ namespace YAML private: void PreWriteIntegralType(std::stringstream& str); + void PreWriteStreamable(std::stringstream& str); void PostWriteIntegralType(const std::stringstream& str); + void PostWriteStreamable(const std::stringstream& str); private: enum ATOMIC_TYPE { AT_SCALAR, AT_SEQ, AT_BLOCK_SEQ, AT_FLOW_SEQ, AT_MAP, AT_BLOCK_MAP, AT_FLOW_MAP }; @@ -114,15 +117,10 @@ namespace YAML if(!good()) return *this; - PreAtomicWrite(); - EmitSeparationIfNecessary(); - std::stringstream str; - str.precision(15); + PreWriteStreamable(str); str << value; - m_stream << str.str(); - - PostAtomicWrite(); + PostWriteStreamable(str); return *this; } diff --git a/include/yaml-cpp/iterator.h b/include/yaml-cpp/iterator.h index e1d95e4..2397db9 100644 --- a/include/yaml-cpp/iterator.h +++ b/include/yaml-cpp/iterator.h @@ -5,6 +5,7 @@ #pragma once #endif +#include "yaml-cpp/dll.h" #include namespace YAML @@ -12,7 +13,7 @@ namespace YAML class Node; struct IterPriv; - class Iterator + class YAML_CPP_API Iterator { public: Iterator(); @@ -28,8 +29,8 @@ namespace YAML const Node& first() const; const Node& second() const; - friend bool operator == (const Iterator& it, const Iterator& jt); - friend bool operator != (const Iterator& it, const Iterator& jt); + friend YAML_CPP_API bool operator == (const Iterator& it, const Iterator& jt); + friend YAML_CPP_API bool operator != (const Iterator& it, const Iterator& jt); private: std::auto_ptr m_pData; diff --git a/include/yaml-cpp/mark.h b/include/yaml-cpp/mark.h index 358f251..09057da 100644 --- a/include/yaml-cpp/mark.h +++ b/include/yaml-cpp/mark.h @@ -6,9 +6,11 @@ #endif +#include "yaml-cpp/dll.h" + namespace YAML { - struct Mark { + struct YAML_CPP_API Mark { Mark(): pos(0), line(0), column(0) {} static const Mark null() { return Mark(-1, -1, -1); } diff --git a/include/yaml-cpp/node.h b/include/yaml-cpp/node.h index 17ef8e0..ff752c4 100644 --- a/include/yaml-cpp/node.h +++ b/include/yaml-cpp/node.h @@ -7,6 +7,7 @@ #include "yaml-cpp/conversion.h" +#include "yaml-cpp/dll.h" #include "yaml-cpp/exceptions.h" #include "yaml-cpp/iterator.h" #include "yaml-cpp/ltnode.h" @@ -29,7 +30,7 @@ namespace YAML struct NodeType { enum value { Null, Scalar, Sequence, Map }; }; - class Node: private noncopyable + class YAML_CPP_API Node: private noncopyable { public: friend class NodeOwnership; @@ -65,7 +66,7 @@ namespace YAML const T to() const; template - friend void operator >> (const Node& node, T& value); + friend YAML_CPP_API void operator >> (const Node& node, T& value); // retrieval for maps and sequences template @@ -82,7 +83,7 @@ namespace YAML const std::string& Tag() const { return m_tag; } // emitting - friend Emitter& operator << (Emitter& out, const Node& node); + friend YAML_CPP_API Emitter& operator << (Emitter& out, const Node& node); // ordering int Compare(const Node& rhs) const; diff --git a/include/yaml-cpp/noncopyable.h b/include/yaml-cpp/noncopyable.h index 0b056e8..1614b68 100644 --- a/include/yaml-cpp/noncopyable.h +++ b/include/yaml-cpp/noncopyable.h @@ -5,20 +5,21 @@ #pragma once #endif +#include "yaml-cpp/dll.h" namespace YAML { // this is basically boost::noncopyable - class noncopyable - { - protected: - noncopyable() {} - ~noncopyable() {} + class YAML_CPP_API noncopyable + { + protected: + noncopyable() {} + ~noncopyable() {} - private: - noncopyable(const noncopyable&); - const noncopyable& operator = (const noncopyable&); - }; + private: + noncopyable(const noncopyable&); + const noncopyable& operator = (const noncopyable&); + }; } #endif // NONCOPYABLE_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/null.h b/include/yaml-cpp/null.h index b430344..9c7986b 100644 --- a/include/yaml-cpp/null.h +++ b/include/yaml-cpp/null.h @@ -6,17 +6,19 @@ #endif +#include "yaml-cpp/dll.h" + namespace YAML { class Node; - struct _Null {}; + struct YAML_CPP_API _Null {}; inline bool operator == (const _Null&, const _Null&) { return true; } inline bool operator != (const _Null&, const _Null&) { return false; } - bool IsNull(const Node& node); + YAML_CPP_API bool IsNull(const Node& node); - extern _Null Null; + extern YAML_CPP_API _Null Null; } #endif // NULL_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/include/yaml-cpp/parser.h b/include/yaml-cpp/parser.h index dc2ce5a..32a2d16 100644 --- a/include/yaml-cpp/parser.h +++ b/include/yaml-cpp/parser.h @@ -6,6 +6,7 @@ #endif +#include "yaml-cpp/dll.h" #include "yaml-cpp/noncopyable.h" #include #include @@ -19,7 +20,7 @@ namespace YAML class Node; class Scanner; - class Parser: private noncopyable + class YAML_CPP_API Parser: private noncopyable { public: Parser(); diff --git a/src/emitter.cpp b/src/emitter.cpp index 8ae2f2e..ad21e22 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -657,12 +657,25 @@ namespace YAML } } + void Emitter::PreWriteStreamable(std::stringstream& str) + { + PreAtomicWrite(); + EmitSeparationIfNecessary(); + str.precision(15); + } + void Emitter::PostWriteIntegralType(const std::stringstream& str) { m_stream << str.str(); PostAtomicWrite(); } + void Emitter::PostWriteStreamable(const std::stringstream& str) + { + m_stream << str.str(); + PostAtomicWrite(); + } + const char *Emitter::ComputeFullBoolName(bool b) const { const EMITTER_MANIP mainFmt = (m_pState->GetBoolLengthFormat() == ShortBool ? YesNoBool : m_pState->GetBoolFormat());