diff --git a/dlls/ntdll/debugtools.c b/dlls/ntdll/debugtools.c index 90ffd79f30..80448df185 100644 --- a/dlls/ntdll/debugtools.c +++ b/dlls/ntdll/debugtools.c @@ -282,7 +282,7 @@ static int NTDLL_dbg_vprintf( const char *format, va_list args ) /*********************************************************************** * NTDLL_dbg_vlog */ -static int NTDLL_dbg_vlog( unsigned int cls, const char *channel, +static int NTDLL_dbg_vlog( enum __wine_debug_class cls, struct __wine_debug_channel *channel, const char *function, const char *format, va_list args ) { static const char * const classes[] = { "fixme", "err", "warn", "trace" }; @@ -295,13 +295,23 @@ static int NTDLL_dbg_vlog( unsigned int cls, const char *channel, if (TRACE_ON(tid)) ret = wine_dbg_printf( "%04lx:", GetCurrentThreadId() ); if (cls < sizeof(classes)/sizeof(classes[0])) - ret += wine_dbg_printf( "%s:%s:%s ", classes[cls], channel + 1, function ); + ret += wine_dbg_printf( "%s:%s:%s ", classes[cls], channel->name, function ); } if (format) ret += NTDLL_dbg_vprintf( format, args ); return ret; } + +static const struct __wine_debug_functions funcs = +{ + NTDLL_dbgstr_an, + NTDLL_dbgstr_wn, + NTDLL_dbg_vsprintf, + NTDLL_dbg_vprintf, + NTDLL_dbg_vlog +}; + /*********************************************************************** * debug_init */ @@ -309,10 +319,6 @@ void debug_init(void) { extern void __wine_dbg_ntdll_init(void); - __wine_dbgstr_an = NTDLL_dbgstr_an; - __wine_dbgstr_wn = NTDLL_dbgstr_wn; - __wine_dbg_vsprintf = NTDLL_dbg_vsprintf; - __wine_dbg_vprintf = NTDLL_dbg_vprintf; - __wine_dbg_vlog = NTDLL_dbg_vlog; + __wine_dbg_set_functions( &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 0b5c249102..a6a2ca75da 100644 --- a/include/wine/debug.h +++ b/include/wine/debug.h @@ -37,7 +37,8 @@ struct _GUID; * Internal definitions (do not use these directly) */ -enum __WINE_DEBUG_CLASS { +enum __wine_debug_class +{ __WINE_DBCL_FIXME, __WINE_DBCL_ERR, __WINE_DBCL_WARN, @@ -45,22 +46,28 @@ enum __WINE_DEBUG_CLASS { __WINE_DBCL_COUNT }; +struct __wine_debug_channel +{ + unsigned char flags; + char name[15]; +}; + #ifndef WINE_NO_TRACE_MSGS -# define __WINE_GET_DEBUGGING_TRACE(dbch) ((dbch)[0] & (1 << __WINE_DBCL_TRACE)) +# define __WINE_GET_DEBUGGING_TRACE(dbch) ((dbch)->flags & (1 << __WINE_DBCL_TRACE)) #else # define __WINE_GET_DEBUGGING_TRACE(dbch) 0 #endif #ifndef WINE_NO_DEBUG_MSGS -# define __WINE_GET_DEBUGGING_WARN(dbch) ((dbch)[0] & (1 << __WINE_DBCL_WARN)) -# define __WINE_GET_DEBUGGING_FIXME(dbch) ((dbch)[0] & (1 << __WINE_DBCL_FIXME)) +# define __WINE_GET_DEBUGGING_WARN(dbch) ((dbch)->flags & (1 << __WINE_DBCL_WARN)) +# define __WINE_GET_DEBUGGING_FIXME(dbch) ((dbch)->flags & (1 << __WINE_DBCL_FIXME)) #else # define __WINE_GET_DEBUGGING_WARN(dbch) 0 # define __WINE_GET_DEBUGGING_FIXME(dbch) 0 #endif /* define error macro regardless of what is configured */ -#define __WINE_GET_DEBUGGING_ERR(dbch) ((dbch)[0] & (1 << __WINE_DBCL_ERR)) +#define __WINE_GET_DEBUGGING_ERR(dbch) ((dbch)->flags & (1 << __WINE_DBCL_ERR)) #define __WINE_GET_DEBUGGING(dbcl,dbch) __WINE_GET_DEBUGGING##dbcl(dbch) #define __WINE_SET_DEBUGGING(dbcl,dbch,on) \ @@ -70,8 +77,8 @@ enum __WINE_DEBUG_CLASS { #define __WINE_DPRINTF(dbcl,dbch) \ do { if(__WINE_GET_DEBUGGING(dbcl,(dbch))) { \ - const char * const __dbch = (dbch); \ - const enum __WINE_DEBUG_CLASS __dbcl = __WINE_DBCL##dbcl; \ + struct __wine_debug_channel * const __dbch = (dbch); \ + const enum __wine_debug_class __dbcl = __WINE_DBCL##dbcl; \ __WINE_DBG_LOG #define __WINE_DBG_LOG(args...) \ @@ -96,7 +103,7 @@ enum __WINE_DEBUG_CLASS { #define __WINE_DPRINTF(dbcl,dbch) \ do { if(__WINE_GET_DEBUGGING(dbcl,(dbch))) { \ - const char * const __dbch = (dbch); \ + struct __wine_debug_channel * const __dbch = (dbch); \ const enum __WINE_DEBUG_CLASS __dbcl = __WINE_DBCL##dbcl; \ __WINE_DBG_LOG @@ -128,6 +135,17 @@ enum __WINE_DEBUG_CLASS { #endif /* !__GNUC__ && !__SUNPRO_C */ +struct __wine_debug_functions +{ + 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 ); /* * Exported definitions and macros @@ -138,14 +156,22 @@ enum __WINE_DEBUG_CLASS { as strings are re-used. */ extern const char *wine_dbgstr_an( const char * s, int n ); extern const char *wine_dbgstr_wn( const WCHAR *s, int n ); -extern const char *wine_dbgstr_a( const char *s ); -extern const char *wine_dbgstr_w( const WCHAR *s ); extern const char *wine_dbg_sprintf( const char *format, ... ) __WINE_PRINTF_ATTR(1,2); extern int wine_dbg_printf( const char *format, ... ) __WINE_PRINTF_ATTR(1,2); -extern int wine_dbg_log( unsigned int cls, const char *ch, const char *func, +extern int wine_dbg_log( enum __wine_debug_class cls, struct __wine_debug_channel *ch, const char *func, const char *format, ... ) __WINE_PRINTF_ATTR(4,5); +extern inline const char *wine_dbgstr_a( const char *s ) +{ + return wine_dbgstr_an( s, -1 ); +} + +extern inline const char *wine_dbgstr_w( const WCHAR *s ) +{ + return wine_dbgstr_wn( s, -1 ); +} + static inline const char *wine_dbgstr_guid( const GUID *id ) { if (!id) return "(null)"; @@ -176,37 +202,38 @@ static inline const char *wine_dbgstr_rect( const RECT *rect ) static inline const char *wine_dbgstr_longlong( ULONGLONG ll ) { - if (ll >> 32) return wine_dbg_sprintf( "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll ); + if (sizeof(ll) > sizeof(unsigned long) && ll >> 32) + return wine_dbg_sprintf( "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll ); else return wine_dbg_sprintf( "%lx", (unsigned long)ll ); } #ifndef WINE_TRACE #define WINE_TRACE __WINE_DPRINTF(_TRACE,__wine_dbch___default) -#define WINE_TRACE_(ch) __WINE_DPRINTF(_TRACE,__wine_dbch_##ch) +#define WINE_TRACE_(ch) __WINE_DPRINTF(_TRACE,&__wine_dbch_##ch) #endif -#define WINE_TRACE_ON(ch) __WINE_GET_DEBUGGING(_TRACE,__wine_dbch_##ch) +#define WINE_TRACE_ON(ch) __WINE_GET_DEBUGGING(_TRACE,&__wine_dbch_##ch) #ifndef WINE_WARN #define WINE_WARN __WINE_DPRINTF(_WARN,__wine_dbch___default) -#define WINE_WARN_(ch) __WINE_DPRINTF(_WARN,__wine_dbch_##ch) +#define WINE_WARN_(ch) __WINE_DPRINTF(_WARN,&__wine_dbch_##ch) #endif -#define WINE_WARN_ON(ch) __WINE_GET_DEBUGGING(_WARN,__wine_dbch_##ch) +#define WINE_WARN_ON(ch) __WINE_GET_DEBUGGING(_WARN,&__wine_dbch_##ch) #ifndef WINE_FIXME #define WINE_FIXME __WINE_DPRINTF(_FIXME,__wine_dbch___default) -#define WINE_FIXME_(ch) __WINE_DPRINTF(_FIXME,__wine_dbch_##ch) +#define WINE_FIXME_(ch) __WINE_DPRINTF(_FIXME,&__wine_dbch_##ch) #endif -#define WINE_FIXME_ON(ch) __WINE_GET_DEBUGGING(_FIXME,__wine_dbch_##ch) +#define WINE_FIXME_ON(ch) __WINE_GET_DEBUGGING(_FIXME,&__wine_dbch_##ch) #define WINE_ERR __WINE_DPRINTF(_ERR,__wine_dbch___default) -#define WINE_ERR_(ch) __WINE_DPRINTF(_ERR,__wine_dbch_##ch) -#define WINE_ERR_ON(ch) __WINE_GET_DEBUGGING(_ERR,__wine_dbch_##ch) +#define WINE_ERR_(ch) __WINE_DPRINTF(_ERR,&__wine_dbch_##ch) +#define WINE_ERR_ON(ch) __WINE_GET_DEBUGGING(_ERR,&__wine_dbch_##ch) #define WINE_DECLARE_DEBUG_CHANNEL(ch) \ - extern char __wine_dbch_##ch[] + extern struct __wine_debug_channel __wine_dbch_##ch #define WINE_DEFAULT_DEBUG_CHANNEL(ch) \ - extern char __wine_dbch_##ch[]; \ - static char * const __wine_dbch___default = __wine_dbch_##ch + extern struct __wine_debug_channel __wine_dbch_##ch; \ + static struct __wine_debug_channel * const __wine_dbch___default = &__wine_dbch_##ch #define WINE_DPRINTF wine_dbg_printf #define WINE_MESSAGE wine_dbg_printf diff --git a/include/wine/library.h b/include/wine/library.h index 60defa61ea..d66bc7c6e2 100644 --- a/include/wine/library.h +++ b/include/wine/library.h @@ -58,13 +58,6 @@ extern void wine_init( int argc, char *argv[], char *error, int error_size ); /* debugging */ -extern const char * (*__wine_dbgstr_an)( const char * s, int n ); -extern const char * (*__wine_dbgstr_wn)( const WCHAR *s, int n ); -extern const char * (*__wine_dbg_vsprintf)( const char *format, va_list args ); -extern int (*__wine_dbg_vprintf)( const char *format, va_list args ); -extern int (*__wine_dbg_vlog)( unsigned int cls, const char *channel, - const char *function, const char *format, va_list args ); - extern void wine_dbg_add_option( const char *name, unsigned char set, unsigned char clear ); extern int wine_dbg_parse_options( const char *str ); diff --git a/libs/wine/debug.c b/libs/wine/debug.c index a25e46832e..377b950b9d 100644 --- a/libs/wine/debug.c +++ b/libs/wine/debug.c @@ -35,7 +35,7 @@ struct dll { struct dll *next; /* linked list of dlls */ struct dll *prev; - char * const *channels; /* array of channels */ + struct __wine_debug_channel * const *channels; /* array of channels */ int nb_channels; /* number of channels in array */ }; @@ -51,14 +51,15 @@ struct debug_option static struct debug_option *first_option; static struct debug_option *last_option; +static struct __wine_debug_functions funcs; static const char * const debug_classes[] = { "fixme", "err", "warn", "trace" }; static int cmp_name( const void *p1, const void *p2 ) { const char *name = p1; - const char * const *chan = p2; - return strcmp( name, *chan + 1 ); + const struct __wine_debug_channel * const *chan = p2; + return strcmp( name, (*chan)->name ); } /* apply a debug option to the channels of a given dll */ @@ -66,20 +67,20 @@ static void apply_option( struct dll *dll, const struct debug_option *opt ) { if (opt->name[0]) { - char **dbch = bsearch( opt->name, dll->channels, dll->nb_channels, - sizeof(*dll->channels), cmp_name ); - if (dbch) **dbch = (**dbch & ~opt->clear) | opt->set; + struct __wine_debug_channel * const *dbch = bsearch( opt->name, dll->channels, dll->nb_channels, + sizeof(*dll->channels), cmp_name ); + if (dbch) (*dbch)->flags = ((*dbch)->flags & ~opt->clear) | opt->set; } else /* all */ { int i; for (i = 0; i < dll->nb_channels; i++) - dll->channels[i][0] = (dll->channels[i][0] & ~opt->clear) | opt->set; + dll->channels[i]->flags = (dll->channels[i]->flags & ~opt->clear) | opt->set; } } /* register a new set of channels for a dll */ -void *__wine_dbg_register( char * const *channels, int nb ) +void *__wine_dbg_register( struct __wine_debug_channel * const *channels, int nb ) { struct debug_option *opt = first_option; struct dll *dll = malloc( sizeof(*dll) ); @@ -204,7 +205,7 @@ int wine_dbg_printf( const char *format, ... ) va_list valist; va_start(valist, format); - ret = __wine_dbg_vprintf( format, valist ); + ret = funcs.dbg_vprintf( format, valist ); va_end(valist); return ret; } @@ -217,20 +218,21 @@ const char *wine_dbg_sprintf( const char *format, ... ) va_list valist; va_start(valist, format); - ret = __wine_dbg_vsprintf( format, valist ); + ret = funcs.dbg_vsprintf( format, valist ); va_end(valist); return ret; } /* varargs wrapper for __wine_dbg_vlog */ -int wine_dbg_log( unsigned int cls, const char *channel, const char *func, const char *format, ... ) +int wine_dbg_log( enum __wine_debug_class cls, struct __wine_debug_channel *channel, + const char *func, const char *format, ... ) { int ret; va_list valist; va_start(valist, format); - ret = __wine_dbg_vlog( cls, channel, func, format, valist ); + ret = funcs.dbg_vlog( cls, channel, func, format, valist ); va_end(valist); return ret; } @@ -372,46 +374,50 @@ static int default_dbg_vprintf( const char *format, va_list args ) /* default implementation of wine_dbg_vlog */ -static int default_dbg_vlog( unsigned int cls, const char *channel, const char *func, - const char *format, va_list args ) +static int default_dbg_vlog( enum __wine_debug_class cls, struct __wine_debug_channel *channel, + const char *func, const char *format, va_list args ) { int ret = 0; if (cls < sizeof(debug_classes)/sizeof(debug_classes[0])) - ret += wine_dbg_printf( "%s:%s:%s ", debug_classes[cls], channel + 1, func ); + ret += wine_dbg_printf( "%s:%s:%s ", debug_classes[cls], channel->name, func ); if (format) - ret += __wine_dbg_vprintf( format, args ); + ret += funcs.dbg_vprintf( format, args ); return ret; } - -/* exported function pointers so that debugging functions can be redirected at run-time */ - -const char * (*__wine_dbgstr_an)( const char * s, int n ) = default_dbgstr_an; -const char * (*__wine_dbgstr_wn)( const WCHAR *s, int n ) = default_dbgstr_wn; -const char * (*__wine_dbg_vsprintf)( const char *format, va_list args ) = default_dbg_vsprintf; -int (*__wine_dbg_vprintf)( const char *format, va_list args ) = default_dbg_vprintf; -int (*__wine_dbg_vlog)( unsigned int cls, const char *channel, const char *function, - const char *format, va_list args ) = default_dbg_vlog; - /* wrappers to use the function pointers */ const char *wine_dbgstr_an( const char * s, int n ) { - return __wine_dbgstr_an(s, n); + return funcs.dbgstr_an(s, n); } const char *wine_dbgstr_wn( const WCHAR *s, int n ) { - return __wine_dbgstr_wn(s, n); + return funcs.dbgstr_wn(s, n); } const char *wine_dbgstr_a( const char *s ) { - return __wine_dbgstr_an( s, -1 ); + return funcs.dbgstr_an( s, -1 ); } const char *wine_dbgstr_w( const WCHAR *s ) { - return __wine_dbgstr_wn( s, -1 ); + return funcs.dbgstr_wn( s, -1 ); } + +void __wine_dbg_set_functions( const struct __wine_debug_functions *new_funcs, size_t size ) +{ + memcpy( &funcs, new_funcs, min(sizeof(funcs),size) ); +} + +static struct __wine_debug_functions funcs = +{ + default_dbgstr_an, + default_dbgstr_wn, + default_dbg_vsprintf, + default_dbg_vprintf, + default_dbg_vlog +}; diff --git a/libs/wine/wine.def b/libs/wine/wine.def index d7f1859e9e..b1adb6b8ef 100644 --- a/libs/wine/wine.def +++ b/libs/wine/wine.def @@ -2,12 +2,8 @@ LIBRARY libwine.dll EXPORTS __wine_dbg_register + __wine_dbg_set_functions __wine_dbg_unregister - __wine_dbg_vlog - __wine_dbg_vprintf - __wine_dbg_vsprintf - __wine_dbgstr_an - __wine_dbgstr_wn __wine_dll_register __wine_main_argc __wine_main_argv diff --git a/libs/wine/wine.map b/libs/wine/wine.map index 4e4104c216..f85c9c9ccc 100644 --- a/libs/wine/wine.map +++ b/libs/wine/wine.map @@ -2,12 +2,8 @@ WINE_1.0 { global: __wine_dbg_register; + __wine_dbg_set_functions; __wine_dbg_unregister; - __wine_dbg_vlog; - __wine_dbg_vprintf; - __wine_dbg_vsprintf; - __wine_dbgstr_an; - __wine_dbgstr_wn; __wine_dll_register; __wine_main_argc; __wine_main_argv; diff --git a/tools/winebuild/spec32.c b/tools/winebuild/spec32.c index 6b93931294..686207f1f6 100644 --- a/tools/winebuild/spec32.c +++ b/tools/winebuild/spec32.c @@ -56,14 +56,17 @@ static int output_debug( FILE *outfile ) if (!nb_debug_channels) return 0; qsort( debug_channels, nb_debug_channels, sizeof(debug_channels[0]), string_compare ); + fprintf( outfile, "#include \"wine/debug.h\"\n\n" ); + for (i = 0; i < nb_debug_channels; i++) - fprintf( outfile, "char __wine_dbch_%s[] = \"\\003%s\";\n", + fprintf( outfile, "struct __wine_debug_channel __wine_dbch_%s = { 3, \"%s\" };\n", debug_channels[i], debug_channels[i] ); - fprintf( outfile, "\nstatic char * const debug_channels[%d] =\n{\n", nb_debug_channels ); + fprintf( outfile, "\nstatic struct __wine_debug_channel * const debug_channels[%d] =\n{\n", + nb_debug_channels ); for (i = 0; i < nb_debug_channels; i++) { - fprintf( outfile, " __wine_dbch_%s", debug_channels[i] ); + fprintf( outfile, " &__wine_dbch_%s", debug_channels[i] ); if (i < nb_debug_channels - 1) fprintf( outfile, ",\n" ); } fprintf( outfile, "\n};\n\n" ); @@ -647,7 +650,7 @@ void BuildDebugFile( FILE *outfile, const char *srcdir, char **argv ) fprintf( outfile, "void %s(void)\n" "{\n" - " extern void *__wine_dbg_register( char * const *, int );\n" + " extern void *__wine_dbg_register( struct __wine_debug_channel * const *, int );\n" " if (!debug_registration) debug_registration = __wine_dbg_register( debug_channels, %d );\n" "}\n\n", constructor, nr_debug ); fprintf( outfile,