Skip to content

Commit

Permalink
More useful error messages.
Browse files Browse the repository at this point in the history
Applied the patch given in #200 with the correct code
style.
  • Loading branch information
Ortham committed Apr 2, 2015
1 parent 5de38a7 commit ec8aa4f
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 16 deletions.
10 changes: 7 additions & 3 deletions include/yaml-cpp/exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ class Exception : public std::runtime_error {
private:
static const std::string build_what(const Mark& mark,
const std::string& msg) {
if (mark.is_null()) {
return msg.c_str();
}

std::stringstream output;
output << "yaml-cpp: error at line " << mark.line + 1 << ", column "
<< mark.column + 1 << ": " << msg;
Expand Down Expand Up @@ -178,14 +182,14 @@ class InvalidNode : public RepresentationException {

class BadConversion : public RepresentationException {
public:
BadConversion()
: RepresentationException(Mark::null_mark(), ErrorMsg::BAD_CONVERSION) {}
explicit BadConversion(const Mark& mark_)
: RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {}
};

template <typename T>
class TypedBadConversion : public BadConversion {
public:
TypedBadConversion() : BadConversion() {}
explicit TypedBadConversion(const Mark& mark_) : BadConversion(mark_) {}
};

class BadDereference : public RepresentationException {
Expand Down
2 changes: 2 additions & 0 deletions include/yaml-cpp/mark.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ struct YAML_CPP_API Mark {

static const Mark null_mark() { return Mark(-1, -1, -1); }

bool is_null() const { return pos == -1 && line == -1 && column == -1; }

int pos;
int line, column;

Expand Down
5 changes: 5 additions & 0 deletions include/yaml-cpp/node/detail/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class node : private boost::noncopyable {
const node_ref* ref() const { return m_pRef.get(); }

bool is_defined() const { return m_pRef->is_defined(); }
const Mark& mark() const { return m_pRef->mark(); }
NodeType::value type() const { return m_pRef->type(); }

const std::string& scalar() const { return m_pRef->scalar(); }
Expand Down Expand Up @@ -64,6 +65,10 @@ class node : private boost::noncopyable {
m_pRef->set_data(*rhs.m_pRef);
}

void set_mark(const Mark& mark) {
m_pRef->set_mark(mark);
}

void set_type(NodeType::value type) {
if (type != NodeType::Undefined)
mark_defined();
Expand Down
3 changes: 3 additions & 0 deletions include/yaml-cpp/node/detail/node_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ class YAML_CPP_API node_data : private boost::noncopyable {
node_data();

void mark_defined();
void set_mark(const Mark& mark);
void set_type(NodeType::value type);
void set_tag(const std::string& tag);
void set_null();
void set_scalar(const std::string& scalar);
void set_style(EmitterStyle::value style);

bool is_defined() const { return m_isDefined; }
const Mark& mark() const { return m_mark; }
NodeType::value type() const {
return m_isDefined ? m_type : NodeType::Undefined;
}
Expand Down Expand Up @@ -97,6 +99,7 @@ class YAML_CPP_API node_data : private boost::noncopyable {

private:
bool m_isDefined;
Mark m_mark;
NodeType::value m_type;
std::string m_tag;
EmitterStyle::value m_style;
Expand Down
2 changes: 2 additions & 0 deletions include/yaml-cpp/node/detail/node_ref.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class node_ref : private boost::noncopyable {
node_ref() : m_pData(new node_data) {}

bool is_defined() const { return m_pData->is_defined(); }
const Mark& mark() const { return m_pData->mark(); }
NodeType::value type() const { return m_pData->type(); }
const std::string& scalar() const { return m_pData->scalar(); }
const std::string& tag() const { return m_pData->tag(); }
Expand All @@ -28,6 +29,7 @@ class node_ref : private boost::noncopyable {
void mark_defined() { m_pData->mark_defined(); }
void set_data(const node_ref& rhs) { m_pData = rhs.m_pData; }

void set_mark(const Mark& mark) { m_pData->set_mark(mark); }
void set_type(NodeType::value type) { m_pData->set_type(type); }
void set_tag(const std::string& tag) { m_pData->set_tag(tag); }
void set_null() { m_pData->set_null(); }
Expand Down
13 changes: 10 additions & 3 deletions include/yaml-cpp/node/impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ inline bool Node::IsDefined() const {
return m_pNode ? m_pNode->is_defined() : true;
}

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

inline NodeType::value Node::Type() const {
if (!m_isValid)
throw InvalidNode();
Expand Down Expand Up @@ -110,12 +117,12 @@ struct as_if<T, void> {

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

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

Expand All @@ -126,7 +133,7 @@ struct as_if<std::string, void> {

const std::string operator()() const {
if (node.Type() != NodeType::Scalar)
throw TypedBadConversion<std::string>();
throw TypedBadConversion<std::string>(node.Mark());
return node.Scalar();
}
};
Expand Down
2 changes: 2 additions & 0 deletions include/yaml-cpp/node/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include "yaml-cpp/dll.h"
#include "yaml-cpp/emitterstyle.h"
#include "yaml-cpp/mark.h"
#include "yaml-cpp/node/detail/bool_type.h"
#include "yaml-cpp/node/detail/iterator_fwd.h"
#include "yaml-cpp/node/ptr.h"
Expand Down Expand Up @@ -48,6 +49,7 @@ class YAML_CPP_API Node {
Node(const Node& rhs);
~Node();

YAML::Mark Mark() const;
NodeType::value Type() const;
bool IsDefined() const;
bool IsNull() const { return Type() == NodeType::Null; }
Expand Down
5 changes: 5 additions & 0 deletions src/node_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ std::string node_data::empty_scalar;

node_data::node_data()
: m_isDefined(false),
m_mark(Mark::null_mark()),
m_type(NodeType::Null),
m_style(EmitterStyle::Default),
m_seqSize(0) {}
Expand All @@ -27,6 +28,10 @@ void node_data::mark_defined() {
m_isDefined = true;
}

void node_data::set_mark(const Mark& mark) {
m_mark = mark;
}

void node_data::set_type(NodeType::value type) {
if (type == NodeType::Undefined) {
m_type = type;
Expand Down
19 changes: 10 additions & 9 deletions src/nodebuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ void NodeBuilder::OnDocumentStart(const Mark&) {}

void NodeBuilder::OnDocumentEnd() {}

void NodeBuilder::OnNull(const Mark& /* mark */, anchor_t anchor) {
detail::node& node = Push(anchor);
void NodeBuilder::OnNull(const Mark& mark, anchor_t anchor) {
detail::node& node = Push(mark, anchor);
node.set_null();
Pop();
}
Expand All @@ -40,28 +40,28 @@ void NodeBuilder::OnAlias(const Mark& /* mark */, anchor_t anchor) {
Pop();
}

void NodeBuilder::OnScalar(const Mark& /* mark */, const std::string& tag,
void NodeBuilder::OnScalar(const Mark& mark, const std::string& tag,
anchor_t anchor, const std::string& value) {
detail::node& node = Push(anchor);
detail::node& node = Push(mark, anchor);
node.set_scalar(value);
node.set_tag(tag);
Pop();
}

void NodeBuilder::OnSequenceStart(const Mark& /* mark */,
void NodeBuilder::OnSequenceStart(const Mark& mark,
const std::string& tag, anchor_t anchor,
EmitterStyle::value style) {
detail::node& node = Push(anchor);
detail::node& node = Push(mark, anchor);
node.set_tag(tag);
node.set_type(NodeType::Sequence);
node.set_style(style);
}

void NodeBuilder::OnSequenceEnd() { Pop(); }

void NodeBuilder::OnMapStart(const Mark& /* mark */, const std::string& tag,
void NodeBuilder::OnMapStart(const Mark& mark, const std::string& tag,
anchor_t anchor, EmitterStyle::value style) {
detail::node& node = Push(anchor);
detail::node& node = Push(mark, anchor);
node.set_type(NodeType::Map);
node.set_tag(tag);
node.set_style(style);
Expand All @@ -74,8 +74,9 @@ void NodeBuilder::OnMapEnd() {
Pop();
}

detail::node& NodeBuilder::Push(anchor_t anchor) {
detail::node& NodeBuilder::Push(const Mark& mark, anchor_t anchor) {
detail::node& node = m_pMemory->create_node();
node.set_mark(mark);
RegisterAnchor(anchor, node);
Push(node);
return node;
Expand Down
2 changes: 1 addition & 1 deletion src/nodebuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class NodeBuilder : public EventHandler {
virtual void OnMapEnd();

private:
detail::node& Push(anchor_t anchor);
detail::node& Push(const Mark& mark, anchor_t anchor);
void Push(detail::node& node);
void Pop();
void RegisterAnchor(anchor_t anchor, detail::node& node);
Expand Down

0 comments on commit ec8aa4f

Please sign in to comment.