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-7 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 
00047 namespace SimTK {
00048 
00049 namespace Exception {
00050     
00051 // SimTK::Exception::Base   
00052 class Base : public std::exception {
00053 public:
00054     explicit Base(const char* fn="<UNKNOWN>", int ln=0) 
00055       : fileName(fn), lineNo(ln) { } 
00056     virtual ~Base() throw() { }
00057     const std::string& getMessage()     const { return msg; }
00058     const std::string& getMessageText() const { return text; }
00059 
00060     // override virtual function from std::exception
00061     const char* what() const throw() {return getMessage().c_str();}
00062 protected:
00063     void setMessage(const std::string& msgin) {
00064         text = msgin;
00065         msg = "SimTK Exception thrown at " + where() + ":\n  " + msgin;
00066     }
00067 private:
00068     std::string fileName;   // where the exception was thrown
00069     int         lineNo; 
00070     std::string msg;        // a message formatted for display by catcher
00071     std::string text;      // the original passed-in text
00072     
00073     static std::string shortenFileName(const std::string& fn) 
00074     {   std::string::size_type pos = fn.find_last_of("/\\");
00075         if (pos+1>=fn.size()) pos=0;
00076         return std::string(fn,(int)(pos+1),(int)(fn.size()-(pos+1)));
00077     }
00078     
00079     std::string where() const {
00080         char buf[32];
00081         sprintf(buf,"%d",lineNo);
00082         return shortenFileName(fileName) + ":" + std::string(buf); 
00083     } 
00084 };
00085 
00092 class Assert : public Base {
00093 public:
00094     Assert(const char* fn, int ln, const char* assertion, 
00095              const char* fmt ...) : Base(fn,ln)
00096     {
00097         char buf[1024];
00098         va_list args;
00099         va_start(args, fmt);
00100         vsprintf(buf, fmt, args);
00101 
00102         setMessage("Internal SimTK bug detected: " + std::string(buf)
00103                    + "\n  (Assertion '" + std::string(assertion) + "' failed).\n"
00104             "  Please file a SimTKcore bug report at https://simtk.org/home/simtkcore (Advanced tab).\n"
00105             "  Include the above information and anything else needed to reproduce the problem.");
00106         va_end(args);
00107     }
00108 };
00109 
00118 class ErrorCheck : public Base {
00119 public:
00120     ErrorCheck(const char* fn, int ln, const char* assertion, 
00121            const char* whereChecked,    // e.g., ClassName::methodName()
00122            const char* fmt ...) : Base(fn,ln)
00123     {
00124         char buf[1024];
00125         va_list args;
00126         va_start(args, fmt);
00127         vsprintf(buf, fmt, args);
00128 
00129         setMessage("Error detected by SimTK method " 
00130             + std::string(whereChecked) + ": "
00131             + std::string(buf)
00132             + "\n  (Required condition '" + std::string(assertion) + "' was not met.)\n");
00133         va_end(args);
00134     }
00135 private:
00136 };
00137 
00145 class APIArgcheckFailed : public Base {
00146 public:
00147     APIArgcheckFailed(const char* fn, int ln, const char* assertion,
00148                       const char* className, const char* methodName,
00149                       const char* fmt ...) : Base(fn,ln)
00150     {
00151         char buf[1024];
00152         va_list args;
00153         va_start(args, fmt);
00154         vsprintf(buf, fmt, args);
00155         setMessage("Bad call to SimTK API method " 
00156                    + std::string(className) + "::" + std::string(methodName) + "(): "
00157                    + std::string(buf)
00158                    + "\n  (Required condition '" + std::string(assertion) + "' was not met.)");
00159         va_end(args);
00160     }
00161 };
00162 
00163 
00164 class IndexOutOfRange : public Base {
00165 public:
00166     IndexOutOfRange(const char* fn, int ln, const char* indexName,
00167                     long lb, long index, long ub, const char* where)
00168       : Base(fn,ln)
00169     {
00170         char buf[1024];
00171 
00172         sprintf(buf, "Index out of range in %s: expected %ld <= %s < %ld but %s=%ld.",
00173             where,lb,indexName,ub,indexName,index);
00174         setMessage(std::string(buf));
00175     }
00176 private:
00177 };
00178 
00179 class SizeOutOfRange : public Base {
00180 public:
00181     SizeOutOfRange(const char* fn, int ln, const char* szName,
00182                    long sz, long maxsz, const char* where)
00183       : Base(fn,ln)
00184     {
00185         char buf[1024];
00186 
00187         sprintf(buf, "Size out of range in %s: expected 0 <= %s <= %ld but %s=%ld.",
00188             where,szName,maxsz,szName,sz);
00189         setMessage(std::string(buf));
00190     }
00191 private:
00192 };
00193 
00194 class SizeWasNegative : public Base {
00195 public:
00196     SizeWasNegative(const char* fn, int ln, const char* szName,
00197                    long sz, const char* where)
00198       : Base(fn,ln)
00199     {
00200         char buf[1024];
00201 
00202         sprintf(buf, "Size argument was negative in %s: expected 0 <= %s but %s=%ld.",
00203             where,szName,szName,sz);
00204         setMessage(std::string(buf));
00205     }
00206 private:
00207 };
00208 
00209 class ValueOutOfRange : public Base {
00210 public:
00211     ValueOutOfRange(const char* fn, int ln, const char* valueName,
00212                     Real lowerBound, Real value, Real upperBound, 
00213                     const char* where)
00214       : Base(fn,ln)
00215     {
00216         char buf[1024];
00217 
00218         sprintf(buf, "Value out of range in %s: expected %g <= %s <= %g but %s=%g.",
00219             where,lowerBound,valueName,upperBound,valueName,value);
00220         setMessage(std::string(buf));
00221     }
00222 private:
00223 };
00224 
00225 class ValueWasNegative : public Base {
00226 public:
00227     ValueWasNegative(const char* fn, int ln, const char* valueName,
00228                      Real value, const char* where)
00229       : Base(fn,ln)
00230     {
00231         char buf[1024];
00232 
00233         sprintf(buf, "Expected non-negative value for %s in %s but got %g.",
00234             valueName,where,value);
00235         setMessage(std::string(buf));
00236     }
00237 private:
00238 };
00239 
00240 class UnimplementedVirtualMethod : public Base {
00241 public:
00242     UnimplementedVirtualMethod(const char* fn, int ln, 
00243         std::string baseClass, std::string methodName) 
00244         : Base(fn,ln)
00245     { 
00246         setMessage("The base class " + baseClass + 
00247             " dummy implementation of method " + methodName
00248             + "() was invoked because a derived class did not provide an implementation.");
00249     }
00250 };
00251 
00252 class IncompatibleValues : public Base {
00253 public:
00254     IncompatibleValues(const char* fn, int ln, std::string src, std::string dest) : Base(fn,ln)
00255     {
00256         setMessage("Attempt to assign a Value<"+src+"> to a Value<"+dest+">");
00257     }
00258 private:
00259 };
00260 
00261 class OperationNotAllowedOnView : public Base {
00262 public:
00263     OperationNotAllowedOnView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
00264     {
00265         setMessage("Operation '" + op + "' allowed only for owners, not views");
00266     }   
00267 };
00268 
00269 class OperationNotAllowedOnOwner : public Base {
00270 public:
00271     OperationNotAllowedOnOwner(const char* fn, int ln, const std::string& op) : Base(fn,ln)
00272     {
00273         setMessage("Operation '" + op + "' allowed only for views, not owners");
00274     }   
00275 };
00276 
00277 class OperationNotAllowedOnNonconstReadOnlyView : public Base {
00278 public:
00279     OperationNotAllowedOnNonconstReadOnlyView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
00280     {
00281         setMessage("Operation '" + op + "' not allowed on non-const readonly view");
00282     }   
00283 };
00284 
00285 // SimTK::Exception::Cant
00286 class Cant : public Base {
00287 public:
00288     Cant(const char* fn, int ln, const std::string& s) : Base(fn,ln)
00289     {
00290         setMessage("Can't perform operation: " + s);
00291     }   
00292 };
00293 
00294 } // namespace Exception
00295 } // namespace SimTK
00296 
00297 #define SimTK_THROW(exc) \
00298     throw exc(__FILE__, __LINE__)
00299 #define SimTK_THROW1(exc,a1) \
00300     throw exc(__FILE__, __LINE__,a1)
00301 #define SimTK_THROW2(exc,a1,a2) \
00302     throw exc(__FILE__, __LINE__,a1,a2)
00303 #define SimTK_THROW3(exc,a1,a2,a3) \
00304     throw exc(__FILE__, __LINE__,a1,a2,a3)
00305 #define SimTK_THROW4(exc,a1,a2,a3,a4) \
00306     throw exc(__FILE__, __LINE__,a1,a2,a3,a4)
00307 #define SimTK_THROW5(exc,a1,a2,a3,a4,a5) \
00308     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5)
00309 #define SimTK_THROW6(exc,a1,a2,a3,a4,a5,a6) \
00310     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6)
00311 #define SimTK_THROW7(exc,a1,a2,a3,a4,a5,a6,a7) \
00312     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7)
00313 #define SimTK_THROW8(exc,a1,a2,a3,a4,a5,a6,a7,a8) \
00314     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8)
00315 #define SimTK_THROW9(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9) \
00316     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9)
00317 #define SimTK_THROW10(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \
00318     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
00319 
00320 #endif // SimTK_SimTKCOMMON_EXCEPTION_H_
00321 

Generated by  doxygen 1.6.2