1/*
2 * Copyright 2007 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _DEBUG_H
6#define _DEBUG_H
7
8
9#include <BeBuild.h>
10#include <OS.h>
11
12#include <stdarg.h>
13#include <stdio.h>
14#include <stdlib.h>
15
16
17/* Private */
18#ifdef __cplusplus
19extern "C" {
20#endif
21	extern bool _rtDebugFlag;
22
23	bool _debugFlag(void);
24	bool _setDebugFlag(bool);
25
26#if __GNUC__
27	int _debugPrintf(const char *, ...) _PRINTFLIKE(1, 2);
28	int _sPrintf(const char *, ...) _PRINTFLIKE(1, 2);
29#else
30	int _debugPrintf(const char *, ...);
31	int _sPrintf(const char *, ...);
32#endif
33	int _xdebugPrintf(const char *, ...);
34	int _debuggerAssert(const char *, int, const char *);
35#ifdef __cplusplus
36}
37#endif
38
39/* Debug macros */
40#if DEBUG
41	#define SET_DEBUG_ENABLED(FLAG)	_setDebugFlag(FLAG)
42	#define	IS_DEBUG_ENABLED()		_debugFlag()
43
44	#define SERIAL_PRINT(ARGS)		_sPrintf ARGS
45	#define PRINT(ARGS) 			_debugPrintf ARGS
46	#define PRINT_OBJECT(OBJ)		if (_rtDebugFlag) {			\
47										PRINT(("%s\t", #OBJ));	\
48										(OBJ).PrintToStream(); 	\
49									} ((void)0)
50	#define TRACE()					_debugPrintf("File: %s, Line: %d, Thread: %" \
51										B_PRId32 "\n", __FILE__, __LINE__, \
52										find_thread(NULL))
53
54	#define SERIAL_TRACE()			_sPrintf("File: %s, Line: %d, Thread: %" \
55										B_PRId32 "\n", __FILE__, __LINE__, \
56										find_thread(NULL))
57
58	#define DEBUGGER(MSG)			if (_rtDebugFlag) debugger(MSG)
59	#if !defined(ASSERT)
60		#define ASSERT(E)			(!(E) ? _debuggerAssert(__FILE__,__LINE__, #E) \
61										: (int)0)
62	#endif
63
64	#define ASSERT_WITH_MESSAGE(expr, msg) \
65								(!(expr) ? _debuggerAssert( __FILE__,__LINE__, msg) \
66										: (int)0)
67
68	#define TRESPASS()			DEBUGGER("Should not be here");
69
70	#define DEBUG_ONLY(arg)		arg
71
72#else /* DEBUG == 0 */
73	#define SET_DEBUG_ENABLED(FLAG)			(void)0
74	#define	IS_DEBUG_ENABLED()				(void)0
75
76	#define SERIAL_PRINT(ARGS)				(void)0
77	#define PRINT(ARGS)						(void)0
78	#define PRINT_OBJECT(OBJ)				(void)0
79	#define TRACE()							(void)0
80	#define SERIAL_TRACE()					(void)0
81
82	#define DEBUGGER(MSG)					(void)0
83	#if !defined(ASSERT)
84		#define ASSERT(E)					(void)0
85	#endif
86	#define ASSERT_WITH_MESSAGE(expr, msg)	(void)0
87	#define TRESPASS()						(void)0
88	#define DEBUG_ONLY(x)
89#endif
90
91/* STATIC_ASSERT is a compile-time check that can be used to             */
92/* verify static expressions such as: STATIC_ASSERT(sizeof(int64) == 8); */
93#if __GNUC__ >= 5 && !defined(__cplusplus)
94#	define STATIC_ASSERT(x) _Static_assert(x, "static assert failed!")
95#elif defined(__cplusplus) && __cplusplus >= 201103L
96#	define STATIC_ASSERT(x) static_assert(x, "static assert failed!")
97#else
98#	define STATIC_ASSERT(x)								\
99		do {												\
100			struct __staticAssertStruct__ {					\
101				char __static_assert_failed__[2*(x) - 1];	\
102			};												\
103		} while (false)
104#endif
105
106
107#endif	/* _DEBUG_H */
108