1*0f743729SConrad Meyer /* ****************************************************************** 2*0f743729SConrad Meyer debug 3*0f743729SConrad Meyer Part of FSE library 4*0f743729SConrad Meyer Copyright (C) 2013-present, Yann Collet. 5*0f743729SConrad Meyer 6*0f743729SConrad Meyer BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 7*0f743729SConrad Meyer 8*0f743729SConrad Meyer Redistribution and use in source and binary forms, with or without 9*0f743729SConrad Meyer modification, are permitted provided that the following conditions are 10*0f743729SConrad Meyer met: 11*0f743729SConrad Meyer 12*0f743729SConrad Meyer * Redistributions of source code must retain the above copyright 13*0f743729SConrad Meyer notice, this list of conditions and the following disclaimer. 14*0f743729SConrad Meyer * Redistributions in binary form must reproduce the above 15*0f743729SConrad Meyer copyright notice, this list of conditions and the following disclaimer 16*0f743729SConrad Meyer in the documentation and/or other materials provided with the 17*0f743729SConrad Meyer distribution. 18*0f743729SConrad Meyer 19*0f743729SConrad Meyer THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20*0f743729SConrad Meyer "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21*0f743729SConrad Meyer LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22*0f743729SConrad Meyer A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23*0f743729SConrad Meyer OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24*0f743729SConrad Meyer SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25*0f743729SConrad Meyer LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26*0f743729SConrad Meyer DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27*0f743729SConrad Meyer THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28*0f743729SConrad Meyer (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29*0f743729SConrad Meyer OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*0f743729SConrad Meyer 31*0f743729SConrad Meyer You can contact the author at : 32*0f743729SConrad Meyer - Source repository : https://github.com/Cyan4973/FiniteStateEntropy 33*0f743729SConrad Meyer ****************************************************************** */ 34*0f743729SConrad Meyer 35*0f743729SConrad Meyer 36*0f743729SConrad Meyer /* 37*0f743729SConrad Meyer * The purpose of this header is to enable debug functions. 38*0f743729SConrad Meyer * They regroup assert(), DEBUGLOG() and RAWLOG() for run-time, 39*0f743729SConrad Meyer * and DEBUG_STATIC_ASSERT() for compile-time. 40*0f743729SConrad Meyer * 41*0f743729SConrad Meyer * By default, DEBUGLEVEL==0, which means run-time debug is disabled. 42*0f743729SConrad Meyer * 43*0f743729SConrad Meyer * Level 1 enables assert() only. 44*0f743729SConrad Meyer * Starting level 2, traces can be generated and pushed to stderr. 45*0f743729SConrad Meyer * The higher the level, the more verbose the traces. 46*0f743729SConrad Meyer * 47*0f743729SConrad Meyer * It's possible to dynamically adjust level using variable g_debug_level, 48*0f743729SConrad Meyer * which is only declared if DEBUGLEVEL>=2, 49*0f743729SConrad Meyer * and is a global variable, not multi-thread protected (use with care) 50*0f743729SConrad Meyer */ 51*0f743729SConrad Meyer 52*0f743729SConrad Meyer #ifndef DEBUG_H_12987983217 53*0f743729SConrad Meyer #define DEBUG_H_12987983217 54*0f743729SConrad Meyer 55*0f743729SConrad Meyer #if defined (__cplusplus) 56*0f743729SConrad Meyer extern "C" { 57*0f743729SConrad Meyer #endif 58*0f743729SConrad Meyer 59*0f743729SConrad Meyer 60*0f743729SConrad Meyer /* static assert is triggered at compile time, leaving no runtime artefact, 61*0f743729SConrad Meyer * but can only work with compile-time constants. 62*0f743729SConrad Meyer * This variant can only be used inside a function. */ 63*0f743729SConrad Meyer #define DEBUG_STATIC_ASSERT(c) (void)sizeof(char[(c) ? 1 : -1]) 64*0f743729SConrad Meyer 65*0f743729SConrad Meyer 66*0f743729SConrad Meyer /* DEBUGLEVEL is expected to be defined externally, 67*0f743729SConrad Meyer * typically through compiler command line. 68*0f743729SConrad Meyer * Value must be a number. */ 69*0f743729SConrad Meyer #ifndef DEBUGLEVEL 70*0f743729SConrad Meyer # define DEBUGLEVEL 0 71*0f743729SConrad Meyer #endif 72*0f743729SConrad Meyer 73*0f743729SConrad Meyer /* recommended values for DEBUGLEVEL : 74*0f743729SConrad Meyer * 0 : no debug, all run-time functions disabled 75*0f743729SConrad Meyer * 1 : no display, enables assert() only 76*0f743729SConrad Meyer * 2 : reserved, for currently active debug path 77*0f743729SConrad Meyer * 3 : events once per object lifetime (CCtx, CDict, etc.) 78*0f743729SConrad Meyer * 4 : events once per frame 79*0f743729SConrad Meyer * 5 : events once per block 80*0f743729SConrad Meyer * 6 : events once per sequence (verbose) 81*0f743729SConrad Meyer * 7+: events at every position (*very* verbose) 82*0f743729SConrad Meyer * 83*0f743729SConrad Meyer * It's generally inconvenient to output traces > 5. 84*0f743729SConrad Meyer * In which case, it's possible to selectively enable higher verbosity levels 85*0f743729SConrad Meyer * by modifying g_debug_level. 86*0f743729SConrad Meyer */ 87*0f743729SConrad Meyer 88*0f743729SConrad Meyer #if (DEBUGLEVEL>=1) 89*0f743729SConrad Meyer # include <assert.h> 90*0f743729SConrad Meyer #else 91*0f743729SConrad Meyer # ifndef assert /* assert may be already defined, due to prior #include <assert.h> */ 92*0f743729SConrad Meyer # define assert(condition) ((void)0) /* disable assert (default) */ 93*0f743729SConrad Meyer # endif 94*0f743729SConrad Meyer #endif 95*0f743729SConrad Meyer 96*0f743729SConrad Meyer #if (DEBUGLEVEL>=2) 97*0f743729SConrad Meyer # include <stdio.h> 98*0f743729SConrad Meyer extern int g_debuglevel; /* here, this variable is only declared, 99*0f743729SConrad Meyer it actually lives in debug.c, 100*0f743729SConrad Meyer and is shared by the whole process. 101*0f743729SConrad Meyer It's typically used to enable very verbose levels 102*0f743729SConrad Meyer on selective conditions (such as position in src) */ 103*0f743729SConrad Meyer 104*0f743729SConrad Meyer # define RAWLOG(l, ...) { \ 105*0f743729SConrad Meyer if (l<=g_debuglevel) { \ 106*0f743729SConrad Meyer fprintf(stderr, __VA_ARGS__); \ 107*0f743729SConrad Meyer } } 108*0f743729SConrad Meyer # define DEBUGLOG(l, ...) { \ 109*0f743729SConrad Meyer if (l<=g_debuglevel) { \ 110*0f743729SConrad Meyer fprintf(stderr, __FILE__ ": " __VA_ARGS__); \ 111*0f743729SConrad Meyer fprintf(stderr, " \n"); \ 112*0f743729SConrad Meyer } } 113*0f743729SConrad Meyer #else 114*0f743729SConrad Meyer # define RAWLOG(l, ...) {} /* disabled */ 115*0f743729SConrad Meyer # define DEBUGLOG(l, ...) {} /* disabled */ 116*0f743729SConrad Meyer #endif 117*0f743729SConrad Meyer 118*0f743729SConrad Meyer 119*0f743729SConrad Meyer #if defined (__cplusplus) 120*0f743729SConrad Meyer } 121*0f743729SConrad Meyer #endif 122*0f743729SConrad Meyer 123*0f743729SConrad Meyer #endif /* DEBUG_H_12987983217 */ 124