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 
00086 // This is for reporting internally-detected bugs only, not
00087 // problems induced by confused users.
00088 class Assert : public Base {
00089 public:
00090     Assert(const char* fn, int ln, const char* assertion, 
00091            const char* fmt ...) : Base(fn,ln)
00092     {
00093         char buf[1024];
00094         va_list args;
00095         va_start(args, fmt);
00096         vsprintf(buf, fmt, args);
00097 
00098         setMessage("Internal SimTK bug detected: " + std::string(buf)
00099                    + " (Assertion '" + std::string(assertion) + "' failed). "
00100                      "Please report this to the appropriate authorities at SimTK.org.");
00101         va_end(args);
00102     }
00103 private:
00104 };
00105 
00106 
00107 class APIArgcheckFailed : public Base {
00108 public:
00109     APIArgcheckFailed(const char* fn, int ln, const char* className, const char* methodName,
00110                       const char* fmt ...) : Base(fn,ln)
00111     {
00112         char buf[1024];
00113         va_list args;
00114         va_start(args, fmt);
00115         vsprintf(buf, fmt, args);
00116         setMessage("Bad call to SimTK API method " 
00117                    + std::string(className) + "::" + std::string(methodName) + "(): "
00118                    + std::string(buf) + ".");
00119         va_end(args);
00120     }
00121 private:
00122 };
00123 
00124 
00125 class IndexOutOfRange : public Base {
00126 public:
00127     IndexOutOfRange(const char* fn, int ln, const char* indexName,
00128                     long lb, long index, long ub, const char* where)
00129       : Base(fn,ln)
00130     {
00131         char buf[1024];
00132 
00133         sprintf(buf, "Index out of range in %s: expected %ld <= %s < %ld but %s=%ld.",
00134             where,lb,indexName,ub,indexName,index);
00135         setMessage(std::string(buf));
00136     }
00137 private:
00138 };
00139 
00140 class SizeOutOfRange : public Base {
00141 public:
00142     SizeOutOfRange(const char* fn, int ln, const char* szName,
00143                    long sz, long maxsz, const char* where)
00144       : Base(fn,ln)
00145     {
00146         char buf[1024];
00147 
00148         sprintf(buf, "Size out of range in %s: expected 0 <= %s <= %ld but %s=%ld.",
00149             where,szName,maxsz,szName,sz);
00150         setMessage(std::string(buf));
00151     }
00152 private:
00153 };
00154 
00155 class SizeWasNegative : public Base {
00156 public:
00157     SizeWasNegative(const char* fn, int ln, const char* szName,
00158                    long sz, const char* where)
00159       : Base(fn,ln)
00160     {
00161         char buf[1024];
00162 
00163         sprintf(buf, "Size argument was negative in %s: expected 0 <= %s but %s=%ld.",
00164             where,szName,szName,sz);
00165         setMessage(std::string(buf));
00166     }
00167 private:
00168 };
00169 
00170 class ValueOutOfRange : public Base {
00171 public:
00172     ValueOutOfRange(const char* fn, int ln, const char* valueName,
00173                     Real lowerBound, Real value, Real upperBound, 
00174                     const char* where)
00175       : Base(fn,ln)
00176     {
00177         char buf[1024];
00178 
00179         sprintf(buf, "Value out of range in %s: expected %g <= %s <= %g but %s=%g.",
00180             where,lowerBound,valueName,upperBound,valueName,value);
00181         setMessage(std::string(buf));
00182     }
00183 private:
00184 };
00185 
00186 class ValueWasNegative : public Base {
00187 public:
00188     ValueWasNegative(const char* fn, int ln, const char* valueName,
00189                      Real value, const char* where)
00190       : Base(fn,ln)
00191     {
00192         char buf[1024];
00193 
00194         sprintf(buf, "Expected non-negative value for %s in %s but got %g.",
00195             valueName,where,value);
00196         setMessage(std::string(buf));
00197     }
00198 private:
00199 };
00200 
00201 class UnimplementedVirtualMethod : public Base {
00202 public:
00203     UnimplementedVirtualMethod(const char* fn, int ln, 
00204         std::string baseClass, std::string methodName) 
00205         : Base(fn,ln)
00206     { 
00207         setMessage("The base class " + baseClass + 
00208             " dummy implementation of method " + methodName
00209             + "() was invoked because a derived class did not provide an implementation.");
00210     }
00211 };
00212 
00213 class IncompatibleValues : public Base {
00214 public:
00215     IncompatibleValues(const char* fn, int ln, std::string src, std::string dest) : Base(fn,ln)
00216     {
00217         setMessage("Attempt to assign a Value<"+src+"> to a Value<"+dest+">");
00218     }
00219 private:
00220 };
00221 
00222 class OperationNotAllowedOnView : public Base {
00223 public:
00224     OperationNotAllowedOnView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
00225     {
00226         setMessage("Operation '" + op + "' allowed only for owners, not views");
00227     }   
00228 };
00229 
00230 class OperationNotAllowedOnOwner : public Base {
00231 public:
00232     OperationNotAllowedOnOwner(const char* fn, int ln, const std::string& op) : Base(fn,ln)
00233     {
00234         setMessage("Operation '" + op + "' allowed only for views, not owners");
00235     }   
00236 };
00237 
00238 class OperationNotAllowedOnNonconstReadOnlyView : public Base {
00239 public:
00240     OperationNotAllowedOnNonconstReadOnlyView(const char* fn, int ln, const std::string& op) : Base(fn,ln)
00241     {
00242         setMessage("Operation '" + op + "' not allowed on non-const readonly view");
00243     }   
00244 };
00245 
00246 // SimTK::Exception::Cant
00247 class Cant : public Base {
00248 public:
00249     Cant(const char* fn, int ln, const std::string& s) : Base(fn,ln)
00250     {
00251         setMessage("Can't perform operation: " + s);
00252     }   
00253 };
00254 
00255 } // namespace Exception
00256 } // namespace SimTK
00257 
00258 #define SimTK_THROW(exc) \
00259     throw exc(__FILE__, __LINE__)
00260 #define SimTK_THROW1(exc,a1) \
00261     throw exc(__FILE__, __LINE__,a1)
00262 #define SimTK_THROW2(exc,a1,a2) \
00263     throw exc(__FILE__, __LINE__,a1,a2)
00264 #define SimTK_THROW3(exc,a1,a2,a3) \
00265     throw exc(__FILE__, __LINE__,a1,a2,a3)
00266 #define SimTK_THROW4(exc,a1,a2,a3,a4) \
00267     throw exc(__FILE__, __LINE__,a1,a2,a3,a4)
00268 #define SimTK_THROW5(exc,a1,a2,a3,a4,a5) \
00269     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5)
00270 #define SimTK_THROW6(exc,a1,a2,a3,a4,a5,a6) \
00271     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6)
00272 #define SimTK_THROW7(exc,a1,a2,a3,a4,a5,a6,a7) \
00273     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7)
00274 #define SimTK_THROW8(exc,a1,a2,a3,a4,a5,a6,a7,a8) \
00275     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8)
00276 #define SimTK_THROW9(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9) \
00277     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9)
00278 #define SimTK_THROW10(exc,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) \
00279     throw exc(__FILE__, __LINE__,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
00280 
00281 #endif // SimTK_SimTKCOMMON_EXCEPTION_H_
00282 

Generated on Thu Feb 28 01:34:28 2008 for SimTKcommon by  doxygen 1.4.7