-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdebug.h
139 lines (128 loc) · 5.67 KB
/
debug.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
* debug - debug, warning and error reporting facility
*
* Copyright (c) 2019-2020 by Landon Curt Noll. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright, this permission notice and text
* this comment, and the disclaimer below appear in all of the following:
*
* supporting documentation
* source copies
* source works derived from this source
* binaries derived from this source or from derived source
*
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* chongo (Landon Curt Noll, http://www.isthe.com/chongo/index.html) /\oo/\
*
* Share and enjoy! :-)
*/
#if !defined(INCLUDE_DEBUG_H)
# define INCLUDE_DEBUG_H
extern const char *program; // our name
extern const char version_string[]; // our package name and version plus newline
extern int debuglevel; // print debug messages <= debuglevel
/*
* DEBUG_LINT - if defined, debug calls turn into fprintf to stderr calls
*
* The purpose of DEBUG_LINT is to let the C compiler do a fprintf format
* argument count and type check against the debug function. With DEBUG_LINT,
* the debug macros are "faked" as best as we can.
*
* NOTE: Use of DEBUG_LINT is intended ONLY for static analysis (ala classic lint)
* with compiler warnings. DEBUG_LINT works best with -Wall. In particular, it
* won't help of you disable warnings that DEBUG_LINT would otherwise generate.
*
* When using DEBUG_LINT, consider compiling with:
*
* -Wall -Werror -pedantic
*
* with at least the c11 standard. As in:
*
* -std=c11 -Wall -Werror -pedantic
*
* During DEBUG_LINT, output will be written to stderr. These macros assume
* that stderr is unbuffered.
*
* No error checking is performed by fprintf and fputc to stderr. Such errors will overwrite
* errno making the calls that perror print incorrect error messages.
*
* The DEBUG_LINT assumes the following global variables is declared elsewhere:
*
* long int debuglevel; // dbg() verbosity cutoff level
*
* The DEBUG_LINT assumes the following file is included somewhere above the include of this file:
*
* #include <stdlib.h>
*
* The DEBUG_LINT only works with compilers newer than 199901L (c11 or newer).
* Defining DEBUG_LINT on an older compiler will be ignored in this file.
* However when it comes to compiling debug.c, nothing will happen resulting
* in a link error. This is a feature, not a bug. It tells you that your
* compiler is too old to make use of DEBUG_LINT so don't use it.
*
* IMPORTANT NOTE:
*
* Executing code with DEBUG_LINT enabled is NOT recommended.
* It might work, but don't count in it!
*
* You are better off defining DEBUG_LINT in CFLAGS with, say:
*
* -std=c11 -Wall -Werror -pedantic
*
* At a minimum, fix warnings (that turn into compiler errors) related to fprintf()
* calls * until the program compiles. For better results, fix ALL warnings as some
* of those warnings may indicate the presence of bugs in your code including but
* not limited to the use of debug functions.
*/
# if defined(DEBUG_LINT) && __STDC_VERSION__ >= 199901L
# include <stdbool.h>
# define msg(...) fprintf(stderr, __VA_ARGS__)
# define dbg(level, ...) ((debuglevel >= (level)) ? printf(__VA_ARGS__) : true)
# define warn(name, ...) (fprintf(stderr, "%s: ", (name)), \
fprintf(stderr, __VA_ARGS__))
# define warnp(name, ...) (fprintf(stderr, "%s: ", (name)), \
fprintf(stderr, __VA_ARGS__), \
fputc('\n', stderr), \
perror(__FUNCTION__))
# define err(exitcode, name, ...) (fprintf(stderr, "%s: ", (name)), \
fprintf(stderr, __VA_ARGS__), \
exit(exitcode))
# define errp(exitcode, name, ...) (fprintf(stderr, "%s: ", (name)), \
fprintf(stderr, __VA_ARGS__), \
fputc('\n', stderr), \
perror(__FUNCTION__), \
exit(exitcode))
# define usage_err(exitcode, name, ...) (fprintf(stderr, "%s: ", (name)), \
fprintf(stderr, __VA_ARGS__), \
exit(exitcode))
# define usage_errp(exitcode, name, ...) (fprintf(stderr, "%s: ", (name)), \
fprintf(stderr, __VA_ARGS__), \
fputc('\n', stderr), perror(__FUNCTION__), \
exit(exitcode))
# else // DEBUG_LINT && __STDC_VERSION__ >= 199901L
extern void msg(const char *fmt, ...);
extern void dbg(int level, const char *fmt, ...);
extern void warn(const char *name, const char *fmt, ...);
extern void warnp(const char *name, const char *fmt, ...);
extern void err(int exitcode, const char *name, const char *fmt, ...);
extern void errp(int exitcode, const char *name, const char *fmt, ...);
extern void usage_err(int exitcode, const char *name, const char *fmt, ...);
extern void usage_errp(int exitcode, const char *name, const char *fmt, ...);
# endif // DEBUG_LINT && __STDC_VERSION__ >= 199901L
# define DBG_NONE (0) // no debugging
# define DBG_LOW (1) // minimal debugging
# define DBG_MED (3) // somewhat more debugging
# define DBG_HIGH (5) // verbose debugging
# define DBG_VHIGH (7) // very verbose debugging
# define DBG_VVHIGH (9) // very very verbose debugging
# define FORCED_EXIT (255) // exit(255) on bad exit code
#endif /* INCLUDE_DEBUG_H */