Simbody

Exception.h

Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_EXCEPTION_H_
00002 #define SimTK_SimTKCOMMON_EXCEPTION_H_
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTKcommon                               *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core biosimulation toolkit originating from      *
00008  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00009  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00010  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2005-10 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors:                                                              *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00035 // Keeps MS VC++ 8 quiet about sprintf, strcpy, etc.
00036 #ifdef _MSC_VER
00037 #pragma warning(disable:4996)
00038 #endif
00039 
00040 #include "SimTKcommon/internal/common.h"
00041 
00042 #include <string>
00043 #include <iostream>
00044 #include <exception>
00045 #include <cstdarg>
00046 #include <cstdio>
00047 
00048 namespace SimTK {
00049 
00050 namespace Exception {
00051     
00052 // SimTK::Exception::Base   
00053 class Base : public std::exception {
00054 public:
00055     explicit Base(const char* fn="<UNKNOWN>", int ln=0) 
00056       : fileName(fn), lineNo(ln) { } 
00057     virtual ~Base() throw() { }
00058     const std::string& getMessage()     const { return msg; }
00059     const std::string& getMessageText() const { return text; }
00060 
00061     // override virtual function from std::exception
00062     const char* what() const throw() {return getMessage().c_str();}
00063 protected:
00064     void setMessage(const std::string& msgin) {
00065         text = msgin;
00066         msg = "SimTK Exception thrown at " + where() + ":\n  " + msgin;
00067     }
00068 private:
00069     std::string fileName;   // where the exception was thrown
00070     int         lineNo; 
00071     std::string msg;        // a message formatted for display by catcher
00072     std::string text;      // the original passed-in text
00073     
00074     static std::string shortenFileName(const std::string& fn) 
00075     {   std::string::size_type pos = fn.find_last_of("/\\");
00076         if (pos+1>=fn.size()) pos=0;
00077         return std::string(fn,(int)(pos+1),(int)(fn.size()-(pos+1)));
00078     }
00079     
00080     std::string where() const {
00081         char buf[32];
00082         sprintf(buf,"%d",lineNo);
00083         return shortenFileName(fileName) + ":" + std::string(buf); 
00084     } 
00085 };
00086 
00093 class Assert : public Base {
00094 public:
00095     Assert(const char* fn, int ln, const char* assertion, 
00096              const char* fmt ...) : Base(fn,ln)
00097     {
00098         char buf[1024];
00099         va_list args;
00100         va_start(args, fmt);
00101         vsprintf(buf, fmt, args);
00102 
00103         setMessage("Internal SimTK bug detected: " + std::string(buf)
00104                    + "\n  (Assertion '" + std::string(assertion) + "' failed).\n"
00105             "  Please file a SimTKcore bug report at https://simtk.org/home/simtkcore (Advanced tab).\n"
00106             "  Include the above information and anything else needed to reproduce the problem.");
00107         va_end(args);
00108     }
00109     virtual ~Assert() throw() { }
00110 };
00111 
00120 class ErrorCheck : public Base {
00121 public:
00122     ErrorCheck(const char* fn, int ln, const char* assertion, 
00123            const char* whereChecked,    // e.g., ClassName::methodName()
00124            const char* fmt ...) : Base(fn,ln)
00125     {
00126         char buf[1024];
00127         va_list args;
00128         va_start(args, fmt);
00129         vsprintf(buf, fmt, args);
00130 
00131         setMessage("Error detected by SimTK method " 
00132             + std::string(whereChecked) + ": "
00133             + std::string(buf)
00134             + "\n  (Required condition '" + std::string(assertion) + "' was not met.)\n");
00135         va_end(args);
00136     }
00137     virtual ~ErrorCheck() throw() { }
00138 };
00139 
00147 class APIArgcheckFailed : public Base {
00148 public:
00149     APIArgcheckFailed(const char* fn, int ln, const char* assertion,
00150                       const char* className, const char* methodName,
00151                       const char* fmt ...) : Base(fn,ln)
00152     {
00153         char buf[1024];
00154         va_list args;
00155         va_start(args, fmt);
00156         vsprintf(buf, fmt, args);
00157         setMessage("Bad call to SimTK API method " 
00158                    + std::string(className) + "::" + std::string(methodName) + "(): "
00159                    + std::string(buf)
00160                    + "\n  (Required condition '" + std::string(assertion) + "' was not met.)");
00161         va_end(args);
00162     }
00163     virtual ~APIArgcheckFailed() throw() { }
00164 };
00165 
00166 
00167 class IndexOutOfRange : public Base {
00168 public:
00169     IndexOutOfRange(const char* fn, int ln, const char* indexName,
00170                     long long lb, long long index, long long ub, const char* where)
00171       : Base(fn,ln)
00172     {
00173         char buf[1024];
00174 
00175         sprintf(buf, "Index out of range in %s: expected %lld <= %s < %lld but %s=%lld.",
00176             where,lb,indexName,ub,indexName,index);
00177         setMessage(std::string(buf));
00178     }
00179     virtual ~IndexOutOfRange() throw() { }
00180 };
00181 
00182 class SizeOutOfRange : public Base {
00183 public:
00184     SizeOutOfRange(const char* fn, int ln, const char* szName,
00185                    unsigned long long sz, unsigned long long maxsz, const char* where)
00186       : Base(fn,ln)
00187     {
00188         char buf[1024];
00189 
00190         sprintf(buf, "Size out of range in %s: expected 0 <= %s <= %llu but %s=%llu.",
00191             where,szName,maxsz,szName,sz);
00192         setMessage(std::string(buf));
00193     }
00194     virtual ~SizeOutOfRange() throw() { }
00195 };
00196 
00197 class SizeWasNegative : public Base {
00198 public:
00199     SizeWasNegative(const char* fn, int ln, const char* szName,
00200                    unsigned long long sz, const char* where)
00201       : Base(fn,ln)
00202     {
00203         char buf[1024];
00204 
00205         sprintf(buf, "Size argument was negative in %s: expected 0 <= %s but %s=%llu.",
00206             where,szName,szName,sz);
00207         setMessage(std::string(buf));
00208     }
00209     virtual ~SizeWasNegative() throw() { }
00210 };
00211 
00212 class ValueOutOfRange : public Base {
00213 public:
00214     ValueOutOfRange(const char* fn, int ln, const char* valueName,
00215                     Real lowerBound, Real value, Real upperBound, 
00216                     const char* where)
00217       : Base(fn,ln)
00218     {
00219         char buf[1024];
00220 
00221         sprintf(buf, "Value out of range in %s: expected %g <= %s <= %g but %s=%g.",
00222             where,lowerBound,valueName,upperBound,valueName,value);
00223         setMessage(std::string(buf));
00224     }
00225     virtual ~ValueOutOfRange() throw() { }
00226 };
00227 
00228 class ValueWasNegative : public Base {
00229 public:
00230     ValueWasNegative(const char* fn, int ln, const char* valueName,
00231                      Real value, const char* where)
00232       : Base(fn,ln)
00233     {
00234         char buf[1024];
00235 
00236         sprintf(buf, "Expected non-negative value for %s in %s but got %g.",
00237             valueName,where,value);
00238         setMessage(std::string(buf));
00239     }
00240     virtual ~ValueWasNegative() throw() { }
00241 };
00242 
00243 class UnimplementedVirtualMethod : public Base {
00244 public:
00245     UnimplementedVirtualMethod(const char* fn, int ln, 
00246         std::string baseClass, std::string methodName) 
00247         : Base(fn,ln)
00248     { 
00249         setMessage("The base class " + baseClass + 
00250             " dummy implementation of method " + methodName
00251             + "() was invoked because a derived class did not provide an implementation.");
00252     }
00253     virtual ~UnimplementedVirtualMethod() throw() { }
00254 };
00255 
00256 class IncompatibleValues : public Base {
00257 public:
00258     IncompatibleValues(const char* fn, int ln, std::string src, std::string dest) : Base(fn,ln)
00259     {
00260         setMessage("Attempt to assign a Value<"+src+"> to a Value<"+dest+">");
00261     }
00262     virtual ~IncompatibleValues() throw() { }
00263 };
00264 
00265 class OperationNotAllowedOnView : public Base {
00266 public:
00267     OperationNotAllowedOnView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
00268     {
00269         setMessage("Operation '" + op + "' allowed only for owners, not views");
00270     }   
00271     virtual ~OperationNotAllowedOnView() throw() { }
00272 };
00273 
00274 class OperationNotAllowedOnOwner : public Base {
00275 public:
00276     OperationNotAllowedOnOwner(const char* fn, int ln, const std::string& op) : Base(fn,ln)
00277     {
00278         setMessage("Operation '" + op + "' allowed only for views, not owners");
00279     }   
00280     virtual ~OperationNotAllowedOnOwner() throw() { }
00281 };
00282 
00283 class OperationNotAllowedOnNonconstReadOnlyView : public Base {
00284 public:
00285     OperationNotAllowedOnNonconstReadOnlyView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
00286     {
00287         setMessage("Operation '" + op + "' not allowed on non-const readonly view");
00288     }   
00289     virtual ~OperationNotAllowedOnNonconstReadOnlyView() throw() { }
00290 };
00291 
00292 // SimTK::Exception::Cant
00293 class Cant : public Base {
00294 public:
00295     Cant(const char* fn, int ln, const std::string& s) : Base(fn,ln)
00296     {
00297         setMessage("Can't perform operation: " + s);
00298     }   
00299     virtual ~Cant() throw() { }
00300 };
00301 
00302 } // namespace Exception
00303 } // namespace SimTK
00304 
00305 #define SimTK_THROW(exc) \
00306     throw exc(__FILE__, __LINE__)
00307 #define SimTK_THROW1(exc,a1) \
00308     throw exc(__FILE__, __LINE__,a1)
00309 #define SimTK_THROW2(exc,a1,a2) \
00310     throw exc(__FILE__, __LINE__,a1,a2)
00311 #define SimTK_THROW3(exc,a1,a2,a3) \
00312     throw exc(__FILE__, __LINE__,a1,a2,a3)
00313 #define SimTK_THROW4(exc,a1,a2,a3,a4) \
00314     throw exc(__FILE__, __LINE__,a1,a2,a3,a4)
00315 #define SimTK_THROW5(exc,a1,a2,a3,a4,a5) \
00316     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5)
00317 #define SimTK_THROW6(exc,a1,a2,a3,a4,a5,a6) \
00318     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6)
00319 #define SimTK_THROW7(exc,a1,a2,a3,a4,a5,a6,a7) \
00320     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7)
00321 #define SimTK_THROW8(exc,a1,a2,a3,a4,a5,a6,a7,a8) \
00322     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8)
00323 #define SimTK_THROW9(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9) \
00324     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9)
00325 #define SimTK_THROW10(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \
00326     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
00327 
00328 #endif // SimTK_SimTKCOMMON_EXCEPTION_H_
00329 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines