Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 namespace ErrorUtil
45 {
46  static boost::optional<std::ostream&> outStream;
47 
48  inline static void SetErrorStream(std::ostream& o)
49  {
50  outStream = o;
51  }
52 
53  inline static bool HasCustomErrorStream()
54  {
55  return outStream ? true : false;
56  }
57 
58  enum ErrType
59  {
62  };
63 
64  class NekError : public std::runtime_error
65  {
66  public:
67  NekError(const std::string& message) : std::runtime_error(message) {}
68  };
69 
70  inline static void Error(ErrType type, const char *routine, int lineNumber, const char *msg, unsigned int level)
71  {
72  // The user of outStream is primarily for the unit tests.
73  // The unit tests often generate errors on purpose to make sure
74  // invalid usage is flagged appropriately. Printing the error
75  // messages to cerr made the unit test output hard to parse.
76 
77  std::string baseMsg = std::string("Level ") +
78  boost::lexical_cast<std::string>(level) +
79  std::string(" assertion violation\n") +
80 #if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
81  std::string("Where : ") + boost::lexical_cast<std::string>(routine) + std::string("[") + boost::lexical_cast<std::string>(lineNumber) + std::string("]\n") + std::string("Message : ") +
82 #endif
83  msg;
84 
85  switch(type)
86  {
87  case efatal:
88  if( outStream )
89  {
90  (*outStream) << "Fatal : " << baseMsg << std::endl;
91  }
92  else
93  {
94  std::cerr << std::endl << "Fatal : " << baseMsg << std::endl;
95  }
96  throw NekError(baseMsg);
97  break;
98 
99  case ewarning:
100  if( outStream )
101  {
102  (*outStream) << "Warning: " << baseMsg << std::endl;
103  }
104  else
105  {
106  std::cerr << "Warning: " << baseMsg << std::endl;
107  }
108  break;
109 
110  default:
111  std::cerr << "Unknown warning type: " << baseMsg << std::endl;
112  }
113  }
114 
115  inline static void Error(ErrType type, const char *routine, int lineNumber, const std::string& msg, unsigned int level)
116  {
117  Error(type, routine, lineNumber, msg.c_str(), level);
118  }
119 
120  inline static void Error(ErrType type, const char *routine, int lineNumber, const char *msg)
121  {
122  Error(type, routine, lineNumber, msg, 0);
123  }
124 } // end of namespace
125 
126 /// Assert Level 0 -- Fundamental assert which
127 /// is used whether in FULLDEBUG, DEBUG or OPT
128 /// compilation mode. This level assert is
129 /// considered code critical, even under
130 /// optimized compilation.
131 
132 #define NEKERROR(type, msg) \
133  ErrorUtil::Error(type, __FILE__, __LINE__, msg, 0);
134 
135 #define ASSERTL0(condition,msg) \
136  if(!(condition)) \
137 { \
138  ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 0); \
139 }
140 
141 #define WARNINGL0(condition,msg) \
142  if(!(condition)) \
143 { \
144  ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 0); \
145 }
146 
147 
148 /// Assert Level 1 -- Debugging which is used whether in FULLDEBUG or
149 /// DEBUG compilation mode. This level assert is designed for aiding
150 /// in standard debug (-g) mode
151 #if defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
152 
153 #define ASSERTL1(condition,msg) \
154  if(!(condition)) \
155 { \
156  ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 1); \
157 }
158 #define WARNINGL1(condition,msg) \
159  if(!(condition)) \
160 { \
161  ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 0); \
162 }
163 
164 #else //defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
165 #define ASSERTL1(condition,msg)
166 #define WARNINGL1(condition,msg)
167 #endif //defined(NEKTAR_DEBUG) || defined(NEKTAR_FULLDEBUG)
168 
169 
170 /// Assert Level 2 -- Debugging which is used FULLDEBUG compilation
171 /// mode. This level assert is designed to provide addition safety
172 /// checks within the code (such as bounds checking, etc.).
173 #ifdef NEKTAR_FULLDEBUG
174 
175 #define ASSERTL2(condition,msg) \
176  if(!(condition)) \
177 { \
178  ErrorUtil::Error(ErrorUtil::efatal, __FILE__, __LINE__, msg, 2); \
179 }
180 #define WARNINGL2(condition,msg) \
181  if(!(condition)) \
182 { \
183  ErrorUtil::Error(ErrorUtil::ewarning, __FILE__, __LINE__, msg, 0); \
184 }
185 
186 #else //NEKTAR_FULLDEBUG
187 #define ASSERTL2(condition,msg)
188 #define WARNINGL2(condition,msg)
189 #endif //NEKTAR_FULLDEBUG
190 
191 #endif //ERRORUTIL_HPP
192