2 * Management of the debugging channels
4 * Copyright 2000 Alexandre Julliard
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <wine/config.h>
27 #include <wine/port.h>
28 #include <wine/debug.h>
30 /* ---------------------------------------------------------------------- */
32 static CRITICAL_SECTION WineDebugCS
;
33 static CRITICAL_SECTION_DEBUG critsect_debug
=
36 { &critsect_debug
.ProcessLocksList
, &critsect_debug
.ProcessLocksList
},
39 static CRITICAL_SECTION WineDebugCS
= { &critsect_debug
, -1, 0, 0, 0, 0 };
40 static DWORD WineDebugTlsIndex
= TLS_OUT_OF_INDEXES
;
42 /* ---------------------------------------------------------------------- */
46 char *str_pos
; /* current position in strings buffer */
47 char *out_pos
; /* current position in output buffer */
48 char strings
[1024]; /* buffer for temporary strings */
49 char output
[1024]; /* current output line */
52 static struct debug_info tmp
= { tmp
.strings
, tmp
.output
};
54 /* get the debug info pointer for the current thread */
55 static inline struct debug_info
*get_info(void)
57 struct debug_info
*info
;
59 if (WineDebugTlsIndex
== TLS_OUT_OF_INDEXES
)
61 EnterCriticalSection(&WineDebugCS
);
62 if (WineDebugTlsIndex
== TLS_OUT_OF_INDEXES
)
64 DWORD NewTlsIndex
= TlsAlloc();
65 if (NewTlsIndex
== TLS_OUT_OF_INDEXES
)
67 LeaveCriticalSection(&WineDebugCS
);
70 info
= HeapAlloc(GetProcessHeap(), 0, sizeof(*info
));
73 LeaveCriticalSection(&WineDebugCS
);
77 info
->str_pos
= info
->strings
;
78 info
->out_pos
= info
->output
;
79 TlsSetValue(NewTlsIndex
, info
);
80 WineDebugTlsIndex
= NewTlsIndex
;
82 LeaveCriticalSection(&WineDebugCS
);
85 return TlsGetValue(WineDebugTlsIndex
);
88 /* allocate some tmp space for a string */
89 static void *gimme1(int n
)
91 struct debug_info
*info
= get_info();
92 char *res
= info
->str_pos
;
94 if (res
+ n
>= &info
->strings
[sizeof(info
->strings
)]) res
= info
->strings
;
95 info
->str_pos
= res
+ n
;
99 /* release extra space that we requested in gimme1() */
100 static inline void release(void *ptr
)
102 struct debug_info
*info
;
103 if (WineDebugTlsIndex
== TLS_OUT_OF_INDEXES
)
106 info
= TlsGetValue(WineDebugTlsIndex
);
110 /***********************************************************************
113 const char *wine_dbgstr_an(const char *src
, int n
)
119 if (!src
) return "(null)";
121 sprintf(res
, "#%04x", (WORD
)(DWORD
)(src
) );
125 else if (n
> 200) n
= 200;
126 dst
= res
= gimme1 (n
* 4 + 6);
128 while (n
-- > 0 && *src
)
130 unsigned char c
= *src
++;
133 case '\n': *dst
++ = '\\'; *dst
++ = 'n'; break;
134 case '\r': *dst
++ = '\\'; *dst
++ = 'r'; break;
135 case '\t': *dst
++ = '\\'; *dst
++ = 't'; break;
136 case '"': *dst
++ = '\\'; *dst
++ = '"'; break;
137 case '\\': *dst
++ = '\\'; *dst
++ = '\\'; break;
139 if (c
>= ' ' && c
<= 126)
144 *dst
++ = '0' + ((c
>> 6) & 7);
145 *dst
++ = '0' + ((c
>> 3) & 7);
146 *dst
++ = '0' + ((c
>> 0) & 7);
162 /***********************************************************************
165 const char *wine_dbgstr_wn(const WCHAR
*src
, int n
)
171 if (!src
) return "(null)";
173 sprintf(res
, "#%04x", (WORD
)(DWORD
)(src
) );
177 else if (n
> 200) n
= 200;
178 dst
= res
= gimme1(n
* 5 + 7);
181 while (n
-- > 0 && *src
)
186 case '\n': *dst
++ = '\\'; *dst
++ = 'n'; break;
187 case '\r': *dst
++ = '\\'; *dst
++ = 'r'; break;
188 case '\t': *dst
++ = '\\'; *dst
++ = 't'; break;
189 case '"': *dst
++ = '\\'; *dst
++ = '"'; break;
190 case '\\': *dst
++ = '\\'; *dst
++ = '\\'; break;
192 if (c
>= ' ' && c
<= 126)
197 sprintf(dst
,"%04x",c
);
214 /***********************************************************************
217 const char *wine_dbgstr_guid(const GUID
*id
)
221 if (!id
) return "(null)";
224 sprintf(str
, "<guid-0x%04x>", (WORD
)(DWORD
)(id
));
227 sprintf(str
, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
228 id
->Data1
, id
->Data2
, id
->Data3
,
229 id
->Data4
[0], id
->Data4
[1], id
->Data4
[2], id
->Data4
[3],
230 id
->Data4
[4], id
->Data4
[5], id
->Data4
[6], id
->Data4
[7]);
235 const char *wine_dbgstr_longlong( unsigned long long ll
)
237 if (ll
>> 32) return wine_dbg_sprintf( "%lx%08lx", (unsigned long)(ll
>> 32), (unsigned long)ll
);
238 else return wine_dbg_sprintf( "%lx", (unsigned long)ll
);
241 /* varargs wrapper for __wine_dbg_vsprintf */
242 const char *wine_dbg_sprintf( const char *format
, ... )
244 char* buffer
= gimme1(1024);
247 va_start(ap
, format
);
248 release(buffer
+vsnprintf(buffer
, 1024, format
, ap
));
254 const char *wine_dbgstr_w( const WCHAR
*s
)
256 return wine_dbgstr_wn( s
, -1 );