Made the server listen for new clients on a Unix socket in
[wine] / misc / debugstr.c
1 #include <stdarg.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <ctype.h>
6
7 #include "debugstr.h"
8 #include "debugtools.h"
9 #include "wtypes.h"
10 #include "xmalloc.h"
11
12 /* ---------------------------------------------------------------------- */
13
14 #define SAVE_STRING_COUNT 50
15 static void *strings[SAVE_STRING_COUNT];
16 static int nextstring;
17
18 /* ---------------------------------------------------------------------- */
19
20 static void *
21 gimme1 (int n)
22 {
23   void *res;
24   if (strings[nextstring]) free (strings[nextstring]);
25   res = strings[nextstring] = xmalloc (n);
26   if (++nextstring == SAVE_STRING_COUNT) nextstring = 0;
27   return res;
28 }
29
30 /* ---------------------------------------------------------------------- */
31
32 LPSTR
33 debugstr_an (LPCSTR src, int n)
34 {
35   LPSTR dst, res;
36
37   if (!src) return "(null)";
38   if (n < 0) n = 0;
39   dst = res = gimme1 (n * 4 + 6);
40   *dst++ = '"';
41   while (n-- > 0 && *src)
42     {
43       BYTE c = *src++;
44       switch (c)
45         {
46         case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
47         case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
48         case '\t': *dst++ = '\\'; *dst++ = 't'; break;
49         case '"': *dst++ = '\\'; *dst++ = '"'; break;
50         case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
51         default:
52           if (c >= ' ' && c <= 126)
53             *dst++ = c;
54           else
55             {
56               *dst++ = '\\';
57               *dst++ = '0' + ((c >> 6) & 7);
58               *dst++ = '0' + ((c >> 3) & 7);
59               *dst++ = '0' + ((c >> 0) & 7);
60             }
61         }
62     }
63   *dst++ = '"';
64   if (*src)
65     {
66       *dst++ = '.';
67       *dst++ = '.';
68       *dst++ = '.';
69     }
70   *dst = '\0';
71   return res;
72 }
73
74 /* ---------------------------------------------------------------------- */
75
76 LPSTR
77 debugstr_a (LPCSTR s)
78 {
79   return debugstr_an (s, 80);
80 }
81
82 /* ---------------------------------------------------------------------- */
83
84 LPSTR
85 debugstr_wn (LPCWSTR src, int n)
86 {
87   LPSTR dst, res;
88
89   if (!src) return "(null)";
90   if (n < 0) n = 0;
91   dst = res = gimme1 (n * 5 + 7);
92   *dst++ = 'L';
93   *dst++ = '"';
94   while (n-- > 0 && *src)
95     {
96       WORD c = *src++;
97       switch (c)
98         {
99         case '\n': *dst++ = '\\'; *dst++ = 'n'; break;
100         case '\r': *dst++ = '\\'; *dst++ = 'r'; break;
101         case '\t': *dst++ = '\\'; *dst++ = 't'; break;
102         case '"': *dst++ = '\\'; *dst++ = '"'; break;
103         case '\\': *dst++ = '\\'; *dst++ = '\\'; break;
104         default:
105           if (c >= ' ' && c <= 126)
106             *dst++ = c;
107           else 
108             {
109               *dst++ = '\\';
110               sprintf(dst,"%04x",c);
111               dst+=4;
112             }
113         }
114     }
115   *dst++ = '"';
116   if (*src)
117     {
118       *dst++ = '.';
119       *dst++ = '.';
120       *dst++ = '.';
121     }
122   *dst = '\0';
123   return res;
124 }
125
126 /* ---------------------------------------------------------------------- */
127
128 LPSTR
129 debugstr_w (LPCWSTR s)
130 {
131   return debugstr_wn (s, 80);
132 }
133
134 /* ---------------------------------------------------------------------- */
135 /* This routine returns a nicely formated name of the resource res
136    If the resource name is a string, it will return '<res-name>'
137    If it is a number, it will return #<4-digit-hex-number> */
138 LPSTR debugres_a( LPCSTR res )
139 {
140     char resname[10];
141     if (HIWORD(res)) return debugstr_a(res);
142     sprintf(resname, "#%04x", LOWORD(res));
143     return debugstr_a (resname);
144 }
145
146 LPSTR debugres_w( LPCWSTR res )
147 {
148     char resname[10];
149     if (HIWORD(res)) return debugstr_w(res);
150     sprintf(resname, "#%04x", LOWORD(res));
151     return debugstr_a (resname);
152 }
153
154 /* ---------------------------------------------------------------------- */
155
156 LPSTR debugstr_guid( const GUID *id )
157 {
158     LPSTR str;
159
160     if (!id) return "(null)";
161     if (!HIWORD(id))
162     {
163         str = gimme1(12);
164         sprintf( str, "<guid-0x%04x>", LOWORD(id) );
165     }
166     else
167     {
168         str = gimme1(40);
169         sprintf( str, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
170                  id->Data1, id->Data2, id->Data3,
171                  id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
172                  id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
173     }
174     return str;
175 }
176
177 /* ---------------------------------------------------------------------- */
178
179 void debug_dumpstr (LPCSTR s)
180 {
181   fputc ('"', stderr);
182   while (*s)
183     {
184       switch (*s)
185         {
186         case '\\':
187         case '"':
188           fputc ('\\', stderr);
189           fputc (*s, stderr);
190           break;
191         case '\n':
192           fputc ('\\', stderr);
193           fputc ('n', stderr);
194           break;
195         case '\r':
196           fputc ('\\', stderr);
197           fputc ('r', stderr);
198           break;
199         case '\t':
200           fputc ('\\', stderr);
201           fputc ('t', stderr);
202           break;
203         default:
204           if (*s<' ')
205             fprintf (stderr, "\\0x%02x", *s);
206           else
207             fputc (*s, stderr);
208         }
209       s++;
210     }
211   fputc ('"', stderr);
212 }
213
214 /* ---------------------------------------------------------------------- */
215
216 int dbg_printf(const char *format, ...)
217 {
218     int ret;
219     va_list valist;
220
221     va_start(valist, format);
222     ret = vfprintf(stderr, format, valist);
223     va_end(valist);
224     return ret;
225 }
226
227
228
229 /*--< Function >---------------------------------------------------------
230 **  
231 **              debugstr_hex_dump
232 **              
233 **  Description:
234 **      This function creates a hex dump, with a readable ascii
235 **  section, for displaying memory.
236 **  
237 **  Parameters:
238 **      1.  ptr             Pointer to memory
239 **      2.  len             How much to dump.
240 **
241 **  Returns:
242 **    Temporarily allocated buffer, with the hex dump in it.
243 **  Don't rely on this pointer being around for very long, just
244 **  long enough to use it in a TRACE statement; e.g.:
245 **  TRACE("struct dump is \n%s", debugstr_hex_dump(&x, sizeof(x)));
246 **          
247 **-------------------------------------------------------------------------*/
248 LPSTR 
249 debugstr_hex_dump (const void *ptr, int len)
250 {
251     /* Locals */
252     char          dumpbuf[59];
253     char          charbuf[20];
254     char          tempbuf[8];
255     const char    *p;
256     int           i;
257     unsigned int  nosign;
258     LPSTR         dst;
259     LPSTR         outptr;
260
261 /* Begin function dbg_hex_dump */
262
263     /*-----------------------------------------------------------------------
264     **  Allocate an output buffer
265     **      A reasonable value is one line overhand (80 chars), and
266     **      then one line (80) for every 16 bytes.
267     **---------------------------------------------------------------------*/
268     outptr = dst = gimme1 ((len * (80 / 16)) + 80);
269
270     /*-----------------------------------------------------------------------
271     **  Loop throught the input buffer, one character at a time
272     **---------------------------------------------------------------------*/
273     for (i = 0, p = ptr; (i < len); i++, p++)
274     {
275
276         /*-------------------------------------------------------------------
277         **  If we're just starting a line, 
278         **      we need to possibly flush the old line, and then
279         **      intialize the line buffer.
280         **-----------------------------------------------------------------*/
281         if ((i % 16) == 0)
282         {
283             if (i)
284             {
285                 sprintf(outptr, "  %-43.43s   %-16.16s\n", dumpbuf, charbuf);
286                 outptr += strlen(outptr);
287             }
288             sprintf (dumpbuf, "%04x: ", i);
289             strcpy (charbuf, "");
290         }
291
292         /*-------------------------------------------------------------------
293         **  Add the current data byte to the dump section.
294         **-----------------------------------------------------------------*/
295         nosign = (unsigned char) *p;
296         sprintf (tempbuf, "%02X", nosign);
297
298         /*-------------------------------------------------------------------
299         **  If we're two DWORDS through, add a hyphen for readability,
300         **      if it's a DWORD boundary, add a space for more
301         **      readability.
302         **-----------------------------------------------------------------*/
303         if ((i % 16) == 7)
304             strcat(tempbuf, " - ");
305         else if ( (i % 4) == 3)
306             strcat(tempbuf, " ");
307         strcat (dumpbuf, tempbuf);
308
309         /*-------------------------------------------------------------------
310         **  Add the current byte to the character display part of the
311         **      hex dump
312         **-----------------------------------------------------------------*/
313         sprintf (tempbuf, "%c", isprint(*p) ? *p : '.');
314         strcat (charbuf, tempbuf);
315     }
316
317     /*-----------------------------------------------------------------------
318     **  Flush the last line, if any
319     **---------------------------------------------------------------------*/
320     if (i > 0)
321     {
322         sprintf(outptr, "  %-43.43s   %-16.16s\n", dumpbuf, charbuf);
323         outptr += strlen(outptr);
324     }
325
326     return(dst);
327 } /* End function dbg_hex_dump */
328
329
330