Line data Source code
1 : /* Copyright (C) 2013 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. 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 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. 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 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #ifndef INCLUDED_ERRORS
19 : #define INCLUDED_ERRORS
20 :
21 : /*
22 :
23 : The overly-complex error system works as follows:
24 :
25 : A source file (typically a .h) can declare errors as follows:
26 :
27 : ERROR_GROUP(ModuleName);
28 : ERROR_TYPE(ModuleName, FrobnificationFailed);
29 : ERROR_SUBGROUP(ModuleName, ComponentName);
30 : ERROR_TYPE(ModuleName_ComponentName, FileNotFound);
31 :
32 : etc, to build up a hierarchy of error types.
33 :
34 : Then you have to run the /build/errorlist/errorlist.pl script, to regenerate
35 : the Errors.cpp file.
36 :
37 : Then you can use the declared errors as an error code:
38 :
39 : PSRETURN foo() { return PSRETURN_ModuleName_FrobnificationFailed; }
40 :
41 : if (ret != PSRETURN_OK)
42 : ... // something failed
43 :
44 : if (ret)
45 : ... // something failed
46 :
47 : if (ret == PSRETURN_ModuleName_FrobnificationFailed)
48 : ... // particular error
49 :
50 : if (ERROR_IS(ret, PSRETURN_ModuleName))
51 : ... // matches any type PSRETURN_ModuleName_* (and PSRETURN_ModuleName_*_* etc)
52 :
53 : And you can use it as an exception:
54 :
55 : void foo() { throw PSERROR_ModuleName_FrobnificationFailed(); }
56 :
57 : void bar() { throw PSERROR_ModuleName_FrobnificationFailed("More informative message"); }
58 :
59 : try {
60 : foo();
61 : } catch (PSERROR_ModuleName_FrobnificationFailed& e) {
62 : // catches that particular error type
63 : } catch (PSERROR_ModuleName& e) {
64 : // catches anything in the hierarchy
65 : } catch (PSERROR& e) {
66 : std::cout << e.what();
67 : }
68 :
69 : plus a few extra things for converting between error codes and exceptions.
70 :
71 : */
72 :
73 : #include <exception>
74 :
75 : typedef u32 PSRETURN;
76 :
77 5 : class PSERROR : public std::exception
78 : {
79 : public:
80 : PSERROR(const char* msg);
81 : virtual const char* what() const throw ();
82 : virtual PSRETURN getCode() const = 0; // for functions that catch exceptions then return error codes
83 : private:
84 : const char* m_msg;
85 : };
86 :
87 : #define ERROR_GROUP(a) class PSERROR_##a : public PSERROR { protected: PSERROR_##a(const char* msg); }; \
88 : extern const PSRETURN MASK__PSRETURN_##a; \
89 : extern const PSRETURN CODE__PSRETURN_##a
90 :
91 : #define ERROR_SUBGROUP(a,b) class PSERROR_##a##_##b : public PSERROR_##a { protected: PSERROR_##a##_##b(const char* msg); }; \
92 : extern const PSRETURN MASK__PSRETURN_##a##_##b; \
93 : extern const PSRETURN CODE__PSRETURN_##a##_##b
94 :
95 :
96 : #define ERROR_TYPE(a,b) class PSERROR_##a##_##b : public PSERROR_##a { public: PSERROR_##a##_##b(); PSERROR_##a##_##b(const char* msg); PSRETURN getCode() const; }; \
97 : extern const PSRETURN MASK__PSRETURN_##a##_##b; \
98 : extern const PSRETURN CODE__PSRETURN_##a##_##b; \
99 : extern const PSRETURN PSRETURN_##a##_##b
100 :
101 : #define ERROR_IS(a, b) ( ((a) & MASK__PSRETURN_##b) == CODE__PSRETURN_##b )
102 :
103 : const PSRETURN PSRETURN_OK = 0;
104 : const PSRETURN MASK__PSRETURN_OK = 0xFFFFFFFF;
105 : const PSRETURN CODE__PSRETURN_OK = 0;
106 :
107 : const char* GetErrorString(PSRETURN code);
108 : void ThrowError(PSRETURN code);
109 :
110 : #endif
|