1 // SuperTux
2 // Copyright (C) 2015 Ingo Ruhnke <grumbel@gmail.com>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 #ifndef HEADER_SUPERTUX_UTIL_READER_ERROR_HPP
18 #define HEADER_SUPERTUX_UTIL_READER_ERROR_HPP
19
20 #include <sexp/value.hpp>
21
22 #include <sstream>
23 #include <stdexcept>
24 #include <sexp/io.hpp>
25
26 #include "util/reader_document.hpp"
27
28 #define raise_exception(doc, sx, msg) raise_exception_real(__FILE__, __LINE__, doc, sx, msg)
29
30 [[noreturn]]
31 inline void
raise_exception_real(const char * filename,int line,ReaderDocument const & doc,sexp::Value const & sx,const char * usermsg)32 raise_exception_real(const char* filename, int line,
33 ReaderDocument const& doc, sexp::Value const& sx,
34 const char* usermsg)
35 {
36 std::ostringstream msg;
37 msg << "[" << filename << ":" << line << "] "
38 << doc.get_filename() << ":" << sx.get_line() << ": "
39 << usermsg << " in expression:"
40 << "\n " << sx;
41 throw std::runtime_error(msg.str());
42 }
43
assert_is_boolean(ReaderDocument const & doc,sexp::Value const & sx)44 inline void assert_is_boolean(ReaderDocument const& doc, sexp::Value const& sx)
45 {
46 if (!sx.is_boolean())
47 {
48 raise_exception(doc, sx, "expected boolean");
49 }
50 }
51
assert_is_integer(ReaderDocument const & doc,sexp::Value const & sx)52 inline void assert_is_integer(ReaderDocument const& doc, sexp::Value const& sx)
53 {
54 if (!sx.is_integer())
55 {
56 raise_exception(doc, sx, "expected integer");
57 }
58 }
59
assert_is_real(ReaderDocument const & doc,sexp::Value const & sx)60 inline void assert_is_real(ReaderDocument const& doc, sexp::Value const& sx)
61 {
62 if (!sx.is_real())
63 {
64 raise_exception(doc, sx, "expected real");
65 }
66 }
67
assert_is_symbol(ReaderDocument const & doc,sexp::Value const & sx)68 inline void assert_is_symbol(ReaderDocument const& doc, sexp::Value const& sx)
69 {
70 if (!sx.is_symbol())
71 {
72 raise_exception(doc, sx, "expected symbol");
73 }
74 }
75
assert_is_string(ReaderDocument const & doc,sexp::Value const & sx)76 inline void assert_is_string(ReaderDocument const& doc, sexp::Value const& sx)
77 {
78 if (!sx.is_string())
79 {
80 raise_exception(doc, sx, "expected string");
81 }
82 }
83
assert_is_array(ReaderDocument const & doc,sexp::Value const & sx)84 inline void assert_is_array(ReaderDocument const& doc, sexp::Value const& sx)
85 {
86 if (!sx.is_array())
87 {
88 raise_exception(doc, sx, "expected array");
89 }
90 }
91
assert_array_size_ge(ReaderDocument const & doc,sexp::Value const & sx,int size)92 inline void assert_array_size_ge(ReaderDocument const& doc, sexp::Value const& sx, int size)
93 {
94 assert_is_array(doc, sx);
95
96 if (!(static_cast<int>(sx.as_array().size()) >= size))
97 {
98 std::ostringstream msg;
99 msg << "array should contain " << size << " elements or more";
100 raise_exception(doc, sx, msg.str().c_str());
101 }
102 }
103
assert_array_size_eq(ReaderDocument const & doc,sexp::Value const & sx,int size)104 inline void assert_array_size_eq(ReaderDocument const& doc, sexp::Value const& sx, int size)
105 {
106 assert_is_array(doc, sx);
107
108 if (static_cast<int>(sx.as_array().size()) != size)
109 {
110 std::ostringstream msg;
111 msg << "array must have " << size << " elements, but has " << sx.as_array().size();
112 raise_exception(doc, sx, msg.str().c_str());
113 }
114 }
115
116 #endif
117
118 /* EOF */
119