MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2004 Sandia Corporation and Argonne National 00005 Laboratory. Under the terms of Contract DE-AC04-94AL85000 00006 with Sandia Corporation, the U.S. Government retains certain 00007 rights in this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 ***************************************************************** */ 00024 00025 #ifndef MSQ_ERROR_HPP 00026 #define MSQ_ERROR_HPP 00027 00028 #include "Mesquite.hpp" 00029 00030 #include <iosfwd> 00031 #include <list> 00032 #include <string> 00033 00034 namespace MBMesquite 00035 { 00036 00037 /**\defgroup error Mesquite internal error handling 00038 */ 00039 /*@{*/ 00040 00041 #ifndef MSQ_FUNCTION 00042 #define MSQ_FUNCTION "" 00043 #endif 00044 00045 /**\brief Mesquite's Error Checking macro. 00046 * 00047 * Check the status of an MsqError. Returns true as pushes the current 00048 * file/line onto the stack trace if the error flag is true. Returns 00049 * false otherwise. 00050 */ 00051 #define MSQ_CHKERR( err ) ( ( err ).error() && ( err ).push( MSQ_FUNCTION, __FILE__, __LINE__ ) ) 00052 00053 /**\brief If passed error is true, return from a void function. 00054 * 00055 * Shorthand for if (MSQ_CHKERR(err)) return 00056 */ 00057 #define MSQ_ERRRTN( err ) \ 00058 if( MSQ_CHKERR( err ) ) return 00059 00060 /**\brief Return zero/NULL on error. 00061 */ 00062 #define MSQ_ERRZERO( err ) \ 00063 if( MSQ_CHKERR( err ) ) return 0 00064 00065 /**\brief Return false on error. 00066 */ 00067 #define MSQ_ERRFALSE( err ) \ 00068 if( MSQ_CHKERR( err ) ) return false 00069 00070 /**\brief Macro to set error - use err.clear() to clear. 00071 * 00072 * Set the error object to the specified error code and optional error message, 00073 * and push the current file/line onto the stack trace. 00074 * Examples: 00075 * - MSQ_SETERR( err )( MsqError::INVALID_ARG ); 00076 * - MSQ_SETERR( err )( "foo cannot be zero", MsqError::INVALID_ARG ); 00077 * - MSQ_SETERR( err )( MsqError::INVALID_ARG, "foo = %d", foo ); 00078 */ 00079 #define MSQ_SETERR( err ) MBMesquite::MsqError::setter( err, MSQ_FUNCTION, __FILE__, __LINE__ ).set 00080 00081 /** 00082 *\class MsqError 00083 *\brief Used to hold the error state and return it to the application. 00084 *\author Jason Kraftcheck 00085 *\date 2004-09-17 00086 * 00087 * Used to hold error state and related information. 00088 * Internal Mesquite code should access this object via 00089 * the MSQ_SETERR() and MSQ_CHKERR() macros. 00090 * 00091 * For applications, the cast-to-bool operator and << operator 00092 * are provided for convenient, if simple access to this data. 00093 * E.g.: if (err) cout << err << endl; 00094 * 00095 * There are two options for an application to gain more detailed 00096 * access to the error data. The application may either access 00097 * the data stored in this class via the provided methods or 00098 * subclass MsqError, overriding set_error() and push() 00099 * to handle the error data as it is generated. 00100 */ 00101 class MsqError 00102 { 00103 public: 00104 /* NOTE: If you add an error to this list, make sure 00105 a) you add it *before* LAST_ERROR_CODE 00106 b) you add the corresponding string in MsqError.cpp 00107 */ 00108 /** \brief Error codes 00109 */ 00110 enum ErrorCode 00111 { 00112 NO_ERROR = 0, /**< no error */ 00113 UNKNOWN_ERROR, /**< unknown error occured */ 00114 OUT_OF_MEMORY, /**< unable to allocate the necessary memory */ 00115 INVALID_ARG, /**< invalid function argument passed */ 00116 NOT_INITIALIZED, /**< object not initialized */ 00117 INVALID_STATE, /**< object is in an invalid state */ 00118 FILE_ACCESS, /**< File cannot be opened/created. */ 00119 FILE_FORMAT, /**< Wrong file type */ 00120 PARSE_ERROR, /**< Error parsing input (or input file) */ 00121 IO_ERROR, /**< An I/O error occured (e.g. read from file failed.) */ 00122 INVALID_MESH, /**< The mesh is invalid */ 00123 NO_PD_STORAGE_MODE, /**< no storage mode chosen within PatchData */ 00124 NOT_IMPLEMENTED, /**< requested functionality is not (yet) implemented */ 00125 INTERNAL_ERROR, /**< A bug in Mesquite */ 00126 INTERRUPTED, /**< Application or user interrupted operation */ 00127 TAG_ALREADY_EXISTS, /**< Attempt to create tag that already exists */ 00128 TAG_NOT_FOUND, /**< Specified tag does not exist */ 00129 UNSUPPORTED_ELEMENT, /**< the element type is not supported. */ 00130 PARALLEL_ERROR, /**< an error occurred in parallel > */ 00131 BARRIER_VIOLATED, /**< barruer violated when processing barrier Target Metric */ 00132 LAST_ERROR_CODE 00133 }; 00134 00135 //! \brief resets error object to non-active state (no error). 00136 MESQUITE_EXPORT void clear(); 00137 00138 //! \brief Check if an error has occured 00139 inline bool error() const 00140 { 00141 return NO_ERROR != errorCode; 00142 } 00143 //! \brief Check if an error has occured 00144 inline operator bool() const 00145 { 00146 return NO_ERROR != errorCode; 00147 } 00148 00149 //! \brief Initialize to cleared state. 00150 MESQUITE_EXPORT MsqError() : errorCode( NO_ERROR ) {} 00151 00152 //! Destructor - empty but must declar virtual destrucor if virtual functions. 00153 MESQUITE_EXPORT virtual ~MsqError(); 00154 00155 /* ************************************************************ * 00156 * Low-level access to error data 00157 * ************************************************************ */ 00158 00159 //! Get error code 00160 inline ErrorCode error_code() const 00161 { 00162 return errorCode; 00163 } 00164 00165 //!\class Trace 00166 //!\brief One line of stack trace data 00167 struct MESQUITE_EXPORT Trace 00168 { 00169 std::string function; 00170 std::string file; 00171 int line; 00172 00173 Trace( const char* fun, const char* fil, int lin ) : function( fun ), file( fil ), line( lin ) {} 00174 }; 00175 00176 //! Get error message 00177 MESQUITE_EXPORT const char* error_message() const; 00178 00179 //! Container type used to store stack trace. 00180 //! Return type for stack() 00181 typedef std::list< Trace > StackTrace; 00182 00183 //! Get stack trace 00184 inline const StackTrace& stack() const 00185 { 00186 return stackTrace; 00187 } 00188 00189 /* ************************************************************ * 00190 * Set error data 00191 * ************************************************************ */ 00192 00193 //! Add to back-trace of call stack. Called by MSQ_CHKERR. 00194 //! Must always return true. 00195 MESQUITE_EXPORT virtual bool push( const char* function, const char* file, int line ); 00196 00197 //! Initialize the error object with the passed data. 00198 MESQUITE_EXPORT virtual bool set_error( ErrorCode num, const char* msg = 0 ); 00199 00200 //!\class setter 00201 //! Used for implementing pre-processor macros for internal use 00202 //! in Mesquite. 00203 class MESQUITE_EXPORT Setter 00204 { 00205 public: 00206 Setter( MsqError& err, const char* function, const char* file, int line ) 00207 : mErr( err ), functionName( function ), fileName( file ), lineNumber( line ) 00208 { 00209 } 00210 00211 bool set( ErrorCode num ); 00212 bool set( const char* message, ErrorCode num ); 00213 bool set( const std::string& message, ErrorCode num ); 00214 bool set( ErrorCode num, const char* format, ... ) 00215 #ifdef __GNUC__ 00216 __attribute__( ( format( printf, 3, 4 ) ) ) 00217 #endif 00218 ; // ending semicolon for set( ErrorCode num, const char* format, ... ) 00219 private: 00220 MsqError& mErr; 00221 const char* functionName; 00222 const char* fileName; 00223 int lineNumber; 00224 }; 00225 00226 static inline Setter setter( MsqError& err, const char* function, const char* file, int line ) 00227 { 00228 return Setter( err, function, file, line ); 00229 } 00230 00231 private: 00232 ErrorCode errorCode; 00233 std::string errorMessage; 00234 StackTrace stackTrace; 00235 }; // class MsqError 00236 00237 //! Print message and stack trace 00238 MESQUITE_EXPORT std::ostream& operator<<( std::ostream&, const MsqError& ); 00239 //! Print MsqError::Trace 00240 MESQUITE_EXPORT std::ostream& operator<<( std::ostream&, const MsqError::Trace& ); 00241 00242 /** 00243 *\class MsqPrintError 00244 *\brief Utility class for printing error data - used in Mesquite tests. 00245 *\author Jason Kraftcheck 00246 *\date 2004-10-11 00247 * 00248 * A subclass of MsqError. Behaves the same as MsqError, except that 00249 * it will automatically print itself to the specified ostream upon 00250 * destruction if an error occured. For objections of this type 00251 * declared on the stack (not new'd), this means that the error will 00252 * be printed when the function returns (if an error occured.) 00253 */ 00254 class MsqPrintError : public MsqError 00255 { 00256 public: 00257 //!\brief Initialize with ostream to print error data to. 00258 MESQUITE_EXPORT MsqPrintError( std::ostream& stream ) : outputStream( stream ) {} 00259 00260 //!\brief On destruction, conditionally prints error data. 00261 MESQUITE_EXPORT virtual ~MsqPrintError(); 00262 00263 private: 00264 std::ostream& outputStream; 00265 }; 00266 00267 /*@}*/ 00268 00269 } // namespace MBMesquite 00270 00271 #endif