1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
16 #ifndef SQUIRRELJME_DEBUG_H
17 #define SQUIRRELJME_DEBUG_H
22 #include "sjme/dylib.h"
26 #ifndef SJME_CXX_IS_EXTERNED
27 #define SJME_CXX_IS_EXTERNED
28 #define SJME_CXX_SQUIRRELJME_DEBUG_H
30 #endif /* #ifdef SJME_CXX_IS_EXTERNED */
31 #endif /* #ifdef __cplusplus */
33 /*--------------------------------------------------------------------------*/
35 #define SJME_DEBUG_DECL_FILE_LINE_FUNC \
36 sjme_attrInNullable sjme_lpcstr file, \
37 sjme_attrInValue int line, \
38 sjme_attrInNullable sjme_lpcstr func
40 /** File, line, and function. */
41 #define SJME_DEBUG_FILE_LINE_FUNC_ALWAYS __FILE__, __LINE__, __func__
43 #if defined(SJME_CONFIG_RELEASE)
45 #define SJME_DEBUG_ONLY_COMMA
47 /** Optional declaration for debugging. */
48 #define SJME_DEBUG_DECL_FILE_LINE_FUNC_OPTIONAL
50 /** File, line, and function. */
51 #define SJME_DEBUG_FILE_LINE_FUNC NULL, -1, NULL
53 /** Copy of file line and function. */
54 #define SJME_DEBUG_FILE_LINE_COPY
56 /** Only emitted in debugging. */
57 #define SJME_ONLY_IN_DEBUG_EXPR(expr) do {} while(0)
59 /** Only emitted in debugging. */
60 #define SJME_ONLY_IN_DEBUG_PP(expr)
62 /** Release/Debug ternary. */
63 #define SJME_DEBUG_TERNARY(debug, release) release
65 /** Debug identifier. */
66 #define SJME_DEBUG_IDENTIFIER(ident) ident
69 #define SJME_DEBUG_ONLY_COMMA ,
71 /** Optional declaration for debugging. */
72 #define SJME_DEBUG_DECL_FILE_LINE_FUNC_OPTIONAL \
73 SJME_DEBUG_DECL_FILE_LINE_FUNC
75 /** File, line, and function. */
76 #define SJME_DEBUG_FILE_LINE_FUNC SJME_DEBUG_FILE_LINE_FUNC_ALWAYS
78 /** Copy of file line and function. */
79 #define SJME_DEBUG_FILE_LINE_COPY file, line, func
81 /** Only emitted in debugging. */
82 #define SJME_ONLY_IN_DEBUG_EXPR(expr) expr
84 /** Only emitted in debugging. */
85 #define SJME_ONLY_IN_DEBUG_PP(expr) expr
87 /** Release/Debug ternary. */
88 #define SJME_DEBUG_TERNARY(debug, release) debug
90 /** Debug identifier. */
91 #define SJME_DEBUG_IDENTIFIER(ident) ident##R
95 * Prints a debug message.
97 * @param file The file printing from.
98 * @param line The line printing from.
99 * @param func The function printing from.
100 * @param isBlank Is this blank?
101 * @param message The @c printf style message.
102 * @param ... Any @c printf style arguments.
105 void sjme_messageR(SJME_DEBUG_DECL_FILE_LINE_FUNC
,
106 sjme_attrInValue sjme_jboolean isBlank
,
107 sjme_attrInNullable sjme_attrFormatArg sjme_lpcstr message
, ...)
108 sjme_attrFormatOuter(4, 5);
110 #if defined(SJME_CONFIG_DEBUG)
112 * Prints a debug message.
114 * @param file The file printing from.
115 * @param line The line printing from.
116 * @param func The function printing from.
117 * @param isBlank Is this blank?
118 * @param message The @c printf style message.
119 * @param args Any @c printf style arguments.
122 void sjme_messageV(SJME_DEBUG_DECL_FILE_LINE_FUNC
,
123 sjme_attrInValue sjme_jboolean isBlank
,
124 sjme_attrInNullable sjme_attrFormatArg sjme_lpcstr message
,
129 * Prints a debug message
131 * @param message The @c printf style message.
132 * @param ... Any @c printf style arguments.
135 #define sjme_message(...) SJME_ONLY_IN_DEBUG_EXPR( \
136 sjme_messageR(SJME_DEBUG_FILE_LINE_FUNC, SJME_JNI_FALSE, __VA_ARGS__))
139 * Indicates a fatal error and exits the program.
141 * @param file The file printing from.
142 * @param line The line printing from.
143 * @param func The function printing from.
144 * @param message The @c printf style message.
145 * @param ... Any @c printf style arguments.
146 * @return Never returns.
149 sjme_errorCode
sjme_dieR(SJME_DEBUG_DECL_FILE_LINE_FUNC
,
150 sjme_attrInNullable sjme_attrFormatArg sjme_lpcstr message
, ...)
151 sjme_attrReturnNever
sjme_attrFormatOuter(3, 4);
154 * Indicates a fatal error and exits the program.
156 * @param message The @c printf style message.
157 * @param ... Any @c printf style arguments.
158 * @return Never returns.
161 #define sjme_die(...) sjme_dieR(SJME_DEBUG_FILE_LINE_FUNC, __VA_ARGS__)
164 * Indicates a fatal error and exits the program.
166 * @param message The @c printf style message.
167 * @param ... Any @c printf style arguments.
168 * @return Never returns.
171 #define sjme_dieP(...) ((sjme_pointer)((intptr_t)sjme_dieR(\
172 SJME_DEBUG_FILE_LINE_FUNC, __VA_ARGS__)))
175 * Indicates a To-Do and then terminates the program.
177 * @param file The file printing from.
178 * @param line The line printing from.
179 * @param func The function printing from.
180 * @param message The @c printf style message.
181 * @param ... Any @c printf style arguments.
182 * @return Never returns.
185 void sjme_todoR(SJME_DEBUG_DECL_FILE_LINE_FUNC
,
186 sjme_attrInNullable sjme_attrFormatArg sjme_lpcstr message
, ...)
187 sjme_attrReturnNever
sjme_attrFormatOuter(3, 4);
190 * Indicates a To-Do and then terminates the program.
192 * @param message The @c printf style message.
193 * @param ... Any @c printf style arguments.
194 * @return Never returns.
197 #define sjme_todo(...) sjme_todoR(SJME_DEBUG_FILE_LINE_FUNC_ALWAYS, \
201 * Potentially debug aborts.
205 void sjme_debug_abort(void);
208 * Shorted the path of the specified file for debug printing purposes.
210 * @param file The file to shorten.
211 * @return The resultant shortened file.
214 sjme_lpcstr
sjme_debug_shortenFile(sjme_lpcstr file
);
217 * Allows for optional debug abort when a fatal error is hit.
219 * @param error The error to return.
220 * @return The @c error value.
223 sjme_errorCode
sjme_error_fatalR(SJME_DEBUG_DECL_FILE_LINE_FUNC
,
224 sjme_attrInValue sjme_errorCode error
);
227 * Allows for optional debug abort when a fatal error is hit.
229 * @param error The error to return.
230 * @return The @c error value.
233 #define sjme_error_fatal(error) \
234 sjme_error_fatalR(SJME_DEBUG_FILE_LINE_FUNC_ALWAYS, error)
237 * Allows for optional debug abort when unimplemented code is hit.
239 * @param context Any value.
240 * @return Always @c SJME_ERROR_NOT_IMPLEMENTED .
243 sjme_errorCode
sjme_error_notImplementedR(SJME_DEBUG_DECL_FILE_LINE_FUNC
,
244 sjme_attrInValue sjme_intPointer context
);
247 * Allows for optional debug abort when unimplemented code is hit.
249 * @param context Any value.
250 * @return Always @c SJME_ERROR_NOT_IMPLEMENTED .
253 #define sjme_error_notImplemented(context) \
254 sjme_error_notImplementedR(SJME_DEBUG_FILE_LINE_FUNC_ALWAYS, \
255 (sjme_intPointer)(context))
258 * Allows for optional debug abort when out of memory is hit.
260 * @param inPool The pool the allocation was within, if applicable.
261 * @param context Any value.
262 * @return Always @c SJME_ERROR_OUT_OF_MEMORY .
265 sjme_errorCode
sjme_error_outOfMemoryR(SJME_DEBUG_DECL_FILE_LINE_FUNC
,
266 sjme_attrInNullable sjme_alloc_pool
* inPool
,
267 sjme_attrInValue sjme_intPointer context
);
270 * Allows for optional debug abort when out of memory is hit.
272 * @param inPool The pool the allocation was within, if applicable.
273 * @param context Any value.
274 * @return Always @c SJME_ERROR_OUT_OF_MEMORY .
277 #define sjme_error_outOfMemory(inPool, context) \
278 sjme_error_outOfMemoryR(SJME_DEBUG_FILE_LINE_FUNC_ALWAYS, \
279 (inPool), (sjme_intPointer)(context))
282 * Handles specific debug abort scenarios.
284 * @return Return @c SJME_JNI_TRUE if it was handled and abort should be
285 * cancelled, otherwise @c SJME_JNI_FALSE will continue aborting.
288 typedef sjme_jboolean (*sjme_debug_abortHandlerFunc
)(void);
291 * Handler for specific debug exit scenarios.
293 * @param exitCode The exit code.
294 * @return Return @c SJME_JNI_TRUE if it was handled.
297 typedef sjme_jboolean (*sjme_debug_exitHandlerFunc
)(int exitCode
);
300 * Emits a dangling reference message.
302 * @param fullMessage The message to emit.
303 * @param partMessage Partial message, without any prepend.
304 * @return Return @c SJME_JNI_TRUE if the message is handled, otherwise
305 * a standard @c fprintf to @c stderr will be used.
308 typedef sjme_jboolean (*sjme_debug_messageHandlerFunc
)(sjme_lpcstr fullMessage
,
309 sjme_lpcstr partMessage
);
312 * The set of functions to use for debugging functions.
316 typedef struct sjme_debug_handlerFunctions
318 /** The handler for debug aborts. */
319 sjme_debug_abortHandlerFunc abort
;
321 /** The handler for debug exits. */
322 sjme_debug_exitHandlerFunc exit
;
324 /** The dangling message implementation to use. */
325 sjme_debug_messageHandlerFunc message
;
326 } sjme_debug_handlerFunctions
;
328 /** The debug handlers to use. */
329 extern SJME_DYLIB_EXPORT
330 sjme_debug_handlerFunctions
* sjme_debug_handlers
;
332 /*--------------------------------------------------------------------------*/
336 #ifdef SJME_CXX_SQUIRRELJME_DEBUG_H
338 #undef SJME_CXX_SQUIRRELJME_DEBUG_H
339 #undef SJME_CXX_IS_EXTERNED
340 #endif /* #ifdef SJME_CXX_SQUIRRELJME_DEBUG_H */
341 #endif /* #ifdef __cplusplus */
343 #endif /* SQUIRRELJME_DEBUG_H */