| #include "debugstr.h" | 
 | #include "xmalloc.h" | 
 | #include <stdlib.h> | 
 | #include <stdio.h> | 
 |  | 
 | /* ---------------------------------------------------------------------- */ | 
 |  | 
 | #define SAVE_STRING_COUNT 50 | 
 | static void *strings[SAVE_STRING_COUNT]; | 
 | static int nextstring; | 
 |  | 
 | /* ---------------------------------------------------------------------- */ | 
 |  | 
 | static void * | 
 | gimme1 (int n) | 
 | { | 
 |   void *res; | 
 |   if (strings[nextstring]) free (strings[nextstring]); | 
 |   res = strings[nextstring] = xmalloc (n); | 
 |   if (++nextstring == SAVE_STRING_COUNT) nextstring = 0; | 
 |   return res; | 
 | } | 
 |  | 
 | /* ---------------------------------------------------------------------- */ | 
 |  | 
 | LPSTR | 
 | debugstr_an (LPCSTR src, int n) | 
 | { | 
 |   LPSTR dst, res; | 
 |  | 
 |   if (!src) return "(null)"; | 
 |   if (n < 0) n = 0; | 
 |   dst = res = gimme1 (n * 4 + 10); | 
 |   *dst++ = '"'; | 
 |   while (n-- > 0 && *src) | 
 |     { | 
 |       BYTE c = *src++; | 
 |       switch (c) | 
 | 	{ | 
 | 	case '\n': *dst++ = '\\'; *dst++ = 'n'; break; | 
 | 	case '\r': *dst++ = '\\'; *dst++ = 'r'; break; | 
 | 	case '\t': *dst++ = '\\'; *dst++ = 't'; break; | 
 | 	case '"': *dst++ = '\\'; *dst++ = '"'; break; | 
 | 	case '\\': *dst++ = '\\'; *dst++ = '\\'; break; | 
 | 	default: | 
 | 	  if (c >= ' ' && c <= 126) | 
 | 	    *dst++ = c; | 
 | 	  else | 
 | 	    { | 
 | 	      *dst++ = '\\'; | 
 | 	      *dst++ = '0' + ((c >> 6) & 7); | 
 | 	      *dst++ = '0' + ((c >> 3) & 7); | 
 | 	      *dst++ = '0' + ((c >> 0) & 7); | 
 | 	    } | 
 | 	} | 
 |     } | 
 |   if (*src) | 
 |     { | 
 |       *dst++ = '.'; | 
 |       *dst++ = '.'; | 
 |       *dst++ = '.'; | 
 |     } | 
 |   *dst++ = '"'; | 
 |   *dst = 0; | 
 |   return res; | 
 | } | 
 |  | 
 | /* ---------------------------------------------------------------------- */ | 
 |  | 
 | LPSTR | 
 | debugstr_a (LPCSTR s) | 
 | { | 
 |   return debugstr_an (s, 80); | 
 | } | 
 |  | 
 | /* ---------------------------------------------------------------------- */ | 
 |  | 
 | LPSTR | 
 | debugstr_wn (LPCWSTR src, int n) | 
 | { | 
 |   LPSTR dst, res; | 
 |  | 
 |   if (!src) return "(null)"; | 
 |   if (n < 0) n = 0; | 
 |   dst = res = gimme1 (n * 4 + 10); | 
 |   *dst++ = '"'; | 
 |   while (n-- > 0 && *src) | 
 |     { | 
 |       WORD c = *src++; | 
 |       switch (c) | 
 | 	{ | 
 | 	case '\n': *dst++ = '\\'; *dst++ = 'n'; break; | 
 | 	case '\r': *dst++ = '\\'; *dst++ = 'r'; break; | 
 | 	case '\t': *dst++ = '\\'; *dst++ = 't'; break; | 
 | 	case '"': *dst++ = '\\'; *dst++ = '"'; break; | 
 | 	case '\\': *dst++ = '\\'; *dst++ = '\\'; break; | 
 | 	default: | 
 | 	  if (c >= ' ' && c <= 126) | 
 | 	    *dst++ = c; | 
 | 	  else | 
 | 	    { | 
 | 	      *dst++ = '\\'; | 
 | 	      *dst++ = '0' + ((c >> 6) & 7); | 
 | 	      *dst++ = '0' + ((c >> 3) & 7); | 
 | 	      *dst++ = '0' + ((c >> 0) & 7); | 
 | 	    } | 
 | 	} | 
 |     } | 
 |   if (*src) | 
 |     { | 
 |       *dst++ = '.'; | 
 |       *dst++ = '.'; | 
 |       *dst++ = '.'; | 
 |     } | 
 |   *dst++ = '"'; | 
 |   *dst = 0; | 
 |   return res; | 
 | } | 
 |  | 
 | /* ---------------------------------------------------------------------- */ | 
 |  | 
 | LPSTR | 
 | debugstr_w (LPCWSTR s) | 
 | { | 
 |   return debugstr_wn (s, 80); | 
 | } | 
 |  | 
 | /* ---------------------------------------------------------------------- */ | 
 | /* This routine returns a nicely formated name of the resource res | 
 |    If the resource name is a string, it will return '<res-name>' | 
 |    If it is a number, it will return #<4-digit-hex-number> */ | 
 | LPSTR debugres_a( LPCSTR res ) | 
 | { | 
 |     char resname[10]; | 
 |     if (HIWORD(res)) return debugstr_a(res); | 
 |     sprintf(resname, "#%04x", LOWORD(res)); | 
 |     return debugstr_a (resname); | 
 | } | 
 |  | 
 | LPSTR debugres_w( LPCWSTR res ) | 
 | { | 
 |     char resname[10]; | 
 |     if (HIWORD(res)) return debugstr_w(res); | 
 |     sprintf(resname, "#%04x", LOWORD(res)); | 
 |     return debugstr_a (resname); | 
 | } | 
 |  | 
 | /* ---------------------------------------------------------------------- */ | 
 |  | 
 | void debug_dumpstr (LPCSTR s) | 
 | { | 
 |   fputc ('"', stderr); | 
 |   while (*s) | 
 |     { | 
 |       switch (*s) | 
 | 	{ | 
 | 	case '\\': | 
 | 	case '"': | 
 | 	  fputc ('\\', stderr); | 
 | 	  fputc (*s, stderr); | 
 | 	  break; | 
 | 	case '\n': | 
 | 	  fputc ('\\', stderr); | 
 | 	  fputc ('n', stderr); | 
 | 	  break; | 
 | 	case '\r': | 
 | 	  fputc ('\\', stderr); | 
 | 	  fputc ('r', stderr); | 
 | 	  break; | 
 | 	case '\t': | 
 | 	  fputc ('\\', stderr); | 
 | 	  fputc ('t', stderr); | 
 | 	  break; | 
 | 	default: | 
 | 	  if (*s<' ') | 
 | 	    fprintf (stderr, "\\0x%02x", *s); | 
 | 	  else | 
 | 	    fputc (*s, stderr); | 
 | 	} | 
 |       s++; | 
 |     } | 
 |   fputc ('"', stderr); | 
 | } | 
 |  |