|
|
1.1 root 1: #ifndef __COMMON__XDEBUG_H__
2: #define __COMMON__XDEBUG_H__
3:
4:
5: /*
6: *-IMPORTS:
7: * <common/ccompat.h>
8: * __STRING ()
9: */
10:
11: #include <common/ccompat.h>
12:
13:
14: /*
15: * This file contains some simple macros for use in debugging and statistics
16: * gathering code. Centralizing these definitions has no real purpose other
17: * than increasing consistency for the person attempting to test code.
18: *
19: * Note that it would be nice if we could hook this into a source-code
20: * control system's notion of version, so that in addition to file name,
21: * build date, and build time we could include version number, author and
22: * last change date by having macros in every .c file's beginning.
23: *
24: * Note that under C++, higher levels of debugging information can use the
25: * constructor/destructor facilities of C++ code to create automatic
26: * dependency information for files and all kinds of other useful facilities
27: * if the source-code control system above can be extended for most file
28: * types.
29: *
30: * Since this file controls compile-time debugging detail, it is intended
31: * that this system be used especially in cases where source distribution
32: * is not desirable. The ability to include multiple library versions
33: * is an invaluable aid to debugging, not merely because of the extra
34: * information that may be provided in case of a simply detected error, but
35: * because the addition of debugging information subtly alters the
36: * characteristics of the system under test. Merely including a range of
37: * different libraries can test a system for a variety of the more subtle
38: * bugs that usually manifest themselves only during the porting process.
39: */
40:
41: /*
42: * We define standard names for system debugging-level macros that are
43: * controlled by a single user symbol defined on the command line for the
44: * compilation, _DEBUG_LEVEL. If not defined, this symbol defaults to the
45: * value zero. The value of this symbol determines the level of detail
46: * included in the compile-time debugging information, and/or the level of
47: * run-time checking that is desired.
48: *
49: * This facility defines a simple linear scale of debugging detail, and is
50: * intended to supplement system-dependent optional debugging facilities in
51: * cases where the systems affected by a problem cannot be easily determined
52: * without experimentation.
53: */
54:
55: #ifndef _DEBUG_LEVEL
56: #define _DEBUG_LEVEL 3
57: #endif
58:
59:
60: /*
61: * Define a bitmap of debugging feature levels that we can combine. Note
62: * that some feature sections are ordered so that the relative magnitudes
63: * and order of the bits are important.
64: */
65:
66: #define __FI_NAME_M__ 0x0001 /* include file name */
67: #define __FI_LINE_M__ 0x0002 /* include file line no */
68: #define __FI_DATE_M__ 0x0004 /* include build date */
69: #define __FI_TIME_M__ 0x0008 /* include build time */
70: #define __FI_USER_M__ 0x0010 /* include user info */
71:
72:
73: /*
74: * Turn the _DEBUG_LEVEL into a __DEBUG_PROFILE__, unless that has already
75: * been overridden.
76: */
77:
78: #if _DEBUG_LEVEL < 1
79:
80: # define __DEBUG_PROFILE__ 0
81:
82: #elif _DEBUG_LEVEL < 2
83:
84: # define __DEBUG_PROFILE__ __FI_NAME_M__
85:
86: #elif _DEBUG_LEVEL < 3
87:
88: # define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__)
89:
90: #elif _DEBUG_LEVEL < 4
91:
92: # define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__ | \
93: __FI_DATE_M__)
94:
95: #elif _DEBUG_LEVEL < 5
96:
97: # define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__ | \
98: __FI_DATE_M__)
99:
100: #elif _DEBUG_LEVEL < 6
101:
102: # define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__ | \
103: __FI_DATE_M__ | __FI_USER_M__)
104:
105: #elif _DEBUG_LEVEL < 7
106:
107: # define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__ | \
108: __FI_DATE_M__ | __FI_USER_M__)
109:
110: #elif _DEBUG_LEVEL < 8
111:
112: # define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__ | \
113: __FI_DATE_M__ | __FI_TIME_M__ | \
114: __FI_USER_M__)
115:
116: #else /* anything else */
117:
118: # define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__ | \
119: __FI_DATE_M__ | __FI_TIME_M__ | \
120: __FI_USER_M__)
121:
122: #endif /* switch (_DEBUG_LEVEL) */
123:
124:
125: /*
126: * Before we get into the _DEBUG_LEVEL feature tests, we note that there is
127: * some other information that the user might like to use to annotate the
128: * __FILE_INFO__ macro, rather than just to redefine it. We allow the user
129: * to define the _USER_NAME macro for the purpose of including the name of
130: * the person performing the build (or other information such as the name
131: * of the translator or cross-development platform being used).
132: */
133:
134: #ifndef _USER_NAME
135:
136: # define _USER_NAME no-one
137:
138: #endif /* ! defined (_USER_NAME) */
139:
140: # define __USER_NAME__ __STRING (_USER_NAME)
141:
142:
143:
144: /*
145: * The "standard" debugging macro __FILE_INFO__ can be used in place of the
146: * more common __FILE__ definition in many cases. At different levels of
147: * debugging information, the value of this symbol (which is an ANSI string)
148: * includes more information. At debugging level 0, this macro expands to
149: * an empty string, allowing it to be used without complex #if statements
150: * in the client.
151: *
152: * A side issue is the way spaces are included in the output string; note
153: * that individual feature tests are done in bit order of the feature
154: * string, so we can do some funky tests of the magnitude of part of the
155: * feature mask to see if anything we are interested in is following the
156: * current bit. Sleazy, but it gives nice output.
157: *
158: * Since including line numbers as strings generates a lot of big strings
159: * that cannot be marged, we provide __FILE_INFO__ which consists of a string
160: * and an optional line number (zero if line numbers are not to be included)
161: * and __FILE_INFO_STRING__ which is a single string.
162: *
163: * We also export the symbol __NO_FILE_INFO__ if we know that the value of
164: * __FILE_INFO__ is an empty string, in order to allow users to replace a
165: * null string expansion with a NULL value.
166: */
167:
168: #if ! defined (__FILE_INFO__) && ! defined (__NO_FILE_INFO__)
169:
170: # define __FI_M__ (__FI_NAME_M__ | __FI_DATE_M__ | __FI_TIME_M__ | \
171: __FI_USER_M__)
172:
173: # if (__DEBUG_PROFILE__ & __FI_NAME_M__) != 0
174: # define __FI_NAME__ __FILE__
175: # else
176: # define __FI_NAME__
177: # endif /* no file name */
178:
179:
180: # if (__DEBUG_PROFILE__ & __FI_LINE_M__) != 0
181: # define __FI_LINE_STR__ " Line # " __STRING (__LINE__)
182: # define __FI_LINE__ , __LINE__
183: #else
184: # define __FI_LINE_STR__
185: # define __FI_LINE__ , 0
186: #endif
187:
188:
189: # if (__DEBUG_PROFILE__ & __FI_M__) > __FI_NAME_M__
190: # define __FI_NAME_S__ " "
191: # else
192: # define __FI_NAME_S__
193: # endif /* don't need a space */
194:
195:
196: # if (__DEBUG_PROFILE__ & __FI_LINE_M__) != 0
197: # define __FI_LINE_S__ " "
198: # else
199: # define __FI_LINE_S__
200: #endif
201:
202:
203: # if (__DEBUG_PROFILE__ & __FI_DATE_M__) != 0
204: # define __FI_DATE__ " built on " __DATE__
205: # else
206: # define __FI_DATE__
207: # endif /* no file build date */
208:
209:
210: # if (__DEBUG_PROFILE__ & __FI_M__) > __FI_DATE_M__
211: # define __FI_DATE_S__ " "
212: # else
213: # define __FI_DATE_S__
214: # endif /* don't need a space */
215:
216:
217: # if (__DEBUG_PROFILE__ & __FI_TIME_M__) != 0
218: # define __FI_TIME__ " at " __TIME__
219: # else
220: # define __FI_TIME__
221: # endif /* no file build time */
222:
223:
224: # if (__DEBUG_PROFILE__ & __FI_M__) > __FI_TIME_M__
225: # define __FI_TIME_S__ " "
226: # else
227: # define __FI_TIME_S__
228: # endif /* don't need a space */
229:
230:
231: # if (__DEBUG_PROFILE__ & __FI_USER_M__) != 0
232: # define __FI_USER__ __USER_NAME__
233: # else
234: # define __FI_USER__
235: # endif /* no file name */
236:
237:
238: /*
239: * Define __NO_FILE_INFO__ iff the user has not requested anything to be
240: * included in the __FILE_INFO__ macro.
241: */
242:
243: # if (__DEBUG_PROFILE__ & __FI_M__) == 0
244: # define __NO_FILE_INFO__ 1
245: # endif
246:
247:
248: /*
249: * Note that we terminate these strings with a "" so that they ALWAYS expand
250: * to a valid ISO C string of some form. If we are using a C compiler than
251: * cannot merge constant strings, create a static string constant.
252: */
253:
254: # define __FILE_INFO_FMT__ __FI_NAME__ __FI_NAME_S__ \
255: __FI_DATE__ __FI_DATE_S__ \
256: __FI_TIME__ __FI_TIME_S__ \
257: __FI_USER__ ""
258:
259: # if ! _SHARED_STRINGS
260: # if (__DEBUG_PROFILE__ & __FI_NAME_M__) != 0 && defined (__BASE_FILE__)
261: /*
262: * Since we are evaluating __FILE__ here in the header, switch over to use
263: * __BASE_FILE__ if the preprocessor knows about that.
264: */
265: # undef __FI_NAME__
266: # define __FI_NAME__ __BASE_FILE__
267:
268: static __CONST__ char * __CONST__ __file_info_fmt__ = __FILE_INFO_FMT__;
269: # undef __FILE_INFO_FMT__
270: # define __FILE_INFO_FMT__ __file_info_fmt__
271:
272: # endif /* defined (__BASE_FILE__) */
273: # endif /* ! _SHARED_STRINGS */
274:
275:
276: # define __FILE_INFO__ __FILE_INFO_FMT__ __FI_LINE__
277:
278: # define __FILE_INFO_STRING__ __FI_NAME__ __FI_NAME_S__ \
279: __FI_LINE_STR__ __FI_LINE_S__ \
280: __FI_DATE__ __FI_DATE_S__ \
281: __FI_TIME__ __FI_TIME_S__ \
282: __FI_USER__ ""
283:
284: /*
285: * Remove unneeded private preprocessor symbols. Note that the __FI_xxx__
286: * symbols cannot be removed because they are needed in the expansion of
287: * __FILE_INFO__. Since they being with double-underscores, this should not
288: * be a problem.
289: */
290:
291: # undef __FI_M__
292:
293: #endif /* ! defined (__FILE_INFO__) && ! defined (__NO_FILE_INFO__) */
294:
295: /*
296: * Other handy stuff: many debugging systems do not maintain a separate
297: * debugger global namespace, and so definitions that have local or file
298: * static scope are not necessarily visible.
299: *
300: * In order to get more control over the global namespace, structures that
301: * should not normally appear visible but whose addresses we may wish to
302: * reveal should be declared with the following storage class prefix.
303: */
304:
305: #ifndef __LOCAL__
306: # ifdef _SHOW
307:
308: # define __LOCAL__
309:
310: # else
311:
312: # define __LOCAL__ static
313:
314: # endif
315: #endif
316:
317:
318: #endif /* ! defined (__COMMON__XDEBUG_H__) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.