00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _SUPPORT_DEBUG_H
00014 #define _SUPPORT_DEBUG_H
00015
00021 #include <stdarg.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <support/atomic.h>
00025 #include <support/SupportDefs.h>
00026 #include <ErrorMgr.h>
00027
00028 #ifndef DEBUG
00029 #define DEBUG 0
00030 #endif
00031
00032 #ifdef __cplusplus
00033 #if _SUPPORTS_NAMESPACE
00034 namespace palmos {
00035 namespace support {
00036 #endif
00037 class SString;
00038 #if _SUPPORTS_NAMESPACE
00039 } }
00040 #endif
00041 #endif
00042
00043
00044
00045 #ifdef __cplusplus
00046 extern "C" {
00047 #endif
00048 #if TARGET_HOST != TARGET_HOST_PALMOS
00049 extern int _rtDebugFlag;
00050 #else
00051 #define _rtDebugFlag true
00052 #endif
00053
00054 int _debugFlag(void);
00055 int _setDebugFlag(int);
00056
00057 #if TARGET_HOST == TARGET_HOST_BEOS
00058 int _debugPrintf(const char *, ...);
00059 int _sPrintf(const char *, ...);
00060 int _xdebugPrintf(const char *, ...);
00061 #else
00062 #define _debugPrintf printf
00063 #define _sPrintf sprintf
00064 #define _xdebugPrintf printf
00065 #endif
00066
00067 typedef void (*b_debug_action)(void* data);
00068 void _exec_debug_action(b_debug_action action, void* data);
00069
00070 #ifdef __cplusplus
00071 }
00072 #endif // __cplusplus
00073
00074
00079
00082
00083 #ifdef __cplusplus
00084 #include <support/Atom.h>
00085 _IMPEXP_SUPPORT void add_debug_atom(BNS(palmos::support::) SAtom * atom, const char *name);
00086 _IMPEXP_SUPPORT void add_debug_atom(const BNS(::palmos::support::)sptr<BNS(palmos::support::) SAtom>& atom, const char *name);
00087 _IMPEXP_SUPPORT void add_debug_sized(const void *key, size_t size, const char *name);
00088 _IMPEXP_SUPPORT void set_debug_fieldwidth(int width);
00089 _IMPEXP_SUPPORT BNS(palmos::support::)SString lookup_debug(const BNS(::palmos::support::)sptr<BNS(palmos::support::) SAtom>& atom, bool padding = true);
00090 _IMPEXP_SUPPORT BNS(palmos::support::)SString lookup_debug(const void *key, bool padding = true);
00091 #endif
00092
00094
00095
00098
00099 #if DEBUG
00100 #define SET_DEBUG_ENABLED(FLAG) _setDebugFlag(FLAG)
00101 #define IS_DEBUG_ENABLED() _debugFlag()
00102
00103 #define SERIAL_PRINT(ARGS) _sPrintf ARGS
00104 #define PRINT(ARGS) _debugPrintf ARGS
00105 #define PRINT_OBJECT(OBJ) if (_rtDebugFlag) { \
00106 PRINT(("%s\t", #OBJ)); \
00107 (OBJ).PrintToStream(); \
00108 } ((void) 0)
00109 #define TRACE() _debugPrintf("File: %s, Line: %d, Thread: %d\n", \
00110 __FILE__, __LINE__, SysCurrentThread())
00111
00112 #define SERIAL_TRACE() _sPrintf("File: %s, Line: %d, Thread: %d\n", \
00113 __FILE__, __LINE__, SysCurrentThread())
00114
00115 #define DEBUGGER(MSG) if (_rtDebugFlag) ErrFatalError(MSG);
00116 #if !defined(ASSERT)
00117 #define ASSERT(E) (!(E) ? ErrFatalError(#E) : (int)0)
00118 #endif
00119
00120 #define ASSERT_WITH_MESSAGE(expr, msg) \
00121 (!(expr) ? ErrFatalError(msg) : (int)0)
00122
00123 #define VALIDATE(x, recover) if (!(x)) { ASSERT(x); recover; }
00124
00125 #define TRESPASS() if (1) { _debugPrintf("Should not be here at File: %s, Line: %d, Thread: %d\n",__FILE__,__LINE__,SysCurrentThread()); DEBUGGER("DO SOMETHING"); }
00126
00127 #define DEBUG_ONLY(arg) arg
00128
00129 #define EXEC_DEBUG_ACTION(action, data) \
00130 _exec_debug_action(actiom data)
00131
00132 #else
00133 #define SET_DEBUG_ENABLED(FLAG) (void)0
00134 #define IS_DEBUG_ENABLED() (void)0
00135
00136 #define SERIAL_PRINT(ARGS) (void)0
00137 #define PRINT(ARGS) (void)0
00138 #define PRINT_OBJECT(OBJ) (void)0
00139 #define TRACE() (void)0
00140 #define SERIAL_TRACE() (void)0
00141
00142 #define DEBUGGER(MSG) (void)0
00143 #if !defined(ASSERT)
00144 #define ASSERT(E) (void)0
00145 #endif
00146 #define ASSERT_WITH_MESSAGE(expr, msg) \
00147 (void)0
00148 #define VALIDATE(x, recover) if (!(x)) { recover; }
00149 #define TRESPASS() (void)0
00150 #define DEBUG_ONLY(x)
00151 #define EXEC_DEBUG_ACTION(action, data) \
00152 (void)0
00153 #endif
00154
00155
00156 #ifdef __cplusplus
00157
00158 template<bool> struct CompileTimeAssert;
00159 template<> struct CompileTimeAssert<true> {};
00160 #define STATIC_ASSERT(x) CompileTimeAssert< (x) >()
00161
00162 #else
00163
00164 #if !defined(__MWERKS__)
00165
00166
00167 #define STATIC_ASSERT(x) \
00168 do { \
00169 enum { __ASSERT_EXPRESSION__ = 2*(x) - 1 }; \
00170 struct __staticAssertStruct__ { \
00171 char __static_assert_failed__[__ASSERT_EXPRESSION__]; \
00172 }; \
00173 } while (false)
00174 #else
00175 #define STATIC_ASSERT(x)
00176
00177
00178 #endif
00179
00180 #endif
00181
00183
00184
00185
00186
00187 #ifdef __cplusplus
00188
00189 template<const char* ENVNAME, int DEFVAL, int MINVAL, int MAXVAL>
00190 class BDebugCondition
00191 {
00192 public:
00193 static inline int32_t Get() {
00194
00195 (void)ENVNAME;
00196 (void)DEFVAL;
00197 (void)MINVAL;
00198 (void)MAXVAL;
00199 if (m_hasLevel > 2) return m_level;
00200 return GetSlow();
00201 }
00202
00203 static int32_t GetSlow() {
00204 if (atomic_or(&m_hasLevel, 1) == 0) {
00205 #if TARGET_HOST == TARGET_HOST_PALMOS
00206 char envBuffer[128];
00207 const char* env = NULL;
00208 if (SysIsInstrumentationAllowed()) {
00209 if (HostGetPreference(ENVNAME, envBuffer)) env = envBuffer;
00210 }
00211 #else
00212 const char* env = getenv(ENVNAME);
00213 #endif
00214 if (env) {
00215 m_level = atoi(env);
00216 if (m_level < MINVAL) m_level = MINVAL;
00217 if (m_level > MAXVAL) m_level = MAXVAL;
00218 } else {
00219 m_level = DEFVAL;
00220 }
00221 atomic_or(&m_hasLevel, 2);
00222 if (m_level > 0)
00223 fprintf(stderr, "%s ENABLED! %s=%d\n", ENVNAME, ENVNAME, m_level);
00224 } else {
00225 while ((m_hasLevel&2) == 0)
00226 SysThreadDelay(B_MICROSECONDS(2), B_RELATIVE_TIMEOUT);
00227 }
00228 return m_level;
00229 }
00230
00231 private:
00232 static int32_t m_hasLevel;
00233 static int32_t m_level;
00234 };
00235
00236 template<const char* ENVNAME, int DEFVAL, int MINVAL, int MAXVAL>
00237 int32_t BDebugCondition<ENVNAME, DEFVAL, MINVAL, MAXVAL>::m_hasLevel = 0;
00238 template<const char* ENVNAME, int DEFVAL, int MINVAL, int MAXVAL>
00239 int32_t BDebugCondition<ENVNAME, DEFVAL, MINVAL, MAXVAL>::m_level = 0;
00240
00241 template<const char* ENVNAME, int DEFVAL, int MINVAL, int MAXVAL>
00242 class BDebugInteger
00243 {
00244 public:
00245 static inline int32_t Get() {
00246
00247 (void)ENVNAME;
00248 (void)DEFVAL;
00249 (void)MINVAL;
00250 (void)MAXVAL;
00251 if (m_hasLevel > 2) return m_level;
00252 return GetSlow();
00253 }
00254
00255 static int32_t GetSlow() {
00256 if (atomic_or(&m_hasLevel, 1) == 0) {
00257 #if TARGET_HOST == TARGET_HOST_PALMOS
00258 char envBuffer[128];
00259 const char* env = NULL;
00260 if (HostGetPreference(ENVNAME, envBuffer)) env = envBuffer;
00261 #else
00262 const char* env = getenv(ENVNAME);
00263 #endif
00264 if (env) {
00265 m_level = atoi(env);
00266 if (m_level < MINVAL) m_level = MINVAL;
00267 if (m_level > MAXVAL) m_level = MAXVAL;
00268 } else {
00269 m_level = DEFVAL;
00270 }
00271 atomic_or(&m_hasLevel, 2);
00272 if (env)
00273 fprintf(stderr, "Adjusting to %s to: %d\n", ENVNAME, m_level);
00274 } else {
00275 while ((m_hasLevel&2) == 0)
00276 SysThreadDelay(B_MICROSECONDS(2), B_RELATIVE_TIMEOUT);
00277 }
00278 return m_level;
00279 }
00280
00281 private:
00282 static int32_t m_hasLevel;
00283 static int32_t m_level;
00284 };
00285
00286 template<const char* ENVNAME, int DEFVAL, int MINVAL, int MAXVAL>
00287 int32_t BDebugInteger<ENVNAME, DEFVAL, MINVAL, MAXVAL>::m_hasLevel = 0;
00288 template<const char* ENVNAME, int DEFVAL, int MINVAL, int MAXVAL>
00289 int32_t BDebugInteger<ENVNAME, DEFVAL, MINVAL, MAXVAL>::m_level = 0;
00290
00291 template<class STATE>
00292 class BDebugState
00293 {
00294 public:
00295 static inline STATE* Get() {
00296
00297 if (m_hasState > 2) return m_state;
00298 return GetSlow();
00299 }
00300
00301 static STATE* GetSlow() {
00302 if (atomic_or(&m_hasState, 1) == 0) {
00303 m_state = new STATE;
00304 atomic_or(&m_hasState, 2);
00305 } else {
00306 while ((m_hasState&2) == 0)
00307 SysThreadDelay(B_MICROSECONDS(2), B_RELATIVE_TIMEOUT);
00308 }
00309 return m_state;
00310 }
00311
00312 ~BDebugState()
00313 {
00314 if ((atomic_or(&m_hasState, 4)&4) == 0) {
00315 delete m_state;
00316 }
00317 }
00318
00319 private:
00320 static int32_t m_hasState;
00321 static STATE* m_state;
00322 };
00323
00324 template<class STATE> int32_t BDebugState<STATE>::m_hasState = 0;
00325 template<class STATE> STATE* BDebugState<STATE>::m_state = NULL;
00326
00327 #endif
00328
00329
00330
00331
00334 #endif