1*a28cd43dSSascha Wildner /* ****************************************************************** 2*a28cd43dSSascha Wildner * debug 3*a28cd43dSSascha Wildner * Part of FSE library 4*a28cd43dSSascha Wildner * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc. 5*a28cd43dSSascha Wildner * 6*a28cd43dSSascha Wildner * You can contact the author at : 7*a28cd43dSSascha Wildner * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy 8*a28cd43dSSascha Wildner * 9*a28cd43dSSascha Wildner * This source code is licensed under both the BSD-style license (found in the 10*a28cd43dSSascha Wildner * LICENSE file in the root directory of this source tree) and the GPLv2 (found 11*a28cd43dSSascha Wildner * in the COPYING file in the root directory of this source tree). 12*a28cd43dSSascha Wildner * You may select, at your option, one of the above-listed licenses. 13*a28cd43dSSascha Wildner ****************************************************************** */ 14*a28cd43dSSascha Wildner 15*a28cd43dSSascha Wildner 16*a28cd43dSSascha Wildner /* 17*a28cd43dSSascha Wildner * The purpose of this header is to enable debug functions. 18*a28cd43dSSascha Wildner * They regroup assert(), DEBUGLOG() and RAWLOG() for run-time, 19*a28cd43dSSascha Wildner * and DEBUG_STATIC_ASSERT() for compile-time. 20*a28cd43dSSascha Wildner * 21*a28cd43dSSascha Wildner * By default, DEBUGLEVEL==0, which means run-time debug is disabled. 22*a28cd43dSSascha Wildner * 23*a28cd43dSSascha Wildner * Level 1 enables assert() only. 24*a28cd43dSSascha Wildner * Starting level 2, traces can be generated and pushed to stderr. 25*a28cd43dSSascha Wildner * The higher the level, the more verbose the traces. 26*a28cd43dSSascha Wildner * 27*a28cd43dSSascha Wildner * It's possible to dynamically adjust level using variable g_debug_level, 28*a28cd43dSSascha Wildner * which is only declared if DEBUGLEVEL>=2, 29*a28cd43dSSascha Wildner * and is a global variable, not multi-thread protected (use with care) 30*a28cd43dSSascha Wildner */ 31*a28cd43dSSascha Wildner 32*a28cd43dSSascha Wildner #ifndef DEBUG_H_12987983217 33*a28cd43dSSascha Wildner #define DEBUG_H_12987983217 34*a28cd43dSSascha Wildner 35*a28cd43dSSascha Wildner #if defined (__cplusplus) 36*a28cd43dSSascha Wildner extern "C" { 37*a28cd43dSSascha Wildner #endif 38*a28cd43dSSascha Wildner 39*a28cd43dSSascha Wildner 40*a28cd43dSSascha Wildner /* static assert is triggered at compile time, leaving no runtime artefact. 41*a28cd43dSSascha Wildner * static assert only works with compile-time constants. 42*a28cd43dSSascha Wildner * Also, this variant can only be used inside a function. */ 43*a28cd43dSSascha Wildner #define DEBUG_STATIC_ASSERT(c) (void)sizeof(char[(c) ? 1 : -1]) 44*a28cd43dSSascha Wildner 45*a28cd43dSSascha Wildner 46*a28cd43dSSascha Wildner /* DEBUGLEVEL is expected to be defined externally, 47*a28cd43dSSascha Wildner * typically through compiler command line. 48*a28cd43dSSascha Wildner * Value must be a number. */ 49*a28cd43dSSascha Wildner #ifndef DEBUGLEVEL 50*a28cd43dSSascha Wildner # define DEBUGLEVEL 0 51*a28cd43dSSascha Wildner #endif 52*a28cd43dSSascha Wildner 53*a28cd43dSSascha Wildner 54*a28cd43dSSascha Wildner /* recommended values for DEBUGLEVEL : 55*a28cd43dSSascha Wildner * 0 : release mode, no debug, all run-time checks disabled 56*a28cd43dSSascha Wildner * 1 : enables assert() only, no display 57*a28cd43dSSascha Wildner * 2 : reserved, for currently active debug path 58*a28cd43dSSascha Wildner * 3 : events once per object lifetime (CCtx, CDict, etc.) 59*a28cd43dSSascha Wildner * 4 : events once per frame 60*a28cd43dSSascha Wildner * 5 : events once per block 61*a28cd43dSSascha Wildner * 6 : events once per sequence (verbose) 62*a28cd43dSSascha Wildner * 7+: events at every position (*very* verbose) 63*a28cd43dSSascha Wildner * 64*a28cd43dSSascha Wildner * It's generally inconvenient to output traces > 5. 65*a28cd43dSSascha Wildner * In which case, it's possible to selectively trigger high verbosity levels 66*a28cd43dSSascha Wildner * by modifying g_debug_level. 67*a28cd43dSSascha Wildner */ 68*a28cd43dSSascha Wildner 69*a28cd43dSSascha Wildner #if (DEBUGLEVEL>=1) 70*a28cd43dSSascha Wildner # define ZSTD_DEPS_NEED_ASSERT 71*a28cd43dSSascha Wildner # include "zstd_deps.h" 72*a28cd43dSSascha Wildner #else 73*a28cd43dSSascha Wildner # ifndef assert /* assert may be already defined, due to prior #include <assert.h> */ 74*a28cd43dSSascha Wildner # define assert(condition) ((void)0) /* disable assert (default) */ 75*a28cd43dSSascha Wildner # endif 76*a28cd43dSSascha Wildner #endif 77*a28cd43dSSascha Wildner 78*a28cd43dSSascha Wildner #if (DEBUGLEVEL>=2) 79*a28cd43dSSascha Wildner # define ZSTD_DEPS_NEED_IO 80*a28cd43dSSascha Wildner # include "zstd_deps.h" 81*a28cd43dSSascha Wildner extern int g_debuglevel; /* the variable is only declared, 82*a28cd43dSSascha Wildner it actually lives in debug.c, 83*a28cd43dSSascha Wildner and is shared by the whole process. 84*a28cd43dSSascha Wildner It's not thread-safe. 85*a28cd43dSSascha Wildner It's useful when enabling very verbose levels 86*a28cd43dSSascha Wildner on selective conditions (such as position in src) */ 87*a28cd43dSSascha Wildner 88*a28cd43dSSascha Wildner # define RAWLOG(l, ...) { \ 89*a28cd43dSSascha Wildner if (l<=g_debuglevel) { \ 90*a28cd43dSSascha Wildner ZSTD_DEBUG_PRINT(__VA_ARGS__); \ 91*a28cd43dSSascha Wildner } } 92*a28cd43dSSascha Wildner # define DEBUGLOG(l, ...) { \ 93*a28cd43dSSascha Wildner if (l<=g_debuglevel) { \ 94*a28cd43dSSascha Wildner ZSTD_DEBUG_PRINT(__FILE__ ": " __VA_ARGS__); \ 95*a28cd43dSSascha Wildner ZSTD_DEBUG_PRINT(" \n"); \ 96*a28cd43dSSascha Wildner } } 97*a28cd43dSSascha Wildner #else 98*a28cd43dSSascha Wildner # define RAWLOG(l, ...) {} /* disabled */ 99*a28cd43dSSascha Wildner # define DEBUGLOG(l, ...) {} /* disabled */ 100*a28cd43dSSascha Wildner #endif 101*a28cd43dSSascha Wildner 102*a28cd43dSSascha Wildner 103*a28cd43dSSascha Wildner #if defined (__cplusplus) 104*a28cd43dSSascha Wildner } 105*a28cd43dSSascha Wildner #endif 106*a28cd43dSSascha Wildner 107*a28cd43dSSascha Wildner #endif /* DEBUG_H_12987983217 */ 108