Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Misc/MsqError.cpp
Go to the documentation of this file.
1 /* *****************************************************************
2  MESQUITE -- The Mesh Quality Improvement Toolkit
3 
4  Copyright 2004 Sandia Corporation and Argonne National
5  Laboratory. Under the terms of Contract DE-AC04-94AL85000
6  with Sandia Corporation, the U.S. Government retains certain
7  rights in this software.
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Lesser General Public
11  License as published by the Free Software Foundation; either
12  version 2.1 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Lesser General Public License for more details.
18 
19  You should have received a copy of the GNU Lesser General Public License
20  (lgpl.txt) along with this library; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 
23  ***************************************************************** */
30 #include "MsqError.hpp"
31 #include "Mesquite.hpp"
32 
33 #ifdef MSQ_USE_OLD_IO_HEADERS
34 # include <ostream.h>
35 #else
36 # include <ostream>
37 #endif
38 
39 #include <stdio.h>
40 #include <stdarg.h>
41 #include <assert.h>
42 
43 namespace Mesquite {
44 
45 const char* MsqError::error_message() const
46 {
47  static const char* const error_messages[] = {
48  "No Error",
49  "<unknown>",
50  "Out of memory",
51  "Invalid argument",
52  "Data not initialized",
53  "Invalid state",
54  "File access error",
55  "File format error",
56  "Syntax error",
57  "I/O error",
58  "Invalid mesh",
59  "No storage mode for PatchData",
60  "Not implemented",
61  "Internal error",
62  "Interrupted",
63  "Duplicate tag name",
64  "Tag not found",
65  "Invalid Error Code"
66  };
67 
68  /* If this is ever false, it should be caught by a unit test.
69  Do an assert here so the unit test fails.
70  This asserts that all error codes have a string in the above list. */
71  assert( sizeof(error_messages) == sizeof(char*) * (LAST_ERROR_CODE+1) );
72 
73  if (!errorMessage.empty())
74  return errorMessage.c_str();
75 
76  if (errorCode >= 0 && errorCode < LAST_ERROR_CODE)
77  return error_messages[errorCode];
78 
79  return error_messages[LAST_ERROR_CODE];
80 }
81 
83 
84 bool MsqError::Setter::set( const msq_std::string& msg, ErrorCode num )
85 {
86  return mErr.set_error( num, msg.c_str() )
88 }
89 
90 bool MsqError::Setter::set( const char* msg, ErrorCode num )
91 {
92  return mErr.set_error( num, msg )
93  && mErr.push( functionName, fileName, lineNumber );
94 }
95 
97 {
98  return mErr.set_error( num )
99  && mErr.push( functionName, fileName, lineNumber );
100 }
101 
102 bool MsqError::Setter::set( ErrorCode num, const char* format, ... )
103 {
104  char buffer[1024];
105 
106 #if defined(HAVE_VSNPRINTF)
107  va_list args;
108  va_start( args, format );
109  vsnprintf( buffer, sizeof(buffer), format, args );
110  va_end( args );
111 #elif defined(HAVE__VSNPRINTF)
112  va_list args;
113  va_start( args, format );
114  _vsnprintf( buffer, sizeof(buffer), format, args );
115  va_end( args );
116 #elif defined(HAVE_VSPRINTF)
117  va_list args;
118  va_start( args, format );
119  vsprintf( buffer, format, args );
120  va_end( args );
121 #else
122  strncpy( buffer, format, sizeof(buffer) );
123  buffer[sizeof(buffer)-1] = '\0';
124 #endif
125 
126  return mErr.set_error( num, buffer )
127  && mErr.push( functionName, fileName, lineNumber );
128 }
129 
130 bool MsqError::push( const char* function, const char* file, int line )
131 {
132  stackTrace.push_back( Trace(function, file, line) );
133  return true;
134 }
135 
136 bool MsqError::set_error( ErrorCode num, const char* msg )
137 {
138  errorCode = num;
139  stackTrace.clear();
140 
141  if (msg)
142  errorMessage = msg;
143  else
144  // MS VC6 doesn't have string::clear()!
145  errorMessage.resize(0);
146 
147  return num != NO_ERROR;
148 }
149 
151 {
153  // MS VC6 doesn't have string::clear()!
154  errorMessage.resize(0);
155  stackTrace.clear();
156 }
157 
158 msq_stdio::ostream& operator<<( msq_stdio::ostream& str, const MsqError::Trace& tr )
159 {
160  return (str << tr.function << " at " << tr.file << ":" << tr.line);
161 }
162 
163 msq_stdio::ostream& operator<<( msq_stdio::ostream& str, const MsqError& err )
164 {
165  str << "MESQUITE ERROR " << (int)err.error_code() << " : "
166  << err.error_message() << msq_stdio::endl;
167 
168  MsqError::StackTrace::const_iterator iter = err.stack().begin();
169  const MsqError::StackTrace::const_iterator end = err.stack().end();
170  if (iter != end)
171  {
172  str << " at " << *iter << msq_stdio::endl;
173  ++iter;
174  }
175  for ( ; iter != end; ++iter)
176  str << " in " << *iter << msq_stdio::endl;
177 
178  return str;
179 }
180 
182  { if (error()) outputStream << *this << msq_stdio::endl; }
183 
184 }
Used to hold the error state and return it to the application.
ErrorCode error_code() const
Get error code.
virtual bool push(const char *function, const char *file, int line)
Add to back-trace of call stack.
virtual bool set_error(ErrorCode num, const char *msg=0)
Initialize the error object with the passed data.
One line of stack trace data.
bool error() const
Check if an error has occured.
bool set(ErrorCode num)
const char * error_message() const
Get error message.
void clear()
resets error object to non-active state (no error).
virtual ~MsqError()
Destructor - empty but must declar virtual destrucor if virtual functions.
msq_stdio::ostream & operator<<(msq_stdio::ostream &s, const Matrix3D &A)
virtual ~MsqPrintError()
On destruction, conditionally prints error data.
const StackTrace & stack() const
Get stack trace.