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