Moving to main tree, needed by SysExplorer
[AROS.git] / workbench / classes / zune / nlist / nbitmap_mcc / Debug.c
blob140f8395a4b7ceef2fafc89a878b25ec8c9065e1
1 /***************************************************************************
3 NBitmap.mcc - New Bitmap MUI Custom Class
4 Copyright (C) 2006 by Daniel Allsopp
5 Copyright (C) 2007 by NList Open Source Team
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 NList classes Support Site: http://www.sf.net/projects/nlist-classes
19 $Id$
21 ***************************************************************************/
23 #ifdef DEBUG
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdarg.h>
28 #include <stdio.h>
30 #include <proto/intuition.h>
31 #include <proto/utility.h>
32 #include <proto/dos.h>
33 #include <proto/exec.h>
35 #include "SDI_compiler.h"
36 #include "Debug.h"
37 #include "version.h"
39 // special flagging macros
40 #define isFlagSet(v,f) (((v) & (f)) == (f)) // return TRUE if the flag is set
41 #define hasFlag(v,f) (((v) & (f)) != 0) // return TRUE if one of the flags in f is set in v
42 #define isFlagClear(v,f) (((v) & (f)) == 0) // return TRUE if flag f is not set in v
43 #define SET_FLAG(v,f) ((v) |= (f)) // set the flag f in v
44 #define CLEAR_FLAG(v,f) ((v) &= ~(f)) // clear the flag f in v
45 #define MASK_FLAG(v,f) ((v) &= (f)) // mask the variable v with flag f bitwise
47 // our static variables with default values
48 static int indent_level = 0;
49 static BOOL ansi_output = FALSE;
50 static ULONG debug_flags = DBF_ALWAYS | DBF_STARTUP; // default debug flags
51 static ULONG debug_classes = DBC_ERROR | DBC_DEBUG | DBC_WARNING | DBC_ASSERT | DBC_REPORT; // default debug classes
53 /****************************************************************************/
55 void SetupDebug(void)
57 char var[256];
59 kprintf("** NBitmap.mcc v" LIB_REV_STRING " startup ***********************\n");
60 kprintf("Initializing runtime debugging:\n");
62 if(GetVar("nbitmap.mcc.debug", var, sizeof(var), 0) > 0)
64 char *tok;
65 char *debug = var;
67 // static list of our debugging classes tokens.
68 // in the yamdebug variable these classes always start with a @
69 static struct { const char *token; unsigned long flag; } dbclasses[] =
71 { "ctrace", DBC_CTRACE },
72 { "report", DBC_REPORT },
73 { "assert", DBC_ASSERT },
74 { "timeval", DBC_TIMEVAL },
75 { "debug", DBC_DEBUG },
76 { "error", DBC_ERROR },
77 { "warning", DBC_WARNING },
78 { "all", DBC_ALL },
79 { NULL, 0 }
82 static struct { const char *token; unsigned long flag; } dbflags[] =
84 { "always", DBF_ALWAYS },
85 { "startup", DBF_STARTUP },
86 { "datatype", DBF_DATATYPE },
87 { "draw", DBF_DRAW },
88 { "all", DBF_ALL },
89 { NULL, 0 }
92 // we parse the env variable token-wise
93 while((tok = strtok(debug, ", ;")) != NULL)
95 ULONG i;
97 // check if the token is class definition or
98 // just a flag definition
99 if(tok[0] == '@')
101 // check if this call is a negation or not
102 if(tok[1] == '!')
104 // search for the token and clear the flag
105 for(i = 0; dbclasses[i].token != NULL; i++)
107 if(stricmp(tok + 2, dbclasses[i].token) == 0)
109 kprintf("clear '%s' debug class flag.\n", dbclasses[i].token);
110 CLEAR_FLAG(debug_classes, dbclasses[i].flag);
114 else
116 // search for the token and set the flag
117 for(i = 0; dbclasses[i].token != NULL; i++)
119 if(stricmp(tok + 1, dbclasses[i].token) == 0)
121 kprintf("set '%s' debug class flag\n", dbclasses[i].token);
122 SET_FLAG(debug_classes, dbclasses[i].flag);
127 else
129 // check if this call is a negation or not
130 if(tok[0] == '!')
132 for(i = 0; dbflags[i].token != NULL; i++)
134 if(stricmp(tok + 1, dbflags[i].token) == 0)
136 kprintf("clear '%s' debug flag\n", dbflags[i].token);
137 CLEAR_FLAG(debug_flags, dbflags[i].flag);
141 else
143 // check if the token was "ansi" and if so enable the ANSI color
144 // output
145 if(stricmp(tok, "ansi") == 0)
147 kprintf("ansi output enabled\n");
148 ansi_output = TRUE;
150 else
152 for(i = 0; dbflags[i].token != NULL; i++)
154 if(stricmp(tok, dbflags[i].token) == 0)
156 kprintf("set '%s' debug flag\n", dbflags[i].token);
157 SET_FLAG(debug_flags, dbflags[i].flag);
164 debug = NULL;
168 kprintf("set debug classes/flags (env:nbitmap.mcc.debug): %08lx/%08lx\n", debug_classes, debug_flags);
169 kprintf("** Normal processing follows ***************************************\n");
172 /****************************************************************************/
174 void CleanupDebug(void)
176 kprintf("** Cleaned up debugging ********************************************\n");
179 /****************************************************************************/
181 // define variables for using ANSI colors in our debugging scheme
182 #define ANSI_ESC_CLR "\033[0m"
183 #define ANSI_ESC_BOLD "\033[1m"
184 #define ANSI_ESC_UNDERLINE "\033[4m"
185 #define ANSI_ESC_BLINK "\033[5m"
186 #define ANSI_ESC_REVERSE "\033[7m"
187 #define ANSI_ESC_INVISIBLE "\033[8m"
188 #define ANSI_ESC_FG_BLACK "\033[0;30m"
189 #define ANSI_ESC_FG_RED "\033[0;31m"
190 #define ANSI_ESC_FG_GREEN "\033[0;32m"
191 #define ANSI_ESC_FG_BROWN "\033[0;33m"
192 #define ANSI_ESC_FG_BLUE "\033[0;34m"
193 #define ANSI_ESC_FG_PURPLE "\033[0;35m"
194 #define ANSI_ESC_FG_CYAN "\033[0;36m"
195 #define ANSI_ESC_FG_LGRAY "\033[0;37m"
196 #define ANSI_ESC_FG_DGRAY "\033[1;30m"
197 #define ANSI_ESC_FG_LRED "\033[1;31m"
198 #define ANSI_ESC_FG_LGREEN "\033[1;32m"
199 #define ANSI_ESC_FG_YELLOW "\033[1;33m"
200 #define ANSI_ESC_FG_LBLUE "\033[1;34m"
201 #define ANSI_ESC_FG_LPURPLE "\033[1;35m"
202 #define ANSI_ESC_FG_LCYAN "\033[1;36m"
203 #define ANSI_ESC_FG_WHITE "\033[1;37m"
204 #define ANSI_ESC_BG "\033[0;4" // background esc-squ start with 4x
205 #define ANSI_ESC_BG_BLACK "\033[0;40m"
206 #define ANSI_ESC_BG_RED "\033[0;41m"
207 #define ANSI_ESC_BG_GREEN "\033[0;42m"
208 #define ANSI_ESC_BG_BROWN "\033[0;43m"
209 #define ANSI_ESC_BG_BLUE "\033[0;44m"
210 #define ANSI_ESC_BG_PURPLE "\033[0;45m"
211 #define ANSI_ESC_BG_CYAN "\033[0;46m"
212 #define ANSI_ESC_BG_LGRAY "\033[0;47m"
214 /****************************************************************************/
216 INLINE void _INDENT(void)
218 int i;
220 for(i = 0; i < indent_level; i++)
221 kprintf(" ");
224 /****************************************************************************/
226 void _ENTER(unsigned long dclass, const char *file, int line, const char *function)
228 if(isFlagSet(debug_classes, dclass))
230 _INDENT();
231 if(ansi_output)
232 kprintf("%s%s:%ld:Entering %s%s\n", ANSI_ESC_FG_BROWN, file, line, function, ANSI_ESC_CLR);
233 else
234 kprintf("%s:%ld:Entering %s\n", file, line, function);
237 indent_level++;
240 void _LEAVE(unsigned long dclass, const char *file, int line, const char *function)
242 if(indent_level > 0)
243 indent_level--;
245 if(isFlagSet(debug_classes, dclass))
247 _INDENT();
248 if(ansi_output)
249 kprintf("%s%s:%ld:Leaving %s%s\n", ANSI_ESC_FG_BROWN, file, line, function, ANSI_ESC_CLR);
250 else
251 kprintf("%s:%ld:Leaving %s\n", file, line, function);
255 void _RETURN(unsigned long dclass, const char *file, int line, const char *function, unsigned long result)
257 if(indent_level > 0)
258 indent_level--;
260 if(isFlagSet(debug_classes, dclass))
262 _INDENT();
263 if(ansi_output)
264 kprintf("%s%s:%ld:Leaving %s (result 0x%08lx, %ld)%s\n", ANSI_ESC_FG_BROWN, file, line, function, result, result, ANSI_ESC_CLR);
265 else
266 kprintf("%s:%ld:Leaving %s (result 0x%08lx, %ld)\n", file, line, function, result, result);
270 /****************************************************************************/
272 void _SHOWVALUE(unsigned long dclass, unsigned long dflags, unsigned long value, int size, const char *name, const char *file, int line)
274 if(isFlagSet(debug_classes, dclass) &&
275 isFlagSet(debug_flags, dflags))
277 const char *fmt;
279 switch(size)
281 case 1:
282 fmt = "%s:%ld:%s = %ld, 0x%02lx";
283 break;
285 case 2:
286 fmt = "%s:%ld:%s = %ld, 0x%04lx";
287 break;
289 default:
290 fmt = "%s:%ld:%s = %ld, 0x%08lx";
291 break;
294 _INDENT();
296 if(ansi_output)
297 kprintf(ANSI_ESC_FG_GREEN);
299 kprintf(fmt, file, line, name, value, value);
301 if(size == 1 && value < 256)
303 if(value < ' ' || (value >= 127 && value < 160))
304 kprintf(", '\\x%02lx'", value);
305 else
306 kprintf(", '%lc'", value);
309 if(ansi_output)
310 kprintf("%s\n", ANSI_ESC_CLR);
311 else
312 kprintf("\n");
316 /****************************************************************************/
318 void _SHOWPOINTER(unsigned long dclass, unsigned long dflags, const void *p, const char *name, const char *file, int line)
320 if(isFlagSet(debug_classes, dclass) &&
321 isFlagSet(debug_flags, dflags))
323 const char *fmt;
325 _INDENT();
327 if(p != NULL)
328 fmt = "%s:%ld:%s = 0x%08lx\n";
329 else
330 fmt = "%s:%ld:%s = NULL\n";
332 if(ansi_output)
334 kprintf(ANSI_ESC_FG_GREEN);
335 kprintf(fmt, file, line, name, p);
336 kprintf(ANSI_ESC_CLR);
338 else
339 kprintf(fmt, file, line, name, p);
343 /****************************************************************************/
345 void _SHOWSTRING(unsigned long dclass, unsigned long dflags, const char *string, const char *name, const char *file, int line)
347 if(isFlagSet(debug_classes, dclass) &&
348 isFlagSet(debug_flags, dflags))
350 _INDENT();
352 if(ansi_output)
353 kprintf("%s%s:%ld:%s = 0x%08lx \"%s\"%s\n", ANSI_ESC_FG_GREEN, file, line, name, string, string, ANSI_ESC_CLR);
354 else
355 kprintf("%s:%ld:%s = 0x%08lx \"%s\"\n", file, line, name, string, string);
359 /****************************************************************************/
361 void _SHOWMSG(unsigned long dclass, unsigned long dflags, const char *msg, const char *file, int line)
363 if(isFlagSet(debug_classes, dclass) &&
364 isFlagSet(debug_flags, dflags))
366 _INDENT();
368 if(ansi_output)
369 kprintf("%s%s:%ld:%s%s\n", ANSI_ESC_FG_GREEN, file, line, msg, ANSI_ESC_CLR);
370 else
371 kprintf("%s:%ld:%s\n", file, line, msg);
375 /****************************************************************************/
377 void _DPRINTF(unsigned long dclass, unsigned long dflags, const char *file, int line, const char *format, ...)
379 if((isFlagSet(debug_classes, dclass) && isFlagSet(debug_flags, dflags)) ||
380 (isFlagSet(dclass, DBC_ERROR) || isFlagSet(dclass, DBC_WARNING)))
382 va_list args;
383 static char buf[1024];
385 _INDENT();
387 va_start(args, format);
388 vsnprintf(buf, 1024, format, args);
389 va_end(args);
391 if(ansi_output)
393 const char *highlight = ANSI_ESC_FG_GREEN;
395 switch(dclass)
397 case DBC_CTRACE: highlight = ANSI_ESC_FG_BROWN; break;
398 case DBC_REPORT: highlight = ANSI_ESC_FG_GREEN; break;
399 case DBC_ASSERT: highlight = ANSI_ESC_FG_RED; break;
400 case DBC_TIMEVAL: highlight = ANSI_ESC_FG_GREEN; break;
401 case DBC_DEBUG: highlight = ANSI_ESC_FG_GREEN; break;
402 case DBC_ERROR: highlight = ANSI_ESC_FG_RED; break;
403 case DBC_WARNING: highlight = ANSI_ESC_FG_PURPLE;break;
406 kprintf("%s%s:%ld:%s%s\n", highlight, file, line, buf, ANSI_ESC_CLR);
408 else
409 kprintf("%s:%ld:%s\n", file, line, buf);
413 /****************************************************************************/
415 #endif