xref: /haiku/src/add-ons/kernel/partitioning_systems/session/Debug.h (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
1 //----------------------------------------------------------------------
2 //  This software is part of the Haiku distribution and is covered
3 //  by the MIT License.
4 //
5 //  This version copyright (c) 2003 Tyler Dauwalder, tyler@dauwalder.net
6 //  Initial version copyright (c) 2002 Axel Dörfler, axeld@pinc-software.de
7 //	dbg_printf() function copyright (c) 2003 Ingo Weinhold, bonefish@cs.tu-berlin.edu
8 //----------------------------------------------------------------------
9 #ifndef MY_DEBUG_H
10 #define MY_DEBUG_H
11 
12 /*! \file Debug.h
13 
14 	Handy debugging macros.
15 */
16 
17 #include <KernelExport.h>
18 
19 #include <OS.h>
20 #ifdef DEBUG
21 #	include <string.h>
22 #endif
23 #include <unistd.h>
24 
25 #define DEBUG_TO_FILE 0
26 
27 #if DEBUG_TO_FILE
28 #	include <stdio.h>
29 #	include <fcntl.h>
30 #	define __out dbg_printf
31 	void dbg_printf(const char *format,...);
32 	void initialize_debugger(const char *filename);
33 #else
34 #	ifdef USER
35 #		include <stdio.h>
36 #		define __out printf
37 #	else
38 #		include <null.h>
39 #		define __out dprintf
40 #	endif
41 #endif
42 
43 #include "util/kernel_cpp.h"
44 
45 class DebugHelper;
46 
47 int32 _get_debug_indent_level();
48 
49 /*! \brief Helper class that is allocated on the stack by
50 	the \c DEBUG_INIT() macro. On creation, it increases the
51 	current indentation level by the amount specified via its
52 	constructor's \c tabCount parameter; on destruction, it
53 	decreases it.
54 */
55 class DebugHelper
56 {
57 public:
58 	DebugHelper(const char *className = NULL, uint8 tabCount = 1);
59 	~DebugHelper();
60 
61 	uint8 TabCount() const { return fTabCount; }
62 	const char* ClassName() const { return fClassName; }
63 
64 private:
65 	uint8 fTabCount;
66 	char *fClassName;
67 };
68 
69 //----------------------------------------------------------------------
70 // NOTE: See Debug.cpp for complete descriptions of the following
71 // debug macros.
72 //----------------------------------------------------------------------
73 
74 
75 //----------------------------------------------------------------------
76 // DEBUG-independent macros
77 //----------------------------------------------------------------------
78 #define INFORM(x) { __out("session: "); __out x; }
79 #ifdef USER
80 #	define DIE(x) debugger x
81 #else
82 #	define DIE(x) kernel_debugger x
83 #endif
84 
85 //----------------------------------------------------------------------
86 // DEBUG-dependent macros
87 //----------------------------------------------------------------------
88 #ifdef DEBUG
89 	#if DEBUG_TO_FILE
90 		#define INITIALIZE_DEBUGGING_OUTPUT_FILE(filename) initialize_debugger(filename);
91 	#else
92 		#define INITIALIZE_DEBUGGING_OUTPUT_FILE(filename) ;
93 	#endif
94 
95 	#define DEBUG_INIT_SILENT(className)			\
96 		DebugHelper _debugHelper(className, 2);
97 
98 	#define DEBUG_INIT(className)		\
99 		DEBUG_INIT_SILENT(className);	\
100 		PRINT(("\n"));
101 
102 	#define DEBUG_INIT_ETC(className, arguments)							\
103 		DEBUG_INIT_SILENT(className)										\
104 		{																	\
105 			PRINT_INDENT();													\
106 			if (_debugHelper.ClassName()) {									\
107 				__out("session: %s::%s(", 									\
108 				      _debugHelper.ClassName(), __FUNCTION__);				\
109 			} else 	{														\
110 				__out("session: %s(", __FUNCTION__);						\
111 			}																\
112 			__out arguments;												\
113 			__out("):\n");													\
114 		}
115 
116 	#define DUMP_INIT(categoryFlags, className)	\
117 		DEBUG_INIT_SILENT(className);
118 
119 	#define PRINT(x) { 														\
120 		{																	\
121 			PRINT_INDENT();													\
122 			if (_debugHelper.ClassName()) {									\
123 				__out("session: %s::%s(): ", 								\
124 				      _debugHelper.ClassName(), __FUNCTION__);				\
125 			} else 	{														\
126 				__out("session: %s(): ",  __FUNCTION__);					\
127 			}																\
128 			__out x; 														\
129 		} 																	\
130 	}
131 
132 	#define LPRINT(x) { 													\
133 		{																	\
134 			PRINT_INDENT();													\
135 			if (_debugHelper.ClassName()) {									\
136 				__out("session: %s::%s(): line %d: ", 						\
137 				      _debugHelper.ClassName(), __FUNCTION__, __LINE__);	\
138 			} else {														\
139 				__out("session: %s(): line %d: ", 							\
140 				      __FUNCTION__, __LINE__);								\
141 			}																\
142 			__out x;														\
143 		} 																	\
144 	}
145 
146 	#define SIMPLE_PRINT(x) { 									\
147 		{														\
148 			__out x; 											\
149 		} 														\
150 	}
151 
152 	#define PRINT_INDENT() { 									\
153 		{														\
154 			int32 _level = _get_debug_indent_level();			\
155 			for (int32 i = 0; i < _level-_debugHelper.TabCount(); i++) {				\
156 				__out(" ");										\
157 			}													\
158 		}														\
159 	}
160 
161 	#define PRINT_DIVIDER()	\
162 		PRINT_INDENT(); 	\
163 		SIMPLE_PRINT(("------------------------------------------------------------\n"));
164 
165 	#define DUMP(object)				\
166 		{								\
167 			(object).dump();			\
168 		}
169 
170 	#define PDUMP(objectPointer)		\
171 		{								\
172 			(objectPointer)->dump();	\
173 		}
174 
175 	#define REPORT_ERROR(error) {											\
176 		LPRINT(("returning error 0x%" B_PRIx32 ", `%s'\n", error, strerror(error)));	\
177 	}
178 
179 	#define RETURN_ERROR(error) { 		\
180 		status_t _status = error; 		\
181 		if (_status < (status_t)B_OK)	\
182 			REPORT_ERROR(_status);		\
183 		return _status;					\
184 	}
185 
186 	#define RETURN(error) { 										\
187 		status_t _status = error; 									\
188 		if (_status < (status_t)B_OK) {								\
189 			REPORT_ERROR(_status); 									\
190 		} else if (_status == (status_t)B_OK) {						\
191 			LPRINT(("returning B_OK\n"));							\
192 		} else {													\
193 			LPRINT(("returning 0x%" B_PRIx32 " = %" B_PRId32 "\n", _status, _status));	\
194 		}															\
195 		return _status; 											\
196 	}
197 
198 	#define FATAL(x) { 								\
199 		PRINT(("fatal error: ")); SIMPLE_PRINT(x);	\
200 	}
201 
202 	#define DBG(x) x ;
203 
204 #else	// ifdef DEBUG
205 	#define INITIALIZE_DEBUGGING_OUTPUT_FILE(filename) ;
206 	#define DEBUG_INIT_SILENT(className)	;
207 	#define DEBUG_INIT(className) ;
208 	#define DEBUG_INIT_ETC(className, arguments) ;
209 	#define DUMP_INIT(className)	;
210 	#define PRINT(x) ;
211 	#define LPRINT(x) ;
212 	#define SIMPLE_PRINT(x) ;
213 	#define PRINT_INDENT(x) ;
214 	#define PRINT_DIVIDER()	;
215 	#define PDUMP(objectPointer) ;
216 	#define REPORT_ERROR(status) ;
217 	#define RETURN_ERROR(status) return status;
218 	#define RETURN(status) return status;
219 	#define FATAL(x) { __out("session: fatal error: "); __out x; }
220 	#define DBG(x) ;
221 	#define DUMP(x) ;
222 #endif	// ifdef DEBUG else
223 
224 #define TRACE(x) DBG(dprintf x)
225 
226 // These macros turn on or off extensive and generally unnecessary
227 // debugging output regarding table of contents parsing
228 //#define WARN(x) (dprintf x)
229 //#define WARN(x)
230 #define WARN(x) DBG(dprintf x)
231 
232 #endif	// MY_DEBUG_H
233