7 #include "debugtools.h"
13 /* ---------------------------------------------------------------------- */
17 char *str_pos
; /* current position in strings buffer */
18 char *out_pos
; /* current position in output buffer */
19 char strings
[500]; /* buffer for temporary strings */
20 char output
[500]; /* current output line */
23 static struct debug_info tmp
;
25 static inline struct debug_info
*get_info(void)
27 struct debug_info
*info
= NtCurrentTeb()->debug_info
;
30 /* setup the temp structure in case HeapAlloc wants to print something */
31 NtCurrentTeb()->debug_info
= &tmp
;
32 tmp
.str_pos
= tmp
.strings
;
33 tmp
.out_pos
= tmp
.output
;
34 info
= HeapAlloc( GetProcessHeap(), 0, sizeof(*info
) );
35 info
->str_pos
= info
->strings
;
36 info
->out_pos
= info
->output
;
37 NtCurrentTeb()->debug_info
= info
;
42 /* ---------------------------------------------------------------------- */
47 struct debug_info
*info
= get_info();
48 char *res
= info
->str_pos
;
50 if (res
+ n
>= &info
->strings
[sizeof(info
->strings
)]) res
= info
->strings
;
51 info
->str_pos
= res
+ n
;
55 /* ---------------------------------------------------------------------- */
57 /* release extra space that we requested in gimme1() */
58 static inline void release( void *ptr
)
60 struct debug_info
*info
= NtCurrentTeb()->debug_info
;
64 /* ---------------------------------------------------------------------- */
66 LPCSTR
debugstr_an (LPCSTR src
, int n
)
70 if (!src
) return "(null)";
72 dst
= res
= gimme1 (n
* 4 + 6);
74 while (n
-- > 0 && *src
)
79 case '\n': *dst
++ = '\\'; *dst
++ = 'n'; break;
80 case '\r': *dst
++ = '\\'; *dst
++ = 'r'; break;
81 case '\t': *dst
++ = '\\'; *dst
++ = 't'; break;
82 case '"': *dst
++ = '\\'; *dst
++ = '"'; break;
83 case '\\': *dst
++ = '\\'; *dst
++ = '\\'; break;
85 if (c
>= ' ' && c
<= 126)
90 *dst
++ = '0' + ((c
>> 6) & 7);
91 *dst
++ = '0' + ((c
>> 3) & 7);
92 *dst
++ = '0' + ((c
>> 0) & 7);
108 /* ---------------------------------------------------------------------- */
110 LPCSTR
debugstr_wn (LPCWSTR src
, int n
)
114 if (!src
) return "(null)";
116 dst
= res
= gimme1 (n
* 5 + 7);
119 while (n
-- > 0 && *src
)
124 case '\n': *dst
++ = '\\'; *dst
++ = 'n'; break;
125 case '\r': *dst
++ = '\\'; *dst
++ = 'r'; break;
126 case '\t': *dst
++ = '\\'; *dst
++ = 't'; break;
127 case '"': *dst
++ = '\\'; *dst
++ = '"'; break;
128 case '\\': *dst
++ = '\\'; *dst
++ = '\\'; break;
130 if (c
>= ' ' && c
<= 126)
135 sprintf(dst
,"%04x",c
);
152 /* ---------------------------------------------------------------------- */
153 /* This routine returns a nicely formated name of the resource res
154 If the resource name is a string, it will return '<res-name>'
155 If it is a number, it will return #<4-digit-hex-number> */
156 LPCSTR
debugres_a( LPCSTR res
)
159 if (HIWORD(res
)) return debugstr_a(res
);
161 sprintf(resname
, "#%04x", LOWORD(res
) );
165 LPCSTR
debugres_w( LPCWSTR res
)
168 if (HIWORD(res
)) return debugstr_w(res
);
170 sprintf( resname
, "#%04x", LOWORD(res
) );
174 /* ---------------------------------------------------------------------- */
176 LPCSTR
debugstr_guid( const GUID
*id
)
180 if (!id
) return "(null)";
184 sprintf( str
, "<guid-0x%04x>", LOWORD(id
) );
189 sprintf( str
, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
190 id
->Data1
, id
->Data2
, id
->Data3
,
191 id
->Data4
[0], id
->Data4
[1], id
->Data4
[2], id
->Data4
[3],
192 id
->Data4
[4], id
->Data4
[5], id
->Data4
[6], id
->Data4
[7] );
197 /* ---------------------------------------------------------------------- */
199 int dbg_vprintf( const char *format
, va_list args
)
201 struct debug_info
*info
= get_info();
203 int ret
= vsprintf( info
->out_pos
, format
, args
);
204 char *p
= strrchr( info
->out_pos
, '\n' );
205 if (!p
) info
->out_pos
+= ret
;
208 char *pos
= info
->output
;
210 write( 2, pos
, p
- pos
);
211 /* move beginning of next line to start of buffer */
212 while ((*pos
= *p
++)) pos
++;
218 /* ---------------------------------------------------------------------- */
220 int dbg_printf(const char *format
, ...)
225 va_start(valist
, format
);
226 ret
= dbg_vprintf( format
, valist
);
232 /*--< Function >---------------------------------------------------------
237 ** This function creates a hex dump, with a readable ascii
238 ** section, for displaying memory.
241 ** 1. ptr Pointer to memory
242 ** 2. len How much to dump.
245 ** Temporarily allocated buffer, with the hex dump in it.
246 ** Don't rely on this pointer being around for very long, just
247 ** long enough to use it in a TRACE statement; e.g.:
248 ** TRACE("struct dump is \n%s", debugstr_hex_dump(&x, sizeof(x)));
250 **-------------------------------------------------------------------------*/
251 LPCSTR
debugstr_hex_dump (const void *ptr
, int len
)
263 /* Begin function dbg_hex_dump */
265 /*-----------------------------------------------------------------------
266 ** Allocate an output buffer
267 ** A reasonable value is one line overhand (80 chars), and
268 ** then one line (80) for every 16 bytes.
269 **---------------------------------------------------------------------*/
270 outptr
= dst
= gimme1 ((len
* (80 / 16)) + 80);
272 /*-----------------------------------------------------------------------
273 ** Loop throught the input buffer, one character at a time
274 **---------------------------------------------------------------------*/
275 for (i
= 0, p
= ptr
; (i
< len
); i
++, p
++)
278 /*-------------------------------------------------------------------
279 ** If we're just starting a line,
280 ** we need to possibly flush the old line, and then
281 ** intialize the line buffer.
282 **-----------------------------------------------------------------*/
287 sprintf(outptr
, " %-43.43s %-16.16s\n", dumpbuf
, charbuf
);
288 outptr
+= strlen(outptr
);
290 sprintf (dumpbuf
, "%04x: ", i
);
291 strcpy (charbuf
, "");
294 /*-------------------------------------------------------------------
295 ** Add the current data byte to the dump section.
296 **-----------------------------------------------------------------*/
297 nosign
= (unsigned char) *p
;
298 sprintf (tempbuf
, "%02X", nosign
);
300 /*-------------------------------------------------------------------
301 ** If we're two DWORDS through, add a hyphen for readability,
302 ** if it's a DWORD boundary, add a space for more
304 **-----------------------------------------------------------------*/
306 strcat(tempbuf
, " - ");
307 else if ( (i
% 4) == 3)
308 strcat(tempbuf
, " ");
309 strcat (dumpbuf
, tempbuf
);
311 /*-------------------------------------------------------------------
312 ** Add the current byte to the character display part of the
314 **-----------------------------------------------------------------*/
315 sprintf (tempbuf
, "%c", isprint(*p
) ? *p
: '.');
316 strcat (charbuf
, tempbuf
);
319 /*-----------------------------------------------------------------------
320 ** Flush the last line, if any
321 **---------------------------------------------------------------------*/
324 sprintf(outptr
, " %-43.43s %-16.16s\n", dumpbuf
, charbuf
);
325 outptr
+= strlen(outptr
);
329 } /* End function dbg_hex_dump */