xref: /haiku/src/add-ons/kernel/file_systems/udf/UdfDebug.h (revision 6011ce6c7495e4e707bd33b12a7e22d66c710aad)
1 //----------------------------------------------------------------------
2 //  This software is part of the OpenBeOS 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 _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 class DebugHelper;
51 
52 int32 _get_debug_indent_level();
53 
54 /*! \brief Helper class that is allocated on the stack by
55 	the \c DEBUG_INIT() macro. On creation, it increases the
56 	current indentation level by the amount specified via its
57 	constructor's \c tabCount parameter; on destruction, it
58 	decreases it.
59 */
60 class DebugHelper
61 {
62 public:
63 	DebugHelper(const char *className = NULL, uint8 tabCount = 1);
64 	~DebugHelper();
65 
66 	uint8 TabCount() const { return fTabCount; }
67 	const char* ClassName() const { return fClassName; }
68 
69 private:
70 	uint8 fTabCount;
71 	char *fClassName;
72 };
73 
74 //----------------------------------------------------------------------
75 // NOTE: See Debug.cpp for complete descriptions of the following
76 // debug macros.
77 //----------------------------------------------------------------------
78 
79 
80 //----------------------------------------------------------------------
81 // DEBUG-independent macros
82 //----------------------------------------------------------------------
83 #define INFORM(x) { __out("udf: "); __out x; }
84 #if !_KERNEL_MODE
85 #	define DIE(x) debugger x
86 #else
87 #	define DIE(x) kernel_debugger x
88 #endif
89 
90 //----------------------------------------------------------------------
91 // DEBUG-dependent macros
92 //----------------------------------------------------------------------
93 #ifdef DEBUG
94 	#if DEBUG_TO_FILE
95 		#define INITIALIZE_DEBUGGING_OUTPUT_FILE(filename) initialize_debugger(filename);
96 	#else
97 		#define INITIALIZE_DEBUGGING_OUTPUT_FILE(filename) ;
98 	#endif
99 
100 	#define DEBUG_INIT_SILENT(className)			\
101 		DebugHelper _debugHelper(className, 2);
102 
103 	#define DEBUG_INIT(className)		\
104 		DEBUG_INIT_SILENT(className);	\
105 		PRINT(("\n"));
106 
107 	#define DEBUG_INIT_ETC(className, arguments)							\
108 		DEBUG_INIT_SILENT(className)										\
109 		{																	\
110 			PRINT_INDENT();													\
111 			if (_debugHelper.ClassName()) {									\
112 				__out("udf: %s::%s(", 									\
113 				      _debugHelper.ClassName(), __FUNCTION__);				\
114 			} else 	{														\
115 				__out("udf: %s(", __FUNCTION__);						\
116 			}																\
117 			__out arguments;												\
118 			__out("):\n");													\
119 		}
120 
121 	#define DUMP_INIT(className)	\
122 		DEBUG_INIT_SILENT(className);
123 
124 	#define PRINT(x) { 														\
125 		{																	\
126 			PRINT_INDENT();													\
127 			if (_debugHelper.ClassName()) {									\
128 				__out("udf: %s::%s(): ", 								\
129 				      _debugHelper.ClassName(), __FUNCTION__);				\
130 			} else 	{														\
131 				__out("udf: %s(): ",  __FUNCTION__);					\
132 			}																\
133 			__out x; 														\
134 		} 																	\
135 	}
136 
137 	#define LPRINT(x) { 													\
138 		{																	\
139 			PRINT_INDENT();													\
140 			if (_debugHelper.ClassName()) {									\
141 				__out("udf: %s::%s(): line %d: ", 						\
142 				      _debugHelper.ClassName(), __FUNCTION__, __LINE__);	\
143 			} else {														\
144 				__out("udf: %s(): line %d: ", 							\
145 				      __FUNCTION__, __LINE__);								\
146 			}																\
147 			__out x;														\
148 		} 																	\
149 	}
150 
151 	#define SIMPLE_PRINT(x) { 									\
152 		{														\
153 			__out x; 											\
154 		} 														\
155 	}
156 
157 	#define PRINT_INDENT() { 									\
158 		{														\
159 			int32 _level = _get_debug_indent_level();			\
160 			for (int32 i = 0; i < _level-_debugHelper.TabCount(); i++) {				\
161 				__out(" ");										\
162 			}													\
163 		}														\
164 	}
165 
166 	#define PRINT_DIVIDER()	\
167 		PRINT_INDENT(); 	\
168 		SIMPLE_PRINT(("------------------------------------------------------------\n"));
169 
170 	#define DUMP(object)				\
171 		{								\
172 			(object).dump();			\
173 		}
174 
175 	#define PDUMP(objectPointer)		\
176 		{								\
177 			(objectPointer)->dump();	\
178 		}
179 
180 	#define REPORT_ERROR(error) {									\
181 		LPRINT(("returning error 0x%" B_PRIx32 ", `%s'\n", error,	\
182 			strerror(error)));										\
183 	}
184 
185 	#define RETURN_ERROR(error) { 		\
186 		status_t _status = error; 		\
187 		if (_status < (status_t)B_OK)	\
188 			REPORT_ERROR(_status);		\
189 		return _status;					\
190 	}
191 
192 	#define RETURN(error) { 										\
193 		status_t _status = error; 									\
194 		if (_status < (status_t)B_OK) {								\
195 			REPORT_ERROR(_status); 									\
196 		} else if (_status == (status_t)B_OK) {						\
197 			LPRINT(("returning B_OK\n"));							\
198 		} else {													\
199 			LPRINT(("returning 0x%" B_PRIx32 " = %" PRId32 "\n",	\
200 				_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 
233 #ifdef TEST_HAIKU
234 	#define TRACE_ERROR(x) printf x
235 #else
236 	#define TRACE_ERROR(x) dprintf x
237 #endif
238 
239 // These macros turn on or off extensive and generally unnecessary
240 // debugging output regarding table of contents parsing
241 //#define WARN(x) (dprintf x)
242 //#define WARN(x)
243 #define WARN(x) DBG(dprintf x)
244 
245 #endif	// _UDF_DEBUG_H
246