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