Merge 'remotes/trunk'
[0ad.git] / source / ps / Errors.h
blobe597c26e7d502eae0af9198fdd57efbb462da692
1 /* Copyright (C) 2013 Wildfire Games.
2 * This file is part of 0 A.D.
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.
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.
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/>.
18 #ifndef INCLUDED_ERRORS
19 #define INCLUDED_ERRORS
23 The overly-complex error system works as follows:
25 A source file (typically a .h) can declare errors as follows:
27 ERROR_GROUP(ModuleName);
28 ERROR_TYPE(ModuleName, FrobnificationFailed);
29 ERROR_SUBGROUP(ModuleName, ComponentName);
30 ERROR_TYPE(ModuleName_ComponentName, FileNotFound);
32 etc, to build up a hierarchy of error types.
34 Then you have to run the /build/errorlist/errorlist.pl script, to regenerate
35 the Errors.cpp file.
37 Then you can use the declared errors as an error code:
39 PSRETURN foo() { return PSRETURN_ModuleName_FrobnificationFailed; }
41 if (ret != PSRETURN_OK)
42 ... // something failed
44 if (ret)
45 ... // something failed
47 if (ret == PSRETURN_ModuleName_FrobnificationFailed)
48 ... // particular error
50 if (ERROR_IS(ret, PSRETURN_ModuleName))
51 ... // matches any type PSRETURN_ModuleName_* (and PSRETURN_ModuleName_*_* etc)
53 And you can use it as an exception:
55 void foo() { throw PSERROR_ModuleName_FrobnificationFailed(); }
57 void bar() { throw PSERROR_ModuleName_FrobnificationFailed("More informative message"); }
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();
69 plus a few extra things for converting between error codes and exceptions.
73 #include <exception>
75 typedef u32 PSRETURN;
77 class PSERROR : public std::exception
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;
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
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
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
101 #define ERROR_IS(a, b) ( ((a) & MASK__PSRETURN_##b) == CODE__PSRETURN_##b )
103 const PSRETURN PSRETURN_OK = 0;
104 const PSRETURN MASK__PSRETURN_OK = 0xFFFFFFFF;
105 const PSRETURN CODE__PSRETURN_OK = 0;
107 const char* GetErrorString(PSRETURN code);
108 void ThrowError(PSRETURN code);
110 #endif