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 \file MsqError.cpp 00026 \brief Used to hold the error state and return it to the application. 00027 \author Jason Kraftcheck 00028 \date 2004-09-17 00029 */ 00030 00031 #include "MsqError.hpp" 00032 #include "Mesquite.hpp" 00033 00034 #include <ostream> 00035 #include <cstdio> 00036 #include <cstdarg> 00037 #include <cassert> 00038 00039 #include <cstring> 00040 using std::strncpy; 00041 00042 namespace MBMesquite 00043 { 00044 00045 const char* MsqError::error_message() const 00046 { 00047 static const char* const error_messages[] = { "No Error", 00048 "<unknown>", 00049 "Out of memory", 00050 "Invalid argument", 00051 "Data not initialized", 00052 "Invalid state", 00053 "File access error", 00054 "File format error", 00055 "Syntax error", 00056 "I/O error", 00057 "Invalid mesh", 00058 "No storage mode for PatchData", 00059 "Not implemented", 00060 "Internal error", 00061 "Interrupted", 00062 "Duplicate tag name", 00063 "Tag not found", 00064 "Unsupported element type", 00065 "Parallel Error - error occurred on at least one processor", 00066 "barruer violated when processing barrier Target Metric", 00067 "Invalid Error Code" }; 00068 00069 /* If this is ever false, it should be caught by a unit test. 00070 Do an assert here so the unit test fails. 00071 This asserts that all error codes have a string in the above list. */ 00072 assert( sizeof( error_messages ) == sizeof( char* ) * ( LAST_ERROR_CODE + 1 ) ); 00073 00074 if( !errorMessage.empty() ) return errorMessage.c_str(); 00075 00076 if( errorCode >= 0 && errorCode < LAST_ERROR_CODE ) return error_messages[errorCode]; 00077 00078 return error_messages[LAST_ERROR_CODE]; 00079 } 00080 00081 MsqError::~MsqError() {} 00082 00083 bool MsqError::Setter::set( const std::string& msg, ErrorCode num ) 00084 { 00085 return mErr.set_error( num, msg.c_str() ) && mErr.push( functionName, fileName, lineNumber ); 00086 } 00087 00088 bool MsqError::Setter::set( const char* msg, ErrorCode num ) 00089 { 00090 return mErr.set_error( num, msg ) && mErr.push( functionName, fileName, lineNumber ); 00091 } 00092 00093 bool MsqError::Setter::set( ErrorCode num ) 00094 { 00095 return mErr.set_error( num ) && mErr.push( functionName, fileName, lineNumber ); 00096 } 00097 00098 bool MsqError::Setter::set( ErrorCode num, const char* format, ... ) 00099 { 00100 char buffer[1024]; 00101 00102 #if defined( HAVE_VSNPRINTF ) 00103 va_list args; 00104 va_start( args, format ); 00105 vsnprintf( buffer, sizeof( buffer ), format, args ); 00106 va_end( args ); 00107 #elif defined( HAVE__VSNPRINTF ) 00108 va_list args; 00109 va_start( args, format ); 00110 _vsnprintf( buffer, sizeof( buffer ), format, args ); 00111 va_end( args ); 00112 #elif defined( HAVE_VSPRINTF ) 00113 va_list args; 00114 va_start( args, format ); 00115 vsprintf( buffer, format, args ); 00116 va_end( args ); 00117 #else 00118 strncpy( buffer, format, sizeof( buffer ) ); 00119 buffer[sizeof( buffer ) - 1] = '\0'; 00120 #endif 00121 00122 return mErr.set_error( num, buffer ) && mErr.push( functionName, fileName, lineNumber ); 00123 } 00124 00125 bool MsqError::push( const char* function, const char* file, int line ) 00126 { 00127 stackTrace.push_back( Trace( function, file, line ) ); 00128 return true; 00129 } 00130 00131 bool MsqError::set_error( ErrorCode num, const char* msg ) 00132 { 00133 errorCode = num; 00134 stackTrace.clear(); 00135 00136 if( msg ) 00137 errorMessage = msg; 00138 else 00139 // MS VC6 doesn't have string::clear()! 00140 errorMessage.resize( 0 ); 00141 00142 return num != NO_ERROR; 00143 } 00144 00145 void MsqError::clear() 00146 { 00147 errorCode = NO_ERROR; 00148 // MS VC6 doesn't have string::clear()! 00149 errorMessage.resize( 0 ); 00150 stackTrace.clear(); 00151 } 00152 00153 std::ostream& operator<<( std::ostream& str, const MsqError::Trace& tr ) 00154 { 00155 return ( str << tr.function << " at " << tr.file << ":" << tr.line ); 00156 } 00157 00158 std::ostream& operator<<( std::ostream& str, const MsqError& err ) 00159 { 00160 str << "MESQUITE ERROR " << (int)err.error_code() << " : " << err.error_message() << std::endl; 00161 00162 MsqError::StackTrace::const_iterator iter = err.stack().begin(); 00163 const MsqError::StackTrace::const_iterator end = err.stack().end(); 00164 if( iter != end ) 00165 { 00166 str << " at " << *iter << std::endl; 00167 ++iter; 00168 } 00169 for( ; iter != end; ++iter ) 00170 str << " in " << *iter << std::endl; 00171 00172 return str; 00173 } 00174 00175 MsqPrintError::~MsqPrintError() 00176 { 00177 if( error() ) outputStream << *this << std::endl; 00178 } 00179 00180 } // namespace MBMesquite