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