Initial commit
[amiga/OpenBoopsi.git] / include / DebugMacros.h
1 #ifndef DEBUGMACROS_H
2 #define DEBUGMACROS_H
3 /*
4 **      $Id: DebugMacros.h,v 1.3 2000/01/12 20:30:24 bernie Exp $
5 **
6 **      Copyright (C) 1995,96,97,98,99 Bernardo Innocenti <bernardo.innocenti@usa.net>
7 **      All rights reserved.
8 **
9 **      Use 4 chars wide TABs to read this file
10 **
11 **      Some handy debug macros which are automatically excluded when the
12 **      _DEBUG preprocessor symbol isn't defined. To make debug executables,
13 **      you must link with debug.lib or any module containing the kprintf()
14 **      function.
15 **
16 **      Here is a short description of the macros defined below:
17 **
18 **      ILLEGAL
19 **              Output an inline "ILLEGAL" 68K opcode, which will
20 **              be interpreted as a breakpoint by most debuggers.
21 **
22 **      bug
23 **      DBPRINTF
24 **              Output a formatted string to the debug console. This
25 **              macro uses the debug.lib/kprintf() function by default.
26 **
27 **      ASSERT(x)
28 **              Do nothing if the expression <x> evalutates to a
29 **              non-zero value, output a debug message otherwise.
30 **
31 **      ASSERT_VALID_PTR(x)
32 **              Checks if the expression <x> points to a valid
33 **              memory location, and outputs a debug message
34 **              otherwise. A NULL pointer is considered VALID.
35 **
36 **      ASSERT_VALID_PTR_OR_NULL(x)
37 **              Checks if the expression <x> points to a valid
38 **              memory location, and outputs a debug message
39 **              otherwise. A NULL pointer is considered INVALID.
40 **
41 **      D(x)
42 **      DB(x)
43 **              Compile the expression <x> when making a debug
44 **              executable, otherwise omit it.
45 **
46 **      DB1(x)
47 **              DB verbosity level 1. Compile the expression <x> when the
48 **              preprocessor symbol DEBUG is defined to a number greater or
49 **              equal to 1.
50 **
51 **      DB2(x)
52 **              DB verbosity level 2. Compile the expression <x> when the
53 **              preprocessor symbol _DEBUG is defined to a number greater or
54 **              equal to 2.
55 */
56
57 /* Accept DEBUG as well as _DEBUG */
58 #ifndef _DEBUG
59 #       ifdef DEBUG
60 #               define _DEBUG DEBUG
61 #       else
62 #               define _DEBUG 0
63 #       endif
64 #endif
65
66 #if _DEBUG
67
68         /* Needed for TypeOfMem() */
69         #ifndef  PROTO_EXEC_H
70         #include <proto/exec.h>
71         #endif /* PROTO_EXEC_H */
72
73         #if defined(__SASC)
74
75                 extern void __builtin_emit (int);
76                 // #define ILLEGAL __builtin_emit(0x4AFC)
77                 #define ILLEGAL 0
78                 STDARGS extern void kprintf (const char *, ...);
79
80         #elif defined(__GNUC__)
81
82                 /* GCC doesn't accept asm statements in the middle of an
83                  * expression such as `a ? b : asm("something")'.
84                  */
85                 #define ILLEGAL illegal()
86                 static __inline__ int illegal(void) { asm("illegal"); return 0; }
87                 extern void STDARGS FORMATCALL(printf,1,2) kprintf(const char *, ...);
88
89         #else
90                 #error Please add compiler specific definitions for your compiler
91         #endif
92
93
94         /* common definitions for ASSERT and DB macros */
95
96         #define DBPRINTF kprintf
97         #define bug kprintf
98
99         /* The trick with THIS_FILE is meant to avoid multiple allocations of
100          * the filename string for each occurrence of these macros. To reduce
101          * debug executable size, each module should cooperate by undefinining
102          * the THIS_FILE macro and declaring a static global symbol with the
103          * same name.
104          */
105         #define THIS_FILE __FILE__
106
107         #define ASSERT(x) ( (x) ? 0 :                                                                   \
108                 ( DBPRINTF("\x07%s:%ld: assertion failed: %s\n",                        \
109                 THIS_FILE, __LINE__, #x) , ILLEGAL ) );
110
111         #define ASSERT_VALID_PTR_OR_NULL(x) ( ((((APTR)(x)) == NULL) || \
112                 (((LONG)(x) > 1024) &&  TypeOfMem((APTR)(x)))) ? 0 :            \
113                 ( DBPRINTF("\x07%s:%ld: bad pointer: %s = $%lx\n",      \
114                 THIS_FILE, __LINE__, #x, (APTR)(x)) , ILLEGAL ) );
115
116         #define ASSERT_VALID_PTR(x) ( (((LONG)(x) > 1024) &&                    \
117                 TypeOfMem((APTR)(x))) ? 0 :                                                                     \
118                 ( DBPRINTF("\x07%s, %ld: bad pointer: %s = $%lx\n",                     \
119                 THIS_FILE, __LINE__, #x, (APTR)(x)) , ILLEGAL ) );
120
121         #define D(x) x
122         #define DB(x) x
123         #define DB1(x) x
124
125         #if _DEBUG >= 2
126                 #define DB2(x) x
127         #else
128                 #define DB2(x)
129         #endif
130
131         #if _DEBUG >= 3
132                 #define DB3(x) x
133         #else
134                 #define DB3(x)
135         #endif
136 #else
137         #define ASSERT_VALID_PTR(x)
138         #define ASSERT_VALID_PTR_OR_NULL(x)
139         #define ASSERT(x)
140         #define DB(x)
141         #define D(x)
142         #define DB1(x)
143         #define DB2(x)
144         #define DB3(x)
145 #endif /* _DEBUG */
146
147 #endif /* !DEBUGMACROS_H */