1 /* $Id: CoinError.hpp 2083 2019-01-06 19:38:09Z unxusr $ */
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 WindowsErrorPopupBlocker();
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:
CoinError()46   CoinError()
47     : message_()
48     , method_()
49     , class_()
50     , file_()
51     , lineNumber_()
52   {
53     // nothing to do here
54   }
55 
56 public:
57   //-------------------------------------------------------------------
58   // Get methods
59   //-------------------------------------------------------------------
60   /**@name Get error attributes */
61   //@{
62   /// get message text
message() const63   inline const std::string &message() const
64   {
65     return message_;
66   }
67   /// get name of method instantiating error
methodName() const68   inline const std::string &methodName() const
69   {
70     return method_;
71   }
72   /// get name of class instantiating error (or hint for assert)
className() const73   inline const std::string &className() const
74   {
75     return class_;
76   }
77   /// get name of file for assert
fileName() const78   inline const std::string &fileName() const
79   {
80     return file_;
81   }
82   /// get line number of assert (-1 if not assert)
lineNumber() const83   inline int lineNumber() const
84   {
85     return lineNumber_;
86   }
87   /// Just print (for asserts)
print(bool doPrint=true) const88   inline void print(bool doPrint = true) const
89   {
90     if (!doPrint)
91       return;
92     if (lineNumber_ < 0) {
93       std::cout << message_ << " in " << class_ << "::" << method_ << std::endl;
94     } else {
95       std::cout << file_ << ":" << lineNumber_ << " method " << method_
96                 << " : assertion \'" << message_ << "\' failed." << std::endl;
97       if (class_ != "")
98         std::cout << "Possible reason: " << class_ << std::endl;
99     }
100   }
101   //@}
102 
103   /**@name Constructors and destructors */
104   //@{
105   /// Alternate Constructor
CoinError(std::string message__,std::string methodName__,std::string className__,std::string fileName_=std::string (),int line=-1)106   CoinError(
107     std::string message__,
108     std::string methodName__,
109     std::string className__,
110     std::string fileName_ = std::string(),
111     int line = -1)
112     : message_(message__)
113     , method_(methodName__)
114     , class_(className__)
115     , file_(fileName_)
116     , lineNumber_(line)
117   {
118     print(printErrors_);
119   }
120 
121   /// Copy constructor
CoinError(const CoinError & source)122   CoinError(const CoinError &source)
123     : message_(source.message_)
124     , method_(source.method_)
125     , class_(source.class_)
126     , file_(source.file_)
127     , lineNumber_(source.lineNumber_)
128   {
129     // nothing to do here
130   }
131 
132   /// Assignment operator
operator =(const CoinError & rhs)133   CoinError &operator=(const CoinError &rhs)
134   {
135     if (this != &rhs) {
136       message_ = rhs.message_;
137       method_ = rhs.method_;
138       class_ = rhs.class_;
139       file_ = rhs.file_;
140       lineNumber_ = rhs.lineNumber_;
141     }
142     return *this;
143   }
144 
145   /// Destructor
~CoinError()146   virtual ~CoinError()
147   {
148     // nothing to do here
149   }
150   //@}
151 
152 private:
153   /**@name Private member data */
154   //@{
155   /// message test
156   std::string message_;
157   /// method name
158   std::string method_;
159   /// class name or hint
160   std::string class_;
161   /// file name
162   std::string file_;
163   /// Line number
164   int lineNumber_;
165   //@}
166 
167 public:
168   /// Whether to print every error
169   static bool printErrors_;
170 };
171 
172 #ifndef __STRING
173 #define __STRING(x) #x
174 #endif
175 
176 #ifndef __GNUC_PREREQ
177 #define __GNUC_PREREQ(maj, min) (0)
178 #endif
179 
180 #ifndef COIN_ASSERT
181 #define CoinAssertDebug(expression) assert(expression)
182 #define CoinAssertDebugHint(expression, hint) assert(expression)
183 #define CoinAssert(expression) assert(expression)
184 #define CoinAssertHint(expression, hint) assert(expression)
185 #else
186 #ifdef NDEBUG
187 #define CoinAssertDebug(expression) \
188   {                                 \
189   }
190 #define CoinAssertDebugHint(expression, hint) \
191   {                                           \
192   }
193 #else
194 #if defined(__GNUC__) && __GNUC_PREREQ(2, 6)
195 #define CoinAssertDebug(expression)                              \
196   {                                                              \
197     if (!(expression)) {                                         \
198       throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \
199         "", __FILE__, __LINE__);                                 \
200     }                                                            \
201   }
202 #define CoinAssertDebugHint(expression, hint)                    \
203   {                                                              \
204     if (!(expression)) {                                         \
205       throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \
206         hint, __FILE__, __LINE__);                               \
207     }                                                            \
208   }
209 #else
210 #define CoinAssertDebug(expression)             \
211   {                                             \
212     if (!(expression)) {                        \
213       throw CoinError(__STRING(expression), "", \
214         "", __FILE__, __LINE__);                \
215     }                                           \
216   }
217 #define CoinAssertDebugHint(expression, hint)   \
218   {                                             \
219     if (!(expression)) {                        \
220       throw CoinError(__STRING(expression), "", \
221         hint, __FILE__, __LINE__);              \
222     }                                           \
223   }
224 #endif
225 #endif
226 #if defined(__GNUC__) && __GNUC_PREREQ(2, 6)
227 #define CoinAssert(expression)                                   \
228   {                                                              \
229     if (!(expression)) {                                         \
230       throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \
231         "", __FILE__, __LINE__);                                 \
232     }                                                            \
233   }
234 #define CoinAssertHint(expression, hint)                         \
235   {                                                              \
236     if (!(expression)) {                                         \
237       throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \
238         hint, __FILE__, __LINE__);                               \
239     }                                                            \
240   }
241 #else
242 #define CoinAssert(expression)                  \
243   {                                             \
244     if (!(expression)) {                        \
245       throw CoinError(__STRING(expression), "", \
246         "", __FILE__, __LINE__);                \
247     }                                           \
248   }
249 #define CoinAssertHint(expression, hint)        \
250   {                                             \
251     if (!(expression)) {                        \
252       throw CoinError(__STRING(expression), "", \
253         hint, __FILE__, __LINE__);              \
254     }                                           \
255   }
256 #endif
257 #endif
258 
259 //#############################################################################
260 /** A function that tests the methods in the CoinError class. The
261     only reason for it not to be a member method is that this way it doesn't
262     have to be compiled into the library. And that's a gain, because the
263     library should be compiled with optimization on, but this method should be
264     compiled with debugging. */
265 void CoinErrorUnitTest();
266 
267 #ifdef __LINE__
268 #define CoinErrorFL(x, y, z) CoinError((x), (y), (z), __FILE__, __LINE__)
269 #endif
270 
271 #endif
272 
273 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
274 */
275