xorp

debug.h

00001 /* -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*- */
00002 /* vim:set sts=4 ts=8: */
00003 
00004 /*
00005  * Copyright (c) 2001-2011 XORP, Inc and Others
00006  *
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU Lesser General Public License, Version
00009  * 2.1, June 1999 as published by the Free Software Foundation.
00010  * Redistribution and/or modification of this program under the terms of
00011  * any other version of the GNU Lesser General Public License is not
00012  * permitted.
00013  * 
00014  * This program is distributed in the hope that it will be useful, but
00015  * WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00017  * see the GNU Lesser General Public License, Version 2.1, a copy of
00018  * which can be found in the XORP LICENSE.lgpl file.
00019  * 
00020  * XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00021  * http://xorp.net
00022  */
00023 
00024 #ifndef __LIBXORP_DEBUG_H__
00025 #define __LIBXORP_DEBUG_H__
00026 
00027 #include "libxorp/xorp.h"
00028 
00029 
00030 #ifdef __cplusplus
00031 class EnvTrace {
00032 public:
00033     EnvTrace(const char* e) {
00034     _do_trace = 0;
00035     const char* elt = getenv(e);
00036     if (elt)
00037         _do_trace = atoi(elt);
00038     }
00039     bool on() const { return _do_trace > 0; }
00040     int getTrace() const { return _do_trace; }
00041 
00042 protected:
00043     int _do_trace;
00044 };
00045 #endif
00046 
00047 /*
00048  * This file defines the debug_msg(), the macro responsible for
00049  * generating debug messages.  It takes the same arguments as
00050  * printf(), e.g.
00051  *
00052  *      debug_msg("The number is %d\n", 5);
00053  *
00054  * Provided DEBUG_LOGGING is defined before this file is included,
00055  * debugging messages are enabled for a particular source file.  If
00056  * `configure' is run with optional flag --enable-debug-msgs, then all
00057  * debug_msg statements in built files will be active.  This latter option
00058  * turns on a huge amount of debug output statements which may not be desired.
00059  *
00060  * An additional macro with pseudo prototype
00061  *      debug_msg_indent(uint32_t n);
00062  * also exists.  It sets the indentation after the debug_msg line and file
00063  * preamble to n spaces.
00064  *
00065  * About this file
00066  * ---------------
00067  *
00068  * There is some additional unpleasantness in this header for
00069  * `configure' related magic.
00070  *
00071  * The macro CPP_SUPPORTS_VA_ARGS is defined by `configure' tests if the
00072  * C preprocessor supports macros with variable length arguments.  We
00073  * use the GNU specific (args...) syntax for variable length arguments
00074  * as the c9x standard (__VA_ARGS__) breaks when the preprocessor is
00075  * invoked via g++.
00076  *
00077  * The macro DEBUG_PRINT_FUNCTION_NAME is intended to be defined as
00078  * the result of a `configure' command line option for people who like
00079  * this feature.
00080  */
00081 
00082 /*
00083  * The following defines and notes we defined __printfike if it does not
00084  * already exist.  The expansion of this macro uses a gcc extension to
00085  * check format strings.
00086  */
00087 #ifndef __printflike
00088 #ifdef __GNUC__
00089 #define __printflike(fmt,va1) __attribute__((__format__(printf, fmt, va1)))
00090 #define __libxorp_debug_defined_printflike
00091 #else
00092 #define __printflike(fmt, va1)
00093 #define __libxorp_debug_defined_printflike
00094 #endif
00095 #endif /* __printflike */
00096 
00097 
00098 // TODO:  Make this configurable in scons  (remove it from xlog.h too)
00099 #define XORP_LOG_PRINT_USECS
00100 
00101 /*
00102  * `configure' defines DEBUG_LOGGING_GLOBAL, user may define DEBUG_LOGGING.
00103  */
00104 #if defined(DEBUG_LOGGING) || defined(DEBUG_LOGGING_GLOBAL)
00105 #   if !defined(DEBUG_LOGGING)
00106 #       define DEBUG_LOGGING
00107 #   elif !defined(DEBUG_LOGGING_GLOBAL)
00108 #       define DEBUG_LOGGING_GLOBAL
00109 #   endif /* DEBUG_LOGGING */
00110 #   ifdef CPP_SUPPORTS_GNU_VA_ARGS
00111 #   ifdef DEBUG_PRINT_FUNCTION_NAME
00112 #       define debug_msg(args...)                   \
00113             _xdebug_msg_long(__FILE__,__LINE__,__FUNCTION__,args)
00114 #   else
00115 #       define debug_msg(args...)                   \
00116             _xdebug_msg_long(__FILE__,__LINE__,0,args)
00117 #   endif
00118 #   else
00119 #   ifdef DEBUG_PRINT_FUNCTION_NAME
00120 #       define debug_msg                        \
00121         _xdebug_entry(__FILE__,__LINE__,__FUNCTION__),      \
00122         _xdebug_msg_short
00123 #   else
00124 #       define debug_msg                    \
00125         _xdebug_entry(__FILE__,__LINE__,0), _xdebug_msg_short
00126 #   endif
00127 #   endif
00128 #
00129 #   define debug_msg_indent(n) _xdebug_set_indent(n)
00130 #
00131 #else
00132 #    ifdef __cplusplus
00133 
00134 /* This cruft and the ensuing version of debug_msg mean that the debug enabled
00135  * and disabled versions of debug_msg have similar sematics, ie both are
00136  * likely to be broken or neither is broken following a change.  However,
00137  * this comes at non-zero cost so an NDEBUG build would probably want to
00138  * define debug_msg to be empty (enabling optimization may not stop
00139  * calls to c_str() in format arguments).
00140  */
00141 inline void swallow_args(const char*) {}
00142 
00143 template <class A>
00144 inline void swallow_args(const char*, A) {}
00145 
00146 template <class A, class B>
00147 inline void swallow_args(const char*, A, B) {}
00148 
00149 template <class A, class B, class C>
00150 inline void swallow_args(const char*, A, B, C) {}
00151 
00152 template <class A, class B, class C, class D>
00153 inline void swallow_args(const char*, A, B, C, D) {}
00154 
00155 template <class A, class B, class C, class D, class E>
00156 inline void swallow_args(const char*, A, B, C, D, E) {}
00157 
00158 template <class A, class B, class C, class D, class E, class F>
00159 inline void swallow_args(const char*, A, B, C, D, E, F) {}
00160 
00161 template <class A, class B, class C, class D, class E, class F, class G>
00162 inline void swallow_args(const char*, A, B, C, D, E, F, G) {}
00163 
00164 template <class A, class B, class C, class D, class E, class F, class G, class H>
00165 inline void swallow_args(const char*, A, B, C, D, E, F, G, H) {}
00166 
00167 template <class A, class B, class C, class D, class E, class F, class G, class H, class I>
00168 inline void swallow_args(const char*, A, B, C, D, E, F, G, H, I) {}
00169 
00170 template <class A, class B, class C, class D, class E, class F, class G, class H, class I, class J>
00171 inline void swallow_args(const char*, A, B, C, D, E, F, G, H, I, J) {}
00172 
00173 template <class A, class B, class C, class D, class E, class F, class G, class H, class I, class J, class K>
00174 inline void swallow_args(const char*, A, B, C, D, E, F, G, H, I, J, K) {}
00175 
00176 template <class A, class B, class C, class D, class E, class F, class G, class H, class I, class J, class K, class L>
00177 inline void swallow_args(const char*, A, B, C, D, E, F, G, H, I, J, K, L) {}
00178 
00179 inline void
00180 check_args(const char* fmt, ...) __printflike(1,2);
00181 
00182 inline void
00183 check_args(const char*, ...) {}
00184 
00185 #define debug_msg(args...)                            \
00186 do {                                                                          \
00187   if (0) {                                    \
00188     check_args(args);                                 \
00189     swallow_args(args);                               \
00190   }                                                                           \
00191 } while (0)
00192 
00193 #    else
00194 #   ifdef CPP_SUPPORTS_GNU_VA_ARGS
00195 #       define debug_msg(args...)
00196 #   else
00197 #       define debug_msg if (1) ; else _xdebug_null
00198 #   endif
00199 #    endif
00200 #
00201 #    define debug_msg_indent(x)
00202 #
00203 #endif
00204 
00205 #ifdef __cplusplus
00206 extern "C" {
00207 #endif
00208 
00209 /* Function for systems with variable argument macros */
00210 void    _xdebug_msg_long(const char* file, int line, const char* fn,
00211              const char* format, ...) __printflike(4, 5);
00212 
00213 /* Functions for systems without variable argument macros */
00214 void    _xdebug_entry(const char* file, int line, const char* fn);
00215 void    _xdebug_msg_short(const char* format, ...) __printflike(1,2);
00216 void    _xdebug_null(const char* format, ...) __printflike(1,2);
00217 
00218 /* Misc */
00219 void    _xdebug_set_indent(uint32_t n);
00220 
00221 /* Undefine __printflike if we defined it */
00222 #ifdef __libxorp_debug_defined_printflike
00223 #undef __libxorp_debug_defined_printflike
00224 #undef __printflike
00225 #endif /* __libxorp_debug_defined_printflike */
00226 
00227 #ifdef __cplusplus
00228 }
00229 #endif
00230 
00231 #endif /* __LIBXORP_DEBUG_H__ */
 All Classes Namespaces Functions Variables Typedefs Enumerations