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 */
19void 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
31This class is used when exceptions are thrown.
32It 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*/
42class CoinError {
43 friend void CoinErrorUnitTest();
44
45private:
46 CoinError()
47 :
48 message_(),
49 method_(),
50 class_(),
51 file_(),
52 lineNumber_()
53 {
54 // nothing to do here
55 }
56
57public:
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
147private:
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
163public:
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. */
250void
251CoinErrorUnitTest();
252
253#ifdef __LINE__
254#define CoinErrorFL(x, y, z) CoinError((x), (y), (z), __FILE__, __LINE__)
255#endif
256
257#endif
258