1 | /* $Id: CoinError.hpp 1372 2011-01-03 23:31:00Z lou $ */ |
2 | // Copyright (C) 2000, International Business Machines |
3 | // Corporation and others. All Rights Reserved. |
4 | // This code is licensed under the terms of the Eclipse Public License (EPL). |
5 | |
6 | #ifndef CoinError_H |
7 | #define CoinError_H |
8 | |
9 | #include <string> |
10 | #include <iostream> |
11 | #include <cassert> |
12 | #include <cstring> |
13 | |
14 | #include "CoinUtilsConfig.h" |
15 | #include "CoinPragma.hpp" |
16 | |
17 | /** A function to block the popup windows that windows creates when the code |
18 | crashes */ |
19 | void (); |
20 | |
21 | //------------------------------------------------------------------- |
22 | // |
23 | // Error class used to throw exceptions |
24 | // |
25 | // Errors contain: |
26 | // |
27 | //------------------------------------------------------------------- |
28 | |
29 | /** Error Class thrown by an exception |
30 | |
31 | This class is used when exceptions are thrown. |
32 | It contains: |
33 | <ul> |
34 | <li>message text |
35 | <li>name of method throwing exception |
36 | <li>name of class throwing exception or hint |
37 | <li>name of file if assert |
38 | <li>line number |
39 | </ul> |
40 | For asserts class=> optional hint |
41 | */ |
42 | class CoinError { |
43 | friend void CoinErrorUnitTest(); |
44 | |
45 | private: |
46 | CoinError() |
47 | : |
48 | message_(), |
49 | method_(), |
50 | class_(), |
51 | file_(), |
52 | lineNumber_() |
53 | { |
54 | // nothing to do here |
55 | } |
56 | |
57 | public: |
58 | |
59 | //------------------------------------------------------------------- |
60 | // Get methods |
61 | //------------------------------------------------------------------- |
62 | /**@name Get error attributes */ |
63 | //@{ |
64 | /// get message text |
65 | inline const std::string & message() const |
66 | { return message_; } |
67 | /// get name of method instantiating error |
68 | inline const std::string & methodName() const |
69 | { return method_; } |
70 | /// get name of class instantiating error (or hint for assert) |
71 | inline const std::string & className() const |
72 | { return class_; } |
73 | /// get name of file for assert |
74 | inline const std::string & fileName() const |
75 | { return file_; } |
76 | /// get line number of assert (-1 if not assert) |
77 | inline int lineNumber() const |
78 | { return lineNumber_; } |
79 | /// Just print (for asserts) |
80 | inline void print(bool doPrint = true) const |
81 | { |
82 | if (! doPrint) |
83 | return; |
84 | if (lineNumber_<0) { |
85 | std::cout<<message_<<" in " <<class_<<"::" <<method_<<std::endl; |
86 | } else { |
87 | std::cout<<file_<<":" <<lineNumber_<<" method " <<method_ |
88 | <<" : assertion \'" <<message_<<"\' failed." <<std::endl; |
89 | if(class_!="" ) |
90 | std::cout<<"Possible reason: " <<class_<<std::endl; |
91 | } |
92 | } |
93 | //@} |
94 | |
95 | |
96 | /**@name Constructors and destructors */ |
97 | //@{ |
98 | /// Alternate Constructor |
99 | CoinError ( |
100 | std::string message__, |
101 | std::string methodName__, |
102 | std::string className__, |
103 | std::string fileName_ = std::string(), |
104 | int line = -1) |
105 | : |
106 | message_(message__), |
107 | method_(methodName__), |
108 | class_(className__), |
109 | file_(fileName_), |
110 | lineNumber_(line) |
111 | { |
112 | print(printErrors_); |
113 | } |
114 | |
115 | /// Copy constructor |
116 | CoinError (const CoinError & source) |
117 | : |
118 | message_(source.message_), |
119 | method_(source.method_), |
120 | class_(source.class_), |
121 | file_(source.file_), |
122 | lineNumber_(source.lineNumber_) |
123 | { |
124 | // nothing to do here |
125 | } |
126 | |
127 | /// Assignment operator |
128 | CoinError & operator=(const CoinError& rhs) |
129 | { |
130 | if (this != &rhs) { |
131 | message_=rhs.message_; |
132 | method_=rhs.method_; |
133 | class_=rhs.class_; |
134 | file_=rhs.file_; |
135 | lineNumber_ = rhs.lineNumber_; |
136 | } |
137 | return *this; |
138 | } |
139 | |
140 | /// Destructor |
141 | virtual ~CoinError () |
142 | { |
143 | // nothing to do here |
144 | } |
145 | //@} |
146 | |
147 | private: |
148 | |
149 | /**@name Private member data */ |
150 | //@{ |
151 | /// message test |
152 | std::string message_; |
153 | /// method name |
154 | std::string method_; |
155 | /// class name or hint |
156 | std::string class_; |
157 | /// file name |
158 | std::string file_; |
159 | /// Line number |
160 | int lineNumber_; |
161 | //@} |
162 | |
163 | public: |
164 | /// Whether to print every error |
165 | static bool printErrors_; |
166 | }; |
167 | |
168 | #ifndef __STRING |
169 | #define __STRING(x) #x |
170 | #endif |
171 | |
172 | #ifndef __GNUC_PREREQ |
173 | # define __GNUC_PREREQ(maj, min) (0) |
174 | #endif |
175 | |
176 | #ifndef COIN_ASSERT |
177 | # define CoinAssertDebug(expression) assert(expression) |
178 | # define CoinAssertDebugHint(expression,hint) assert(expression) |
179 | # define CoinAssert(expression) assert(expression) |
180 | # define CoinAssertHint(expression,hint) assert(expression) |
181 | #else |
182 | # ifdef NDEBUG |
183 | # define CoinAssertDebug(expression) {} |
184 | # define CoinAssertDebugHint(expression,hint) {} |
185 | # else |
186 | # if defined(__GNUC__) && __GNUC_PREREQ(2, 6) |
187 | # define CoinAssertDebug(expression) { \ |
188 | if (!(expression)) { \ |
189 | throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \ |
190 | "", __FILE__, __LINE__); \ |
191 | } \ |
192 | } |
193 | # define CoinAssertDebugHint(expression,hint) { \ |
194 | if (!(expression)) { \ |
195 | throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \ |
196 | hint, __FILE__,__LINE__); \ |
197 | } \ |
198 | } |
199 | # else |
200 | # define CoinAssertDebug(expression) { \ |
201 | if (!(expression)) { \ |
202 | throw CoinError(__STRING(expression), "", \ |
203 | "", __FILE__,__LINE__); \ |
204 | } \ |
205 | } |
206 | # define CoinAssertDebugHint(expression,hint) { \ |
207 | if (!(expression)) { \ |
208 | throw CoinError(__STRING(expression), "", \ |
209 | hint, __FILE__,__LINE__); \ |
210 | } \ |
211 | } |
212 | # endif |
213 | # endif |
214 | # if defined(__GNUC__) && __GNUC_PREREQ(2, 6) |
215 | # define CoinAssert(expression) { \ |
216 | if (!(expression)) { \ |
217 | throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \ |
218 | "", __FILE__, __LINE__); \ |
219 | } \ |
220 | } |
221 | # define CoinAssertHint(expression,hint) { \ |
222 | if (!(expression)) { \ |
223 | throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \ |
224 | hint, __FILE__,__LINE__); \ |
225 | } \ |
226 | } |
227 | # else |
228 | # define CoinAssert(expression) { \ |
229 | if (!(expression)) { \ |
230 | throw CoinError(__STRING(expression), "", \ |
231 | "", __FILE__,__LINE__); \ |
232 | } \ |
233 | } |
234 | # define CoinAssertHint(expression,hint) { \ |
235 | if (!(expression)) { \ |
236 | throw CoinError(__STRING(expression), "", \ |
237 | hint, __FILE__,__LINE__); \ |
238 | } \ |
239 | } |
240 | # endif |
241 | #endif |
242 | |
243 | |
244 | //############################################################################# |
245 | /** A function that tests the methods in the CoinError class. The |
246 | only reason for it not to be a member method is that this way it doesn't |
247 | have to be compiled into the library. And that's a gain, because the |
248 | library should be compiled with optimization on, but this method should be |
249 | compiled with debugging. */ |
250 | void |
251 | CoinErrorUnitTest(); |
252 | |
253 | #ifdef __LINE__ |
254 | #define CoinErrorFL(x, y, z) CoinError((x), (y), (z), __FILE__, __LINE__) |
255 | #endif |
256 | |
257 | #endif |
258 | |