Defined a proper structure for debug channels.

Also put all the function pointers inside a structure and added
__wine_dbg_set_functions to change them instead of exporting the
pointers directly.
This commit is contained in:
Alexandre Julliard 2005-09-23 10:52:07 +00:00
parent 170278dfe0
commit 75c27e17b6
7 changed files with 108 additions and 81 deletions

View file

@ -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 */
}

View file

@ -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

View file

@ -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 );

View file

@ -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
};

View file

@ -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

View file

@ -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;

View file

@ -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,