From a443761b8d97ed9b0e6f017f9bc27ddc3eb7ae23 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 26 Sep 2005 16:45:25 +0000 Subject: [PATCH] Export the temp buffer functionality in the debug functions interface to allow sharing more code between libwine and ntdll. --- dlls/ntdll/debugtools.c | 153 ++++++------------------------------------------ include/wine/debug.h | 6 +- libs/wine/debug.c | 80 +++++++++++++------------ 3 files changed, 66 insertions(+), 173 deletions(-) diff --git a/dlls/ntdll/debugtools.c b/dlls/ntdll/debugtools.c index 80448df185f..2f0be3dcad7 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 @@ static inline struct debug_info *get_info(void) } /* 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 @@ static void *gimme1(int n) } /* 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 @@ inline static char *put_string_w( const WCHAR *src, int n ) */ 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_an( const char *src, int n ) */ 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 @@ static const char *NTDLL_dbgstr_wn( const WCHAR *src, int n ) } /*********************************************************************** - * 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 int NTDLL_dbg_vlog( enum __wine_debug_class cls, struct __wine_debug_chan 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 @@ void debug_init(void) { 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 a6a2ca75da3..181d718bd9d 100644 --- a/include/wine/debug.h +++ b/include/wine/debug.h @@ -137,15 +137,17 @@ struct __wine_debug_channel 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 34ebc149cbb..28a179ad728 100644 --- a/libs/wine/debug.c +++ b/libs/wine/debug.c @@ -198,7 +198,7 @@ int wine_dbg_parse_options( const char *str ) 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 @@ int wine_dbg_printf( const char *format, ... ) 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 @@ int wine_dbg_log( enum __wine_debug_class cls, struct __wine_debug_channel *chan /* 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 @@ static char *get_tmp_space( int size ) } +/* 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 @@ static const char *default_dbgstr_an( const char *str, int n ) 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 @@ static const char *default_dbgstr_an( const char *str, int n ) *dst++ = '.'; *dst++ = '.'; } - *dst = 0; + *dst++ = 0; + funcs.release_temp_buffer( res, dst - res ); return res; } @@ -308,21 +322,22 @@ static const char *default_dbgstr_an( const char *str, int n ) 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 @@ static const char *default_dbgstr_wn( const WCHAR *str, int n ) *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 @@ const char *wine_dbgstr_w( const WCHAR *s ) 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 }; -- 2.11.4.GIT