|
|
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.