Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / classes / gadgets / texteditor / mcp / Debug.c
blobdc166c9b595f8e7784229e822570acbcb0a1d696
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.mcp.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 { "all", DBF_ALL },
89 { NULL, 0 }
92 // we parse the env variable token-wise
93 while((tok = strtok(debug, ", ;")))
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; 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; 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[1] == '!')
132 for(i=0; dbflags[i].token; 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; 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:texteditor.mcp.debug): %08x/%08x\n", debug_classes, debug_flags);
169 kprintf("** Normal processing follows ***************************************\n");
172 /****************************************************************************/
174 // define variables for using ANSI colors in our debugging scheme
175 #define ANSI_ESC_CLR "\033[0m"
176 #define ANSI_ESC_BOLD "\033[1m"
177 #define ANSI_ESC_UNDERLINE "\033[4m"
178 #define ANSI_ESC_BLINK "\033[5m"
179 #define ANSI_ESC_REVERSE "\033[7m"
180 #define ANSI_ESC_INVISIBLE "\033[8m"
181 #define ANSI_ESC_FG_BLACK "\033[0;30m"
182 #define ANSI_ESC_FG_RED "\033[0;31m"
183 #define ANSI_ESC_FG_GREEN "\033[0;32m"
184 #define ANSI_ESC_FG_BROWN "\033[0;33m"
185 #define ANSI_ESC_FG_BLUE "\033[0;34m"
186 #define ANSI_ESC_FG_PURPLE "\033[0;35m"
187 #define ANSI_ESC_FG_CYAN "\033[0;36m"
188 #define ANSI_ESC_FG_LGRAY "\033[0;37m"
189 #define ANSI_ESC_FG_DGRAY "\033[1;30m"
190 #define ANSI_ESC_FG_LRED "\033[1;31m"
191 #define ANSI_ESC_FG_LGREEN "\033[1;32m"
192 #define ANSI_ESC_FG_YELLOW "\033[1;33m"
193 #define ANSI_ESC_FG_LBLUE "\033[1;34m"
194 #define ANSI_ESC_FG_LPURPLE "\033[1;35m"
195 #define ANSI_ESC_FG_LCYAN "\033[1;36m"
196 #define ANSI_ESC_FG_WHITE "\033[1;37m"
197 #define ANSI_ESC_BG "\033[0;4" // background esc-squ start with 4x
198 #define ANSI_ESC_BG_BLACK "\033[0;40m"
199 #define ANSI_ESC_BG_RED "\033[0;41m"
200 #define ANSI_ESC_BG_GREEN "\033[0;42m"
201 #define ANSI_ESC_BG_BROWN "\033[0;43m"
202 #define ANSI_ESC_BG_BLUE "\033[0;44m"
203 #define ANSI_ESC_BG_PURPLE "\033[0;45m"
204 #define ANSI_ESC_BG_CYAN "\033[0;46m"
205 #define ANSI_ESC_BG_LGRAY "\033[0;47m"
207 /****************************************************************************/
209 INLINE void _INDENT(void)
211 int i;
212 for(i=0; i < indent_level; i++)
213 kprintf(" ");
216 /****************************************************************************/
218 void _ENTER(unsigned long dclass, const char *file, int line, const char *function)
220 if(isFlagSet(debug_classes, dclass))
222 _INDENT();
223 if(ansi_output)
224 kprintf("%s%s:%ld:Entering %s%s\n", ANSI_ESC_FG_BROWN, file, line, function, ANSI_ESC_CLR);
225 else
226 kprintf("%s:%ld:Entering %s\n", file, line, function);
229 indent_level++;
232 void _LEAVE(unsigned long dclass, const char *file, int line, const char *function)
234 indent_level--;
236 if(isFlagSet(debug_classes, dclass))
238 _INDENT();
239 if(ansi_output)
240 kprintf("%s%s:%ld:Leaving %s%s\n", ANSI_ESC_FG_BROWN, file, line, function, ANSI_ESC_CLR);
241 else
242 kprintf("%s:%ld:Leaving %s\n", file, line, function);
246 void _RETURN(unsigned long dclass, const char *file, int line, const char *function, unsigned long result)
248 indent_level--;
250 if(isFlagSet(debug_classes, dclass))
252 _INDENT();
253 if(ansi_output)
254 kprintf("%s%s:%ld:Leaving %s (result 0x%08lx, %ld)%s\n", ANSI_ESC_FG_BROWN, file, line, function, result, result, ANSI_ESC_CLR);
255 else
256 kprintf("%s:%ld:Leaving %s (result 0x%08lx, %ld)\n", file, line, function, result, result);
260 /****************************************************************************/
262 void _SHOWVALUE(unsigned long dclass, unsigned long dflags, unsigned long value, int size, const char *name, const char *file, int line)
264 if(isFlagSet(debug_classes, dclass) &&
265 isFlagSet(debug_flags, dflags))
267 char *fmt;
269 switch(size)
271 case 1:
272 fmt = "%s:%ld:%s = %ld, 0x%02lx";
273 break;
275 case 2:
276 fmt = "%s:%ld:%s = %ld, 0x%04lx";
277 break;
279 default:
280 fmt = "%s:%ld:%s = %ld, 0x%08lx";
281 break;
284 _INDENT();
286 if(ansi_output)
287 kprintf(ANSI_ESC_FG_GREEN);
289 kprintf(fmt, file, line, name, value, value);
291 if(size == 1 && value < 256)
293 if(value < ' ' || (value >= 127 && value < 160))
294 kprintf(", '\\x%02lx'", value);
295 else
296 kprintf(", '%lc'", value);
299 if(ansi_output)
300 kprintf("%s\n", ANSI_ESC_CLR);
301 else
302 kprintf("\n");
306 /****************************************************************************/
308 void _SHOWPOINTER(unsigned long dclass, unsigned long dflags, const void *p, const char *name, const char *file, int line)
310 if(isFlagSet(debug_classes, dclass) &&
311 isFlagSet(debug_flags, dflags))
313 char *fmt;
315 _INDENT();
317 if(p != NULL)
318 fmt = "%s:%ld:%s = 0x%08lx\n";
319 else
320 fmt = "%s:%ld:%s = NULL\n";
322 if(ansi_output)
324 kprintf(ANSI_ESC_FG_GREEN);
325 kprintf(fmt, file, line, name, p);
326 kprintf(ANSI_ESC_CLR);
328 else
329 kprintf(fmt, file, line, name, p);
333 /****************************************************************************/
335 void _SHOWSTRING(unsigned long dclass, unsigned long dflags, const char *string, const char *name, const char *file, int line)
337 if(isFlagSet(debug_classes, dclass) &&
338 isFlagSet(debug_flags, dflags))
340 _INDENT();
342 if(ansi_output)
343 kprintf("%s%s:%ld:%s = 0x%08lx \"%s\"%s\n", ANSI_ESC_FG_GREEN, file, line, name, string, string, ANSI_ESC_CLR);
344 else
345 kprintf("%s:%ld:%s = 0x%08lx \"%s\"\n", file, line, name, string, string);
349 /****************************************************************************/
351 void _SHOWMSG(unsigned long dclass, unsigned long dflags, const char *msg, const char *file, int line)
353 if(isFlagSet(debug_classes, dclass) &&
354 isFlagSet(debug_flags, dflags))
356 _INDENT();
358 if(ansi_output)
359 kprintf("%s%s:%ld:%s%s\n", ANSI_ESC_FG_GREEN, file, line, msg, ANSI_ESC_CLR);
360 else
361 kprintf("%s:%ld:%s\n", file, line, msg);
365 /****************************************************************************/
367 void _DPRINTF(unsigned long dclass, unsigned long dflags, const char *file, int line, const char *format, ...)
369 if(isFlagSet(debug_classes, dclass) &&
370 isFlagSet(debug_flags, dflags))
372 va_list args;
374 _INDENT();
376 va_start(args, format);
378 if(ansi_output)
380 char *highlight = ANSI_ESC_FG_GREEN;
382 switch(dclass)
384 case DBC_CTRACE: highlight = ANSI_ESC_FG_BROWN; break;
385 case DBC_REPORT: highlight = ANSI_ESC_FG_GREEN; break;
386 case DBC_ASSERT: highlight = ANSI_ESC_FG_RED; break;
387 case DBC_TIMEVAL: highlight = ANSI_ESC_FG_GREEN; break;
388 case DBC_DEBUG: highlight = ANSI_ESC_FG_GREEN; break;
389 case DBC_ERROR: highlight = ANSI_ESC_FG_RED; break;
390 case DBC_WARNING: highlight = ANSI_ESC_FG_YELLOW;break;
393 kprintf("%s%s:%ld:", highlight, file, line);
395 KPutFmt((char *)format, args);
397 kprintf("%s\n", ANSI_ESC_CLR);
399 else
401 kprintf("%s:%ld:", file, line);
403 KPutFmt((char *)format, args);
405 kprintf("\n");
408 va_end(args);
412 /****************************************************************************/
414 #endif