summaryrefslogtreecommitdiffstats
path: root/src/civetweb/src/third_party/duktape-1.5.2/src-separate/duk_debug.h
blob: 256d2dcd28aae9feb6906b23c206f9bb589e0864 (plain)
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
 *  Debugging macros, DUK_DPRINT() and its variants in particular.
 *
 *  DUK_DPRINT() allows formatted debug prints, and supports standard
 *  and Duktape specific formatters.  See duk_debug_vsnprintf.c for details.
 *
 *  DUK_D(x), DUK_DD(x), and DUK_DDD(x) are used together with log macros
 *  for technical reasons.  They are concretely used to hide 'x' from the
 *  compiler when the corresponding log level is disabled.  This allows
 *  clean builds on non-C99 compilers, at the cost of more verbose code.
 *  Examples:
 *
 *    DUK_D(DUK_DPRINT("foo"));
 *    DUK_DD(DUK_DDPRINT("foo"));
 *    DUK_DDD(DUK_DDDPRINT("foo"));
 *
 *  This approach is preferable to the old "double parentheses" hack because
 *  double parentheses make the C99 solution worse: __FILE__ and __LINE__ can
 *  no longer be added transparently without going through globals, which
 *  works poorly with threading.
 */

#ifndef DUK_DEBUG_H_INCLUDED
#define DUK_DEBUG_H_INCLUDED

#ifdef DUK_USE_DEBUG

#if defined(DUK_USE_DPRINT)
#define DUK_D(x) x
#else
#define DUK_D(x) do { } while (0) /* omit */
#endif

#if defined(DUK_USE_DDPRINT)
#define DUK_DD(x) x
#else
#define DUK_DD(x) do { } while (0) /* omit */
#endif

#if defined(DUK_USE_DDDPRINT)
#define DUK_DDD(x) x
#else
#define DUK_DDD(x) do { } while (0) /* omit */
#endif

/*
 *  Exposed debug macros: debugging enabled
 */

#define DUK_LEVEL_DEBUG    1
#define DUK_LEVEL_DDEBUG   2
#define DUK_LEVEL_DDDEBUG  3

#ifdef DUK_USE_VARIADIC_MACROS

/* Note: combining __FILE__, __LINE__, and __func__ into fmt would be
 * possible compile time, but waste some space with shared function names.
 */
#define DUK__DEBUG_LOG(lev,...)  duk_debug_log((duk_small_int_t) (lev), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, DUK_FUNC_MACRO, __VA_ARGS__);

#define DUK_DPRINT(...)          DUK__DEBUG_LOG(DUK_LEVEL_DEBUG, __VA_ARGS__)

#ifdef DUK_USE_DDPRINT
#define DUK_DDPRINT(...)         DUK__DEBUG_LOG(DUK_LEVEL_DDEBUG, __VA_ARGS__)
#else
#define DUK_DDPRINT(...)
#endif

#ifdef DUK_USE_DDDPRINT
#define DUK_DDDPRINT(...)        DUK__DEBUG_LOG(DUK_LEVEL_DDDEBUG, __VA_ARGS__)
#else
#define DUK_DDDPRINT(...)
#endif

#else  /* DUK_USE_VARIADIC_MACROS */

#define DUK__DEBUG_STASH(lev)    \
	(void) DUK_SNPRINTF(duk_debug_file_stash, DUK_DEBUG_STASH_SIZE, "%s", (const char *) DUK_FILE_MACRO), \
	duk_debug_file_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0; \
	(void) DUK_SNPRINTF(duk_debug_line_stash, DUK_DEBUG_STASH_SIZE, "%ld", (long) DUK_LINE_MACRO), \
	duk_debug_line_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0; \
	(void) DUK_SNPRINTF(duk_debug_func_stash, DUK_DEBUG_STASH_SIZE, "%s", (const char *) DUK_FUNC_MACRO), \
	duk_debug_func_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0; \
	(void) (duk_debug_level_stash = (lev))

/* Without variadic macros resort to comma expression trickery to handle debug
 * prints.  This generates a lot of harmless warnings.  These hacks are not
 * needed normally because DUK_D() and friends will hide the entire debug log
 * statement from the compiler.
 */

#ifdef DUK_USE_DPRINT
#define DUK_DPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DEBUG), (void) duk_debug_log  /* args go here in parens */
#else
#define DUK_DPRINT  0 && /* args go here as a comma expression in parens */
#endif

#ifdef DUK_USE_DDPRINT
#define DUK_DDPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DDEBUG), (void) duk_debug_log  /* args go here in parens */
#else
#define DUK_DDPRINT  0 && /* args */
#endif

#ifdef DUK_USE_DDDPRINT
#define DUK_DDDPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DDDEBUG), (void) duk_debug_log  /* args go here in parens */
#else
#define DUK_DDDPRINT  0 && /* args */
#endif

#endif  /* DUK_USE_VARIADIC_MACROS */

#else  /* DUK_USE_DEBUG */

/*
 *  Exposed debug macros: debugging disabled
 */

#define DUK_D(x) do { } while (0) /* omit */
#define DUK_DD(x) do { } while (0) /* omit */
#define DUK_DDD(x) do { } while (0) /* omit */

#ifdef DUK_USE_VARIADIC_MACROS

#define DUK_DPRINT(...)
#define DUK_DDPRINT(...)
#define DUK_DDDPRINT(...)

#else  /* DUK_USE_VARIADIC_MACROS */

#define DUK_DPRINT    0 && /* args go here as a comma expression in parens */
#define DUK_DDPRINT   0 && /* args */
#define DUK_DDDPRINT  0 && /* args */

#endif  /* DUK_USE_VARIADIC_MACROS */

#endif  /* DUK_USE_DEBUG */

/*
 *  Structs
 */

#ifdef DUK_USE_DEBUG
struct duk_fixedbuffer {
	duk_uint8_t *buffer;
	duk_size_t length;
	duk_size_t offset;
	duk_bool_t truncated;
};
#endif

/*
 *  Prototypes
 */

#ifdef DUK_USE_DEBUG
DUK_INTERNAL_DECL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap);
#if 0  /*unused*/
DUK_INTERNAL_DECL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...);
#endif
DUK_INTERNAL_DECL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_uint8_t *fptr, duk_size_t fptr_size);

#ifdef DUK_USE_VARIADIC_MACROS
DUK_INTERNAL_DECL void duk_debug_log(duk_small_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...);
#else  /* DUK_USE_VARIADIC_MACROS */
/* parameter passing, not thread safe */
#define DUK_DEBUG_STASH_SIZE  128
#if !defined(DUK_SINGLE_FILE)
DUK_INTERNAL_DECL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE];
DUK_INTERNAL_DECL char duk_debug_line_stash[DUK_DEBUG_STASH_SIZE];
DUK_INTERNAL_DECL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE];
DUK_INTERNAL_DECL duk_small_int_t duk_debug_level_stash;
#endif
DUK_INTERNAL_DECL void duk_debug_log(const char *fmt, ...);
#endif  /* DUK_USE_VARIADIC_MACROS */

DUK_INTERNAL_DECL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffer, duk_size_t length);
DUK_INTERNAL_DECL void duk_fb_put_byte(duk_fixedbuffer *fb, duk_uint8_t x);
DUK_INTERNAL_DECL void duk_fb_put_cstring(duk_fixedbuffer *fb, const char *x);
DUK_INTERNAL_DECL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...);
DUK_INTERNAL_DECL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size);
DUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);

#endif  /* DUK_USE_DEBUG */

#endif  /* DUK_DEBUG_H_INCLUDED */