Coherent4.2.10/include/common/_xdebug.h
/* (-lgl
* Coherent 386 release 4.2
* Copyright (c) 1982, 1993 by Mark Williams Company.
* All rights reserved. May not be copied without permission.
* For copying permission and licensing info, write licensing@mwc.com
-lgl) */
#ifndef __COMMON__XDEBUG_H__
#define __COMMON__XDEBUG_H__
#include <common/ccompat.h>
/*
* This file contains some simple macros for use in debugging and statistics
* gathering code. Centralizing these definitions has no real purpose other
* than increasing consistency for the person attempting to test code.
*
* Note that it would be nice if we could hook this into a source-code
* control system's notion of version, so that in addition to file name,
* build date, and build time we could include version number, author and
* last change date by having macros in every .c file's beginning.
*
* Note that under C++, higher levels of debugging information can use the
* constructor/destructor facilities of C++ code to create automatic
* dependency information for files and all kinds of other useful facilities
* if the source-code control system above can be extended for most file types.
*
* Because this file controls compile-time debugging detail, it is intended
* for instances where source distribution is not desirable. The ability to
* include multiple library versions is an invaluable aid to debugging, not
* merely because of the extra information that may be provided in case of a
* simply detected error, but because the addition of debugging information
* subtly alters the characteristics of the system under test. Merely
* including a range of different libraries can test a system for a variety
* of the more subtle bugs that usually manifest themselves only during the
* porting process.
*/
/*
* We define standard names for system debugging-level macros that are
* controlled by a single user symbol defined on the command line for the
* compilation, _DEBUG_LEVEL. If not defined, this symbol defaults to the
* value zero. The value of this symbol determines the level of detail
* included in the compile-time debugging information, and/or the level of
* run-time checking that is desired.
*
* This facility defines a simple linear scale of debugging detail, and is
* intended to supplement system-dependent optional debugging facilities in
* cases where the systems affected by a problem cannot be easily determined
* without experimentation.
*/
#ifndef _DEBUG_LEVEL
#define _DEBUG_LEVEL 3
#endif
/*
* Define a bitmap of debugging feature levels that we can combine. Note
* that some feature sections are ordered so that the relative magnitudes
* and order of the bits are important.
*/
#define __FI_NAME_M__ 0x0001 /* include file name */
#define __FI_LINE_M__ 0x0002 /* include file line no */
#define __FI_DATE_M__ 0x0004 /* include build date */
#define __FI_TIME_M__ 0x0008 /* include build time */
#define __FI_USER_M__ 0x0010 /* include user info */
/*
* Turn the _DEBUG_LEVEL into a __DEBUG_PROFILE__, unless that has already
* been overridden.
*/
#if _DEBUG_LEVEL < 1
# define __DEBUG_PROFILE__ 0
#elif _DEBUG_LEVEL < 2
# define __DEBUG_PROFILE__ __FI_NAME_M__
#elif _DEBUG_LEVEL < 3
# define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__)
#elif _DEBUG_LEVEL < 4
# define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__ | \
__FI_DATE_M__)
#elif _DEBUG_LEVEL < 5
# define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__ | \
__FI_DATE_M__)
#elif _DEBUG_LEVEL < 6
# define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__ | \
__FI_DATE_M__ | __FI_USER_M__)
#elif _DEBUG_LEVEL < 7
# define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__ | \
__FI_DATE_M__ | __FI_USER_M__)
#elif _DEBUG_LEVEL < 8
# define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__ | \
__FI_DATE_M__ | __FI_TIME_M__ | \
__FI_USER_M__)
#else /* anything else */
# define __DEBUG_PROFILE__ (__FI_NAME_M__ | __FI_LINE_M__ | \
__FI_DATE_M__ | __FI_TIME_M__ | \
__FI_USER_M__)
#endif /* switch (_DEBUG_LEVEL) */
/*
* Before we get into the _DEBUG_LEVEL feature tests, we note that there is
* some other information that the user might like to use to annotate the
* __FILE_INFO__ macro, rather than just to redefine it. We allow the user
* to define the _USER_NAME macro for the purpose of including the name of
* the person performing the build (or other information such as the name
* of the translator or cross-development platform being used).
*/
#ifndef _USER_NAME
# define _USER_NAME no-one
#endif /* ! defined (_USER_NAME) */
# define __USER_NAME__ __STRINGVAL (_USER_NAME)
/*
* The "standard" debugging macro __FILE_INFO__ can be used in place of the
* more common __FILE__ definition in many cases. At different levels of
* debugging information, the value of this symbol (which is an ANSI string)
* includes more information. At debugging level 0, this macro expands to
* an empty string, allowing it to be used without complex #if statements
* in the client.
*
* A side issue is the way spaces are included in the output string; note
* that individual feature tests are done in bit order of the feature
* string, so we can do some funky tests of the magnitude of part of the
* feature mask to see if anything we are interested in is following the
* current bit. Sleazy, but it gives nice output.
*
* Because including line numbers as strings generates a lot of big strings
* that cannot be merged, we provide __FILE_INFO__, which consists of a string
* and an optional line number (zero if line numbers are not to be included),
* and __FILE_INFO_STRING__, which is a single string.
*
* We also export the symbol __NO_FILE_INFO__ if we know that the value of
* __FILE_INFO__ is an empty string, in order to allow users to replace a
* null string expansion with a NULL value.
*/
#if ! defined (__FILE_INFO__) && ! defined (__NO_FILE_INFO__)
# define __FI_M__ (__FI_NAME_M__ | __FI_DATE_M__ | __FI_TIME_M__ | \
__FI_USER_M__)
# if (__DEBUG_PROFILE__ & __FI_NAME_M__) != 0
# define __FI_NAME__ __FILE__
# else
# define __FI_NAME__
# endif /* no file name */
# if (__DEBUG_PROFILE__ & __FI_LINE_M__) != 0
# define __FI_LINE_STR__ " Line # " __STRINGVAL (__LINE__)
# define __FI_LINE__ , __LINE__
#else
# define __FI_LINE_STR__
# define __FI_LINE__ , 0
#endif
# if (__DEBUG_PROFILE__ & __FI_M__) > __FI_NAME_M__
# define __FI_NAME_S__ " "
# else
# define __FI_NAME_S__
# endif /* don't need a space */
# if (__DEBUG_PROFILE__ & __FI_LINE_M__) != 0
# define __FI_LINE_S__ " "
# else
# define __FI_LINE_S__
#endif
# if (__DEBUG_PROFILE__ & __FI_DATE_M__) != 0
# define __FI_DATE__ " built on " __DATE__
# else
# define __FI_DATE__
# endif /* no file build date */
# if (__DEBUG_PROFILE__ & __FI_M__) > __FI_DATE_M__
# define __FI_DATE_S__ " "
# else
# define __FI_DATE_S__
# endif /* don't need a space */
# if (__DEBUG_PROFILE__ & __FI_TIME_M__) != 0
# define __FI_TIME__ " at " __TIME__
# else
# define __FI_TIME__
# endif /* no file build time */
# if (__DEBUG_PROFILE__ & __FI_M__) > __FI_TIME_M__
# define __FI_TIME_S__ " "
# else
# define __FI_TIME_S__
# endif /* don't need a space */
# if (__DEBUG_PROFILE__ & __FI_USER_M__) != 0
# define __FI_USER__ __USER_NAME__
# else
# define __FI_USER__
# endif /* no file name */
/*
* Define __NO_FILE_INFO__ iff the user has not requested anything to be
* included in the __FILE_INFO__ macro.
*/
# if (__DEBUG_PROFILE__ & __FI_M__) == 0
# define __NO_FILE_INFO__ 1
# endif
/*
* Note that we terminate these strings with a "" so that they ALWAYS expand
* to a valid ISO C string of some form. If we are using a C compiler that
* cannot merge constant strings, create a static string constant.
*/
# define __FILE_INFO_FMT__ __FI_NAME__ __FI_NAME_S__ \
__FI_DATE__ __FI_DATE_S__ \
__FI_TIME__ __FI_TIME_S__ \
__FI_USER__ ""
# if ! _SHARED_STRINGS
# if (__DEBUG_PROFILE__ & __FI_NAME_M__) != 0 && defined (__BASE_FILE__)
/*
* Because we are evaluating __FILE__ here in the header, switch over to use
* __BASE_FILE__ if the preprocessor knows about that.
*/
# undef __FI_NAME__
# define __FI_NAME__ __BASE_FILE__
static __CONST__ char * __CONST__ __file_info_fmt__ = __FILE_INFO_FMT__;
# undef __FILE_INFO_FMT__
# define __FILE_INFO_FMT__ __file_info_fmt__
# endif /* defined (__BASE_FILE__) */
# endif /* ! _SHARED_STRINGS */
# define __FILE_INFO__ __FILE_INFO_FMT__ __FI_LINE__
# define __FILE_INFO_STRING__ __FI_NAME__ __FI_NAME_S__ \
__FI_LINE_STR__ __FI_LINE_S__ \
__FI_DATE__ __FI_DATE_S__ \
__FI_TIME__ __FI_TIME_S__ \
__FI_USER__ ""
/*
* Remove unneeded private preprocessor symbols. Note that the __FI_xxx__
* symbols cannot be removed because they are needed in the expansion of
* __FILE_INFO__. Becausee they begin with double-underscores, this should not
* be a problem.
*/
# undef __FI_M__
#endif /* ! defined (__FILE_INFO__) && ! defined (__NO_FILE_INFO__) */
/*
* Other handy stuff: many debugging systems do not maintain a separate
* debugger global namespace, so definitions that have local or file static
* scope are not necessarily visible.
*
* To get more control over the global namespace, structures that should
* not normally appear visible but whose addresses we may wish to
* reveal should be declared with the following storage class prefix.
*/
#ifndef __LOCAL__
# ifdef _SHOW
# define __LOCAL__
# else
# define __LOCAL__ static
# endif
#endif
#endif /* ! defined (__COMMON__XDEBUG_H__) */