Reactos
at listview 421 lines 16 kB view raw
1/* 2 * Wine debugging interface 3 * 4 * Copyright 1999 Patrik Stridvall 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21#ifndef __WINE_DEBUG_H 22#define __WINE_DEBUG_H 23 24#include <stdarg.h> 25#include <stdio.h> 26#include <windef.h> 27#ifndef GUID_DEFINED 28#include <guiddef.h> 29#endif 30 31#ifndef __RELFILE__ 32#define __RELFILE__ __FILE__ 33#endif 34 35#ifdef __WINE_WINE_TEST_H 36#error This file should not be used in Wine tests 37#endif 38 39#ifdef __cplusplus 40extern "C" { 41#endif 42 43struct _GUID; 44 45/* 46 * Internal definitions (do not use these directly) 47 */ 48 49enum __wine_debug_class 50{ 51 __WINE_DBCL_FIXME = 0, /* 0x1 */ 52 __WINE_DBCL_ERR = 1, /* 0x2 */ 53 __WINE_DBCL_WARN = 2, /* 0x4 */ 54 __WINE_DBCL_TRACE = 3, /* 0x8 */ 55 56 /* lazy init flag */ 57 __WINE_DBCL_INIT = 0x7 58}; 59 60struct __wine_debug_channel 61{ 62 unsigned char flags; 63 char name[15]; 64}; 65 66#define UNIMPLEMENTED WINE_FIXME("%s is UNIMPLEMENTED!\n", __FUNCTION__) 67 68#ifndef WINE_NO_TRACE_MSGS 69# define __WINE_GET_DEBUGGING_TRACE(dbch) ((dbch)->flags & (1 << __WINE_DBCL_TRACE)) 70#else 71# define __WINE_GET_DEBUGGING_TRACE(dbch) 0 72#endif 73 74#ifndef WINE_NO_DEBUG_MSGS 75# define __WINE_GET_DEBUGGING_WARN(dbch) ((dbch)->flags & (1 << __WINE_DBCL_WARN)) 76# define __WINE_GET_DEBUGGING_FIXME(dbch) ((dbch)->flags & (1 << __WINE_DBCL_FIXME)) 77#else 78# define __WINE_GET_DEBUGGING_WARN(dbch) 0 79# define __WINE_GET_DEBUGGING_FIXME(dbch) 0 80#endif 81 82/* define error macro regardless of what is configured */ 83#define __WINE_GET_DEBUGGING_ERR(dbch) ((dbch)->flags & (1 << __WINE_DBCL_ERR)) 84 85#define __WINE_GET_DEBUGGING(dbcl,dbch) __WINE_GET_DEBUGGING##dbcl(dbch) 86 87#define __WINE_IS_DEBUG_ON(dbcl,dbch) \ 88 (__WINE_GET_DEBUGGING##dbcl(dbch) && (__wine_dbg_get_channel_flags(dbch) & (1 << __WINE_DBCL##dbcl))) 89 90#ifdef __GNUC__ 91 92#define __WINE_DPRINTF(dbcl,dbch) \ 93 do { if(__WINE_GET_DEBUGGING(dbcl,(dbch))) { \ 94 struct __wine_debug_channel * const __dbch = (dbch); \ 95 const enum __wine_debug_class __dbcl = __WINE_DBCL##dbcl; \ 96 __WINE_DBG_LOG 97 98#define __WINE_DBG_LOG(args...) \ 99 ros_dbg_log( __dbcl, __dbch, __RELFILE__, __FUNCTION__, __LINE__, args); } } while(0) 100 101#define __WINE_PRINTF_ATTR(fmt,args) /*__attribute__((format (printf,fmt,args)))*/ 102 103 104#ifdef WINE_NO_TRACE_MSGS 105#define WINE_TRACE(args...) do { } while(0) 106#define WINE_TRACE_(ch) WINE_TRACE 107#endif 108 109#ifdef WINE_NO_DEBUG_MSGS 110#define WINE_WARN(args...) do { } while(0) 111#define WINE_WARN_(ch) WINE_WARN 112#define WINE_FIXME(args...) do { } while(0) 113#define WINE_FIXME_(ch) WINE_FIXME 114#endif 115 116#elif defined(__SUNPRO_C) 117 118#define __WINE_DPRINTF(dbcl,dbch) \ 119 do { if(__WINE_GET_DEBUGGING(dbcl,(dbch))) { \ 120 struct __wine_debug_channel * const __dbch = (dbch); \ 121 const enum __WINE_DEBUG_CLASS __dbcl = __WINE_DBCL##dbcl; \ 122 __WINE_DBG_LOG 123 124#define __WINE_DBG_LOG(...) \ 125 wine_dbg_log( __dbcl, __dbch, __func__, __VA_ARGS__); } } while(0) 126 127#define __WINE_PRINTF_ATTR(fmt,args) 128 129#ifdef WINE_NO_TRACE_MSGS 130#define WINE_TRACE(...) do { } while(0) 131#define WINE_TRACE_(ch) WINE_TRACE 132#endif 133 134#ifdef WINE_NO_DEBUG_MSGS 135#define WINE_WARN(...) do { } while(0) 136#define WINE_WARN_(ch) WINE_WARN 137#define WINE_FIXME(...) do { } while(0) 138#define WINE_FIXME_(ch) WINE_FIXME 139#endif 140 141#else /* !__GNUC__ && !__SUNPRO_C */ 142 143#define __WINE_DPRINTF(dbcl,dbch) \ 144 (!__WINE_GET_DEBUGGING(dbcl,(dbch)) || \ 145 (ros_dbg_log(__WINE_DBCL##dbcl,(dbch),__RELFILE__,__FUNCTION__,__LINE__,"") == -1)) ? \ 146 (void)0 : (void)wine_dbg_printf 147 148#define __WINE_PRINTF_ATTR(fmt, args) 149 150#endif /* !__GNUC__ && !__SUNPRO_C */ 151 152struct __wine_debug_functions 153{ 154 char * (*get_temp_buffer)( size_t n ); 155 void (*release_temp_buffer)( char *buffer, size_t n ); 156 const char * (*dbgstr_an)( const char * s, int n ); 157 const char * (*dbgstr_wn)( const WCHAR *s, int n ); 158 int (*dbg_vprintf)( const char *format, va_list args ); 159 int (*dbg_vlog)( enum __wine_debug_class cls, struct __wine_debug_channel *channel, 160 const char *file, const char *function, const int line, const char *format, va_list args ); 161}; 162 163extern unsigned char __wine_dbg_get_channel_flags( struct __wine_debug_channel *channel ); 164extern int __wine_dbg_set_channel_flags( struct __wine_debug_channel *channel, 165 unsigned char set, unsigned char clear ); 166extern void __wine_dbg_set_functions( const struct __wine_debug_functions *new_funcs, 167 struct __wine_debug_functions *old_funcs, size_t size ); 168 169/* 170 * Exported definitions and macros 171 */ 172 173/* These functions return a printable version of a string, including 174 quotes. The string will be valid for some time, but not indefinitely 175 as strings are re-used. */ 176extern const char *wine_dbgstr_an( const char * s, int n ); 177extern const char *wine_dbgstr_wn( const WCHAR *s, int n ); 178extern const char *wine_dbg_sprintf( const char *format, ... ) __WINE_PRINTF_ATTR(1,2); 179 180extern int wine_dbg_printf( const char *format, ... ) __WINE_PRINTF_ATTR(1,2); 181extern int wine_dbg_log( enum __wine_debug_class cls, struct __wine_debug_channel *ch, const char *func, 182 const char *format, ... ) __WINE_PRINTF_ATTR(4,5); 183/* ReactOS compliant debug format */ 184extern int ros_dbg_log( enum __wine_debug_class cls, struct __wine_debug_channel *ch, const char *file, 185 const char *func, const int line, const char *format, ... ) __WINE_PRINTF_ATTR(6,7); 186 187static __inline const char *wine_dbgstr_a( const char *s ) 188{ 189 return wine_dbgstr_an( s, -1 ); 190} 191 192static __inline const char *wine_dbgstr_w( const WCHAR *s ) 193{ 194 return wine_dbgstr_wn( s, -1 ); 195} 196 197static __inline const char *wine_dbgstr_guid( const GUID *id ) 198{ 199 if (!id) return "(null)"; 200 if (!((ULONG_PTR)id >> 16)) return wine_dbg_sprintf( "<guid-0x%04lx>", (ULONG_PTR)id & 0xffff ); 201 return wine_dbg_sprintf( "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", 202 id->Data1, id->Data2, id->Data3, 203 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3], 204 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] ); 205} 206 207static __inline const char *wine_dbgstr_point( const POINT *pt ) 208{ 209 if (!pt) return "(null)"; 210 return wine_dbg_sprintf( "(%ld,%ld)", pt->x, pt->y ); 211} 212 213static __inline const char *wine_dbgstr_size( const SIZE *size ) 214{ 215 if (!size) return "(null)"; 216 return wine_dbg_sprintf( "(%ld,%ld)", size->cx, size->cy ); 217} 218 219static __inline const char *wine_dbgstr_rect( const RECT *rect ) 220{ 221 if (!rect) return "(null)"; 222 return wine_dbg_sprintf( "(%ld,%ld)-(%ld,%ld)", rect->left, rect->top, 223 rect->right, rect->bottom ); 224} 225 226static __inline const char *wine_dbgstr_longlong( ULONGLONG ll ) 227{ 228 if (/*sizeof(ll) > sizeof(unsigned long) &&*/ ll >> 32) /* ULONGLONG is always > long in ReactOS */ 229 return wine_dbg_sprintf( "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll ); 230 else return wine_dbg_sprintf( "%lx", (unsigned long)ll ); 231} 232 233#if defined(__oaidl_h__) && defined(V_VT) 234 235static inline const char *wine_dbgstr_vt( VARTYPE vt ) 236{ 237 static const char *const variant_types[] = 238 { 239 "VT_EMPTY","VT_NULL","VT_I2","VT_I4","VT_R4","VT_R8","VT_CY","VT_DATE", 240 "VT_BSTR","VT_DISPATCH","VT_ERROR","VT_BOOL","VT_VARIANT","VT_UNKNOWN", 241 "VT_DECIMAL","15","VT_I1","VT_UI1","VT_UI2","VT_UI4","VT_I8","VT_UI8", 242 "VT_INT","VT_UINT","VT_VOID","VT_HRESULT","VT_PTR","VT_SAFEARRAY", 243 "VT_CARRAY","VT_USERDEFINED","VT_LPSTR","VT_LPWSTR","32","33","34","35", 244 "VT_RECORD","VT_INT_PTR","VT_UINT_PTR","39","40","41","42","43","44","45", 245 "46","47","48","49","50","51","52","53","54","55","56","57","58","59","60", 246 "61","62","63","VT_FILETIME","VT_BLOB","VT_STREAM","VT_STORAGE", 247 "VT_STREAMED_OBJECT","VT_STORED_OBJECT","VT_BLOB_OBJECT","VT_CF","VT_CLSID", 248 "VT_VERSIONED_STREAM" 249 }; 250 251 static const char *const variant_flags[16] = 252 { 253 "", 254 "|VT_VECTOR", 255 "|VT_ARRAY", 256 "|VT_VECTOR|VT_ARRAY", 257 "|VT_BYREF", 258 "|VT_VECTOR|VT_BYREF", 259 "|VT_ARRAY|VT_BYREF", 260 "|VT_VECTOR|VT_ARRAY|VT_BYREF", 261 "|VT_RESERVED", 262 "|VT_VECTOR|VT_RESERVED", 263 "|VT_ARRAY|VT_RESERVED", 264 "|VT_VECTOR|VT_ARRAY|VT_RESERVED", 265 "|VT_BYREF|VT_RESERVED", 266 "|VT_VECTOR|VT_BYREF|VT_RESERVED", 267 "|VT_ARRAY|VT_BYREF|VT_RESERVED", 268 "|VT_VECTOR|VT_ARRAY|VT_BYREF|VT_RESERVED", 269 }; 270 271 if (vt & ~VT_TYPEMASK) 272 return wine_dbg_sprintf( "%s%s", wine_dbgstr_vt(vt&VT_TYPEMASK), variant_flags[vt>>12] ); 273 274 if (vt < sizeof(variant_types)/sizeof(*variant_types)) 275 return variant_types[vt]; 276 277 if (vt == VT_BSTR_BLOB) 278 return "VT_BSTR_BLOB"; 279 280 return wine_dbg_sprintf( "vt(invalid %x)", vt ); 281} 282 283static inline const char *wine_dbgstr_variant( const VARIANT *v ) 284{ 285 if (!v) 286 return "(null)"; 287 288 if (V_VT(v) & VT_BYREF) { 289 if (V_VT(v) == (VT_VARIANT|VT_BYREF)) 290 return wine_dbg_sprintf( "%p {VT_VARIANT|VT_BYREF: %s}", v, wine_dbgstr_variant(V_VARIANTREF(v)) ); 291 if (V_VT(v) == (VT_BSTR|VT_BYREF)) 292 return wine_dbg_sprintf( "%p {VT_BSTR|VT_BYREF: %s}", v, V_BSTRREF(v) ? wine_dbgstr_w(*V_BSTRREF(v)) : "(none)" ); 293 return wine_dbg_sprintf( "%p {%s %p}", v, wine_dbgstr_vt(V_VT(v)), V_BYREF(v) ); 294 } 295 296 if (V_ISARRAY(v) || V_ISVECTOR(v)) 297 return wine_dbg_sprintf( "%p {%s %p}", v, wine_dbgstr_vt(V_VT(v)), V_ARRAY(v) ); 298 299 switch(V_VT(v)) { 300 case VT_EMPTY: 301 return wine_dbg_sprintf( "%p {VT_EMPTY}", v ); 302 case VT_NULL: 303 return wine_dbg_sprintf( "%p {VT_NULL}", v ); 304 case VT_I2: 305 return wine_dbg_sprintf( "%p {VT_I2: %d}", v, V_I2(v) ); 306 case VT_I4: 307 return wine_dbg_sprintf( "%p {VT_I4: %d}", v, V_I4(v) ); 308 case VT_R4: 309 return wine_dbg_sprintf( "%p {VT_R4: %f}", v, V_R4(v) ); 310 case VT_R8: 311 return wine_dbg_sprintf( "%p {VT_R8: %lf}", v, V_R8(v) ); 312 case VT_CY: 313 return wine_dbg_sprintf( "%p {VT_CY: %s}", v, wine_dbgstr_longlong(V_CY(v).int64) ); 314 case VT_DATE: 315 return wine_dbg_sprintf( "%p {VT_DATE: %lf}", v, V_DATE(v) ); 316 case VT_BSTR: 317 return wine_dbg_sprintf( "%p {VT_BSTR: %s}", v, wine_dbgstr_w(V_BSTR(v)) ); 318 case VT_DISPATCH: 319 return wine_dbg_sprintf( "%p {VT_DISPATCH: %p}", v, V_DISPATCH(v) ); 320 case VT_ERROR: 321 return wine_dbg_sprintf( "%p {VT_ERROR: %08x}", v, V_ERROR(v) ); 322 case VT_BOOL: 323 return wine_dbg_sprintf( "%p {VT_BOOL: %x}", v, V_BOOL(v) ); 324 case VT_UNKNOWN: 325 return wine_dbg_sprintf( "%p {VT_UNKNOWN: %p}", v, V_UNKNOWN(v) ); 326 case VT_I1: 327 return wine_dbg_sprintf( "%p {VT_I1: %d}", v, V_I1(v) ); 328 case VT_UI1: 329 return wine_dbg_sprintf( "%p {VT_UI1: %u}", v, V_UI1(v) ); 330 case VT_UI2: 331 return wine_dbg_sprintf( "%p {VT_UI2: %d}", v, V_UI2(v) ); 332 case VT_UI4: 333 return wine_dbg_sprintf( "%p {VT_UI4: %d}", v, V_UI4(v) ); 334 case VT_I8: 335 return wine_dbg_sprintf( "%p {VT_I8: %s}", v, wine_dbgstr_longlong(V_I8(v)) ); 336 case VT_UI8: 337 return wine_dbg_sprintf( "%p {VT_UI8: %s}", v, wine_dbgstr_longlong(V_UI8(v)) ); 338 case VT_INT: 339 return wine_dbg_sprintf( "%p {VT_INT: %d}", v, V_INT(v) ); 340 case VT_UINT: 341 return wine_dbg_sprintf( "%p {VT_UINT: %u}", v, V_UINT(v) ); 342 case VT_VOID: 343 return wine_dbg_sprintf( "%p {VT_VOID}", v ); 344 case VT_RECORD: 345 return wine_dbg_sprintf( "%p {VT_RECORD: %p %p}", v, V_RECORD(v), V_RECORDINFO(v) ); 346 default: 347 return wine_dbg_sprintf( "%p {vt %s}", v, wine_dbgstr_vt(V_VT(v)) ); 348 } 349} 350 351#endif /* defined(__oaidl_h__) && defined(V_VT) */ 352 353#ifndef WINE_TRACE 354#define WINE_TRACE __WINE_DPRINTF(_TRACE,__wine_dbch___default) 355#define WINE_TRACE_(ch) __WINE_DPRINTF(_TRACE,&__wine_dbch_##ch) 356#endif 357#define WINE_TRACE_ON(ch) __WINE_IS_DEBUG_ON(_TRACE,&__wine_dbch_##ch) 358 359#ifndef WINE_WARN 360#define WINE_WARN __WINE_DPRINTF(_WARN,__wine_dbch___default) 361#define WINE_WARN_(ch) __WINE_DPRINTF(_WARN,&__wine_dbch_##ch) 362#endif 363#define WINE_WARN_ON(ch) __WINE_IS_DEBUG_ON(_WARN,&__wine_dbch_##ch) 364 365#ifndef WINE_FIXME 366#define WINE_FIXME __WINE_DPRINTF(_FIXME,__wine_dbch___default) 367#define WINE_FIXME_(ch) __WINE_DPRINTF(_FIXME,&__wine_dbch_##ch) 368#endif 369#define WINE_FIXME_ON(ch) __WINE_IS_DEBUG_ON(_FIXME,&__wine_dbch_##ch) 370 371#define WINE_ERR __WINE_DPRINTF(_ERR,__wine_dbch___default) 372#define WINE_ERR_(ch) __WINE_DPRINTF(_ERR,&__wine_dbch_##ch) 373#define WINE_ERR_ON(ch) __WINE_IS_DEBUG_ON(_ERR,&__wine_dbch_##ch) 374 375#define WINE_DECLARE_DEBUG_CHANNEL(ch) \ 376 static struct __wine_debug_channel __wine_dbch_##ch = { (unsigned char)~0, #ch } 377#define WINE_DEFAULT_DEBUG_CHANNEL(ch) \ 378 static struct __wine_debug_channel __wine_dbch_##ch = { (unsigned char)~0, #ch }; \ 379 static struct __wine_debug_channel * const __wine_dbch___default = &__wine_dbch_##ch 380 381#define WINE_DPRINTF wine_dbg_printf 382#define WINE_MESSAGE wine_dbg_printf 383 384/* Wine uses shorter names that are very likely to conflict with other software */ 385 386static __inline const char *debugstr_an( const char * s, int n ) { return wine_dbgstr_an( s, n ); } 387static __inline const char *debugstr_wn( const WCHAR *s, int n ) { return wine_dbgstr_wn( s, n ); } 388static __inline const char *debugstr_guid( const struct _GUID *id ) { return wine_dbgstr_guid(id); } 389static __inline const char *debugstr_a( const char *s ) { return wine_dbgstr_an( s, -1 ); } 390static __inline const char *debugstr_w( const WCHAR *s ) { return wine_dbgstr_wn( s, -1 ); } 391 392#if defined(__oaidl_h__) && defined(V_VT) 393static __inline const char *debugstr_vt( VARTYPE vt ) { return wine_dbgstr_vt( vt ); } 394static __inline const char *debugstr_variant( const VARIANT *v ) { return wine_dbgstr_variant( v ); } 395#endif 396 397#define TRACE WINE_TRACE 398#define TRACE_(ch) WINE_TRACE_(ch) 399#define TRACE_ON(ch) WINE_TRACE_ON(ch) 400 401#define WARN WINE_WARN 402#define WARN_(ch) WINE_WARN_(ch) 403#define WARN_ON(ch) WINE_WARN_ON(ch) 404 405#define FIXME WINE_FIXME 406#define FIXME_(ch) WINE_FIXME_(ch) 407#define FIXME_ON(ch) WINE_FIXME_ON(ch) 408 409#undef ERR /* Solaris got an 'ERR' define in <sys/reg.h> */ 410#define ERR WINE_ERR 411#define ERR_(ch) WINE_ERR_(ch) 412#define ERR_ON(ch) WINE_ERR_ON(ch) 413 414#define DPRINTF WINE_DPRINTF 415#define MESSAGE WINE_MESSAGE 416 417#ifdef __cplusplus 418} 419#endif 420 421#endif /* __WINE_DEBUG_H */