Simbody  3.5
Exception.h
Go to the documentation of this file.
1 #ifndef SimTK_SimTKCOMMON_EXCEPTION_H_
2 #define SimTK_SimTKCOMMON_EXCEPTION_H_
3 
4 /* -------------------------------------------------------------------------- *
5  * Simbody(tm): SimTKcommon *
6  * -------------------------------------------------------------------------- *
7  * This is part of the SimTK biosimulation toolkit originating from *
8  * Simbios, the NIH National Center for Physics-Based Simulation of *
9  * Biological Structures at Stanford, funded under the NIH Roadmap for *
10  * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. *
11  * *
12  * Portions copyright (c) 2005-12 Stanford University and the Authors. *
13  * Authors: Michael Sherman *
14  * Contributors: *
15  * *
16  * Licensed under the Apache License, Version 2.0 (the "License"); you may *
17  * not use this file except in compliance with the License. You may obtain a *
18  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
19  * *
20  * Unless required by applicable law or agreed to in writing, software *
21  * distributed under the License is distributed on an "AS IS" BASIS, *
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
23  * See the License for the specific language governing permissions and *
24  * limitations under the License. *
25  * -------------------------------------------------------------------------- */
26 
27 // Keeps MS VC++ 8 quiet about sprintf, strcpy, etc.
28 #ifdef _MSC_VER
29 #pragma warning(disable:4996)
30 #endif
31 
33 
34 #include <string>
35 #include <iostream>
36 #include <exception>
37 #include <cstdarg>
38 #include <cstdio>
39 
40 namespace SimTK {
41 
42 namespace Exception {
43 
44 // SimTK::Exception::Base
45 class Base : public std::exception {
46 public:
47  explicit Base(const char* fn="<UNKNOWN>", int ln=0)
48  : fileName(fn), lineNo(ln) { }
49  virtual ~Base() throw() { }
50  const std::string& getMessage() const { return msg; }
51  const std::string& getMessageText() const { return text; }
52 
53  // override virtual function from std::exception
54  const char* what() const throw() {return getMessage().c_str();}
55 protected:
56  void setMessage(const std::string& msgin) {
57  text = msgin;
58  msg = "SimTK Exception thrown at " + where() + ":\n " + msgin;
59  }
60 private:
61  std::string fileName; // where the exception was thrown
62  int lineNo;
63  std::string msg; // a message formatted for display by catcher
64  std::string text; // the original passed-in text
65 
66  static std::string shortenFileName(const std::string& fn)
67  { std::string::size_type pos = fn.find_last_of("/\\");
68  if (pos+1>=fn.size()) pos=0;
69  return std::string(fn,(int)(pos+1),(int)(fn.size()-(pos+1)));
70  }
71 
72  std::string where() const {
73  char buf[32];
74  sprintf(buf,"%d",lineNo);
75  return shortenFileName(fileName) + ":" + std::string(buf);
76  }
77 };
78 
85 class Assert : public Base {
86 public:
87  Assert(const char* fn, int ln, const char* assertion,
88  const char* fmt ...) : Base(fn,ln)
89  {
90  char buf[1024];
91  va_list args;
92  va_start(args, fmt);
93  vsprintf(buf, fmt, args);
94 
95  setMessage("Internal bug detected: " + std::string(buf)
96  + "\n (Assertion '" + std::string(assertion) + "' failed).\n"
97  " Please file an Issue at https://github.com/simbody/simbody/issues.\n"
98  " Include the above information and anything else needed to reproduce the problem.");
99  va_end(args);
100  }
101  virtual ~Assert() throw() { }
102 };
103 
112 class ErrorCheck : public Base {
113 public:
114  ErrorCheck(const char* fn, int ln, const char* assertion,
115  const char* whereChecked, // e.g., ClassName::methodName()
116  const char* fmt ...) : Base(fn,ln)
117  {
118  char buf[1024];
119  va_list args;
120  va_start(args, fmt);
121  vsprintf(buf, fmt, args);
122 
123  setMessage("Error detected by Simbody method "
124  + std::string(whereChecked) + ": "
125  + std::string(buf)
126  + "\n (Required condition '" + std::string(assertion) + "' was not met.)\n");
127  va_end(args);
128  }
129  virtual ~ErrorCheck() throw() { }
130 };
131 
139 class APIArgcheckFailed : public Base {
140 public:
141  APIArgcheckFailed(const char* fn, int ln, const char* assertion,
142  const char* className, const char* methodName,
143  const char* fmt ...) : Base(fn,ln)
144  {
145  char buf[1024];
146  va_list args;
147  va_start(args, fmt);
148  vsprintf(buf, fmt, args);
149  setMessage("Bad call to Simbody API method "
150  + std::string(className) + "::" + std::string(methodName) + "(): "
151  + std::string(buf)
152  + "\n (Required condition '" + std::string(assertion) + "' was not met.)");
153  va_end(args);
154  }
155  virtual ~APIArgcheckFailed() throw() { }
156 };
157 
158 
159 class IndexOutOfRange : public Base {
160 public:
161  IndexOutOfRange(const char* fn, int ln, const char* indexName,
162  long long lb, long long index, long long ub, const char* where)
163  : Base(fn,ln)
164  {
165  char buf[1024];
166 
167  sprintf(buf, "Index out of range in %s: expected %lld <= %s < %lld but %s=%lld.",
168  where,lb,indexName,ub,indexName,index);
169  setMessage(std::string(buf));
170  }
171  virtual ~IndexOutOfRange() throw() { }
172 };
173 
174 class SizeOutOfRange : public Base {
175 public:
176  SizeOutOfRange(const char* fn, int ln, const char* szName,
177  unsigned long long sz, unsigned long long maxsz, const char* where)
178  : Base(fn,ln)
179  {
180  char buf[1024];
181 
182  sprintf(buf, "Size out of range in %s: expected 0 <= %s <= %llu but %s=%llu.",
183  where,szName,maxsz,szName,sz);
184  setMessage(std::string(buf));
185  }
186  virtual ~SizeOutOfRange() throw() { }
187 };
188 
189 class SizeWasNegative : public Base {
190 public:
191  SizeWasNegative(const char* fn, int ln, const char* szName,
192  unsigned long long sz, const char* where)
193  : Base(fn,ln)
194  {
195  char buf[1024];
196 
197  sprintf(buf, "Size argument was negative in %s: expected 0 <= %s but %s=%llu.",
198  where,szName,szName,sz);
199  setMessage(std::string(buf));
200  }
201  virtual ~SizeWasNegative() throw() { }
202 };
203 
204 class ValueOutOfRange : public Base {
205 public:
206  ValueOutOfRange(const char* fn, int ln, const char* valueName,
207  double lowerBound, double value, double upperBound,
208  const char* where)
209  : Base(fn,ln)
210  {
211  char buf[1024];
212 
213  sprintf(buf, "Value out of range in %s: expected %g <= %s <= %g but %s=%g.",
214  where,lowerBound,valueName,upperBound,valueName,value);
215  setMessage(std::string(buf));
216  }
217  virtual ~ValueOutOfRange() throw() { }
218 };
219 
220 class ValueWasNegative : public Base {
221 public:
222  ValueWasNegative(const char* fn, int ln, const char* valueName,
223  double value, const char* where)
224  : Base(fn,ln)
225  {
226  char buf[1024];
227 
228  sprintf(buf, "Expected non-negative value for %s in %s but got %g.",
229  valueName,where,value);
230  setMessage(std::string(buf));
231  }
232  virtual ~ValueWasNegative() throw() { }
233 };
234 
235 class UnimplementedMethod : public Base {
236 public:
237  UnimplementedMethod(const char* fn, int ln, std::string methodName)
238  : Base(fn,ln)
239  {
240  setMessage("The method " + methodName
241  + "is not yet implemented. Please post to the Simbody forum"
242  " to find a workaround or request implementation.");
243  }
244  virtual ~UnimplementedMethod() throw() { }
245 };
246 
248 public:
249  UnimplementedVirtualMethod(const char* fn, int ln,
250  std::string baseClass, std::string methodName)
251  : Base(fn,ln)
252  {
253  setMessage("The base class " + baseClass +
254  " dummy implementation of method " + methodName
255  + "() was invoked because a derived class did not provide an implementation.");
256  }
257  virtual ~UnimplementedVirtualMethod() throw() { }
258 };
259 
260 class IncompatibleValues : public Base {
261 public:
262  IncompatibleValues(const char* fn, int ln, std::string src, std::string dest) : Base(fn,ln)
263  {
264  setMessage("Attempt to assign a Value<"+src+"> to a Value<"+dest+">");
265  }
266  virtual ~IncompatibleValues() throw() { }
267 };
268 
270 public:
271  OperationNotAllowedOnView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
272  {
273  setMessage("Operation '" + op + "' allowed only for owners, not views");
274  }
275  virtual ~OperationNotAllowedOnView() throw() { }
276 };
277 
279 public:
280  OperationNotAllowedOnOwner(const char* fn, int ln, const std::string& op) : Base(fn,ln)
281  {
282  setMessage("Operation '" + op + "' allowed only for views, not owners");
283  }
284  virtual ~OperationNotAllowedOnOwner() throw() { }
285 };
286 
288 public:
289  OperationNotAllowedOnNonconstReadOnlyView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
290  {
291  setMessage("Operation '" + op + "' not allowed on non-const readonly view");
292  }
294 };
295 
296 // SimTK::Exception::Cant
297 class Cant : public Base {
298 public:
299  Cant(const char* fn, int ln, const std::string& s) : Base(fn,ln)
300  {
301  setMessage("Can't perform operation: " + s);
302  }
303  virtual ~Cant() throw() { }
304 };
305 
306 } // namespace Exception
307 } // namespace SimTK
308 
309 #define SimTK_THROW(exc) \
310  throw exc(__FILE__, __LINE__)
311 #define SimTK_THROW1(exc,a1) \
312  throw exc(__FILE__, __LINE__,a1)
313 #define SimTK_THROW2(exc,a1,a2) \
314  throw exc(__FILE__, __LINE__,a1,a2)
315 #define SimTK_THROW3(exc,a1,a2,a3) \
316  throw exc(__FILE__, __LINE__,a1,a2,a3)
317 #define SimTK_THROW4(exc,a1,a2,a3,a4) \
318  throw exc(__FILE__, __LINE__,a1,a2,a3,a4)
319 #define SimTK_THROW5(exc,a1,a2,a3,a4,a5) \
320  throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5)
321 #define SimTK_THROW6(exc,a1,a2,a3,a4,a5,a6) \
322  throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6)
323 #define SimTK_THROW7(exc,a1,a2,a3,a4,a5,a6,a7) \
324  throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7)
325 #define SimTK_THROW8(exc,a1,a2,a3,a4,a5,a6,a7,a8) \
326  throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8)
327 #define SimTK_THROW9(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9) \
328  throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9)
329 #define SimTK_THROW10(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \
330  throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
331 
332 #endif // SimTK_SimTKCOMMON_EXCEPTION_H_
333 
virtual ~UnimplementedMethod()
Definition: Exception.h:244
ValueOutOfRange(const char *fn, int ln, const char *valueName, double lowerBound, double value, double upperBound, const char *where)
Definition: Exception.h:206
Definition: Exception.h:204
virtual ~Assert()
Definition: Exception.h:101
const char * what() const
Definition: Exception.h:54
const std::string & getMessage() const
Definition: Exception.h:50
SizeOutOfRange(const char *fn, int ln, const char *szName, unsigned long long sz, unsigned long long maxsz, const char *where)
Definition: Exception.h:176
Base(const char *fn="<UNKNOWN>", int ln=0)
Definition: Exception.h:47
virtual ~Base()
Definition: Exception.h:49
void setMessage(const std::string &msgin)
Definition: Exception.h:56
This is the top-level SimTK namespace into which all SimTK names are placed to avoid collision with o...
Definition: Assembler.h:37
This is for reporting internally-detected bugs only, not problems induced by confused users (that is...
Definition: Exception.h:85
virtual ~IndexOutOfRange()
Definition: Exception.h:171
OperationNotAllowedOnNonconstReadOnlyView(const char *fn, int ln, const std::string &op)
Definition: Exception.h:289
SizeWasNegative(const char *fn, int ln, const char *szName, unsigned long long sz, const char *where)
Definition: Exception.h:191
Definition: Exception.h:297
virtual ~ErrorCheck()
Definition: Exception.h:129
const std::string & getMessageText() const
Definition: Exception.h:51
ErrorCheck(const char *fn, int ln, const char *assertion, const char *whereChecked, const char *fmt...)
Definition: Exception.h:114
Definition: Exception.h:174
Definition: Exception.h:189
UnimplementedMethod(const char *fn, int ln, std::string methodName)
Definition: Exception.h:237
virtual ~OperationNotAllowedOnView()
Definition: Exception.h:275
virtual ~SizeWasNegative()
Definition: Exception.h:201
virtual ~SizeOutOfRange()
Definition: Exception.h:186
This is for reporting errors occurring during execution of SimTK core methods, beyond those caused by...
Definition: Exception.h:112
virtual ~Cant()
Definition: Exception.h:303
Definition: Exception.h:45
Definition: Exception.h:159
Assert(const char *fn, int ln, const char *assertion, const char *fmt...)
Definition: Exception.h:87
Definition: Exception.h:260
UnimplementedVirtualMethod(const char *fn, int ln, std::string baseClass, std::string methodName)
Definition: Exception.h:249
virtual ~UnimplementedVirtualMethod()
Definition: Exception.h:257
virtual ~OperationNotAllowedOnNonconstReadOnlyView()
Definition: Exception.h:293
IncompatibleValues(const char *fn, int ln, std::string src, std::string dest)
Definition: Exception.h:262
virtual ~APIArgcheckFailed()
Definition: Exception.h:155
Definition: Exception.h:220
This is for reporting problems detected by checking the caller&#39;s supplied arguments to a SimTK API me...
Definition: Exception.h:139
OperationNotAllowedOnOwner(const char *fn, int ln, const std::string &op)
Definition: Exception.h:280
ValueWasNegative(const char *fn, int ln, const char *valueName, double value, const char *where)
Definition: Exception.h:222
virtual ~ValueOutOfRange()
Definition: Exception.h:217
Mandatory first inclusion for any Simbody source or header file.
Definition: Exception.h:235
IndexOutOfRange(const char *fn, int ln, const char *indexName, long long lb, long long index, long long ub, const char *where)
Definition: Exception.h:161
Cant(const char *fn, int ln, const std::string &s)
Definition: Exception.h:299
APIArgcheckFailed(const char *fn, int ln, const char *assertion, const char *className, const char *methodName, const char *fmt...)
Definition: Exception.h:141
virtual ~IncompatibleValues()
Definition: Exception.h:266
virtual ~OperationNotAllowedOnOwner()
Definition: Exception.h:284
OperationNotAllowedOnView(const char *fn, int ln, const std::string &op)
Definition: Exception.h:271
virtual ~ValueWasNegative()
Definition: Exception.h:232