w_debug.h

00001 /* -*- mode:C++; c-basic-offset:4 -*-
00002      Shore-MT -- Multi-threaded port of the SHORE storage manager
00003    
00004                        Copyright (c) 2007-2009
00005       Data Intensive Applications and Systems Labaratory (DIAS)
00006                Ecole Polytechnique Federale de Lausanne
00007    
00008                          All Rights Reserved.
00009    
00010    Permission to use, copy, modify and distribute this software and
00011    its documentation is hereby granted, provided that both the
00012    copyright notice and this permission notice appear in all copies of
00013    the software, derivative works or modified versions, and any
00014    portions thereof, and that both notices appear in supporting
00015    documentation.
00016    
00017    This code is distributed in the hope that it will be useful, but
00018    WITHOUT ANY WARRANTY; without even the implied warranty of
00019    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS
00020    DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
00021    RESULTING FROM THE USE OF THIS SOFTWARE.
00022 */
00023 
00024 /*<std-header orig-src='shore' incl-file-exclusion='W_DEBUG_H'>
00025 
00026  $Id: w_debug.h,v 1.1 2010/12/09 15:29:05 nhall Exp $
00027 
00028 SHORE -- Scalable Heterogeneous Object REpository
00029 
00030 Copyright (c) 1994-99 Computer Sciences Department, University of
00031                       Wisconsin -- Madison
00032 All Rights Reserved.
00033 
00034 Permission to use, copy, modify and distribute this software and its
00035 documentation is hereby granted, provided that both the copyright
00036 notice and this permission notice appear in all copies of the
00037 software, derivative works or modified versions, and any portions
00038 thereof, and that both notices appear in supporting documentation.
00039 
00040 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
00041 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
00042 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
00043 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00044 
00045 This software was developed with support by the Advanced Research
00046 Project Agency, ARPA order number 018 (formerly 8230), monitored by
00047 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
00048 Further funding for this work was provided by DARPA through
00049 Rome Research Laboratory Contract No. F30602-97-2-0247.
00050 
00051 */
00052 
00053 #ifndef W_DEBUG_H
00054 #define W_DEBUG_H
00055 
00056 #include "w_defines.h"
00057 
00058 /*  -- do not edit anything above this line --   </std-header>*/
00059 
00060 #ifdef __GNUG__
00061 #pragma interface
00062 #endif
00063 
00064 #ifndef W_BASE_H
00065 /* NB: DO NOT make this include w.h -- not yet */
00066 #include <w_base.h>
00067 #endif /* W_BASE_H */
00068 
00069 #include <w_stream.h>
00070 
00071 #ifndef ERRLOG_H
00072 #include <errlog.h>
00073 #endif /* ERRLOG_H */
00074 
00075 /**\file w_debug.h
00076  *\ingroup MACROS
00077  *
00078 *  This is a set of macros for use with C or C++. They give various
00079 *  levels of debugging printing when compiled with --enable-trace.
00080 *  With tracing, message printing is under the control of an environment
00081 *  variable DEBUG_FLAGS (see debug.cpp).  
00082 *  If that variable is set, its value must 
00083 *  be  a string.  The string is searched for __FILE__ and the function name 
00084 *  in which the debugging message occurs.  If either one appears in the
00085 *  string (value of the env variable), or if the string contains the
00086 *  word "all", the message is printed.  
00087 *
00088 *
00089 **** FUNC(fname)  dumps the function name.
00090 **** RETURN   prints that the function named by __func__ is returning
00091 *             This macro  MUST appear within braces if used after "if",
00092 *              "else", "while", etc.
00093 *
00094 **** DBG(arg) prints line & file and the message arg if __func__
00095 *              appears in the debug environment variable.
00096 *             The argument must be the innermost part of legit C++
00097 *             print statement, and it works ONLY in C++ sources.
00098 *
00099 *  Example :
00100 *
00101 * \code
00102 *    returntype
00103 *    proc(args)
00104 *    {
00105 *        FUNC(proc);
00106 *       ....body...
00107 *
00108 *       DBG(
00109 *          << "message" << value
00110 *          << "more message";
00111 *          if(test) {
00112 *             cerr << "xyz";
00113 *          }
00114 *          cerr
00115 *       )
00116 *
00117 *       ....more body...
00118 *       if(predicate) {
00119 *           RETURN value;
00120 *        }
00121 *    }
00122 *  \endcode
00123 *
00124  * FUNC, and RETURN macros' definitions depend on how
00125  * the storage manager is configured.
00126  * They don't do a lot unless configured with --enable-trace
00127 */
00128 #include <cassert>
00129 
00130 #undef USE_REGEX
00131 
00132 #ifdef USE_REGEX
00133 #include "regex_posix.h"
00134 #endif /* USE_REGEX */
00135 
00136 /* XXX missing type in vc++, hack around it here too, don't pollute
00137    global namespace too badly. */
00138 typedef    ios::fmtflags    w_dbg_fmtflags;
00139 
00140 
00141 #ifdef W_TRACE
00142 
00143 #define _strip_filename(f) f
00144 
00145 
00146 #define FUNC(fn)\
00147   do { \
00148     if(_w_debug.flag_on(__func__,__FILE__)) {              \
00149         _w_debug.clog << __LINE__ << " "                   \
00150         << _strip_filename(__FILE__) << ": " << __func__   \
00151         << flushl;                                         \
00152     }                                                      \
00153   } while(0)
00154 
00155 #define RETURN \
00156                 do { \
00157             if(_w_debug.flag_on(__func__,__FILE__)) {\
00158             w_dbg_fmtflags old = _w_debug.clog.setf(ios::dec, ios::basefield); \
00159             _w_debug.clog  << __LINE__ << " " << _strip_filename(__FILE__) << ":" ; \
00160             _w_debug.clog.setf(old, ios::basefield); \
00161             _w_debug.clog << "return from " << __func__ << flushl; } } while(0); \
00162             return 
00163 
00164 #else /* -UW_TRACE */
00165 #    define FUNC(fn)
00166 #    undef RETURN
00167 #    define RETURN return
00168 #endif  /* W_TRACE*/
00169 
00170 /* ************************************************************************  */
00171 
00172 /* ************************************************************************  
00173  * 
00174  * Class w_debug, macros DBG, DBG_NONL, DBG1, DBG1_NONL:
00175  */
00176 
00177 
00178 /**\brief An ErrLog used for tracing (configure --enable-trace)
00179  *
00180  * For tracing to be used, you must set the environment variable
00181  * DEBUG_FLAGS to a string containing the names of the files you
00182  * want traced, and
00183  *
00184  * DEBUG_FILE to the name of the output file to which the output
00185  * should be sent. If DEBUG_FILE is not set, the output goes to
00186  * stderr.
00187  */
00188 class w_debug : public ErrLog {
00189     private:
00190         char *_flags;
00191         enum { _all = 0x1, _none = 0x2 };
00192         unsigned int        mask;
00193         int            _trace_level;
00194 
00195 #ifdef USE_REGEX
00196         static regex_t        re_posix_re;
00197         static bool        re_ready;
00198         static char*        re_error_str;
00199         static char*        re_comp_debug(const char* pattern);
00200         static int        re_exec_debug(const char* string);
00201 #endif /* USE_REGEX */
00202 
00203         int            all(void) { return (mask & _all) ? 1 : 0; }
00204         int            none(void) { return (mask & _none) ? 1 : 0; }
00205 
00206     public:
00207         w_debug(const char *n, const char *f);
00208         ~w_debug();
00209         int flag_on(const char *fn, const char *file);
00210         const char *flags() { return _flags; }
00211         void setflags(const char *newflags);
00212         void memdump(void *p, int len); // hex dump of memory
00213         int trace_level() { return _trace_level; }
00214 };
00215 extern w_debug _w_debug;
00216 
00217 #if defined(W_TRACE)
00218 
00219 #    define DBG2(a,file,line) \
00220         w_dbg_fmtflags old = _w_debug.clog.setf(ios::dec, ios::basefield); \
00221         _w_debug.clog  << _strip_filename(file) << ":" << line << ":" ; \
00222         _w_debug.clog.setf(old, ios::basefield); \
00223         _w_debug.clog  a    << flushl; 
00224 
00225 #    define DBG1(a) do {\
00226     if(_w_debug.flag_on(__func__,__FILE__)) {                \
00227         DBG2(a,__FILE__,__LINE__) \
00228     } } while(0)
00229 
00230 #    define DBG(a) DBG1(a)
00231 
00232 #else
00233 #    define DBG(a) 
00234 #endif  /* defined(W_TRACE) */
00235 /* ************************************************************************  */
00236 
00237 
00238 #define DBGTHRD(arg) DBG(<<" th."<<sthread_t::me()->id << " " arg)
00239 
00240 /*<std-footer incl-file-exclusion='W_DEBUG_H'>  -- do not edit anything below this line -- */
00241 
00242 #endif          /*</std-footer>*/

Generated on Mon Jan 2 15:13:56 2012 for Shore Storage Manager by  doxygen 1.4.7