Export the temp buffer functionality in the debug functions interface
to allow sharing more code between libwine and ntdll.
diff --git a/dlls/ntdll/debugtools.c b/dlls/ntdll/debugtools.c
index 80448df..2f0be3d 100644
--- a/dlls/ntdll/debugtools.c
+++ b/dlls/ntdll/debugtools.c
@@ -42,6 +42,8 @@
WINE_DECLARE_DEBUG_CHANNEL(tid);
+static struct __wine_debug_functions default_funcs;
+
/* ---------------------------------------------------------------------- */
/* filter for page-fault exceptions */
@@ -59,7 +61,7 @@
}
/* allocate some tmp space for a string */
-static void *gimme1(int n)
+static char *get_temp_buffer( size_t n )
{
struct debug_info *info = get_info();
char *res = info->str_pos;
@@ -70,101 +72,10 @@
}
/* release extra space that we requested in gimme1() */
-static inline void release( void *ptr )
+static void release_temp_buffer( char *ptr, size_t size )
{
struct debug_info *info = get_info();
- info->str_pos = ptr;
-}
-
-/* put an ASCII string into the debug buffer */
-inline static char *put_string_a( const char *src, int n )
-{
- static const char hex[16] = "0123456789abcdef";
- char *dst, *res;
- size_t size;
-
- if (n == -1) n = strlen(src);
- if (n < 0) n = 0;
- size = 10 + min( 300, n * 4 );
- dst = res = gimme1( size );
- *dst++ = '"';
- while (n-- > 0 && dst <= res + size - 9)
- {
- unsigned char 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++ = 'x';
- *dst++ = hex[(c >> 4) & 0x0f];
- *dst++ = hex[c & 0x0f];
- }
- }
- }
- *dst++ = '"';
- if (*src)
- {
- *dst++ = '.';
- *dst++ = '.';
- *dst++ = '.';
- }
- *dst++ = '\0';
- release( dst );
- return res;
-}
-
-/* put a Unicode string into the debug buffer */
-inline static char *put_string_w( const WCHAR *src, int n )
-{
- char *dst, *res;
- size_t size;
-
- if (n == -1) n = strlenW(src);
- if (n < 0) n = 0;
- size = 12 + min( 300, n * 5 );
- dst = res = gimme1( size );
- *dst++ = 'L';
- *dst++ = '"';
- while (n-- > 0 && dst <= res + size - 10)
- {
- WCHAR 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++ = '\\';
- sprintf(dst,"%04x",c);
- dst+=4;
- }
- }
- }
- *dst++ = '"';
- if (*src)
- {
- *dst++ = '.';
- *dst++ = '.';
- *dst++ = '.';
- }
- *dst++ = '\0';
- release( dst );
- return res;
+ info->str_pos = ptr + size;
}
/***********************************************************************
@@ -172,25 +83,18 @@
*/
static const char *NTDLL_dbgstr_an( const char *src, int n )
{
- char *res, *old_pos;
+ const char *res;
struct debug_info *info = get_info();
-
- if (!HIWORD(src))
- {
- if (!src) return "(null)";
- res = gimme1(6);
- sprintf(res, "#%04x", LOWORD(src) );
- return res;
- }
/* save current position to restore it on exception */
- old_pos = info->str_pos;
+ char *old_pos = info->str_pos;
+
__TRY
{
- res = put_string_a( src, n );
+ res = default_funcs.dbgstr_an( src, n );
}
__EXCEPT(page_fault)
{
- release( old_pos );
+ release_temp_buffer( old_pos, 0 );
return "(invalid)";
}
__ENDTRY
@@ -202,26 +106,18 @@
*/
static const char *NTDLL_dbgstr_wn( const WCHAR *src, int n )
{
- char *res, *old_pos;
+ const char *res;
struct debug_info *info = get_info();
-
- if (!HIWORD(src))
- {
- if (!src) return "(null)";
- res = gimme1(6);
- sprintf(res, "#%04x", LOWORD(src) );
- return res;
- }
-
/* save current position to restore it on exception */
- old_pos = info->str_pos;
+ char *old_pos = info->str_pos;
+
__TRY
{
- res = put_string_w( src, n );
+ res = default_funcs.dbgstr_wn( src, n );
}
__EXCEPT(page_fault)
{
- release( old_pos );
+ release_temp_buffer( old_pos, 0 );
return "(invalid)";
}
__ENDTRY
@@ -229,20 +125,6 @@
}
/***********************************************************************
- * NTDLL_dbg_vsprintf
- */
-static const char *NTDLL_dbg_vsprintf( const char *format, va_list args )
-{
- static const int max_size = 200;
-
- char *res = gimme1( max_size );
- int len = vsnprintf( res, max_size, format, args );
- if (len == -1 || len >= max_size) res[max_size-1] = 0;
- else release( res + len + 1 );
- return res;
-}
-
-/***********************************************************************
* NTDLL_dbg_vprintf
*/
static int NTDLL_dbg_vprintf( const char *format, va_list args )
@@ -305,9 +187,10 @@
static const struct __wine_debug_functions funcs =
{
+ get_temp_buffer,
+ release_temp_buffer,
NTDLL_dbgstr_an,
NTDLL_dbgstr_wn,
- NTDLL_dbg_vsprintf,
NTDLL_dbg_vprintf,
NTDLL_dbg_vlog
};
@@ -319,6 +202,6 @@
{
extern void __wine_dbg_ntdll_init(void);
- __wine_dbg_set_functions( &funcs, sizeof(funcs) );
+ __wine_dbg_set_functions( &funcs, &default_funcs, sizeof(funcs) );
__wine_dbg_ntdll_init(); /* hack: register debug channels early */
}
diff --git a/include/wine/debug.h b/include/wine/debug.h
index a6a2ca7..181d718 100644
--- a/include/wine/debug.h
+++ b/include/wine/debug.h
@@ -137,15 +137,17 @@
struct __wine_debug_functions
{
+ char * (*get_temp_buffer)( size_t n );
+ void (*release_temp_buffer)( char *buffer, size_t n );
const char * (*dbgstr_an)( const char * s, int n );
const char * (*dbgstr_wn)( const WCHAR *s, int n );
- const char * (*dbg_vsprintf)( const char *format, va_list args );
int (*dbg_vprintf)( const char *format, va_list args );
int (*dbg_vlog)( enum __wine_debug_class cls, struct __wine_debug_channel *channel,
const char *function, const char *format, va_list args );
};
-extern void __wine_dbg_set_functions( const struct __wine_debug_functions *funcs, size_t size );
+extern void __wine_dbg_set_functions( const struct __wine_debug_functions *new_funcs,
+ struct __wine_debug_functions *old_funcs, size_t size );
/*
* Exported definitions and macros
diff --git a/libs/wine/debug.c b/libs/wine/debug.c
index 34ebc14..28a179a 100644
--- a/libs/wine/debug.c
+++ b/libs/wine/debug.c
@@ -198,7 +198,7 @@
return errors;
}
-/* varargs wrapper for __wine_dbg_vprintf */
+/* varargs wrapper for funcs.dbg_vprintf */
int wine_dbg_printf( const char *format, ... )
{
int ret;
@@ -210,21 +210,25 @@
return ret;
}
-
-/* varargs wrapper for __wine_dbg_vsprintf */
+/* printf with temp buffer allocation */
const char *wine_dbg_sprintf( const char *format, ... )
{
- const char *ret;
+ static const int max_size = 200;
+ char *ret;
+ int len;
va_list valist;
va_start(valist, format);
- ret = funcs.dbg_vsprintf( format, valist );
+ ret = funcs.get_temp_buffer( max_size );
+ len = vsnprintf( ret, max_size, format, valist );
+ if (len == -1 || len >= max_size) ret[max_size-1] = 0;
+ else funcs.release_temp_buffer( ret, len + 1 );
va_end(valist);
return ret;
}
-/* varargs wrapper for __wine_dbg_vlog */
+/* varargs wrapper for funcs.dbg_vlog */
int wine_dbg_log( enum __wine_debug_class cls, struct __wine_debug_channel *channel,
const char *func, const char *format, ... )
{
@@ -240,7 +244,7 @@
/* allocate some tmp string space */
/* FIXME: this is not 100% thread-safe */
-static char *get_tmp_space( int size )
+static char *get_temp_buffer( size_t size )
{
static char *list[32];
static int pos;
@@ -253,24 +257,33 @@
}
+/* release unused part of the buffer */
+static void release_temp_buffer( char *buffer, size_t size )
+{
+ /* don't bother doing anything */
+}
+
+
/* default implementation of wine_dbgstr_an */
static const char *default_dbgstr_an( const char *str, int n )
{
+ static const char hex[16] = "0123456789abcdef";
char *dst, *res;
+ size_t size;
- if (!HIWORD(str))
+ if (!((ULONG_PTR)str >> 16))
{
if (!str) return "(null)";
- res = get_tmp_space( 6 );
+ res = funcs.get_temp_buffer( 6 );
sprintf( res, "#%04x", LOWORD(str) );
return res;
}
if (n == -1) n = strlen(str);
if (n < 0) n = 0;
- else if (n > 200) n = 200;
- dst = res = get_tmp_space( n * 4 + 6 );
+ size = 10 + min( 300, n * 4 );
+ dst = res = funcs.get_temp_buffer( size );
*dst++ = '"';
- while (n-- > 0)
+ while (n-- > 0 && dst <= res + size - 9)
{
unsigned char c = *str++;
switch (c)
@@ -286,9 +299,9 @@
else
{
*dst++ = '\\';
- *dst++ = '0' + ((c >> 6) & 7);
- *dst++ = '0' + ((c >> 3) & 7);
- *dst++ = '0' + ((c >> 0) & 7);
+ *dst++ = 'x';
+ *dst++ = hex[(c >> 4) & 0x0f];
+ *dst++ = hex[c & 0x0f];
}
}
}
@@ -299,7 +312,8 @@
*dst++ = '.';
*dst++ = '.';
}
- *dst = 0;
+ *dst++ = 0;
+ funcs.release_temp_buffer( res, dst - res );
return res;
}
@@ -308,21 +322,22 @@
static const char *default_dbgstr_wn( const WCHAR *str, int n )
{
char *dst, *res;
+ size_t size;
- if (!HIWORD(str))
+ if (!((ULONG_PTR)str >> 16))
{
if (!str) return "(null)";
- res = get_tmp_space( 6 );
+ res = funcs.get_temp_buffer( 6 );
sprintf( res, "#%04x", LOWORD(str) );
return res;
}
if (n == -1) n = strlenW(str);
if (n < 0) n = 0;
- else if (n > 200) n = 200;
- dst = res = get_tmp_space( n * 5 + 7 );
+ size = 12 + min( 300, n * 5 );
+ dst = res = funcs.get_temp_buffer( n * 5 + 7 );
*dst++ = 'L';
*dst++ = '"';
- while (n-- > 0)
+ while (n-- > 0 && dst <= res + size - 10)
{
WCHAR c = *str++;
switch (c)
@@ -350,22 +365,12 @@
*dst++ = '.';
*dst++ = '.';
}
- *dst = 0;
+ *dst++ = 0;
+ funcs.release_temp_buffer( res, dst - res );
return res;
}
-/* default implementation of wine_dbg_vsprintf */
-static const char *default_dbg_vsprintf( const char *format, va_list args )
-{
- static const int max_size = 200;
-
- char *res = get_tmp_space( max_size );
- int len = vsnprintf( res, max_size, format, args );
- if (len == -1 || len >= max_size) res[max_size-1] = 0;
- return res;
-}
-
/* default implementation of wine_dbg_vprintf */
static int default_dbg_vprintf( const char *format, va_list args )
{
@@ -408,16 +413,19 @@
return funcs.dbgstr_wn( s, -1 );
}
-void __wine_dbg_set_functions( const struct __wine_debug_functions *new_funcs, size_t size )
+void __wine_dbg_set_functions( const struct __wine_debug_functions *new_funcs,
+ struct __wine_debug_functions *old_funcs, size_t size )
{
- memcpy( &funcs, new_funcs, min(sizeof(funcs),size) );
+ if (old_funcs) memcpy( old_funcs, &funcs, min(sizeof(funcs),size) );
+ if (new_funcs) memcpy( &funcs, new_funcs, min(sizeof(funcs),size) );
}
static struct __wine_debug_functions funcs =
{
+ get_temp_buffer,
+ release_temp_buffer,
default_dbgstr_an,
default_dbgstr_wn,
- default_dbg_vsprintf,
default_dbg_vprintf,
default_dbg_vlog
};