#ifndef __DEBUG_H__ #define __DEBUG_H__ /** @file Debug.h * @brief Define a simple debugging interface to use in C programs * @details One method of debugging your C program is to add printf() * statements to your code. This file provides a way of including debug * output, and being able to turn it on/off either at compile time or * at runtime, without making any changes to your code. * Two levels of debugging are provided. If the value DEBUG is * defined, your debug calls are compiled into your code. Otherwise, they are * removed by the optimizer. There is an additional run time check as to * whether to actually print the debugging output. This is controlled by the * value debugLevel. *

* To use it with gcc, simply write a printf() call, but * replace the printf() call by debug(). *

* To easily print the value of a single variable, use *


    vDebug("format", var); // "format" is the specifier (e.g. "%d" or "%s", etc)
 *  
*

* To use debug(), but control when it prints, use *


    lDebug(level, "format", var); // print when debugLevel >= level
 *  
*

* Based on code and ideas found * * here and * * here. *

* @author Fritz Sieker **/ #ifdef __cplusplus extern "C" { #endif #include /** Initialize the variable debugLevel depending on the value * of argv[1]. Normally called from main with the program * arguments. If argv[1] is or begins with -debug, the * value of debugLevel is set and argc, argv are * modified appropriately. An entry of -debug5 sets the level to 5. * If the function is not called, the user is responsible for setting * debugLevel in other code. * @param argc the number of command line arguments * @param argv the array of command line arguments. */ void debugInit(int* argc, const char* argv[]); /** Send the debug output to a file * @param fileName name of file to write debug output to */ void debugToFile(const char* fileName); /** Close the external file and reset debugFile to stderr */ void debugClose(void); /** Control how much debug output is produced. Higher values produce more * output. See the use in lDebug(). */ extern int debugLevel; /** The file where debug output is written. Defaults to stderr. * debugToFile() allows output to any file. */ extern FILE* debugFile; #ifdef DEBUG #define DEBUG_ENABLED 1 // debug code available at runtime #else /** This macro controls whether all debugging code is optimized out of the * executable, or is compiled and controlled at runtime by the * debugLevel variable. The value (0/1) depends on whether * the macro DEBUG is defined during the compile. */ #define DEBUG_ENABLED 0 // all debug code optimized out #endif /** Print the file name, line number, function name and "HERE" */ #define HERE debug("HERE") /** Expand a name into a string and a value * @param name name of variable */ #define debugV(name) #name,(name) /** Output the name and value of a single variable * @param name name of the variable to print */ #define vDebug(fmt, name) debug("%s=(" fmt ")" , debugV(name)) /** Simple alias for lDebug() */ #define debug(fmt, ...) lDebug(1, fmt, ##__VA_ARGS__) /** Print this message if the variable debugLevel is greater * than or equal to the parameter. * @param level the level at which this information should be printed * @param fmt the formatting string (MUST be a literal */ #define lDebug(level, fmt, ...) \ do { \ if (DEBUG_ENABLED && (debugLevel >= level)) \ fprintf((debugFile ? debugFile : stderr), "DEBUG %s[%d] %s() " fmt "\n", __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ } while(0) #ifdef __cplusplus } #endif #endif