Skip to content

Commit

Permalink
Support for building with exceptions disabled
Browse files Browse the repository at this point in the history
1) A new macro YAML_CPP_NORETURN to annotate functions as not returning in dll.h
2) A new function YAML_throw<ExceptionType>(args...) in exception.h
   this function will throw an exception unless exceptions are disabled in the compiler,
   detected by checking the pre-defined macro __cpp_exceptions
   In this case the exception class will be instantiated, and the user-provided function
   YAML::handle_exception(const char*) will be called on the exception's what() method
3) if exceptions are disabled,and the library's user does not provide YAML::handle_exception,
   there will be a linker error
4) all other files have been changed automatedly by running the following sed commands
   sed -i "s/throw \([A-Za-z]*\)(\(.*\))/YAML_throw<\1>(\2)/g" # throw statements for non-templated exceptions
   sed -i "s/throw \(.*\)<\(.*\)>(/YAML_throw<\1<\2> >(/g" # throw statements for templated exceptions
  • Loading branch information
twestenkarl committed Oct 21, 2022
1 parent 1b50109 commit 5b1c606
Show file tree
Hide file tree
Showing 13 changed files with 87 additions and 64 deletions.
8 changes: 8 additions & 0 deletions include/yaml-cpp/dll.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@
# endif
#endif

#ifndef YAML_CPP_NORETURN
# ifdef _MSC_VER
# define YAML_CPP_NORETURN __declspec(noreturn)
# else
# define YAML_CPP_NORETURN __attribute__ ((noreturn))
# endif
#endif

#ifndef YAML_CPP_DEPRECATED_EXPORT
# define YAML_CPP_DEPRECATED_EXPORT YAML_CPP_API YAML_CPP_DEPRECATED
#endif
Expand Down
15 changes: 15 additions & 0 deletions include/yaml-cpp/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@
#include <string>

namespace YAML {

#if defined(__cpp_exceptions) || (defined(_MSC_VER) && defined(_CPPUNWIND))
template<typename Ex, typename... Args>
YAML_CPP_NORETURN void YAML_throw(Args&&... args) {
throw Ex(std::forward<Args>(args)...);
}
#else
YAML_CPP_NORETURN void handle_exception(const char* what);

template<typename Ex, typename... Args>
YAML_CPP_NORETURN void YAML_throw(Args&&... args) {
handle_exception(Ex(std::forward<Args>(args)...).what());
}
#endif

// error messages
namespace ErrorMsg {
const char* const YAML_DIRECTIVE_ARGS =
Expand Down
6 changes: 3 additions & 3 deletions include/yaml-cpp/node/detail/impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ inline node* node_data::get(const Key& key,
return pNode;
return nullptr;
case NodeType::Scalar:
throw BadSubscript(m_mark, key);
YAML_throw<BadSubscript>(m_mark, key);
}

auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
Expand All @@ -154,7 +154,7 @@ inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
convert_to_map(pMemory);
break;
case NodeType::Scalar:
throw BadSubscript(m_mark, key);
YAML_throw<BadSubscript>(m_mark, key);
}

auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) {
Expand Down Expand Up @@ -213,7 +213,7 @@ inline void node_data::force_insert(const Key& key, const Value& value,
convert_to_map(pMemory);
break;
case NodeType::Scalar:
throw BadInsert();
YAML_throw<BadInsert>();
}

node& k = convert_to_node(key, pMemory);
Expand Down
32 changes: 16 additions & 16 deletions include/yaml-cpp/node/impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ inline Node::~Node() = default;

inline void Node::EnsureNodeExists() const {
if (!m_isValid)
throw InvalidNode(m_invalidKey);
YAML_throw<InvalidNode>(m_invalidKey);
if (!m_pNode) {
m_pMemory.reset(new detail::memory_holder);
m_pNode = &m_pMemory->create_node();
Expand All @@ -74,14 +74,14 @@ inline bool Node::IsDefined() const {

inline Mark Node::Mark() const {
if (!m_isValid) {
throw InvalidNode(m_invalidKey);
YAML_throw<InvalidNode>(m_invalidKey);
}
return m_pNode ? m_pNode->mark() : Mark::null_mark();
}

inline NodeType::value Node::Type() const {
if (!m_isValid)
throw InvalidNode(m_invalidKey);
YAML_throw<InvalidNode>(m_invalidKey);
return m_pNode ? m_pNode->type() : NodeType::Null;
}

Expand Down Expand Up @@ -125,12 +125,12 @@ struct as_if<T, void> {

T operator()() const {
if (!node.m_pNode)
throw TypedBadConversion<T>(node.Mark());
YAML_throw<TypedBadConversion<T> >(node.Mark());

T t;
if (convert<T>::decode(node, t))
return t;
throw TypedBadConversion<T>(node.Mark());
YAML_throw<TypedBadConversion<T> >(node.Mark());
}
};

Expand All @@ -143,7 +143,7 @@ struct as_if<std::string, void> {
if (node.Type() == NodeType::Null)
return "null";
if (node.Type() != NodeType::Scalar)
throw TypedBadConversion<std::string>(node.Mark());
YAML_throw<TypedBadConversion<std::string> >(node.Mark());
return node.Scalar();
}
};
Expand All @@ -152,7 +152,7 @@ struct as_if<std::string, void> {
template <typename T>
inline T Node::as() const {
if (!m_isValid)
throw InvalidNode(m_invalidKey);
YAML_throw<InvalidNode>(m_invalidKey);
return as_if<T, void>(*this)();
}

Expand All @@ -165,13 +165,13 @@ inline T Node::as(const S& fallback) const {

inline const std::string& Node::Scalar() const {
if (!m_isValid)
throw InvalidNode(m_invalidKey);
YAML_throw<InvalidNode>(m_invalidKey);
return m_pNode ? m_pNode->scalar() : detail::node_data::empty_scalar();
}

inline const std::string& Node::Tag() const {
if (!m_isValid)
throw InvalidNode(m_invalidKey);
YAML_throw<InvalidNode>(m_invalidKey);
return m_pNode ? m_pNode->tag() : detail::node_data::empty_scalar();
}

Expand All @@ -182,7 +182,7 @@ inline void Node::SetTag(const std::string& tag) {

inline EmitterStyle::value Node::Style() const {
if (!m_isValid)
throw InvalidNode(m_invalidKey);
YAML_throw<InvalidNode>(m_invalidKey);
return m_pNode ? m_pNode->style() : EmitterStyle::Default;
}

Expand All @@ -194,7 +194,7 @@ inline void Node::SetStyle(EmitterStyle::value style) {
// assignment
inline bool Node::is(const Node& rhs) const {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode(m_invalidKey);
YAML_throw<InvalidNode>(m_invalidKey);
if (!m_pNode || !rhs.m_pNode)
return false;
return m_pNode->is(*rhs.m_pNode);
Expand All @@ -215,15 +215,15 @@ inline Node& Node::operator=(const Node& rhs) {

inline void Node::reset(const YAML::Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode(m_invalidKey);
YAML_throw<InvalidNode>(m_invalidKey);
m_pMemory = rhs.m_pMemory;
m_pNode = rhs.m_pNode;
}

template <typename T>
inline void Node::Assign(const T& rhs) {
if (!m_isValid)
throw InvalidNode(m_invalidKey);
YAML_throw<InvalidNode>(m_invalidKey);
AssignData(convert<T>::encode(rhs));
}

Expand Down Expand Up @@ -253,7 +253,7 @@ inline void Node::AssignData(const Node& rhs) {

inline void Node::AssignNode(const Node& rhs) {
if (!m_isValid)
throw InvalidNode(m_invalidKey);
YAML_throw<InvalidNode>(m_invalidKey);
rhs.EnsureNodeExists();

if (!m_pNode) {
Expand All @@ -270,7 +270,7 @@ inline void Node::AssignNode(const Node& rhs) {
// size/iterator
inline std::size_t Node::size() const {
if (!m_isValid)
throw InvalidNode(m_invalidKey);
YAML_throw<InvalidNode>(m_invalidKey);
return m_pNode ? m_pNode->size() : 0;
}

Expand Down Expand Up @@ -303,7 +303,7 @@ inline iterator Node::end() {
template <typename T>
inline void Node::push_back(const T& rhs) {
if (!m_isValid)
throw InvalidNode(m_invalidKey);
YAML_throw<InvalidNode>(m_invalidKey);
push_back(Node(rhs));
}

Expand Down
6 changes: 3 additions & 3 deletions src/exp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ unsigned ParseHex(const std::string& str, const Mark& mark) {
else if ('0' <= ch && ch <= '9')
digit = ch - '0';
else
throw ParserException(mark, ErrorMsg::INVALID_HEX);
YAML_throw<ParserException>(mark, ErrorMsg::INVALID_HEX);

value = (value << 4) + digit;
}
Expand All @@ -48,7 +48,7 @@ std::string Escape(Stream& in, int codeLength) {
if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) {
std::stringstream msg;
msg << ErrorMsg::INVALID_UNICODE << value;
throw ParserException(in.mark(), msg.str());
YAML_throw<ParserException>(in.mark(), msg.str());
}

// now break it up into chars
Expand Down Expand Up @@ -131,7 +131,7 @@ std::string Escape(Stream& in) {
}

std::stringstream msg;
throw ParserException(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);
YAML_throw<ParserException>(in.mark(), std::string(ErrorMsg::INVALID_ESCAPE) + ch);
}
} // namespace Exp
} // namespace YAML
6 changes: 3 additions & 3 deletions src/node_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ void node_data::push_back(node& node,
}

if (m_type != NodeType::Sequence)
throw BadPushback();
YAML_throw<BadPushback>();

m_sequence.push_back(&node);
}
Expand All @@ -200,7 +200,7 @@ void node_data::insert(node& key, node& value,
convert_to_map(pMemory);
break;
case NodeType::Scalar:
throw BadSubscript(m_mark, key);
YAML_throw<BadSubscript>(m_mark, key);
}

insert_map_pair(key, value);
Expand Down Expand Up @@ -231,7 +231,7 @@ node& node_data::get(node& key, const shared_memory_holder& pMemory) {
convert_to_map(pMemory);
break;
case NodeType::Scalar:
throw BadSubscript(m_mark, key);
YAML_throw<BadSubscript>(m_mark, key);
}

for (const auto& it : m_map) {
Expand Down
4 changes: 2 additions & 2 deletions src/parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Node Load(std::istream& input) {
Node LoadFile(const std::string& filename) {
std::ifstream fin(filename);
if (!fin) {
throw BadFile(filename);
YAML_throw<BadFile>(filename);
}
return Load(fin);
}
Expand Down Expand Up @@ -65,7 +65,7 @@ std::vector<Node> LoadAll(std::istream& input) {
std::vector<Node> LoadAllFromFile(const std::string& filename) {
std::ifstream fin(filename);
if (!fin) {
throw BadFile(filename);
YAML_throw<BadFile>(filename);
}
return LoadAll(fin);
}
Expand Down
10 changes: 5 additions & 5 deletions src/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ void Parser::HandleDirective(const Token& token) {

void Parser::HandleYamlDirective(const Token& token) {
if (token.params.size() != 1) {
throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
YAML_throw<ParserException>(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
}

if (!m_pDirectives->version.isDefault) {
throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE);
YAML_throw<ParserException>(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE);
}

std::stringstream str(token.params[0]);
Expand All @@ -86,7 +86,7 @@ void Parser::HandleYamlDirective(const Token& token) {
}

if (m_pDirectives->version.major > 1) {
throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION);
YAML_throw<ParserException>(token.mark, ErrorMsg::YAML_MAJOR_VERSION);
}

m_pDirectives->version.isDefault = false;
Expand All @@ -95,12 +95,12 @@ void Parser::HandleYamlDirective(const Token& token) {

void Parser::HandleTagDirective(const Token& token) {
if (token.params.size() != 2)
throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS);
YAML_throw<ParserException>(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS);

const std::string& handle = token.params[0];
const std::string& prefix = token.params[1];
if (m_pDirectives->tags.find(handle) != m_pDirectives->tags.end()) {
throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE);
YAML_throw<ParserException>(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE);
}

m_pDirectives->tags[handle] = prefix;
Expand Down
4 changes: 2 additions & 2 deletions src/scanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ void Scanner::ScanNextToken() {
}

// don't know what it is!
throw ParserException(INPUT.mark(), ErrorMsg::UNKNOWN_TOKEN);
YAML_throw<ParserException>(INPUT.mark(), ErrorMsg::UNKNOWN_TOKEN);
}

void Scanner::ScanToNextToken() {
Expand Down Expand Up @@ -386,6 +386,6 @@ void Scanner::ThrowParserException(const std::string& msg) const {
const Token& token = m_tokens.front();
mark = token.mark;
}
throw ParserException(mark, msg);
YAML_throw<ParserException>(mark, msg);
}
} // namespace YAML
6 changes: 3 additions & 3 deletions src/scanscalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) {
break;
}
if (params.onDocIndicator == THROW) {
throw ParserException(INPUT.mark(), ErrorMsg::DOC_IN_SCALAR);
YAML_throw<ParserException>(INPUT.mark(), ErrorMsg::DOC_IN_SCALAR);
}
}

Expand Down Expand Up @@ -85,7 +85,7 @@ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) {
// eof? if we're looking to eat something, then we throw
if (!INPUT) {
if (params.eatEnd) {
throw ParserException(INPUT.mark(), ErrorMsg::EOF_IN_SCALAR);
YAML_throw<ParserException>(INPUT.mark(), ErrorMsg::EOF_IN_SCALAR);
}
break;
}
Expand Down Expand Up @@ -135,7 +135,7 @@ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) {
// we check for tabs that masquerade as indentation
if (INPUT.peek() == '\t' && INPUT.column() < params.indent &&
params.onTabInIndentation == THROW) {
throw ParserException(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION);
YAML_throw<ParserException>(INPUT.mark(), ErrorMsg::TAB_IN_INDENTATION);
}

if (!params.eatLeadingWhitespace) {
Expand Down
6 changes: 3 additions & 3 deletions src/scantag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const std::string ScanVerbatimTag(Stream& INPUT) {
tag += INPUT.get(n);
}

throw ParserException(INPUT.mark(), ErrorMsg::END_OF_VERBATIM_TAG);
YAML_throw<ParserException>(INPUT.mark(), ErrorMsg::END_OF_VERBATIM_TAG);
}

const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle) {
Expand All @@ -37,7 +37,7 @@ const std::string ScanTagHandle(Stream& INPUT, bool& canBeHandle) {
while (INPUT) {
if (INPUT.peek() == Keys::Tag) {
if (!canBeHandle)
throw ParserException(firstNonWordChar, ErrorMsg::CHAR_IN_TAG_HANDLE);
YAML_throw<ParserException>(firstNonWordChar, ErrorMsg::CHAR_IN_TAG_HANDLE);
break;
}

Expand Down Expand Up @@ -74,7 +74,7 @@ const std::string ScanTagSuffix(Stream& INPUT) {
}

if (tag.empty())
throw ParserException(INPUT.mark(), ErrorMsg::TAG_WITH_NO_SUFFIX);
YAML_throw<ParserException>(INPUT.mark(), ErrorMsg::TAG_WITH_NO_SUFFIX);

return tag;
}
Expand Down
Loading

0 comments on commit 5b1c606

Please sign in to comment.