8 #include "debugtools.h"
11 /* ---------------------------------------------------------------------- */
13 #define SAVE_STRING_COUNT 50
14 static void *strings[SAVE_STRING_COUNT];
15 static int nextstring;
17 /* ---------------------------------------------------------------------- */
23 if (strings[nextstring]) free (strings[nextstring]);
24 res = strings[nextstring] = xmalloc (n);
25 if (++nextstring == SAVE_STRING_COUNT) nextstring = 0;
29 /* ---------------------------------------------------------------------- */
32 debugstr_an (LPCSTR src, int n)
36 if (!src) return "(null)";
38 dst = res = gimme1 (n * 4 + 10);
40 while (n-- > 0 && *src)
45 case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
46 case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
47 case '\t': *dst++ = '\\'; *dst++ = 't'; break;
48 case '"': *dst++ = '\\'; *dst++ = '"'; break;
49 case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
51 if (c >= ' ' && c <= 126)
56 *dst++ = '0' + ((c >> 6) & 7);
57 *dst++ = '0' + ((c >> 3) & 7);
58 *dst++ = '0' + ((c >> 0) & 7);
73 /* ---------------------------------------------------------------------- */
78 return debugstr_an (s, 80);
81 /* ---------------------------------------------------------------------- */
84 debugstr_wn (LPCWSTR src, int n)
88 if (!src) return "(null)";
90 dst = res = gimme1 (n * 4 + 10);
92 while (n-- > 0 && *src)
97 case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
98 case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
99 case '\t': *dst++ = '\\'; *dst++ = 't'; break;
100 case '"': *dst++ = '\\'; *dst++ = '"'; break;
101 case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
103 if (c >= ' ' && c <= 126)
108 *dst++ = '0' + ((c >> 6) & 7);
109 *dst++ = '0' + ((c >> 3) & 7);
110 *dst++ = '0' + ((c >> 0) & 7);
125 /* ---------------------------------------------------------------------- */
128 debugstr_w (LPCWSTR s)
130 return debugstr_wn (s, 80);
133 /* ---------------------------------------------------------------------- */
134 /* This routine returns a nicely formated name of the resource res
135 If the resource name is a string, it will return '<res-name>'
136 If it is a number, it will return #<4-digit-hex-number> */
137 LPSTR debugres_a( LPCSTR res )
140 if (HIWORD(res)) return debugstr_a(res);
141 sprintf(resname, "#%04x", LOWORD(res));
142 return debugstr_a (resname);
145 LPSTR debugres_w( LPCWSTR res )
148 if (HIWORD(res)) return debugstr_w(res);
149 sprintf(resname, "#%04x", LOWORD(res));
150 return debugstr_a (resname);
153 /* ---------------------------------------------------------------------- */
155 void debug_dumpstr (LPCSTR s)
164 fputc ('\\', stderr);
168 fputc ('\\', stderr);
172 fputc ('\\', stderr);
176 fputc ('\\', stderr);
181 fprintf (stderr, "\\0x%02x", *s);
190 /* ---------------------------------------------------------------------- */
192 int dbg_printf(const char *format, ...)
197 va_start(valist, format);
198 ret = vfprintf(stderr, format, valist);
205 /*--< Function >---------------------------------------------------------
210 ** This function creates a hex dump, with a readable ascii
211 ** section, for displaying memory.
214 ** 1. ptr Pointer to memory
215 ** 2. len How much to dump.
218 ** Temporarily allocated buffer, with the hex dump in it.
219 ** Don't rely on this pointer being around for very long, just
220 ** long enough to use it in a TRACE statement; e.g.:
221 ** TRACE("struct dump is \n%s", debugstr_hex_dump(&x, sizeof(x)));
223 **-------------------------------------------------------------------------*/
225 debugstr_hex_dump (const void *ptr, int len)
237 /* Begin function dbg_hex_dump */
239 /*-----------------------------------------------------------------------
240 ** Allocate an output buffer
241 ** A reasonable value is one line overhand (80 chars), and
242 ** then one line (80) for every 16 bytes.
243 **---------------------------------------------------------------------*/
244 outptr = dst = gimme1 ((len * (80 / 16)) + 80);
246 /*-----------------------------------------------------------------------
247 ** Loop throught the input buffer, one character at a time
248 **---------------------------------------------------------------------*/
249 for (i = 0, p = ptr; (i < len); i++, p++)
252 /*-------------------------------------------------------------------
253 ** If we're just starting a line,
254 ** we need to possibly flush the old line, and then
255 ** intialize the line buffer.
256 **-----------------------------------------------------------------*/
261 sprintf(outptr, " %-43.43s %-16.16s\n", dumpbuf, charbuf);
262 outptr += strlen(outptr);
264 sprintf (dumpbuf, "%04x: ", i);
265 strcpy (charbuf, "");
268 /*-------------------------------------------------------------------
269 ** Add the current data byte to the dump section.
270 **-----------------------------------------------------------------*/
271 nosign = (unsigned char) *p;
272 sprintf (tempbuf, "%02X", nosign);
274 /*-------------------------------------------------------------------
275 ** If we're two DWORDS through, add a hyphen for readability,
276 ** if it's a DWORD boundary, add a space for more
278 **-----------------------------------------------------------------*/
280 strcat(tempbuf, " - ");
281 else if ( (i % 4) == 3)
282 strcat(tempbuf, " ");
283 strcat (dumpbuf, tempbuf);
285 /*-------------------------------------------------------------------
286 ** Add the current byte to the character display part of the
288 **-----------------------------------------------------------------*/
289 sprintf (tempbuf, "%c", isprint(*p) ? *p : '.');
290 strcat (charbuf, tempbuf);
293 /*-----------------------------------------------------------------------
294 ** Flush the last line, if any
295 **---------------------------------------------------------------------*/
298 sprintf(outptr, " %-43.43s %-16.16s\n", dumpbuf, charbuf);
299 outptr += strlen(outptr);
303 } /* End function dbg_hex_dump */