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