Debug.h

Go to the documentation of this file.
00001 /****************** <VPR heading BEGIN do not edit this line> *****************
00002  *
00003  * VR Juggler Portable Runtime
00004  *
00005  * Original Authors:
00006  *   Allen Bierbaum, Patrick Hartling, Kevin Meinert, Carolina Cruz-Neira
00007  *
00008  * -----------------------------------------------------------------
00009  * File:          $RCSfile$
00010  * Date modified: $Date: 2005-06-15 09:11:46 -0500 (Wed, 15 Jun 2005) $
00011  * Version:       $Revision: 17686 $
00012  * -----------------------------------------------------------------
00013  *
00014  ****************** <VPR heading END do not edit this line> ******************/
00015 
00016 /*************** <auto-copyright.pl BEGIN do not edit this line> **************
00017  *
00018  * VR Juggler is (C) Copyright 1998-2005 by Iowa State University
00019  *
00020  * Original Authors:
00021  *   Allen Bierbaum, Christopher Just,
00022  *   Patrick Hartling, Kevin Meinert,
00023  *   Carolina Cruz-Neira, Albert Baker
00024  *
00025  * This library is free software; you can redistribute it and/or
00026  * modify it under the terms of the GNU Library General Public
00027  * License as published by the Free Software Foundation; either
00028  * version 2 of the License, or (at your option) any later version.
00029  *
00030  * This library is distributed in the hope that it will be useful,
00031  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00032  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00033  * Library General Public License for more details.
00034  *
00035  * You should have received a copy of the GNU Library General Public
00036  * License along with this library; if not, write to the
00037  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00038  * Boston, MA 02111-1307, USA.
00039  *
00040  *************** <auto-copyright.pl END do not edit this line> ***************/
00041 
00042 #ifndef _VPR_Debug_h_
00043 #define _VPR_Debug_h_
00044 
00045 #include <vpr/vprConfig.h>
00046 
00047 #include <iostream>
00048 #include <stdlib.h>
00049 #include <vector>
00050 #include <string>
00051 #include <map>
00052 
00053 #include <vpr/Sync/Mutex.h>
00054 #include <vpr/Sync/Guard.h>
00055 #include <vpr/Util/StreamLock.h>
00056 #include <vpr/Util/Singleton.h>
00057 #include <vpr/Util/GUID.h>
00058 
00059 
00060 // Suggested use of val/debugLevel
00061 //
00062 // 0 - Critical messages (always need to be seen)
00063 // 1 - Warnings and potential problems
00064 // 2 - Results of system configuration
00065 // 3 - Configuration of system
00066 // 4 - State changes & who is doing what
00067 // 5 - Verbose (don't need source) ex
00068 // 6 - Highly verbose (may need source)
00069 // 7 - Very detailed: i.e. Function entry and exit
00070 // 8 - You will be reading hexidecimal
00071 #define vprDBG_CRITICAL_LVL 0
00072 #define vprDBG_WARNING_LVL 1
00073 #define vprDBG_CONFIG_STATUS_LVL 2
00074 #define vprDBG_CONFIG_LVL 3
00075 #define vprDBG_STATE_LVL 4
00076 #define vprDBG_VERB_LVL 5
00077 #define vprDBG_HVERB_LVL 6
00078 #define vprDBG_DETAILED_LVL 7
00079 #define vprDBG_HEX_LVL 8
00080 
00081 // ANSI COLOR CONTROL CODES
00082 // TODO: Make the work for windows
00083 // 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
00084 // 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
00085 // Add 10 for background colors.
00086 #define clrNONE "00"
00087 #define clrBOLD "01"
00088 #define clrBLACK "30"
00089 #define clrRED "31"
00090 #define clrGREEN "32"
00091 #define clrYELLOW "33"
00092 #define clrBLUE "34"
00093 #define clrMAGENTA "35"
00094 #define clrCYAN "36"
00095 #define clrWHITE "37"
00096 
00097 #ifdef VPR_OS_Windows
00098 #  define clrESC ""
00099 #  define clrCONTROL_CHARS(font, color) ""
00100 #  define clrSetNORM(color) ""
00101 #  define clrSetBOLD(color) ""
00102 #  define clrRESET ""
00103 #  define clrOutBOLD(color,text) text
00104 #  define clrOutNORM(color,text) text
00105 #else
00106 #  define clrESC char(27)
00107 #  define clrCONTROL_CHARS(font, color) clrESC << "[" << font << ";" << color << "m"
00108 #  define clrSetNORM(color) clrESC << "[" << color << "m"
00109 #  define clrSetBOLD(color) clrCONTROL_CHARS(clrBOLD, color)
00110 #  define clrRESET clrESC << "[" << clrNONE << "m"
00111 #  define clrOutBOLD(color,text) clrSetBOLD(color) << text << clrRESET
00112 #  define clrOutNORM(color,text) clrSetNORM(color) << text << clrRESET
00113 #endif
00114 
00115 
00116 #ifdef VPR_DEBUG
00117 
00118 //#  define vprDEBUG(cat,val) if (0) ; else if((val <= vprDebug::instance()->getLevel()) && (vprDebug::instance()->isCategoryAllowed(cat))) vprDebug::instance()->getStream(cat, val)
00119 //#  define vprDEBUG_BEGIN(cat,val) if (0) ; else if((val <= vprDebug::instance()->getLevel()) && (vprDebug::instance()->isCategoryAllowed(cat))) vprDebug::instance()->getStream(cat, val, true, 1)
00120 //#  define vprDEBUG_END(cat,val) if (0) ; else if((val <= vprDebug::instance()->getLevel()) && (vprDebug::instance()->isCategoryAllowed(cat))) vprDebug::instance()->getStream(cat, val, true, -1)
00121 #  define LOCK_DEBUG_STREAM
00122 #  define VPR_MAX_DBG_LEVEL 100
00123 #else
00124 #  define LOCK_DEBUG_STREAM
00125 #  define VPR_MAX_DBG_LEVEL vprDBG_CONFIG_LVL
00126 
00127 //#  define vprDEBUG(cat,val) if (1) ; else std::cout
00128 //#  define vprDEBUG_BEGIN(cat,val) if (1) ; else std::cout
00129 //#  define vprDEBUG_END(cat,val) if (1) ; else std::cout
00130 #endif
00131 
00132 // #undef LOCK_DEBUG_STREAM
00133 
00134 // Define the actual macros to use
00135 // vprDEBUG - Outputs debug info
00136 // vprDEBUG_BEGIN - Starts some indenting of the thread information
00137 // vprDEBUG_END - Ends the indenting level of the information
00138 // vprDEBUG_CONT - Continue on the same line (no thread info, no indent)
00139 // vprDEBUG_CONT_END - Continue on the same line AND decrease indent one level (no thread info, no indent)
00140 // vprDEBUG_NEXT - Outputing more info on next line (no thread info)
00141 // vprDEBUG_NEXT_BEGIN - Output more infor on next line AND indent one level more
00142 // vprDEBUG_NEXT_END - Ouput more info on the next line AND decrease indent one level
00143 #define vprDEBUG(cat,val) if (val>VPR_MAX_DBG_LEVEL) ; else if((vpr::Debug::instance()->isDebugEnabled()) && (val <= vpr::Debug::instance()->getLevel()) && (vpr::Debug::instance()->isCategoryAllowed(cat))) vpr::Debug::instance()->getStream(cat, val, true)
00144 #define vprDEBUGlg(cat,val,show_thread,use_indent,lockIt) if (val>VPR_MAX_DBG_LEVEL) ; else if((vpr::Debug::instance()->isDebugEnabled()) && (val <= vpr::Debug::instance()->getLevel()) && (vpr::Debug::instance()->isCategoryAllowed(cat))) vpr::Debug::instance()->getStream(cat, val, show_thread, use_indent, 0, lockIt)
00145 #define vprDEBUG_BEGIN(cat,val) if (val>VPR_MAX_DBG_LEVEL) ; else if((vpr::Debug::instance()->isDebugEnabled()) && (val <= vpr::Debug::instance()->getLevel()) && (vpr::Debug::instance()->isCategoryAllowed(cat))) vpr::Debug::instance()->getStream(cat, val, true, true, 1)
00146 #define vprDEBUG_BEGINlg(cat,val,show_thread,use_indent,lockIt) if (val>VPR_MAX_DBG_LEVEL) ; else if((vpr::Debug::instance()->isDebugEnabled()) && (val <= vpr::Debug::instance()->getLevel()) && (vpr::Debug::instance()->isCategoryAllowed(cat))) vpr::Debug::instance()->getStream(cat, val, show_thread, use_indent, 1, lockIt)
00147 #define vprDEBUG_END(cat,val) if (val>VPR_MAX_DBG_LEVEL) ; else if((vpr::Debug::instance()->isDebugEnabled()) && (val <= vpr::Debug::instance()->getLevel()) && (vpr::Debug::instance()->isCategoryAllowed(cat))) vpr::Debug::instance()->getStream(cat, val, true, true, -1)
00148 #define vprDEBUG_ENDlg(cat,val,show_thread,use_indent,lockIt) if (val>VPR_MAX_DBG_LEVEL) ; else if((vpr::Debug::instance()->isDebugEnabled()) && (val <= vpr::Debug::instance()->getLevel()) && (vpr::Debug::instance()->isCategoryAllowed(cat))) vpr::Debug::instance()->getStream(cat, val, show_thread, use_indent, -1, lockIt)
00149 #define vprDEBUG_DECREMENT_INDENT(cat, val) if (val>VPR_MAX_DBG_LEVEL) ; else if((vpr::Debug::instance()->isDebugEnabled()) && (val <= vpr::Debug::instance()->getLevel()) && (vpr::Debug::instance()->isCategoryAllowed(cat))) vpr::Debug::instance()->decrementIndentLevel()
00150 
00151 
00152 #define vprDEBUG_CONT(cat,val) vprDEBUGlg(cat,val,false,false,true)
00153 #define vprDEBUG_CONT_END(cat,val) vprDEBUG_ENDlg(cat,val,false,false,true)
00154 #define vprDEBUG_NEXT(cat,val) vprDEBUGlg(cat,val,false,true,true)
00155 #define vprDEBUG_NEXT_BEGIN(cat,val) vprDEBUG_BEGINlg(cat,val,false,true,true)
00156 #define vprDEBUG_NEXT_END(cat,val) vprDEBUG_ENDlg(cat,val,false,true,true)
00157 
00158 // Versions that don't lock the stream
00159 // NOTE: USE WITH EXTREME RISK
00160 #define vprDEBUGnl(cat,val) vprDEBUGlg(cat,val,true,true,false)
00161 #define vprDEBUG_ENDnl(cat,val) vprDEBUG_ENDlg(cat,val,true,true,false)
00162 #define vprDEBUG_BEGINnl(cat,val) vprDEBUG_BEGINlg(cat,val,true,true,false)
00163 #define vprDEBUG_CONTnl(cat,val) vprDEBUGlg(cat,val,false,false,false)
00164 #define vprDEBUG_CONT_ENDnl(cat,val) vprDEBUG_ENDlg(cat,val,false,false,false)
00165 #define vprDEBUG_NEXTnl(cat,val) vprDEBUGlg(cat,val,false,true,false)
00166 #define vprDEBUG_NEXT_BEGINnl(cat,val) vprDEBUG_BEGINlg(cat,val,false,true,false)
00167 #define vprDEBUG_NEXT_ENDnl(cat,val) vprDEBUG_ENDlg(cat,val,false,true,false)
00168 
00169 #define vprDEBUG_PushColumn(val) vpr::Debug::instance()->pushThreadLocalColumn(val)
00170 #define vprDEBUG_PopColumn() vpr::Debug::instance()->popThreadLocalColumn()
00171 #define vprDEBUG_ColumnGuard(val) vpr::DebugColumnGuard debug_col_guard(val)
00172 
00173 #define vprDEBUG_PushTSColor(color) vpr::Debug::instance()->pushThreadLocalColor(color)
00174 #define vprDEBUG_PopTSColor() vpr::Debug::instance()->popThreadLocalColor()
00175 #define vprDEBUG_TSColorGuard(color) vpr::DebugColorGuard debug_color_guard(color)
00176 
00177 #define vprDEBUG_ThreadLocalEnable() vpr::Debug::instance()->enableThreadLocalSettings()
00178 #define vprDEBUG_ThreadLocalDisable() vpr::Debug::instance()->disableThreadLocalSettings()
00179 
00180 #define vprDEBUG_OutputGuard(cat, level, entryText, exitText) vpr::DebugOutputGuard debug_output_guard(cat, level, entryText, exitText)
00181 #define vprDEBUG_OutputGuard_i(cat, level, indent, entryText, exitText) vpr::DebugOutputGuard debug_output_guard(cat, level, entryText, exitText, indent)
00182 
00183 
00184 #ifdef LOCK_DEBUG_STREAM
00185 #  define vprDEBUG_STREAM_LOCK vpr::StreamLock(vpr::Debug::instance()->debugLock())
00186 #  define vprDEBUG_STREAM_UNLOCK vpr::StreamUnLock(vpr::Debug::instance()->debugLock())
00187 #  define vprDEBUG_FLUSH vprDEBUG_STREAM_UNLOCK << std::flush
00188 #else
00189 #  define vprDEBUG_STREAM_LOCK std::flush
00190 #  define vprDEBUG_STREAM_UNLOCK std::flush
00191 #  define vprDEBUG_FLUSH std::flush
00192 #endif
00193 
00194 namespace vpr
00195 {
00200    struct DebugCategory
00201    {
00202       DebugCategory(const vpr::GUID& guid, const std::string& name,
00203                     const std::string& prefix)
00204          : mGuid(guid)
00205          , mName(name)
00206          , mPrefix(prefix)
00207       {
00208          /* Do nothing. */ ;
00209       }
00210 
00211       vpr::GUID   mGuid;
00212       std::string mName;
00213       std::string mPrefix;
00214    };
00215 
00216 
00221    class VPR_CLASS_API Debug
00222    {
00223    protected:
00228       Debug();
00229 
00230       // These two have to be here because Visual C++ will try to make them
00231       // exported public symbols.  This causes problems because copying 
00232       // vpr::Mutex objects is not allowed.
00233       Debug(const Debug&) {;}
00234       void operator= (const Debug&) {;}
00235 
00237       void init();
00238 
00239    public:
00240 
00241       ~Debug()
00242       {
00243       }
00244 
00255       bool setOutputFile(const std::string& output);
00256 
00263       void setOutputStream(std::ostream& stream);
00264       
00266       std::ostream& getStream(const vpr::DebugCategory& cat, const int level,
00267                               const bool show_thread_info = true,
00268                               const bool use_indent = true, 
00269                               const int indentChange = 0,
00270                               const bool lockStream = true);
00271 
00272       int getLevel()
00273       {
00274          return debugLevel;
00275       }
00276 
00277       Mutex& debugLock()
00278       {
00279          return mDebugLock;
00280       }
00281 
00283       void addCategory(const vpr::DebugCategory& catId);
00284 
00286       bool isCategoryAllowed(const vpr::DebugCategory& catId);
00287 
00289       void setDefaultCategoryNames();
00290 
00292       void updateAllowedCategories();
00293 
00294       void enableThreadLocalSettings()
00295       {
00296          mUseThreadLocal = true;
00297       }
00298 
00299       void disableThreadLocalSettings()
00300       {
00301          mUseThreadLocal = false;
00302          std::cout << clrRESET;     // Reset colors
00303       }
00304 
00311       void pushThreadLocalColumn(int column);
00312       void popThreadLocalColumn();
00313       void pushThreadLocalColor(std::string color);
00314       void popThreadLocalColor();
00316 
00320       bool isDebugEnabled()
00321       {
00322          return mDebugEnabled;
00323       }
00324 
00326       void enableOutput()
00327       {
00328          mDebugEnabled = true;
00329       }
00330 
00332       void disableOutput()
00333       {
00334          mDebugEnabled = false;
00335       }
00337 
00339       void debugDump();
00340 
00342       void decrementIndentLevel();
00343 
00345       void incrementIndentLevel();
00346 
00347    private:
00348       bool mDebugEnabled;  
00349       int debugLevel;      
00350       int indentLevel;     
00352       std::ofstream* mFile;     
00354       std::ostream* mStreamPtr;
00355 
00356       bool  mUseThreadLocal;  
00358       Mutex mDebugLock;
00359 
00360       //std::vector<bool> mAllowedCategories;  /**< The categories we allow */
00361 
00362       struct CategoryInfo
00363       {
00364          /*CategoryInfo()
00365           : mName("un-named"), mPrefix("unset"), mAllowed(false)
00366          {;}*/
00367 
00368          CategoryInfo(const std::string& name, const std::string& prefix,
00369                       const bool allowed, const bool disallowed)
00370             : mName(name)
00371             , mPrefix(prefix)
00372             , mAllowed(allowed)
00373             , mDisallowed(disallowed)
00374          {;}
00375 
00376          std::string mName;         
00377          std::string mPrefix;       
00378          bool        mAllowed;      
00379          bool        mDisallowed;   
00380       };
00381 
00382       // GUID, pair( name, prefix )
00383       typedef std::map<vpr::GUID, CategoryInfo > category_map_t;
00384       std::map<vpr::GUID, CategoryInfo > mCategories;    
00386       vprSingletonHeaderWithInitFunc(Debug, init);
00387    };
00388 
00393    struct DebugColumnGuard
00394    {
00395       DebugColumnGuard(const int colVal)
00396       {
00397          vprDEBUG_PushColumn(colVal);
00398       }
00399 
00400       ~DebugColumnGuard()
00401       {
00402          vprDEBUG_PopColumn();
00403       }
00404    };
00405 
00410    struct DebugColorGuard
00411    {
00412       DebugColorGuard(std::string color_val)
00413       {
00414          vprDEBUG_PushTSColor(color_val);
00415       }
00416 
00417       ~DebugColorGuard()
00418       {
00419          vprDEBUG_PopTSColor();
00420       }
00421    };
00422 
00428    struct VPR_CLASS_API DebugOutputGuard
00429    {
00430       DebugOutputGuard(const vpr::DebugCategory& cat, const int level,
00431                        std::string entryText,
00432                        std::string exitText = std::string(""),
00433                        bool indent = true);
00434 
00435       ~DebugOutputGuard();
00436 
00437       const vpr::DebugCategory& mCat;
00438       int                       mLevel;
00439       std::string               mEntryText;
00440       std::string               mExitText;
00441       bool                      mIndent;
00442    };
00443 
00444 } // End of vpr namespace
00445 
00446 // Debug output categories
00447 // GUID, Name, Prefix
00448 const vpr::DebugCategory vprDBG_ALL(vpr::GUID("660b4b06-1f5b-4e4b-abb8-d44229ce1319"), "DBG_ALL", "DBG:");
00449 const vpr::DebugCategory vprDBG_ERROR(vpr::GUID("b081eb68-0a61-4a65-a0a1-dd3ccc90a82b"), "DBG_ERROR", "ERR:");   /* Error output */
00450 const vpr::DebugCategory vprDBG_SIM(vpr::GUID("64872313-a5b7-4d1d-b7a3-5f269b4adde4"), "DBG_SIM", "SIM:");   /* Sim output */
00451 const vpr::DebugCategory vprDBG_VPR(vpr::GUID("28648014-ec63-4707-90e3-76a3ea450036"), "DBG_VPR", "VPR:");
00452 
00453 #endif

Generated on Thu Jan 4 10:52:09 2007 for VR Juggler Portable Runtime by  doxygen 1.5.1