Line data Source code
1 : #ifndef EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 2 : #define EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66 3 : 4 : #if defined(_MSC_VER) || \ 5 : (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ 6 : (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 7 : #pragma once 8 : #endif 9 : 10 : #include "yaml-cpp/mark.h" 11 : #include "yaml-cpp/noexcept.h" 12 : #include "yaml-cpp/traits.h" 13 : #include <sstream> 14 : #include <stdexcept> 15 : #include <string> 16 : 17 : namespace YAML { 18 : // error messages 19 : namespace ErrorMsg { 20 : const char* const YAML_DIRECTIVE_ARGS = 21 : "YAML directives must have exactly one argument"; 22 : const char* const YAML_VERSION = "bad YAML version: "; 23 : const char* const YAML_MAJOR_VERSION = "YAML major version too large"; 24 : const char* const REPEATED_YAML_DIRECTIVE = "repeated YAML directive"; 25 : const char* const TAG_DIRECTIVE_ARGS = 26 : "TAG directives must have exactly two arguments"; 27 : const char* const REPEATED_TAG_DIRECTIVE = "repeated TAG directive"; 28 : const char* const CHAR_IN_TAG_HANDLE = 29 : "illegal character found while scanning tag handle"; 30 : const char* const TAG_WITH_NO_SUFFIX = "tag handle with no suffix"; 31 : const char* const END_OF_VERBATIM_TAG = "end of verbatim tag not found"; 32 : const char* const END_OF_MAP = "end of map not found"; 33 : const char* const END_OF_MAP_FLOW = "end of map flow not found"; 34 : const char* const END_OF_SEQ = "end of sequence not found"; 35 : const char* const END_OF_SEQ_FLOW = "end of sequence flow not found"; 36 : const char* const MULTIPLE_TAGS = 37 : "cannot assign multiple tags to the same node"; 38 : const char* const MULTIPLE_ANCHORS = 39 : "cannot assign multiple anchors to the same node"; 40 : const char* const MULTIPLE_ALIASES = 41 : "cannot assign multiple aliases to the same node"; 42 : const char* const ALIAS_CONTENT = 43 : "aliases can't have any content, *including* tags"; 44 : const char* const INVALID_HEX = "bad character found while scanning hex number"; 45 : const char* const INVALID_UNICODE = "invalid unicode: "; 46 : const char* const INVALID_ESCAPE = "unknown escape character: "; 47 : const char* const UNKNOWN_TOKEN = "unknown token"; 48 : const char* const DOC_IN_SCALAR = "illegal document indicator in scalar"; 49 : const char* const EOF_IN_SCALAR = "illegal EOF in scalar"; 50 : const char* const CHAR_IN_SCALAR = "illegal character in scalar"; 51 : const char* const TAB_IN_INDENTATION = 52 : "illegal tab when looking for indentation"; 53 : const char* const FLOW_END = "illegal flow end"; 54 : const char* const BLOCK_ENTRY = "illegal block entry"; 55 : const char* const MAP_KEY = "illegal map key"; 56 : const char* const MAP_VALUE = "illegal map value"; 57 : const char* const ALIAS_NOT_FOUND = "alias not found after *"; 58 : const char* const ANCHOR_NOT_FOUND = "anchor not found after &"; 59 : const char* const CHAR_IN_ALIAS = 60 : "illegal character found while scanning alias"; 61 : const char* const CHAR_IN_ANCHOR = 62 : "illegal character found while scanning anchor"; 63 : const char* const ZERO_INDENT_IN_BLOCK = 64 : "cannot set zero indentation for a block scalar"; 65 : const char* const CHAR_IN_BLOCK = "unexpected character in block scalar"; 66 : const char* const AMBIGUOUS_ANCHOR = 67 : "cannot assign the same alias to multiple nodes"; 68 : const char* const UNKNOWN_ANCHOR = "the referenced anchor is not defined"; 69 : 70 : const char* const INVALID_NODE = 71 : "invalid node; this may result from using a map iterator as a sequence " 72 : "iterator, or vice-versa"; 73 : const char* const INVALID_SCALAR = "invalid scalar"; 74 : const char* const KEY_NOT_FOUND = "key not found"; 75 : const char* const BAD_CONVERSION = "bad conversion"; 76 : const char* const BAD_DEREFERENCE = "bad dereference"; 77 : const char* const BAD_SUBSCRIPT = "operator[] call on a scalar"; 78 : const char* const BAD_PUSHBACK = "appending to a non-sequence"; 79 : const char* const BAD_INSERT = "inserting in a non-convertible-to-map"; 80 : 81 : const char* const UNMATCHED_GROUP_TAG = "unmatched group tag"; 82 : const char* const UNEXPECTED_END_SEQ = "unexpected end sequence token"; 83 : const char* const UNEXPECTED_END_MAP = "unexpected end map token"; 84 : const char* const SINGLE_QUOTED_CHAR = 85 : "invalid character in single-quoted string"; 86 : const char* const INVALID_ANCHOR = "invalid anchor"; 87 : const char* const INVALID_ALIAS = "invalid alias"; 88 : const char* const INVALID_TAG = "invalid tag"; 89 : const char* const BAD_FILE = "bad file"; 90 : 91 : template <typename T> 92 : inline const std::string KEY_NOT_FOUND_WITH_KEY( 93 : const T&, typename disable_if<is_numeric<T>>::type* = 0) { 94 : return KEY_NOT_FOUND; 95 : } 96 : 97 : inline const std::string KEY_NOT_FOUND_WITH_KEY(const std::string& key) { 98 : std::stringstream stream; 99 : stream << KEY_NOT_FOUND << ": " << key; 100 : return stream.str(); 101 : } 102 : 103 : inline const std::string KEY_NOT_FOUND_WITH_KEY(const char* key) { 104 : std::stringstream stream; 105 : stream << KEY_NOT_FOUND << ": " << key; 106 : return stream.str(); 107 : } 108 : 109 : template <typename T> 110 : inline const std::string KEY_NOT_FOUND_WITH_KEY( 111 : const T& key, typename enable_if<is_numeric<T>>::type* = 0) { 112 : std::stringstream stream; 113 : stream << KEY_NOT_FOUND << ": " << key; 114 : return stream.str(); 115 : } 116 : 117 : template <typename T> 118 : inline const std::string BAD_SUBSCRIPT_WITH_KEY( 119 : const T&, typename disable_if<is_numeric<T>>::type* = nullptr) { 120 : return BAD_SUBSCRIPT; 121 : } 122 : 123 0 : inline const std::string BAD_SUBSCRIPT_WITH_KEY(const std::string& key) { 124 0 : std::stringstream stream; 125 0 : stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")"; 126 0 : return stream.str(); 127 0 : } 128 : 129 0 : inline const std::string BAD_SUBSCRIPT_WITH_KEY(const char* key) { 130 0 : std::stringstream stream; 131 0 : stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")"; 132 0 : return stream.str(); 133 0 : } 134 : 135 : template <typename T> 136 : inline const std::string BAD_SUBSCRIPT_WITH_KEY( 137 : const T& key, typename enable_if<is_numeric<T>>::type* = nullptr) { 138 : std::stringstream stream; 139 : stream << BAD_SUBSCRIPT << " (key: \"" << key << "\")"; 140 : return stream.str(); 141 : } 142 : 143 6 : inline const std::string INVALID_NODE_WITH_KEY(const std::string& key) { 144 6 : std::stringstream stream; 145 6 : if (key.empty()) { 146 0 : return INVALID_NODE; 147 : } 148 6 : stream << "invalid node; first invalid key: \"" << key << "\""; 149 6 : return stream.str(); 150 6 : } 151 : } // namespace ErrorMsg 152 : 153 : class YAML_CPP_API Exception : public std::runtime_error { 154 : public: 155 6 : Exception(const Mark& mark_, const std::string& msg_) 156 6 : : std::runtime_error(build_what(mark_, msg_)), mark(mark_), msg(msg_) {} 157 : ~Exception() YAML_CPP_NOEXCEPT override; 158 : 159 : Exception(const Exception&) = default; 160 : 161 : Mark mark; 162 : std::string msg; 163 : 164 : private: 165 6 : static const std::string build_what(const Mark& mark, 166 : const std::string& msg) { 167 6 : if (mark.is_null()) { 168 6 : return msg; 169 : } 170 : 171 0 : std::stringstream output; 172 0 : output << "yaml-cpp: error at line " << mark.line + 1 << ", column " 173 0 : << mark.column + 1 << ": " << msg; 174 0 : return output.str(); 175 0 : } 176 : }; 177 : 178 : class YAML_CPP_API ParserException : public Exception { 179 : public: 180 : ParserException(const Mark& mark_, const std::string& msg_) 181 : : Exception(mark_, msg_) {} 182 : ParserException(const ParserException&) = default; 183 : ~ParserException() YAML_CPP_NOEXCEPT override; 184 : }; 185 : 186 : class YAML_CPP_API RepresentationException : public Exception { 187 : public: 188 6 : RepresentationException(const Mark& mark_, const std::string& msg_) 189 6 : : Exception(mark_, msg_) {} 190 : RepresentationException(const RepresentationException&) = default; 191 : ~RepresentationException() YAML_CPP_NOEXCEPT override; 192 : }; 193 : 194 : // representation exceptions 195 : class YAML_CPP_API InvalidScalar : public RepresentationException { 196 : public: 197 : InvalidScalar(const Mark& mark_) 198 : : RepresentationException(mark_, ErrorMsg::INVALID_SCALAR) {} 199 : InvalidScalar(const InvalidScalar&) = default; 200 : ~InvalidScalar() YAML_CPP_NOEXCEPT override; 201 : }; 202 : 203 : class YAML_CPP_API KeyNotFound : public RepresentationException { 204 : public: 205 : template <typename T> 206 : KeyNotFound(const Mark& mark_, const T& key_) 207 : : RepresentationException(mark_, ErrorMsg::KEY_NOT_FOUND_WITH_KEY(key_)) { 208 : } 209 : KeyNotFound(const KeyNotFound&) = default; 210 : ~KeyNotFound() YAML_CPP_NOEXCEPT override; 211 : }; 212 : 213 : template <typename T> 214 : class YAML_CPP_API TypedKeyNotFound : public KeyNotFound { 215 : public: 216 : TypedKeyNotFound(const Mark& mark_, const T& key_) 217 : : KeyNotFound(mark_, key_), key(key_) {} 218 : ~TypedKeyNotFound() YAML_CPP_NOEXCEPT override = default; 219 : 220 : T key; 221 : }; 222 : 223 : template <typename T> 224 : inline TypedKeyNotFound<T> MakeTypedKeyNotFound(const Mark& mark, 225 : const T& key) { 226 : return TypedKeyNotFound<T>(mark, key); 227 : } 228 : 229 : class YAML_CPP_API InvalidNode : public RepresentationException { 230 : public: 231 6 : InvalidNode(const std::string& key) 232 6 : : RepresentationException(Mark::null_mark(), 233 12 : ErrorMsg::INVALID_NODE_WITH_KEY(key)) {} 234 : InvalidNode(const InvalidNode&) = default; 235 : ~InvalidNode() YAML_CPP_NOEXCEPT override; 236 : }; 237 : 238 : class YAML_CPP_API BadConversion : public RepresentationException { 239 : public: 240 0 : explicit BadConversion(const Mark& mark_) 241 0 : : RepresentationException(mark_, ErrorMsg::BAD_CONVERSION) {} 242 : BadConversion(const BadConversion&) = default; 243 : ~BadConversion() YAML_CPP_NOEXCEPT override; 244 : }; 245 : 246 : template <typename T> 247 : class TypedBadConversion : public BadConversion { 248 : public: 249 0 : explicit TypedBadConversion(const Mark& mark_) : BadConversion(mark_) {} 250 : }; 251 : 252 : class YAML_CPP_API BadDereference : public RepresentationException { 253 : public: 254 : BadDereference() 255 : : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_DEREFERENCE) {} 256 : BadDereference(const BadDereference&) = default; 257 : ~BadDereference() YAML_CPP_NOEXCEPT override; 258 : }; 259 : 260 : class YAML_CPP_API BadSubscript : public RepresentationException { 261 : public: 262 : template <typename Key> 263 0 : BadSubscript(const Mark& mark_, const Key& key) 264 0 : : RepresentationException(mark_, ErrorMsg::BAD_SUBSCRIPT_WITH_KEY(key)) {} 265 : BadSubscript(const BadSubscript&) = default; 266 : ~BadSubscript() YAML_CPP_NOEXCEPT override; 267 : }; 268 : 269 : class YAML_CPP_API BadPushback : public RepresentationException { 270 : public: 271 : BadPushback() 272 : : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_PUSHBACK) {} 273 : BadPushback(const BadPushback&) = default; 274 : ~BadPushback() YAML_CPP_NOEXCEPT override; 275 : }; 276 : 277 : class YAML_CPP_API BadInsert : public RepresentationException { 278 : public: 279 : BadInsert() 280 : : RepresentationException(Mark::null_mark(), ErrorMsg::BAD_INSERT) {} 281 : BadInsert(const BadInsert&) = default; 282 : ~BadInsert() YAML_CPP_NOEXCEPT override; 283 : }; 284 : 285 : class YAML_CPP_API EmitterException : public Exception { 286 : public: 287 : EmitterException(const std::string& msg_) 288 : : Exception(Mark::null_mark(), msg_) {} 289 : EmitterException(const EmitterException&) = default; 290 : ~EmitterException() YAML_CPP_NOEXCEPT override; 291 : }; 292 : 293 : class YAML_CPP_API BadFile : public Exception { 294 : public: 295 : explicit BadFile(const std::string& filename) 296 : : Exception(Mark::null_mark(), 297 : std::string(ErrorMsg::BAD_FILE) + ": " + filename) {} 298 : BadFile(const BadFile&) = default; 299 : ~BadFile() YAML_CPP_NOEXCEPT override; 300 : }; 301 : } // namespace YAML 302 : 303 : #endif // EXCEPTIONS_H_62B23520_7C8E_11DE_8A39_0800200C9A66