MOAB: Mesh Oriented datABase  (version 5.2.1)
MsqError.hpp
Go to the documentation of this file.
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 };
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines