unified_debug/example-c/unified_debug.h (64 lines of code) (raw):

/* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef INCLUDE_UNIFIED_DEBUG_H #define INCLUDE_UNIFIED_DEBUG_H #include <assert.h> /* Unified debugging library for C++ and JavaScript. JavaScript code can control debugging output. C++ and JavaScript can both create messages. Debugging can be enabled or disabled for individual source files. (The implementation takes a hash of the filename and looks up a single bit in a bitmask indexes. Hash collisions are possible.) */ enum { UDEB_OFF = 0, UDEB_URGENT = 1, UDEB_NOTICE = 2, UDEB_INFO = 3, UDEB_DEBUG = 4, UDEB_DETAIL = 5 }; /* Maximum size of a debug message */ #define UDEB_MSG_BUF 8000 #define UDEB_SOURCE_FILE_BITMASK_BYTES 2048 #define UDEB_SOURCE_FILE_BITMASK_BITS (8 * 2048) #ifdef __cplusplus #define DECLARE_FUNCTIONS_WITH_C_LINKAGE extern "C" { #define END_FUNCTIONS_WITH_C_LINKAGE } #else #define DECLARE_FUNCTIONS_WITH_C_LINKAGE #define END_FUNCTIONS_WITH_C_LINKAGE #endif DECLARE_FUNCTIONS_WITH_C_LINKAGE /* Macros in the Public API: * * DEBUG_PRINT(level, fmt, ...) : print message at level * DEBUG_ENTER() : enter a function (DEBUG level) * DEBUG_TRACE() : print a line number trace (DETAIL level) * DEBUG_LEAVE() : leave a function (DEBUG level) * DEBUG_MARKER() : automatic enter & leave for C++ code * */ void udeb_print(const char *, int level, const char *fmt, ...); inline void udeb_trace(const char *src_path, int line) { udeb_print(src_path, UDEB_DETAIL, " Trace: %27s line %d", ".....", line); } inline void udeb_leave(int level, const char *src_path, const char *function) { udeb_print(src_path, level, " Leave: %25s", function); } void udeb_enter(int, const char *, const char *, int); END_FUNCTIONS_WITH_C_LINKAGE /* The C-style API uses macros. DEBUG_ENTER(), DEBUG_PRINT(), DEBUG_TRACE(). There is also a macro wrapper for the C++ marker. */ #ifdef UNIFIED_DEBUG extern int uni_debug; #define DEBUG_ENTER() if(uni_debug) udeb_enter(UDEB_DEBUG, __FILE__, __func__, __LINE__) #define DEBUG_PRINT(...) if(uni_debug) udeb_print(__FILE__, UDEB_DEBUG, __VA_ARGS__) #define DEBUG_PRINT_DETAIL(...) if(uni_debug) udeb_print(__FILE__, UDEB_DETAIL, __VA_ARGS__) #define DEBUG_PRINT_INFO(...) if(uni_debug) udeb_print(__FILE__, UDEB_INFO, __VA_ARGS__) #define DEBUG_TRACE() if(uni_debug) udeb_trace(__FILE__, __LINE__) #define DEBUG_LEAVE() if(uni_debug) udeb_leave(UDEB_DEBUG, __FILE__, __func__) #define DEBUG_MARKER(lvl) u_DebugMarker _dm( __FILE__, __func__, __LINE__, lvl) #define DEBUG_ASSERT(x) assert(x) /* For a C++ API, you can declare a DEBUG_MARKER() on the stack in any scope. Its constructor will write a message when the scope is entered, and its destructor will write a message when the scope is exited. */ #ifdef __cplusplus class u_DebugMarker { public: const char *sfile, *sfunc; int level; u_DebugMarker(const char *sfl, const char * sfn, int ln, int l=UDEB_DEBUG) : sfile(sfl), sfunc(sfn), level(l) { if(uni_debug) udeb_enter(level, sfile, sfunc, ln); } ~u_DebugMarker() { if(uni_debug) udeb_leave(level, sfile, sfunc); } }; #endif #else #define DEBUG_PRINT(...) #define DEBUG_PRINT_INFO(...) #define DEBUG_PRINT_DETAIL(...) #define DEBUG_ENTER() #define DEBUG_TRACE() #define DEBUG_LEAVE() #define DEBUG_MARKER(lvl) #define DEBUG_ASSERT(x) #endif #endif