2 * Debugging functions for WINE
5 #include <wine/debugtools.h>
7 DECLARE_DEBUG_CHANNEL(tid);
9 /* ---------------------------------------------------------------------- */
13 char *str_pos; /* current position in strings buffer */
14 char *out_pos; /* current position in output buffer */
15 char strings[1024]; /* buffer for temporary strings */
16 char output[1024]; /* current output line */
19 static struct debug_info tmp;
21 /* get the debug info pointer for the current thread */
22 static inline struct debug_info *get_info(void)
24 struct debug_info *info = NtCurrentTeb()->WineDebugInfo;
29 tmp.str_pos = tmp.strings;
30 tmp.out_pos = tmp.output;
32 if (!RtlGetProcessHeap()) return &tmp;
33 /* setup the temp structure in case HeapAlloc wants to print something */
34 NtCurrentTeb()->WineDebugInfo = &tmp;
35 info = RtlAllocateHeap( RtlGetProcessHeap(), 0, sizeof(*info) );
36 info->str_pos = info->strings;
37 info->out_pos = info->output;
38 NtCurrentTeb()->WineDebugInfo = info;
43 /* allocate some tmp space for a string */
44 static void *gimme1(int n)
46 struct debug_info *info = get_info();
47 char *res = info->str_pos;
49 if (res + n >= &info->strings[sizeof(info->strings)]) res = info->strings;
50 info->str_pos = res + n;
54 /* release extra space that we requested in gimme1() */
55 static inline void release( void *ptr )
57 struct debug_info *info = NtCurrentTeb()->WineDebugInfo;
61 /***********************************************************************
62 * wine_dbgstr_an (NTDLL.@)
64 const char *wine_dbgstr_an( const char *src, int n )
68 if (!((WORD)(DWORD)(src) >> 16))
70 if (!src) return "(null)";
72 sprintf(res, "#%04x", (WORD)(DWORD)(src) );
76 else if (n > 200) n = 200;
77 dst = res = gimme1 (n * 4 + 6);
79 while (n-- > 0 && *src)
81 unsigned char c = *src++;
84 case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
85 case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
86 case '\t': *dst++ = '\\'; *dst++ = 't'; break;
87 case '"': *dst++ = '\\'; *dst++ = '"'; break;
88 case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
90 if (c >= ' ' && c <= 126)
95 *dst++ = '0' + ((c >> 6) & 7);
96 *dst++ = '0' + ((c >> 3) & 7);
97 *dst++ = '0' + ((c >> 0) & 7);
113 /***********************************************************************
114 * wine_dbgstr_wn (NTDLL.@)
116 const char *wine_dbgstr_wn( const WCHAR *src, int n )
120 if (!((WORD)(DWORD)(src) >> 16))
122 if (!src) return "(null)";
124 sprintf(res, "#%04x", (WORD)(DWORD)(src) );
128 else if (n > 200) n = 200;
129 dst = res = gimme1 (n * 5 + 7);
132 while (n-- > 0 && *src)
137 case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
138 case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
139 case '\t': *dst++ = '\\'; *dst++ = 't'; break;
140 case '"': *dst++ = '\\'; *dst++ = '"'; break;
141 case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
143 if (c >= ' ' && c <= 126)
148 sprintf(dst,"%04x",c);
165 /***********************************************************************
166 * wine_dbgstr_guid (NTDLL.@)
168 const char *wine_dbgstr_guid( const GUID *id )
172 if (!id) return "(null)";
173 if (!((WORD)(DWORD)(id) >> 16))
176 sprintf( str, "<guid-0x%04x>", (WORD)(DWORD)(id) );
181 sprintf( str, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
182 id->Data1, id->Data2, id->Data3,
183 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
184 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
189 /***********************************************************************
190 * wine_dbg_vprintf (NTDLL.@)
192 int wine_dbg_vprintf( const char *format, va_list args )
194 struct debug_info *info = get_info();
197 int ret = _vsnprintf( info->out_pos, sizeof(info->output) - (info->out_pos - info->output),
200 p = strrchr( info->out_pos, '\n' );
201 if (!p) info->out_pos += ret;
204 char *pos = info->output;
211 /* move beginning of next line to start of buffer */
212 while ((*pos = *p++)) pos++;
218 /***********************************************************************
219 * wine_dbg_printf (NTDLL.@)
221 int wine_dbg_printf(const char *format, ...)
226 va_start(valist, format);
227 ret = wine_dbg_vprintf( format, valist );
232 /***********************************************************************
233 * wine_dbg_log (NTDLL.@)
235 int wine_dbg_log(enum __DEBUG_CLASS cls, const char *channel,
236 const char *function, const char *format, ... )
238 static const char *classes[__DBCL_COUNT] = { "fixme", "err", "warn", "trace" };
242 va_start(valist, format);
244 ret = wine_dbg_printf( "%08lx:", NtCurrentTeb()->Cid.UniqueThread);
245 if (cls < __DBCL_COUNT)
246 ret += wine_dbg_printf( "%s:%s:%s ", classes[cls], channel + 1, function );
248 ret += wine_dbg_vprintf( format, valist );