summaryrefslogtreecommitdiffstats
path: root/yaml-cpp/include/yaml-cpp/exceptions.h
blob: 394d586872e7372fc8e9315897e0d3c4784bd478 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66
#define EXCEPTIONS_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
#pragma once
#endif


#include "yaml-cpp/mark.h"
#include "yaml-cpp/traits.h"
#include <stdexcept>
#include <string>
#include <sstream>

namespace YAML
{
	// error messages
	namespace ErrorMsg
	{
		const char * const YAML_DIRECTIVE_ARGS    = "YAML directives must have exactly one argument";
		const char * const YAML_VERSION           = "bad YAML version: ";
		const char * const YAML_MAJOR_VERSION     = "YAML major version too large";
		const char * const REPEATED_YAML_DIRECTIVE= "repeated YAML directive";
		const char * const TAG_DIRECTIVE_ARGS     = "TAG directives must have exactly two arguments";
		const char * const REPEATED_TAG_DIRECTIVE = "repeated TAG directive";
		const char * const CHAR_IN_TAG_HANDLE     = "illegal character found while scanning tag handle";
		const char * const TAG_WITH_NO_SUFFIX     = "tag handle with no suffix";
		const char * const END_OF_VERBATIM_TAG    = "end of verbatim tag not found";
		const char * const END_OF_MAP             = "end of map not found";
		const char * const END_OF_MAP_FLOW        = "end of map flow not found";
		const char * const END_OF_SEQ             = "end of sequence not found";
		const char * const END_OF_SEQ_FLOW        = "end of sequence flow not found";
		const char * const MULTIPLE_TAGS          = "cannot assign multiple tags to the same node";
		const char * const MULTIPLE_ANCHORS       = "cannot assign multiple anchors to the same node";
		const char * const MULTIPLE_ALIASES       = "cannot assign multiple aliases to the same node";
		const char * const ALIAS_CONTENT          = "aliases can't have any content, *including* tags";
		const char * const INVALID_HEX            = "bad character found while scanning hex number";
		const char * const INVALID_UNICODE        = "invalid unicode: ";
		const char * const INVALID_ESCAPE         = "unknown escape character: ";
		const char * const UNKNOWN_TOKEN          = "unknown token";
		const char * const DOC_IN_SCALAR          = "illegal document indicator in scalar";
		const char * const EOF_IN_SCALAR          = "illegal EOF in scalar";
		const char * const CHAR_IN_SCALAR         = "illegal character in scalar";
		const char * const TAB_IN_INDENTATION     = "illegal tab when looking for indentation";
		const char * const FLOW_END               = "illegal flow end";
		const char * const BLOCK_ENTRY            = "illegal block entry";
		const char * const MAP_KEY                = "illegal map key";
		const char * const MAP_VALUE              = "illegal map value";
		const char * const ALIAS_NOT_FOUND        = "alias not found after *";
		const char * const ANCHOR_NOT_FOUND       = "anchor not found after &";
		const char * const CHAR_IN_ALIAS          = "illegal character found while scanning alias";
		const char * const CHAR_IN_ANCHOR         = "illegal character found while scanning anchor";
		const char * const ZERO_INDENT_IN_BLOCK   = "cannot set zero indentation for a block scalar";
		const char * const CHAR_IN_BLOCK          = "unexpected character in block scalar";
		const char * const AMBIGUOUS_ANCHOR       = "cannot assign the same alias to multiple nodes";
		const char * const UNKNOWN_ANCHOR         = "the referenced anchor is not defined";

		const char * const INVALID_SCALAR         = "invalid scalar";
		const char * const KEY_NOT_FOUND          = "key not found";
		const char * const BAD_DEREFERENCE        = "bad dereference";
		
		const char * const UNMATCHED_GROUP_TAG    = "unmatched group tag";
		const char * const UNEXPECTED_END_SEQ     = "unexpected end sequence token";
		const char * const UNEXPECTED_END_MAP     = "unexpected end map token";
		const char * const SINGLE_QUOTED_CHAR     = "invalid character in single-quoted string";
		const char * const INVALID_ANCHOR         = "invalid anchor";
		const char * const INVALID_ALIAS          = "invalid alias";
		const char * const INVALID_TAG            = "invalid tag";
		const char * const EXPECTED_KEY_TOKEN     = "expected key token";
		const char * const EXPECTED_VALUE_TOKEN   = "expected value token";
		const char * const UNEXPECTED_KEY_TOKEN   = "unexpected key token";
		const char * const UNEXPECTED_VALUE_TOKEN = "unexpected value token";

		template <typename T>
		inline const std::string KEY_NOT_FOUND_WITH_KEY(const T&, typename disable_if<is_numeric<T> >::type * = 0) {
			return KEY_NOT_FOUND;
		}

		inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) {
			std::stringstream stream;
			stream << KEY_NOT_FOUND << ": " << key;
			return stream.str();
		}
		
		template <typename T>
		inline const std::string KEY_NOT_FOUND_WITH_KEY(const T& key, typename enable_if<is_numeric<T> >::type * = 0) {
			std::stringstream stream;
			stream << KEY_NOT_FOUND << ": " << key;
			return stream.str();
		}
	}

	class Exception: public std::runtime_error {
	public:
		Exception(const Mark& mark_, const std::string& msg_)
		: std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {}
		virtual ~Exception() throw() {}

		Mark mark;
		std::string msg;

	private:
		static const std::string build_what(const Mark& mark, const std::string& msg) {
			std::stringstream output;
			output << "yaml-cpp: error at line " << mark.line+1 << ", column " << mark.column+1 << ": " << msg;
			return output.str();
		}
	};

	class ParserException: public Exception {
	public:
		ParserException(const Mark& mark_, const std::string& msg_)
			: Exception(mark_, msg_) {}
	};

	class RepresentationException: public Exception {
	public:
		RepresentationException(const Mark& mark_, const std::string& msg_)
			: Exception(mark_, msg_) {}
	};

	// representation exceptions
	class InvalidScalar: public RepresentationException {
	public:
		InvalidScalar(const Mark& mark_)
			: RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {}
	};

	class KeyNotFound: public RepresentationException {
	public:
		template <typename T>
		KeyNotFound(const Mark& mark_, const T& key_)
			: RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) {}
	};
	
	template <typename T>
	class TypedKeyNotFound: public KeyNotFound {
	public:
		TypedKeyNotFound(const Mark& mark_, const T& key_)
			: KeyNotFound(mark_, key_), key(key_) {}
		virtual ~TypedKeyNotFound() throw() {}

		T key;
	};

	template <typename T>
	inline TypedKeyNotFound <T> MakeTypedKeyNotFound(const Mark& mark, const T& key) {
		return TypedKeyNotFound <T> (mark, key);
	}

	class BadDereference: public RepresentationException {
	public:
		BadDereference()
		: RepresentationException(Mark::null(), ErrorMsg::BAD_DEREFERENCE) {}
	};
	
	class EmitterException: public Exception {
	public:
		EmitterException(const std::string& msg_)
		: Exception(Mark::null(), msg_) {}
	};
}

#endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66