Index  Source Files  Annotated Class List  Alphabetical Class List  Class Hierarchy  Graphical Class Hierarchy 

CallStack.h

Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 
00003 /****************************************************************************
00004 ** Copyright (c) quickfixengine.org  All rights reserved.
00005 **
00006 ** This file is part of the QuickFIX FIX Engine
00007 **
00008 ** This file may be distributed under the terms of the quickfixengine.org
00009 ** license as defined by quickfixengine.org and appearing in the file
00010 ** LICENSE included in the packaging of this file.
00011 **
00012 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 **
00015 ** See http://www.quickfixengine.org/LICENSE for licensing information.
00016 **
00017 ** Contact ask@quickfixengine.org if any conditions of this licensing are
00018 ** not clear to you.
00019 **
00020 ****************************************************************************/
00021 
00022 #ifndef FIX_CALLSTACK_H
00023 #define FIX_CALLSTACK_H
00024 
00025 #ifdef _MSC_VER
00026 #pragma warning( disable : 4297 4550 4551 4552 4786 )
00027 #endif
00028 
00029 #include <iostream>
00030 #include <exception>
00031 #include <map>
00032 #include <stack>
00033 #include <string>
00034 #include "Mutex.h"
00035 
00036 namespace FIX
00037 {
00039 class CallStack
00040 {
00041 public:
00043   struct Method
00044   {
00045     Method() {}
00046     Method(const std::string& n, const std::string& f, int l)
00047     : name(n), file(f), line(l) {}
00048 
00049     std::string name;
00050     std::string file;
00051     int line;
00052 
00053     Method& operator=( const Method& rhs )
00054     {
00055       name = rhs.name;
00056       file = rhs.file;
00057       line = rhs.line;
00058       return *this;
00059     }
00060 
00061     friend bool operator==( const Method& lhs, const Method& rhs );
00062     friend std::ostream& operator<<( std::ostream&, const Method& );
00063   };
00064 
00066   class Context : public std::stack<Method>
00067   {
00068   public:
00069     Context() : ignore(false) {}
00070     void caught( std::exception& );
00071     void caught();
00072 
00073     std::string exception;
00074     bool ignore;
00075   };
00076 
00078   class Ignore
00079   {
00080   public:
00081     Ignore()
00082     { s_count++;
00083       CallStack::ignore(true);
00084     }
00085     ~Ignore()
00086     { s_count--;
00087       if( s_count == 0 )
00088         CallStack::ignore(false);
00089     }
00090 
00091   private:
00092     static int s_count;
00093   };
00094 
00095   CallStack(const std::string& name, const std::string& file, int line);
00096   ~CallStack();
00097 
00098   static void output();
00099   static void ignore( bool );
00100   static void caught( std::exception& e );
00101   static void caught();
00102   static void terminate();
00103 
00104 private:
00105   static Context& getContext();
00106   static Context& getErrorContext();
00107 
00108   static std::map<thread_id, Context> s_stack;
00109   static std::map<thread_id, Context> s_error;
00110   static Mutex s_mutex;
00111 };
00112 
00113 inline std::ostream& operator<<
00114 ( std::ostream& ostream, const CallStack::Method& method )
00115 {
00116   return ostream
00117          << method.name.c_str()
00118          << "(" << method.file.c_str() << ":" << method.line << ")";
00119 }
00120 
00121 inline bool operator==( const CallStack::Method& rhs, const CallStack::Method& lhs )
00122 {
00123   return lhs.name == rhs.name
00124          && lhs.file == rhs.file
00125          && lhs.line == rhs.line;
00126 }
00127 }
00128 
00129 #ifdef ENABLE_CALLSTACK
00130 #define QF_STACK_PUSH(name) \
00131   CallStack cs_(#name, __FILE__, __LINE__); \
00132   try \
00133   {
00134 #define QF_STACK_POP \
00135   } \
00136   catch( std::exception& e ) \
00137   { \
00138     CallStack::caught(e); \
00139     throw; \
00140   } \
00141   catch( ... ) \
00142   { \
00143     CallStack::caught(); \
00144     throw; \
00145   }
00146 
00147 #define QF_STACK_IGNORE_BEGIN \
00148   { CallStack::Ignore ignore_;
00149 #define QF_STACK_IGNORE_END \
00150   }
00151 
00152 #define QF_STACK_TRY \
00153   try {
00154 #define QF_STACK_CATCH \
00155   } catch( ... ) { FIX::CallStack::output(); throw; }
00156 #else //ENABLE_CALLSTACK
00157 #define QF_STACK_PUSH(name)
00158 #define QF_STACK_POP
00159 #define QF_STACK_IGNORE_BEGIN
00160 #define QF_STACK_IGNORE_END
00161 #define QF_STACK_TRY
00162 #define QF_STACK_CATCH
00163 #endif //ENABLE_CALLSTACK
00164 
00165 #endif

Generated on Mon Apr 5 20:59:50 2010 for QuickFIX by doxygen 1.6.1 written by Dimitri van Heesch, © 1997-2001