Got rid of PROFILE_ functions, now accessing Wine config options
[wine.git] / misc / debugstr.c
blob242d0f385b9deb19e6cb3754549cb7401b9b03d4
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <ctype.h>
7 #include "debugtools.h"
8 #include "wtypes.h"
9 #include "thread.h"
11 /* ---------------------------------------------------------------------- */
13 struct debug_info
15 char *str_pos; /* current position in strings buffer */
16 char *out_pos; /* current position in output buffer */
17 char strings[500]; /* buffer for temporary strings */
18 char output[500]; /* current output line */
21 static struct debug_info tmp;
23 static inline struct debug_info *get_info(void)
25 struct debug_info *info = NtCurrentTeb()->debug_info;
26 if (!info)
28 /* setup the temp structure in case HeapAlloc wants to print something */
29 NtCurrentTeb()->debug_info = &tmp;
30 tmp.str_pos = tmp.strings;
31 tmp.out_pos = tmp.output;
32 info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info) );
33 info->str_pos = info->strings;
34 info->out_pos = info->output;
35 NtCurrentTeb()->debug_info = info;
37 return info;
40 /* ---------------------------------------------------------------------- */
42 static void *
43 gimme1 (int n)
45 struct debug_info *info = get_info();
46 char *res = info->str_pos;
48 if (res + n >= &info->strings[sizeof(info->strings)]) res = info->strings;
49 info->str_pos = res + n;
50 return res;
53 /* ---------------------------------------------------------------------- */
55 LPCSTR debugstr_an (LPCSTR src, int n)
57 LPSTR dst, res;
59 if (!src) return "(null)";
60 if (n < 0) n = 0;
61 dst = res = gimme1 (n * 4 + 6);
62 *dst++ = '"';
63 while (n-- > 0 && *src)
65 BYTE c = *src++;
66 switch (c)
68 case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
69 case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
70 case '\t': *dst++ = '\\'; *dst++ = 't'; break;
71 case '"': *dst++ = '\\'; *dst++ = '"'; break;
72 case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
73 default:
74 if (c >= ' ' && c <= 126)
75 *dst++ = c;
76 else
78 *dst++ = '\\';
79 *dst++ = '0' + ((c >> 6) & 7);
80 *dst++ = '0' + ((c >> 3) & 7);
81 *dst++ = '0' + ((c >> 0) & 7);
85 *dst++ = '"';
86 if (*src)
88 *dst++ = '.';
89 *dst++ = '.';
90 *dst++ = '.';
92 *dst = '\0';
93 return res;
96 /* ---------------------------------------------------------------------- */
98 LPCSTR debugstr_wn (LPCWSTR src, int n)
100 LPSTR dst, res;
102 if (!src) return "(null)";
103 if (n < 0) n = 0;
104 dst = res = gimme1 (n * 5 + 7);
105 *dst++ = 'L';
106 *dst++ = '"';
107 while (n-- > 0 && *src)
109 WORD c = *src++;
110 switch (c)
112 case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
113 case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
114 case '\t': *dst++ = '\\'; *dst++ = 't'; break;
115 case '"': *dst++ = '\\'; *dst++ = '"'; break;
116 case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
117 default:
118 if (c >= ' ' && c <= 126)
119 *dst++ = c;
120 else
122 *dst++ = '\\';
123 sprintf(dst,"%04x",c);
124 dst+=4;
128 *dst++ = '"';
129 if (*src)
131 *dst++ = '.';
132 *dst++ = '.';
133 *dst++ = '.';
135 *dst = '\0';
136 return res;
139 /* ---------------------------------------------------------------------- */
140 /* This routine returns a nicely formated name of the resource res
141 If the resource name is a string, it will return '<res-name>'
142 If it is a number, it will return #<4-digit-hex-number> */
143 LPCSTR debugres_a( LPCSTR res )
145 char *resname;
146 if (HIWORD(res)) return debugstr_a(res);
147 resname = gimme1(6);
148 sprintf(resname, "#%04x", LOWORD(res) );
149 return resname;
152 LPCSTR debugres_w( LPCWSTR res )
154 char *resname;
155 if (HIWORD(res)) return debugstr_w(res);
156 resname = gimme1(6);
157 sprintf( resname, "#%04x", LOWORD(res) );
158 return resname;
161 /* ---------------------------------------------------------------------- */
163 LPCSTR debugstr_guid( const GUID *id )
165 LPSTR str;
167 if (!id) return "(null)";
168 if (!HIWORD(id))
170 str = gimme1(12);
171 sprintf( str, "<guid-0x%04x>", LOWORD(id) );
173 else
175 str = gimme1(40);
176 sprintf( str, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
177 id->Data1, id->Data2, id->Data3,
178 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
179 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
181 return str;
184 /* ---------------------------------------------------------------------- */
186 int dbg_vprintf( const char *format, va_list args )
188 struct debug_info *info = get_info();
190 int ret = vsprintf( info->out_pos, format, args );
191 char *p = strrchr( info->out_pos, '\n' );
192 if (!p) info->out_pos += ret;
193 else
195 char *pos = info->output;
196 p++;
197 write( 2, pos, p - pos );
198 /* move beginning of next line to start of buffer */
199 while ((*pos = *p++)) pos++;
200 info->out_pos = pos;
202 return ret;
205 /* ---------------------------------------------------------------------- */
207 int dbg_printf(const char *format, ...)
209 int ret;
210 va_list valist;
212 va_start(valist, format);
213 ret = dbg_vprintf( format, valist);
214 va_end(valist);
215 return ret;
219 /*--< Function >---------------------------------------------------------
221 ** debugstr_hex_dump
223 ** Description:
224 ** This function creates a hex dump, with a readable ascii
225 ** section, for displaying memory.
227 ** Parameters:
228 ** 1. ptr Pointer to memory
229 ** 2. len How much to dump.
231 ** Returns:
232 ** Temporarily allocated buffer, with the hex dump in it.
233 ** Don't rely on this pointer being around for very long, just
234 ** long enough to use it in a TRACE statement; e.g.:
235 ** TRACE("struct dump is \n%s", debugstr_hex_dump(&x, sizeof(x)));
237 **-------------------------------------------------------------------------*/
238 LPCSTR debugstr_hex_dump (const void *ptr, int len)
240 /* Locals */
241 char dumpbuf[59];
242 char charbuf[20];
243 char tempbuf[8];
244 const char *p;
245 int i;
246 unsigned int nosign;
247 LPSTR dst;
248 LPSTR outptr;
250 /* Begin function dbg_hex_dump */
252 /*-----------------------------------------------------------------------
253 ** Allocate an output buffer
254 ** A reasonable value is one line overhand (80 chars), and
255 ** then one line (80) for every 16 bytes.
256 **---------------------------------------------------------------------*/
257 outptr = dst = gimme1 ((len * (80 / 16)) + 80);
259 /*-----------------------------------------------------------------------
260 ** Loop throught the input buffer, one character at a time
261 **---------------------------------------------------------------------*/
262 for (i = 0, p = ptr; (i < len); i++, p++)
265 /*-------------------------------------------------------------------
266 ** If we're just starting a line,
267 ** we need to possibly flush the old line, and then
268 ** intialize the line buffer.
269 **-----------------------------------------------------------------*/
270 if ((i % 16) == 0)
272 if (i)
274 sprintf(outptr, " %-43.43s %-16.16s\n", dumpbuf, charbuf);
275 outptr += strlen(outptr);
277 sprintf (dumpbuf, "%04x: ", i);
278 strcpy (charbuf, "");
281 /*-------------------------------------------------------------------
282 ** Add the current data byte to the dump section.
283 **-----------------------------------------------------------------*/
284 nosign = (unsigned char) *p;
285 sprintf (tempbuf, "%02X", nosign);
287 /*-------------------------------------------------------------------
288 ** If we're two DWORDS through, add a hyphen for readability,
289 ** if it's a DWORD boundary, add a space for more
290 ** readability.
291 **-----------------------------------------------------------------*/
292 if ((i % 16) == 7)
293 strcat(tempbuf, " - ");
294 else if ( (i % 4) == 3)
295 strcat(tempbuf, " ");
296 strcat (dumpbuf, tempbuf);
298 /*-------------------------------------------------------------------
299 ** Add the current byte to the character display part of the
300 ** hex dump
301 **-----------------------------------------------------------------*/
302 sprintf (tempbuf, "%c", isprint(*p) ? *p : '.');
303 strcat (charbuf, tempbuf);
306 /*-----------------------------------------------------------------------
307 ** Flush the last line, if any
308 **---------------------------------------------------------------------*/
309 if (i > 0)
311 sprintf(outptr, " %-43.43s %-16.16s\n", dumpbuf, charbuf);
312 outptr += strlen(outptr);
315 return(dst);
316 } /* End function dbg_hex_dump */