10f743729SConrad Meyer /* ****************************************************************** 237f1f268SConrad Meyer * debug 337f1f268SConrad Meyer * Part of FSE library 4*5ff13fbcSAllan Jude * Copyright (c) Yann Collet, Facebook, Inc. 537f1f268SConrad Meyer * 637f1f268SConrad Meyer * You can contact the author at : 737f1f268SConrad Meyer * - Source repository : https://github.com/Cyan4973/FiniteStateEntropy 837f1f268SConrad Meyer * 937f1f268SConrad Meyer * This source code is licensed under both the BSD-style license (found in the 1037f1f268SConrad Meyer * LICENSE file in the root directory of this source tree) and the GPLv2 (found 1137f1f268SConrad Meyer * in the COPYING file in the root directory of this source tree). 1237f1f268SConrad 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 540f743729SConrad Meyer /* recommended values for DEBUGLEVEL : 55a0483764SConrad Meyer * 0 : release mode, no debug, all run-time checks disabled 56a0483764SConrad Meyer * 1 : enables assert() only, no display 570f743729SConrad Meyer * 2 : reserved, for currently active debug path 580f743729SConrad Meyer * 3 : events once per object lifetime (CCtx, CDict, etc.) 590f743729SConrad Meyer * 4 : events once per frame 600f743729SConrad Meyer * 5 : events once per block 610f743729SConrad Meyer * 6 : events once per sequence (verbose) 620f743729SConrad Meyer * 7+: events at every position (*very* verbose) 630f743729SConrad Meyer * 640f743729SConrad Meyer * It's generally inconvenient to output traces > 5. 65a0483764SConrad Meyer * In which case, it's possible to selectively trigger high verbosity levels 660f743729SConrad Meyer * by modifying g_debug_level. 670f743729SConrad Meyer */ 680f743729SConrad Meyer 690f743729SConrad Meyer #if (DEBUGLEVEL>=1) 70f7cd7fe5SConrad Meyer # define ZSTD_DEPS_NEED_ASSERT 71f7cd7fe5SConrad Meyer # include "zstd_deps.h" 720f743729SConrad Meyer #else 730f743729SConrad Meyer # ifndef assert /* assert may be already defined, due to prior #include <assert.h> */ 740f743729SConrad Meyer # define assert(condition) ((void)0) /* disable assert (default) */ 750f743729SConrad Meyer # endif 760f743729SConrad Meyer #endif 770f743729SConrad Meyer 780f743729SConrad Meyer #if (DEBUGLEVEL>=2) 79f7cd7fe5SConrad Meyer # define ZSTD_DEPS_NEED_IO 80f7cd7fe5SConrad Meyer # include "zstd_deps.h" 81a0483764SConrad Meyer extern int g_debuglevel; /* the variable is only declared, 820f743729SConrad Meyer it actually lives in debug.c, 830f743729SConrad Meyer and is shared by the whole process. 84a0483764SConrad Meyer It's not thread-safe. 85a0483764SConrad Meyer It's useful when enabling very verbose levels 860f743729SConrad Meyer on selective conditions (such as position in src) */ 870f743729SConrad Meyer 880f743729SConrad Meyer # define RAWLOG(l, ...) { \ 890f743729SConrad Meyer if (l<=g_debuglevel) { \ 90f7cd7fe5SConrad Meyer ZSTD_DEBUG_PRINT(__VA_ARGS__); \ 910f743729SConrad Meyer } } 920f743729SConrad Meyer # define DEBUGLOG(l, ...) { \ 930f743729SConrad Meyer if (l<=g_debuglevel) { \ 94f7cd7fe5SConrad Meyer ZSTD_DEBUG_PRINT(__FILE__ ": " __VA_ARGS__); \ 95f7cd7fe5SConrad Meyer ZSTD_DEBUG_PRINT(" \n"); \ 960f743729SConrad Meyer } } 970f743729SConrad Meyer #else 980f743729SConrad Meyer # define RAWLOG(l, ...) {} /* disabled */ 990f743729SConrad Meyer # define DEBUGLOG(l, ...) {} /* disabled */ 1000f743729SConrad Meyer #endif 1010f743729SConrad Meyer 1020f743729SConrad Meyer 1030f743729SConrad Meyer #if defined (__cplusplus) 1040f743729SConrad Meyer } 1050f743729SConrad Meyer #endif 1060f743729SConrad Meyer 1070f743729SConrad Meyer #endif /* DEBUG_H_12987983217 */ 108