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.
diff --git a/dlls/ntdll/debugtools.c b/dlls/ntdll/debugtools.c
index 90ffd79..80448df 100644
--- a/dlls/ntdll/debugtools.c
+++ b/dlls/ntdll/debugtools.c
@@ -282,7 +282,7 @@
/***********************************************************************
* 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 @@
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 @@
{
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 0b5c249..a6a2ca7 100644
--- a/include/wine/debug.h
+++ b/include/wine/debug.h
@@ -37,7 +37,8 @@
* 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 @@
__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 @@
#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 @@
#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 @@
#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 @@
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_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 60defa6..d66bc7c 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -58,13 +58,6 @@
/* 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 a25e468..377b950 100644
--- a/libs/wine/debug.c
+++ b/libs/wine/debug.c
@@ -35,7 +35,7 @@
{
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 @@
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 @@
{
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 @@
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 @@
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 @@
/* 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 d7f1859..b1adb6b 100644
--- a/libs/wine/wine.def
+++ b/libs/wine/wine.def
@@ -2,12 +2,8 @@
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 4e4104c..f85c9c9 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -2,12 +2,8 @@
{
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 6b93931..686207f 100644
--- a/tools/winebuild/spec32.c
+++ b/tools/winebuild/spec32.c
@@ -56,14 +56,17 @@
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 @@
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,