Updated from original SVN.
[cake.git] / workbench / classes / gadgets / texteditor / mcc / Debug.c
blob8637d62239a98b33c1ba690f73c17d0deb329939
1 /***************************************************************************
3 TextEditor.mcc - Textediting MUI Custom Class
4 Copyright (C) 1997-2000 Allan Odgaard
5 Copyright (C) 2005 by TextEditor.mcc 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 TextEditor class Support Site: http://www.sf.net/projects/texteditor-mcc
19 $Id$
21 ***************************************************************************/
23 #ifdef DEBUG
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdarg.h>
29 #include <proto/intuition.h>
30 #include <proto/utility.h>
31 #include <proto/dos.h>
33 #include "SDI_compiler.h"
34 #include "Debug.h"
35 #include "rev.h"
37 // special flagging macros
38 #define isFlagSet(v,f) (((v) & (f)) == (f)) // return TRUE if the flag is set
39 #define hasFlag(v,f) (((v) & (f)) != 0) // return TRUE if one of the flags in f is set in v
40 #define isFlagClear(v,f) (((v) & (f)) == 0) // return TRUE if flag f is not set in v
41 #define SET_FLAG(v,f) ((v) |= (f)) // set the flag f in v
42 #define CLEAR_FLAG(v,f) ((v) &= ~(f)) // clear the flag f in v
43 #define MASK_FLAG(v,f) ((v) &= (f)) // mask the variable v with flag f bitwise
45 #if !defined(__MORPHOS__) && !defined(__AROS__)
46 extern void KPutFmt(const char *format, va_list arg);
47 #endif
49 // our static variables with default values
50 static int indent_level = 0;
51 static BOOL ansi_output = FALSE;
52 static ULONG debug_flags = DBF_ALWAYS | DBF_STARTUP; // default debug flags
53 static ULONG debug_classes = DBC_ERROR | DBC_DEBUG | DBC_WARNING | DBC_ASSERT | DBC_REPORT; // default debug classes
55 /****************************************************************************/
57 void SetupDebug(void)
59 char var[256];
61 kprintf("** TextEditor.mcc v" LIB_REV_STRING " startup ***********************\n");
62 kprintf("Initializing runtime debugging:\n");
64 if(GetVar("texteditor.mcc.debug", var, sizeof(var), 0) > 0)
66 char *tok;
67 char *debug = var;
69 // static list of our debugging classes tokens.
70 // in the yamdebug variable these classes always start with a @
71 static struct { char *token; unsigned long flag; } dbclasses[] =
73 { "ctrace", DBC_CTRACE },
74 { "report", DBC_REPORT },
75 { "assert", DBC_ASSERT },
76 { "timeval", DBC_TIMEVAL },
77 { "debug", DBC_DEBUG },
78 { "error", DBC_ERROR },
79 { "warning", DBC_WARNING },
80 { "all", DBC_ALL },
81 { NULL, 0 }
84 static struct { char *token; unsigned long flag; } dbflags[] =
86 { "always", DBF_ALWAYS },
87 { "startup", DBF_STARTUP },
88 { "input", DBF_INPUT },
89 { "all", DBF_ALL },
90 { NULL, 0 }
93 // we parse the env variable token-wise
94 while((tok = strtok(debug, ", ;")))
96 ULONG i;
98 // check if the token is class definition or
99 // just a flag definition
100 if(tok[0] == '@')
102 // check if this call is a negation or not
103 if(tok[1] == '!')
105 // search for the token and clear the flag
106 for(i=0; dbclasses[i].token; i++)
108 if(stricmp(tok+2, dbclasses[i].token) == 0)
110 kprintf("clear '%s' debug class flag.\n", dbclasses[i].token);
111 CLEAR_FLAG(debug_classes, dbclasses[i].flag);
115 else
117 // search for the token and set the flag
118 for(i=0; dbclasses[i].token; i++)
120 if(stricmp(tok+1, dbclasses[i].token) == 0)
122 kprintf("set '%s' debug class flag\n", dbclasses[i].token);
123 SET_FLAG(debug_classes, dbclasses[i].flag);
128 else
130 // check if this call is a negation or not
131 if(tok[1] == '!')
133 for(i=0; dbflags[i].token; i++)
135 if(stricmp(tok+1, dbflags[i].token) == 0)
137 kprintf("clear '%s' debug flag\n", dbflags[i].token);
138 CLEAR_FLAG(debug_flags, dbflags[i].flag);
142 else
144 // check if the token was "ansi" and if so enable the ANSI color
145 // output
146 if(stricmp(tok, "ansi") == 0)
148 kprintf("ansi output enabled\n");
149 ansi_output = TRUE;
151 else
153 for(i=0; dbflags[i].token; i++)
155 if(stricmp(tok, dbflags[i].token) == 0)
157 kprintf("set '%s' debug flag\n", dbflags[i].token);
158 SET_FLAG(debug_flags, dbflags[i].flag);
165 debug = NULL;
169 kprintf("set debug classes/flags (env:texteditor.mcc.debug): %08x/%08x\n", debug_classes, debug_flags);
170 kprintf("** Normal processing follows ***************************************\n");
173 /****************************************************************************/
175 // define variables for using ANSI colors in our debugging scheme
176 #define ANSI_ESC_CLR "\033[0m"
177 #define ANSI_ESC_BOLD "\033[1m"
178 #define ANSI_ESC_UNDERLINE "\033[4m"
179 #define ANSI_ESC_BLINK "\033[5m"
180 #define ANSI_ESC_REVERSE "\033[7m"
181 #define ANSI_ESC_INVISIBLE "\033[8m"
182 #define ANSI_ESC_FG_BLACK "\033[0;30m"
183 #define ANSI_ESC_FG_RED "\033[0;31m"
184 #define ANSI_ESC_FG_GREEN "\033[0;32m"
185 #define ANSI_ESC_FG_BROWN "\033[0;33m"
186 #define ANSI_ESC_FG_BLUE "\033[0;34m"
187 #define ANSI_ESC_FG_PURPLE "\033[0;35m"
188 #define ANSI_ESC_FG_CYAN "\033[0;36m"
189 #define ANSI_ESC_FG_LGRAY "\033[0;37m"
190 #define ANSI_ESC_FG_DGRAY "\033[1;30m"
191 #define ANSI_ESC_FG_LRED "\033[1;31m"
192 #define ANSI_ESC_FG_LGREEN "\033[1;32m"
193 #define ANSI_ESC_FG_YELLOW "\033[1;33m"
194 #define ANSI_ESC_FG_LBLUE "\033[1;34m"
195 #define ANSI_ESC_FG_LPURPLE "\033[1;35m"
196 #define ANSI_ESC_FG_LCYAN "\033[1;36m"
197 #define ANSI_ESC_FG_WHITE "\033[1;37m"
198 #define ANSI_ESC_BG "\033[0;4" // background esc-squ start with 4x
199 #define ANSI_ESC_BG_BLACK "\033[0;40m"
200 #define ANSI_ESC_BG_RED "\033[0;41m"
201 #define ANSI_ESC_BG_GREEN "\033[0;42m"
202 #define ANSI_ESC_BG_BROWN "\033[0;43m"
203 #define ANSI_ESC_BG_BLUE "\033[0;44m"
204 #define ANSI_ESC_BG_PURPLE "\033[0;45m"
205 #define ANSI_ESC_BG_CYAN "\033[0;46m"
206 #define ANSI_ESC_BG_LGRAY "\033[0;47m"
208 /****************************************************************************/
210 INLINE void _INDENT(void)
212 int i;
213 for(i=0; i < indent_level; i++)
214 kprintf(" ");
217 /****************************************************************************/
219 void _ENTER(unsigned long dclass, const char *file, int line, const char *function)
221 if(isFlagSet(debug_classes, dclass))
223 _INDENT();
224 if(ansi_output)
225 kprintf("%s%s:%ld:Entering %s%s\n", ANSI_ESC_FG_BROWN, file, line, function, ANSI_ESC_CLR);
226 else
227 kprintf("%s:%ld:Entering %s\n", file, line, function);
230 indent_level++;
233 void _LEAVE(unsigned long dclass, const char *file, int line, const char *function)
235 indent_level--;
237 if(isFlagSet(debug_classes, dclass))
239 _INDENT();
240 if(ansi_output)
241 kprintf("%s%s:%ld:Leaving %s%s\n", ANSI_ESC_FG_BROWN, file, line, function, ANSI_ESC_CLR);
242 else
243 kprintf("%s:%ld:Leaving %s\n", file, line, function);
247 void _RETURN(unsigned long dclass, const char *file, int line, const char *function, unsigned long result)
249 indent_level--;
251 if(isFlagSet(debug_classes, dclass))
253 _INDENT();
254 if(ansi_output)
255 kprintf("%s%s:%ld:Leaving %s (result 0x%08lx, %ld)%s\n", ANSI_ESC_FG_BROWN, file, line, function, result, result, ANSI_ESC_CLR);
256 else
257 kprintf("%s:%ld:Leaving %s (result 0x%08lx, %ld)\n", file, line, function, result, result);
261 /****************************************************************************/
263 void _SHOWVALUE(unsigned long dclass, unsigned long dflags, unsigned long value, int size, const char *name, const char *file, int line)
265 if(isFlagSet(debug_classes, dclass) &&
266 isFlagSet(debug_flags, dflags))
268 char *fmt;
270 switch(size)
272 case 1:
273 fmt = "%s:%ld:%s = %ld, 0x%02lx";
274 break;
276 case 2:
277 fmt = "%s:%ld:%s = %ld, 0x%04lx";
278 break;
280 default:
281 fmt = "%s:%ld:%s = %ld, 0x%08lx";
282 break;
285 _INDENT();
287 if(ansi_output)
288 kprintf(ANSI_ESC_FG_GREEN);
290 kprintf(fmt, file, line, name, value, value);
292 if(size == 1 && value < 256)
294 if(value < ' ' || (value >= 127 && value < 160))
295 kprintf(", '\\x%02lx'", value);
296 else
297 kprintf(", '%lc'", value);
300 if(ansi_output)
301 kprintf("%s\n", ANSI_ESC_CLR);
302 else
303 kprintf("\n");
307 /****************************************************************************/
309 void _SHOWPOINTER(unsigned long dclass, unsigned long dflags, const void *p, const char *name, const char *file, int line)
311 if(isFlagSet(debug_classes, dclass) &&
312 isFlagSet(debug_flags, dflags))
314 char *fmt;
316 _INDENT();
318 if(p != NULL)
319 fmt = "%s:%ld:%s = 0x%08lx\n";
320 else
321 fmt = "%s:%ld:%s = NULL\n";
323 if(ansi_output)
325 kprintf(ANSI_ESC_FG_GREEN);
326 kprintf(fmt, file, line, name, p);
327 kprintf(ANSI_ESC_CLR);
329 else
330 kprintf(fmt, file, line, name, p);
334 /****************************************************************************/
336 void _SHOWSTRING(unsigned long dclass, unsigned long dflags, const char *string, const char *name, const char *file, int line)
338 if(isFlagSet(debug_classes, dclass) &&
339 isFlagSet(debug_flags, dflags))
341 _INDENT();
343 if(ansi_output)
344 kprintf("%s%s:%ld:%s = 0x%08lx \"%s\"%s\n", ANSI_ESC_FG_GREEN, file, line, name, string, string, ANSI_ESC_CLR);
345 else
346 kprintf("%s:%ld:%s = 0x%08lx \"%s\"\n", file, line, name, string, string);
350 /****************************************************************************/
352 void _SHOWMSG(unsigned long dclass, unsigned long dflags, const char *msg, const char *file, int line)
354 if(isFlagSet(debug_classes, dclass) &&
355 isFlagSet(debug_flags, dflags))
357 _INDENT();
359 if(ansi_output)
360 kprintf("%s%s:%ld:%s%s\n", ANSI_ESC_FG_GREEN, file, line, msg, ANSI_ESC_CLR);
361 else
362 kprintf("%s:%ld:%s\n", file, line, msg);
366 /****************************************************************************/
368 void _DPRINTF(unsigned long dclass, unsigned long dflags, const char *file, int line, const char *format, ...)
370 if(isFlagSet(debug_classes, dclass) &&
371 isFlagSet(debug_flags, dflags))
373 va_list args;
375 _INDENT();
377 va_start(args, format);
379 if(ansi_output)
381 char *highlight = ANSI_ESC_FG_GREEN;
383 switch(dclass)
385 case DBC_CTRACE: highlight = ANSI_ESC_FG_BROWN; break;
386 case DBC_REPORT: highlight = ANSI_ESC_FG_GREEN; break;
387 case DBC_ASSERT: highlight = ANSI_ESC_FG_RED; break;
388 case DBC_TIMEVAL: highlight = ANSI_ESC_FG_GREEN; break;
389 case DBC_DEBUG: highlight = ANSI_ESC_FG_GREEN; break;
390 case DBC_ERROR: highlight = ANSI_ESC_FG_RED; break;
391 case DBC_WARNING: highlight = ANSI_ESC_FG_YELLOW;break;
394 kprintf("%s%s:%ld:", highlight, file, line);
396 KPutFmt((char *)format, args);
398 kprintf("%s\n", ANSI_ESC_CLR);
400 else
402 kprintf("%s:%ld:", file, line);
404 KPutFmt((char *)format, args);
406 kprintf("\n");
409 va_end(args);
413 /****************************************************************************/
415 #endif