Nektar++
ErrorUtil.hpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File ErrorUtil.hpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: error related utilities
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 #ifndef ERRORUTIL_HPP
36 #define ERRORUTIL_HPP
37 
38 #include <iostream>
39 #include <stdexcept>
40 #include <boost/lexical_cast.hpp>
41 #include <boost/optional.hpp>
43 
44 #ifndef _WIN32
45 #include <execinfo.h>
46 #endif
47 
48 namespace ErrorUtil
49 {
50  static boost::optional<std::ostream&> outStream;
51 
52  inline static void SetErrorStream(std::ostream& o)
53  {
54  outStream = o;
55  }
56 
57  inline static bool HasCustomErrorStream()
58  {
59  return outStream ? true : false;
60  }
61 
62  enum ErrType
63  {
66  };
67 
68  class NekError : public std::runtime_error
69  {
70  public:
71  NekError(const std::string& message) : std::runtime_error(message) {}
72  };
73 
74  inline static void Error(ErrType type, const char *routine, int lineNumber, const char *msg, unsigned int level)
75  {
76  // The user of outStream is primarily for the unit tests.
77  // The unit tests often generate errors on purpose to make sure
78  // invalid usage is flagged appropriately. Printing the error
79  // messages to cerr made the unit test output hard to parse.
80 
81  std::string baseMsg = std::string("Level ") +
82  boost::lexical_cast<std::string>(level) +
83  std::string(" assertion violation\n") +
84 #if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
85  std::string("Where : ") + boost::lexical_cast<std::string>(routine) + std::string("[") + boost::lexical_cast<std::string>(lineNumber) + std::string("]\n") + std::string("Message : ") +
86 #endif
87  msg;
88 
89  std::string btMessage("");
90 #if defined(NEKTAR_FULLDEBUG)
91 #ifndef _WIN32
92  void *btArray[40];
93  int btSize;
94  char **btStrings;
95 
96  btSize = backtrace(btArray, 40);
97  btStrings = backtrace_symbols(btArray, btSize);
98 
99  for (int i = 0 ; i < btSize ; ++i)
100  {
101  btMessage += std::string(btStrings[i]) + "\n";
102  }
103  free(btStrings);
104 #endif
105 #endif
106  switch(type)
107  {
108  case efatal:
109  if( outStream )
110  {
111  (*outStream) << btMessage;
112  (*outStream) << "Fatal : " << baseMsg << std::endl;
113  }
114  else
115  {
116  std::cerr << btMessage;
117  std::cerr << std::endl << "Fatal : " << baseMsg << std::endl;
118  }
119 
120  throw NekError(baseMsg);
121  break;
122 
123  case ewarning:
124  if( outStream )
125  {
126  (*outStream) << btMessage;
127  (*outStream) << "Warning: " << baseMsg << std::endl;
128  }
129  else
130  {
131  std::cerr << btMessage;
132  std::cerr << "Warning: " << baseMsg << std::endl;
133  }
134  break;
135 
136  default:
137  std::cerr << "Unknown warning type: " << baseMsg << std::endl;
138  }
139  }
140 
141  inline static void Error(ErrType type, const char *routine, int lineNumber, const std::string& msg, unsigned int level)
142  {
143  Error(type, routine, lineNumber, msg.c_str(), level);
144  }
145 
146  inline static void Error(ErrType type, const char *routine, int lineNumber, const char *msg)
147  {
148  Error(type, routine, lineNumber, msg, 0);
149  }
150 } // end of namespace
151 
152 /// Assert Level 0 -- Fundamental assert which
153 /// is used whether in FULLDEBUG, DEBUG or OPT
154 /// compilation mode. This level assert is
155 /// considered code critical, even under
156 /// optimized compilation.
157 
158 #define NEKERROR(type, msg) \
159  ErrorUtil::Error(type, __FILE__, __LINE__, msg, 0);
160 
161 #define ASSERTL0(condition,msg) \
162  if(!(condition)) \
163 { \
164  ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 0); \
165 }
166 
167 #define WARNINGL0(condition,msg) \
168  if(!(condition)) \
169 { \
170  ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 0); \
171 }
172 
173 
174 /// Assert Level 1 -- Debugging which is used whether in FULLDEBUG or
175 /// DEBUG compilation mode. This level assert is designed for aiding
176 /// in standard debug (-g) mode
177 #if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
178 
179 #define ASSERTL1(condition,msg) \
180  if(!(condition)) \
181 { \
182  ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 1); \
183 }
184 #define WARNINGL1(condition,msg) \
185  if(!(condition)) \
186 { \
187  ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 0); \
188 }
189 
190 #else //defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
191 #define ASSERTL1(condition,msg)
192 #define WARNINGL1(condition,msg)
193 #endif //defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
194 
195 
196 /// Assert Level 2 -- Debugging which is used FULLDEBUG compilation
197 /// mode. This level assert is designed to provide addition safety
198 /// checks within the code (such as bounds checking, etc.).
199 #ifdef NEKTAR_FULLDEBUG
200 
201 #define ASSERTL2(condition,msg) \
202  if(!(condition)) \
203 { \
204  ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 2); \
205 }
206 #define WARNINGL2(condition,msg) \
207  if(!(condition)) \
208 { \
209  ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 0); \
210 }
211 
212 #else //NEKTAR_FULLDEBUG
213 #define ASSERTL2(condition,msg)
214 #define WARNINGL2(condition,msg)
215 #endif //NEKTAR_FULLDEBUG
216 
217 #endif //ERRORUTIL_HPP
218 
NekError(const std::string &message)
Definition: ErrorUtil.hpp:71
STL namespace.
static bool HasCustomErrorStream()
Definition: ErrorUtil.hpp:57
static void SetErrorStream(std::ostream &o)
Definition: ErrorUtil.hpp:52
static boost::optional< std::ostream & > outStream
Definition: ErrorUtil.hpp:50
static void Error(ErrType type, const char *routine, int lineNumber, const char *msg, unsigned int level)
Definition: ErrorUtil.hpp:74