Merging NList MCC 0.119 into the main branch.
[AROS.git] / workbench / classes / zune / nlist / nlisttree_mcp / Debug.c
blob8ea563a6652807cbc03802137667574f780fdf2b
1 /***************************************************************************
3 NListtree.mcc - New Listtree MUI Custom Class
4 Copyright (C) 1999-2001 by Carsten Scholling
5 Copyright (C) 2001-2014 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("** NListtree.mcp v" LIB_REV_STRING " startup ***********************\n");
60 kprintf("Initializing runtime debugging:\n");
62 if(GetVar("nlisttree.mcp.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 { "all", DBF_ALL },
87 { NULL, 0 }
90 // we parse the env variable token-wise
91 while((tok = strtok(debug, ", ;")))
93 ULONG i;
95 // check if the token is class definition or
96 // just a flag definition
97 if(tok[0] == '@')
99 // check if this call is a negation or not
100 if(tok[1] == '!')
102 // search for the token and clear the flag
103 for(i=0; dbclasses[i].token; i++)
105 if(stricmp(tok+2, dbclasses[i].token) == 0)
107 kprintf("clear '%s' debug class flag.\n", dbclasses[i].token);
108 CLEAR_FLAG(debug_classes, dbclasses[i].flag);
112 else
114 // search for the token and set the flag
115 for(i=0; dbclasses[i].token; i++)
117 if(stricmp(tok+1, dbclasses[i].token) == 0)
119 kprintf("set '%s' debug class flag\n", dbclasses[i].token);
120 SET_FLAG(debug_classes, dbclasses[i].flag);
125 else
127 // check if this call is a negation or not
128 if(tok[0] == '!')
130 for(i=0; dbflags[i].token; i++)
132 if(stricmp(tok+1, dbflags[i].token) == 0)
134 kprintf("clear '%s' debug flag\n", dbflags[i].token);
135 CLEAR_FLAG(debug_flags, dbflags[i].flag);
139 else
141 // check if the token was "ansi" and if so enable the ANSI color
142 // output
143 if(stricmp(tok, "ansi") == 0)
145 kprintf("ansi output enabled\n");
146 ansi_output = TRUE;
148 else
150 for(i=0; dbflags[i].token; i++)
152 if(stricmp(tok, dbflags[i].token) == 0)
154 kprintf("set '%s' debug flag\n", dbflags[i].token);
155 SET_FLAG(debug_flags, dbflags[i].flag);
162 debug = NULL;
166 kprintf("set debug classes/flags (env:nlisttree.mcp.debug): %08lx/%08lx\n", debug_classes, debug_flags);
167 kprintf("** Normal processing follows ***************************************\n");
170 /****************************************************************************/
172 void CleanupDebug(void)
174 kprintf("** Cleaned up debugging ********************************************\n");
177 /****************************************************************************/
179 // define variables for using ANSI colors in our debugging scheme
180 #define ANSI_ESC_CLR "\033[0m"
181 #define ANSI_ESC_BOLD "\033[1m"
182 #define ANSI_ESC_UNDERLINE "\033[4m"
183 #define ANSI_ESC_BLINK "\033[5m"
184 #define ANSI_ESC_REVERSE "\033[7m"
185 #define ANSI_ESC_INVISIBLE "\033[8m"
186 #define ANSI_ESC_FG_BLACK "\033[0;30m"
187 #define ANSI_ESC_FG_RED "\033[0;31m"
188 #define ANSI_ESC_FG_GREEN "\033[0;32m"
189 #define ANSI_ESC_FG_BROWN "\033[0;33m"
190 #define ANSI_ESC_FG_BLUE "\033[0;34m"
191 #define ANSI_ESC_FG_PURPLE "\033[0;35m"
192 #define ANSI_ESC_FG_CYAN "\033[0;36m"
193 #define ANSI_ESC_FG_LGRAY "\033[0;37m"
194 #define ANSI_ESC_FG_DGRAY "\033[1;30m"
195 #define ANSI_ESC_FG_LRED "\033[1;31m"
196 #define ANSI_ESC_FG_LGREEN "\033[1;32m"
197 #define ANSI_ESC_FG_YELLOW "\033[1;33m"
198 #define ANSI_ESC_FG_LBLUE "\033[1;34m"
199 #define ANSI_ESC_FG_LPURPLE "\033[1;35m"
200 #define ANSI_ESC_FG_LCYAN "\033[1;36m"
201 #define ANSI_ESC_FG_WHITE "\033[1;37m"
202 #define ANSI_ESC_BG "\033[0;4" // background esc-squ start with 4x
203 #define ANSI_ESC_BG_BLACK "\033[0;40m"
204 #define ANSI_ESC_BG_RED "\033[0;41m"
205 #define ANSI_ESC_BG_GREEN "\033[0;42m"
206 #define ANSI_ESC_BG_BROWN "\033[0;43m"
207 #define ANSI_ESC_BG_BLUE "\033[0;44m"
208 #define ANSI_ESC_BG_PURPLE "\033[0;45m"
209 #define ANSI_ESC_BG_CYAN "\033[0;46m"
210 #define ANSI_ESC_BG_LGRAY "\033[0;47m"
212 /****************************************************************************/
214 INLINE void _INDENT(void)
216 int i;
217 for(i=0; i < indent_level; i++)
218 kprintf(" ");
221 /****************************************************************************/
223 void _ENTER(unsigned long dclass, const char *file, int line, const char *function)
225 if(isFlagSet(debug_classes, dclass))
227 _INDENT();
228 if(ansi_output)
229 kprintf("%s%s:%ld:Entering %s%s\n", ANSI_ESC_FG_BROWN, file, line, function, ANSI_ESC_CLR);
230 else
231 kprintf("%s:%ld:Entering %s\n", file, line, function);
234 indent_level++;
237 void _LEAVE(unsigned long dclass, const char *file, int line, const char *function)
239 indent_level--;
241 if(isFlagSet(debug_classes, dclass))
243 _INDENT();
244 if(ansi_output)
245 kprintf("%s%s:%ld:Leaving %s%s\n", ANSI_ESC_FG_BROWN, file, line, function, ANSI_ESC_CLR);
246 else
247 kprintf("%s:%ld:Leaving %s\n", file, line, function);
251 void _RETURN(unsigned long dclass, const char *file, int line, const char *function, unsigned long result)
253 indent_level--;
255 if(isFlagSet(debug_classes, dclass))
257 _INDENT();
258 if(ansi_output)
259 kprintf("%s%s:%ld:Leaving %s (result 0x%08lx, %ld)%s\n", ANSI_ESC_FG_BROWN, file, line, function, result, result, ANSI_ESC_CLR);
260 else
261 kprintf("%s:%ld:Leaving %s (result 0x%08lx, %ld)\n", file, line, function, result, result);
265 /****************************************************************************/
267 void _SHOWVALUE(unsigned long dclass, unsigned long dflags, unsigned long value, int size, const char *name, const char *file, int line)
269 if(isFlagSet(debug_classes, dclass) &&
270 isFlagSet(debug_flags, dflags))
272 const char *fmt;
274 switch(size)
276 case 1:
277 fmt = "%s:%ld:%s = %ld, 0x%02lx";
278 break;
280 case 2:
281 fmt = "%s:%ld:%s = %ld, 0x%04lx";
282 break;
284 default:
285 fmt = "%s:%ld:%s = %ld, 0x%08lx";
286 break;
289 _INDENT();
291 if(ansi_output)
292 kprintf(ANSI_ESC_FG_GREEN);
294 kprintf(fmt, file, line, name, value, value);
296 if(size == 1 && value < 256)
298 if(value < ' ' || (value >= 127 && value < 160))
299 kprintf(", '\\x%02lx'", value);
300 else
301 kprintf(", '%lc'", value);
304 if(ansi_output)
305 kprintf("%s\n", ANSI_ESC_CLR);
306 else
307 kprintf("\n");
311 /****************************************************************************/
313 void _SHOWPOINTER(unsigned long dclass, unsigned long dflags, const void *p, const char *name, const char *file, int line)
315 if(isFlagSet(debug_classes, dclass) &&
316 isFlagSet(debug_flags, dflags))
318 const char *fmt;
320 _INDENT();
322 if(p != NULL)
323 fmt = "%s:%ld:%s = 0x%08lx\n";
324 else
325 fmt = "%s:%ld:%s = NULL\n";
327 if(ansi_output)
329 kprintf(ANSI_ESC_FG_GREEN);
330 kprintf(fmt, file, line, name, p);
331 kprintf(ANSI_ESC_CLR);
333 else
334 kprintf(fmt, file, line, name, p);
338 /****************************************************************************/
340 void _SHOWSTRING(unsigned long dclass, unsigned long dflags, const char *string, const char *name, const char *file, int line)
342 if(isFlagSet(debug_classes, dclass) &&
343 isFlagSet(debug_flags, dflags))
345 _INDENT();
347 if(ansi_output)
348 kprintf("%s%s:%ld:%s = 0x%08lx \"%s\"%s\n", ANSI_ESC_FG_GREEN, file, line, name, string, string, ANSI_ESC_CLR);
349 else
350 kprintf("%s:%ld:%s = 0x%08lx \"%s\"\n", file, line, name, string, string);
354 /****************************************************************************/
356 void _SHOWMSG(unsigned long dclass, unsigned long dflags, const char *msg, const char *file, int line)
358 if(isFlagSet(debug_classes, dclass) &&
359 isFlagSet(debug_flags, dflags))
361 _INDENT();
363 if(ansi_output)
364 kprintf("%s%s:%ld:%s%s\n", ANSI_ESC_FG_GREEN, file, line, msg, ANSI_ESC_CLR);
365 else
366 kprintf("%s:%ld:%s\n", file, line, msg);
370 /****************************************************************************/
372 void _DPRINTF(unsigned long dclass, unsigned long dflags, const char *file, int line, const char *format, ...)
374 if((isFlagSet(debug_classes, dclass) && isFlagSet(debug_flags, dflags)) ||
375 (isFlagSet(dclass, DBC_ERROR) || isFlagSet(dclass, DBC_WARNING)))
377 va_list args;
378 static char buf[1024];
380 _INDENT();
382 va_start(args, format);
383 vsnprintf(buf, 1024, format, args);
384 va_end(args);
386 if(ansi_output)
388 const char *highlight = ANSI_ESC_FG_GREEN;
390 switch(dclass)
392 case DBC_CTRACE: highlight = ANSI_ESC_FG_BROWN; break;
393 case DBC_REPORT: highlight = ANSI_ESC_FG_GREEN; break;
394 case DBC_ASSERT: highlight = ANSI_ESC_FG_RED; break;
395 case DBC_TIMEVAL: highlight = ANSI_ESC_FG_GREEN; break;
396 case DBC_DEBUG: highlight = ANSI_ESC_FG_GREEN; break;
397 case DBC_ERROR: highlight = ANSI_ESC_FG_RED; break;
398 case DBC_WARNING: highlight = ANSI_ESC_FG_PURPLE;break;
401 kprintf("%s%s:%ld:%s%s\n", highlight, file, line, buf, ANSI_ESC_CLR);
403 else
404 kprintf("%s:%ld:%s\n", file, line, buf);
408 /****************************************************************************/
410 #endif