10f743729SConrad Meyer /* ****************************************************************** 2*37f1f268SConrad Meyer * debug 3*37f1f268SConrad Meyer * Part of FSE library 4*37f1f268SConrad Meyer * Copyright (c) 2013-2020, Yann Collet, Facebook, Inc. 5*37f1f268SConrad Meyer * 6*37f1f268SConrad Meyer * You can contact the author at : 7*37f1f268SConrad Meyer * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy 8*37f1f268SConrad Meyer * 9*37f1f268SConrad Meyer * This source code is licensed under both the BSD-style license (found in the 10*37f1f268SConrad Meyer * LICENSE file in the root directory of this source tree) and the GPLv2 (found 11*37f1f268SConrad Meyer * in the COPYING file in the root directory of this source tree). 12*37f1f268SConrad Meyer * You may select, at your option, one of the above-listed licenses. 130f743729SConrad Meyer ****************************************************************** */ 140f743729SConrad Meyer 150f743729SConrad Meyer 160f743729SConrad Meyer /* 170f743729SConrad Meyer * The purpose of this header is to enable debug functions. 180f743729SConrad Meyer * They regroup assert(), DEBUGLOG() and RAWLOG() for run-time, 190f743729SConrad Meyer * and DEBUG_STATIC_ASSERT() for compile-time. 200f743729SConrad Meyer * 210f743729SConrad Meyer * By default, DEBUGLEVEL==0, which means run-time debug is disabled. 220f743729SConrad Meyer * 230f743729SConrad Meyer * Level 1 enables assert() only. 240f743729SConrad Meyer * Starting level 2, traces can be generated and pushed to stderr. 250f743729SConrad Meyer * The higher the level, the more verbose the traces. 260f743729SConrad Meyer * 270f743729SConrad Meyer * It's possible to dynamically adjust level using variable g_debug_level, 280f743729SConrad Meyer * which is only declared if DEBUGLEVEL>=2, 290f743729SConrad Meyer * and is a global variable, not multi-thread protected (use with care) 300f743729SConrad Meyer */ 310f743729SConrad Meyer 320f743729SConrad Meyer #ifndef DEBUG_H_12987983217 330f743729SConrad Meyer #define DEBUG_H_12987983217 340f743729SConrad Meyer 350f743729SConrad Meyer #if defined (__cplusplus) 360f743729SConrad Meyer extern "C" { 370f743729SConrad Meyer #endif 380f743729SConrad Meyer 390f743729SConrad Meyer 40a0483764SConrad Meyer /* static assert is triggered at compile time, leaving no runtime artefact. 41a0483764SConrad Meyer * static assert only works with compile-time constants. 42a0483764SConrad Meyer * Also, this variant can only be used inside a function. */ 430f743729SConrad Meyer #define DEBUG_STATIC_ASSERT(c) (void)sizeof(char[(c) ? 1 : -1]) 440f743729SConrad Meyer 450f743729SConrad Meyer 460f743729SConrad Meyer /* DEBUGLEVEL is expected to be defined externally, 470f743729SConrad Meyer * typically through compiler command line. 480f743729SConrad Meyer * Value must be a number. */ 490f743729SConrad Meyer #ifndef DEBUGLEVEL 500f743729SConrad Meyer # define DEBUGLEVEL 0 510f743729SConrad Meyer #endif 520f743729SConrad Meyer 53a0483764SConrad Meyer 54a0483764SConrad Meyer /* DEBUGFILE can be defined externally, 55a0483764SConrad Meyer * typically through compiler command line. 56a0483764SConrad Meyer * note : currently useless. 57a0483764SConrad Meyer * Value must be stderr or stdout */ 58a0483764SConrad Meyer #ifndef DEBUGFILE 59a0483764SConrad Meyer # define DEBUGFILE stderr 60a0483764SConrad Meyer #endif 61a0483764SConrad Meyer 62a0483764SConrad Meyer 630f743729SConrad Meyer /* recommended values for DEBUGLEVEL : 64a0483764SConrad Meyer * 0 : release mode, no debug, all run-time checks disabled 65a0483764SConrad Meyer * 1 : enables assert() only, no display 660f743729SConrad Meyer * 2 : reserved, for currently active debug path 670f743729SConrad Meyer * 3 : events once per object lifetime (CCtx, CDict, etc.) 680f743729SConrad Meyer * 4 : events once per frame 690f743729SConrad Meyer * 5 : events once per block 700f743729SConrad Meyer * 6 : events once per sequence (verbose) 710f743729SConrad Meyer * 7+: events at every position (*very* verbose) 720f743729SConrad Meyer * 730f743729SConrad Meyer * It's generally inconvenient to output traces > 5. 74a0483764SConrad Meyer * In which case, it's possible to selectively trigger high verbosity levels 750f743729SConrad Meyer * by modifying g_debug_level. 760f743729SConrad Meyer */ 770f743729SConrad Meyer 780f743729SConrad Meyer #if (DEBUGLEVEL>=1) 790f743729SConrad Meyer # include <assert.h> 800f743729SConrad Meyer #else 810f743729SConrad Meyer # ifndef assert /* assert may be already defined, due to prior #include <assert.h> */ 820f743729SConrad Meyer # define assert(condition) ((void)0) /* disable assert (default) */ 830f743729SConrad Meyer # endif 840f743729SConrad Meyer #endif 850f743729SConrad Meyer 860f743729SConrad Meyer #if (DEBUGLEVEL>=2) 870f743729SConrad Meyer # include <stdio.h> 88a0483764SConrad Meyer extern int g_debuglevel; /* the variable is only declared, 890f743729SConrad Meyer it actually lives in debug.c, 900f743729SConrad Meyer and is shared by the whole process. 91a0483764SConrad Meyer It's not thread-safe. 92a0483764SConrad Meyer It's useful when enabling very verbose levels 930f743729SConrad Meyer on selective conditions (such as position in src) */ 940f743729SConrad Meyer 950f743729SConrad Meyer # define RAWLOG(l, ...) { \ 960f743729SConrad Meyer if (l<=g_debuglevel) { \ 970f743729SConrad Meyer fprintf(stderr, __VA_ARGS__); \ 980f743729SConrad Meyer } } 990f743729SConrad Meyer # define DEBUGLOG(l, ...) { \ 1000f743729SConrad Meyer if (l<=g_debuglevel) { \ 1010f743729SConrad Meyer fprintf(stderr, __FILE__ ": " __VA_ARGS__); \ 1020f743729SConrad Meyer fprintf(stderr, " \n"); \ 1030f743729SConrad Meyer } } 1040f743729SConrad Meyer #else 1050f743729SConrad Meyer # define RAWLOG(l, ...) {} /* disabled */ 1060f743729SConrad Meyer # define DEBUGLOG(l, ...) {} /* disabled */ 1070f743729SConrad Meyer #endif 1080f743729SConrad Meyer 1090f743729SConrad Meyer 1100f743729SConrad Meyer #if defined (__cplusplus) 1110f743729SConrad Meyer } 1120f743729SConrad Meyer #endif 1130f743729SConrad Meyer 1140f743729SConrad Meyer #endif /* DEBUG_H_12987983217 */ 115