exceptions.h 10 KB

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