New debug channel mechanism allowing decentralized channel
declarations.
diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
index 9dfbccf..1d7450f 100644
--- a/dlls/ntdll/Makefile.in
+++ b/dlls/ntdll/Makefile.in
@@ -7,6 +7,7 @@
C_SRCS = \
critsection.c \
+ debugtools.c \
exception.c \
error.c \
file.c \
diff --git a/dlls/ntdll/debugtools.c b/dlls/ntdll/debugtools.c
new file mode 100644
index 0000000..22ceb34
--- /dev/null
+++ b/dlls/ntdll/debugtools.c
@@ -0,0 +1,238 @@
+/*
+ * Debugging functions
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include "debugtools.h"
+#include "thread.h"
+#include "winbase.h"
+#include "winnt.h"
+#include "wtypes.h"
+
+/* ---------------------------------------------------------------------- */
+
+struct debug_info
+{
+ char *str_pos; /* current position in strings buffer */
+ char *out_pos; /* current position in output buffer */
+ char strings[504]; /* buffer for temporary strings */
+ char output[504]; /* current output line */
+};
+
+static struct debug_info tmp;
+
+/* get the debug info pointer for the current thread */
+static inline struct debug_info *get_info(void)
+{
+ struct debug_info *info = NtCurrentTeb()->debug_info;
+ if (!info)
+ {
+ /* setup the temp structure in case HeapAlloc wants to print something */
+ NtCurrentTeb()->debug_info = &tmp;
+ tmp.str_pos = tmp.strings;
+ tmp.out_pos = tmp.output;
+ info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info) );
+ info->str_pos = info->strings;
+ info->out_pos = info->output;
+ NtCurrentTeb()->debug_info = info;
+ }
+ return info;
+}
+
+/* allocate some tmp space for a string */
+static void *gimme1(int n)
+{
+ struct debug_info *info = get_info();
+ char *res = info->str_pos;
+
+ if (res + n >= &info->strings[sizeof(info->strings)]) res = info->strings;
+ info->str_pos = res + n;
+ return res;
+}
+
+/* release extra space that we requested in gimme1() */
+static inline void release( void *ptr )
+{
+ struct debug_info *info = NtCurrentTeb()->debug_info;
+ info->str_pos = ptr;
+}
+
+/* ---------------------------------------------------------------------- */
+
+const char *debugstr_an( const char *src, int n )
+{
+ char *dst, *res;
+
+ if (!HIWORD(src))
+ {
+ if (!src) return "(null)";
+ res = gimme1(6);
+ sprintf(res, "#%04x", LOWORD(src) );
+ return res;
+ }
+ if (n < 0) n = 0;
+ dst = res = gimme1 (n * 4 + 6);
+ *dst++ = '"';
+ while (n-- > 0 && *src)
+ {
+ 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++ = '0' + ((c >> 6) & 7);
+ *dst++ = '0' + ((c >> 3) & 7);
+ *dst++ = '0' + ((c >> 0) & 7);
+ }
+ }
+ }
+ *dst++ = '"';
+ if (*src)
+ {
+ *dst++ = '.';
+ *dst++ = '.';
+ *dst++ = '.';
+ }
+ *dst++ = '\0';
+ release( dst );
+ return res;
+}
+
+/* ---------------------------------------------------------------------- */
+
+const char *debugstr_wn( const WCHAR *src, int n )
+{
+ char *dst, *res;
+
+ if (!HIWORD(src))
+ {
+ if (!src) return "(null)";
+ res = gimme1(6);
+ sprintf(res, "#%04x", LOWORD(src) );
+ return res;
+ }
+ if (n < 0) n = 0;
+ dst = res = gimme1 (n * 5 + 7);
+ *dst++ = 'L';
+ *dst++ = '"';
+ while (n-- > 0 && *src)
+ {
+ 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;
+}
+
+/* ---------------------------------------------------------------------- */
+
+const char *debugstr_guid( const GUID *id )
+{
+ char *str;
+
+ if (!id) return "(null)";
+ if (!HIWORD(id))
+ {
+ str = gimme1(12);
+ sprintf( str, "<guid-0x%04x>", LOWORD(id) );
+ }
+ else
+ {
+ str = gimme1(40);
+ sprintf( str, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ id->Data1, id->Data2, id->Data3,
+ id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
+ id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
+ }
+ return str;
+}
+
+/* ---------------------------------------------------------------------- */
+
+int wine_dbg_vprintf( const char *format, va_list args )
+{
+ struct debug_info *info = get_info();
+
+ int ret = vsprintf( info->out_pos, format, args );
+ char *p = strrchr( info->out_pos, '\n' );
+ if (!p) info->out_pos += ret;
+ else
+ {
+ char *pos = info->output;
+ p++;
+ write( 2, pos, p - pos );
+ /* move beginning of next line to start of buffer */
+ while ((*pos = *p++)) pos++;
+ info->out_pos = pos;
+ }
+ return ret;
+}
+
+int wine_dbg_printf(const char *format, ...)
+{
+ int ret;
+ va_list valist;
+
+ va_start(valist, format);
+ ret = wine_dbg_vprintf( format, valist);
+ va_end(valist);
+ return ret;
+}
+
+int __wine_dbg_header_err( const char *dbg_channel, const char *func )
+{
+ return wine_dbg_printf( "err:%s:%s ", dbg_channel + 1, func );
+}
+
+int __wine_dbg_header_fixme( const char *dbg_channel, const char *func )
+{
+ return wine_dbg_printf( "fixme:%s:%s ", dbg_channel + 1, func );
+}
+
+int __wine_dbg_header_warn( const char *dbg_channel, const char *func )
+{
+ return wine_dbg_printf( "warn:%s:%s ", dbg_channel + 1, func );
+}
+
+int __wine_dbg_header_trace( const char *dbg_channel, const char *func )
+{
+ return wine_dbg_printf( "trace:%s:%s ", dbg_channel + 1, func );
+}
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 7799499..1c66a3c 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1,6 +1,12 @@
name ntdll
type win32
+debug_channels (aspi atom cdrom console ddraw debug delayhlp dll dosfs dosmem
+ elfdll file fixup global heap int int10 int16 int17 int19 int21
+ int31 io ldt local module ntdll process profile reg relay resource
+ segment seh selector server snoop string system tape task thread
+ thunk timer toolhelp tweak ver virtual vxd win32)
+
#note that the Zw... functions are alternate names for the
#Nt... functions. (see www.sysinternals.com for details)
#if you change a Nt.. function DON'T FORGET to change the
@@ -1000,6 +1006,20 @@
@ stub RtlSetPropertySetClassId
@ stdcall NtPowerInformation(long long long long long) NtPowerInformation
+##################
# Wine extensions
+#
+# All functions must be prefixed with '__wine_' (for internal functions)
+# or 'wine_' (for user-visible functions) to avoid namespace conflicts.
+
+# Exception handling
@ cdecl __wine_exception_handler(ptr ptr ptr ptr) __wine_exception_handler
@ cdecl __wine_finally_handler(ptr ptr ptr ptr) __wine_finally_handler
+
+# Debugging interface
+@ cdecl __wine_dbg_header_err(ptr str) __wine_dbg_header_err
+@ cdecl __wine_dbg_header_fixme(ptr str) __wine_dbg_header_fixme
+@ cdecl __wine_dbg_header_warn(ptr str) __wine_dbg_header_warn
+@ cdecl __wine_dbg_header_trace(ptr str) __wine_dbg_header_trace
+@ cdecl wine_dbg_vprintf(str ptr) wine_dbg_vprintf
+@ varargs wine_dbg_printf(str) wine_dbg_printf
diff --git a/include/debugdefs.h b/include/debugdefs.h
deleted file mode 100644
index 67941f4..0000000
--- a/include/debugdefs.h
+++ /dev/null
@@ -1,365 +0,0 @@
-/* Do not modify this file -- it is automatically generated! */
-
-#include "debugtools.h"
-
-#define DEBUG_CLASS_COUNT __DBCL_COUNT
-
-static const char * const debug_cl_name[] = { "fixme", "err", "warn", "trace" };
-
-char dbch_accel[] = "\003accel";
-char dbch_advapi[] = "\003advapi";
-char dbch_animate[] = "\003animate";
-char dbch_aspi[] = "\003aspi";
-char dbch_atom[] = "\003atom";
-char dbch_avifile[] = "\003avifile";
-char dbch_bitblt[] = "\003bitblt";
-char dbch_bitmap[] = "\003bitmap";
-char dbch_caret[] = "\003caret";
-char dbch_cdrom[] = "\003cdrom";
-char dbch_class[] = "\003class";
-char dbch_clipboard[] = "\003clipboard";
-char dbch_clipping[] = "\003clipping";
-char dbch_combo[] = "\003combo";
-char dbch_comboex[] = "\003comboex";
-char dbch_comm[] = "\003comm";
-char dbch_commctrl[] = "\003commctrl";
-char dbch_commdlg[] = "\003commdlg";
-char dbch_console[] = "\003console";
-char dbch_crtdll[] = "\003crtdll";
-char dbch_cursor[] = "\003cursor";
-char dbch_datetime[] = "\003datetime";
-char dbch_dc[] = "\003dc";
-char dbch_ddeml[] = "\003ddeml";
-char dbch_ddraw[] = "\003ddraw";
-char dbch_debug[] = "\003debug";
-char dbch_debugstr[] = "\003debugstr";
-char dbch_delayhlp[] = "\003delayhlp";
-char dbch_dialog[] = "\003dialog";
-char dbch_dinput[] = "\003dinput";
-char dbch_dll[] = "\003dll";
-char dbch_dosfs[] = "\003dosfs";
-char dbch_dosmem[] = "\003dosmem";
-char dbch_dplay[] = "\003dplay";
-char dbch_driver[] = "\003driver";
-char dbch_dsound[] = "\003dsound";
-char dbch_edit[] = "\003edit";
-char dbch_elfdll[] = "\003elfdll";
-char dbch_enhmetafile[] = "\003enhmetafile";
-char dbch_event[] = "\003event";
-char dbch_exec[] = "\003exec";
-char dbch_file[] = "\003file";
-char dbch_fixup[] = "\003fixup";
-char dbch_font[] = "\003font";
-char dbch_gdi[] = "\003gdi";
-char dbch_global[] = "\003global";
-char dbch_graphics[] = "\003graphics";
-char dbch_header[] = "\003header";
-char dbch_heap[] = "\003heap";
-char dbch_hook[] = "\003hook";
-char dbch_hotkey[] = "\003hotkey";
-char dbch_icmp[] = "\003icmp";
-char dbch_icon[] = "\003icon";
-char dbch_imagehlp[] = "\003imagehlp";
-char dbch_imagelist[] = "\003imagelist";
-char dbch_imm[] = "\003imm";
-char dbch_int[] = "\003int";
-char dbch_int10[] = "\003int10";
-char dbch_int16[] = "\003int16";
-char dbch_int17[] = "\003int17";
-char dbch_int19[] = "\003int19";
-char dbch_int21[] = "\003int21";
-char dbch_int31[] = "\003int31";
-char dbch_io[] = "\003io";
-char dbch_ipaddress[] = "\003ipaddress";
-char dbch_joystick[] = "\003joystick";
-char dbch_key[] = "\003key";
-char dbch_keyboard[] = "\003keyboard";
-char dbch_ldt[] = "\003ldt";
-char dbch_listbox[] = "\003listbox";
-char dbch_listview[] = "\003listview";
-char dbch_local[] = "\003local";
-char dbch_mci[] = "\003mci";
-char dbch_mcianim[] = "\003mcianim";
-char dbch_mciavi[] = "\003mciavi";
-char dbch_mcicda[] = "\003mcicda";
-char dbch_mcimidi[] = "\003mcimidi";
-char dbch_mciwave[] = "\003mciwave";
-char dbch_mdi[] = "\003mdi";
-char dbch_menu[] = "\003menu";
-char dbch_message[] = "\003message";
-char dbch_metafile[] = "\003metafile";
-char dbch_midi[] = "\003midi";
-char dbch_mmaux[] = "\003mmaux";
-char dbch_mmio[] = "\003mmio";
-char dbch_mmsys[] = "\003mmsys";
-char dbch_mmtime[] = "\003mmtime";
-char dbch_module[] = "\003module";
-char dbch_monthcal[] = "\003monthcal";
-char dbch_mpr[] = "\003mpr";
-char dbch_msacm[] = "\003msacm";
-char dbch_msg[] = "\003msg";
-char dbch_msvideo[] = "\003msvideo";
-char dbch_nativefont[] = "\003nativefont";
-char dbch_nonclient[] = "\003nonclient";
-char dbch_ntdll[] = "\003ntdll";
-char dbch_odbc[] = "\003odbc";
-char dbch_ole[] = "\003ole";
-char dbch_opengl[] = "\003opengl";
-char dbch_pager[] = "\003pager";
-char dbch_palette[] = "\003palette";
-char dbch_pidl[] = "\003pidl";
-char dbch_print[] = "\003print";
-char dbch_process[] = "\003process";
-char dbch_profile[] = "\003profile";
-char dbch_progress[] = "\003progress";
-char dbch_prop[] = "\003prop";
-char dbch_propsheet[] = "\003propsheet";
-char dbch_psapi[] = "\003psapi";
-char dbch_psdrv[] = "\003psdrv";
-char dbch_ras[] = "\003ras";
-char dbch_rebar[] = "\003rebar";
-char dbch_reg[] = "\003reg";
-char dbch_region[] = "\003region";
-char dbch_relay[] = "\003relay";
-char dbch_resource[] = "\003resource";
-char dbch_richedit[] = "\003richedit";
-char dbch_scroll[] = "\003scroll";
-char dbch_segment[] = "\003segment";
-char dbch_seh[] = "\003seh";
-char dbch_selector[] = "\003selector";
-char dbch_sendmsg[] = "\003sendmsg";
-char dbch_server[] = "\003server";
-char dbch_setupapi[] = "\003setupapi";
-char dbch_setupx[] = "\003setupx";
-char dbch_shell[] = "\003shell";
-char dbch_snoop[] = "\003snoop";
-char dbch_sound[] = "\003sound";
-char dbch_static[] = "\003static";
-char dbch_statusbar[] = "\003statusbar";
-char dbch_storage[] = "\003storage";
-char dbch_stress[] = "\003stress";
-char dbch_string[] = "\003string";
-char dbch_syscolor[] = "\003syscolor";
-char dbch_system[] = "\003system";
-char dbch_tab[] = "\003tab";
-char dbch_tape[] = "\003tape";
-char dbch_tapi[] = "\003tapi";
-char dbch_task[] = "\003task";
-char dbch_text[] = "\003text";
-char dbch_thread[] = "\003thread";
-char dbch_thunk[] = "\003thunk";
-char dbch_timer[] = "\003timer";
-char dbch_toolbar[] = "\003toolbar";
-char dbch_toolhelp[] = "\003toolhelp";
-char dbch_tooltips[] = "\003tooltips";
-char dbch_trackbar[] = "\003trackbar";
-char dbch_treeview[] = "\003treeview";
-char dbch_ttydrv[] = "\003ttydrv";
-char dbch_tweak[] = "\003tweak";
-char dbch_typelib[] = "\003typelib";
-char dbch_updown[] = "\003updown";
-char dbch_ver[] = "\003ver";
-char dbch_virtual[] = "\003virtual";
-char dbch_vxd[] = "\003vxd";
-char dbch_wave[] = "\003wave";
-char dbch_win[] = "\003win";
-char dbch_win16drv[] = "\003win16drv";
-char dbch_win32[] = "\003win32";
-char dbch_wing[] = "\003wing";
-char dbch_wininet[] = "\003wininet";
-char dbch_winsock[] = "\003winsock";
-char dbch_winspool[] = "\003winspool";
-char dbch_wnet[] = "\003wnet";
-char dbch_x11[] = "\003x11";
-char dbch_x11drv[] = "\003x11drv";
-
-#define DEBUG_CHANNEL_COUNT 166
-
-static char * const debug_channels[DEBUG_CHANNEL_COUNT] = {
- dbch_accel,
- dbch_advapi,
- dbch_animate,
- dbch_aspi,
- dbch_atom,
- dbch_avifile,
- dbch_bitblt,
- dbch_bitmap,
- dbch_caret,
- dbch_cdrom,
- dbch_class,
- dbch_clipboard,
- dbch_clipping,
- dbch_combo,
- dbch_comboex,
- dbch_comm,
- dbch_commctrl,
- dbch_commdlg,
- dbch_console,
- dbch_crtdll,
- dbch_cursor,
- dbch_datetime,
- dbch_dc,
- dbch_ddeml,
- dbch_ddraw,
- dbch_debug,
- dbch_debugstr,
- dbch_delayhlp,
- dbch_dialog,
- dbch_dinput,
- dbch_dll,
- dbch_dosfs,
- dbch_dosmem,
- dbch_dplay,
- dbch_driver,
- dbch_dsound,
- dbch_edit,
- dbch_elfdll,
- dbch_enhmetafile,
- dbch_event,
- dbch_exec,
- dbch_file,
- dbch_fixup,
- dbch_font,
- dbch_gdi,
- dbch_global,
- dbch_graphics,
- dbch_header,
- dbch_heap,
- dbch_hook,
- dbch_hotkey,
- dbch_icmp,
- dbch_icon,
- dbch_imagehlp,
- dbch_imagelist,
- dbch_imm,
- dbch_int,
- dbch_int10,
- dbch_int16,
- dbch_int17,
- dbch_int19,
- dbch_int21,
- dbch_int31,
- dbch_io,
- dbch_ipaddress,
- dbch_joystick,
- dbch_key,
- dbch_keyboard,
- dbch_ldt,
- dbch_listbox,
- dbch_listview,
- dbch_local,
- dbch_mci,
- dbch_mcianim,
- dbch_mciavi,
- dbch_mcicda,
- dbch_mcimidi,
- dbch_mciwave,
- dbch_mdi,
- dbch_menu,
- dbch_message,
- dbch_metafile,
- dbch_midi,
- dbch_mmaux,
- dbch_mmio,
- dbch_mmsys,
- dbch_mmtime,
- dbch_module,
- dbch_monthcal,
- dbch_mpr,
- dbch_msacm,
- dbch_msg,
- dbch_msvideo,
- dbch_nativefont,
- dbch_nonclient,
- dbch_ntdll,
- dbch_odbc,
- dbch_ole,
- dbch_opengl,
- dbch_pager,
- dbch_palette,
- dbch_pidl,
- dbch_print,
- dbch_process,
- dbch_profile,
- dbch_progress,
- dbch_prop,
- dbch_propsheet,
- dbch_psapi,
- dbch_psdrv,
- dbch_ras,
- dbch_rebar,
- dbch_reg,
- dbch_region,
- dbch_relay,
- dbch_resource,
- dbch_richedit,
- dbch_scroll,
- dbch_segment,
- dbch_seh,
- dbch_selector,
- dbch_sendmsg,
- dbch_server,
- dbch_setupapi,
- dbch_setupx,
- dbch_shell,
- dbch_snoop,
- dbch_sound,
- dbch_static,
- dbch_statusbar,
- dbch_storage,
- dbch_stress,
- dbch_string,
- dbch_syscolor,
- dbch_system,
- dbch_tab,
- dbch_tape,
- dbch_tapi,
- dbch_task,
- dbch_text,
- dbch_thread,
- dbch_thunk,
- dbch_timer,
- dbch_toolbar,
- dbch_toolhelp,
- dbch_tooltips,
- dbch_trackbar,
- dbch_treeview,
- dbch_ttydrv,
- dbch_tweak,
- dbch_typelib,
- dbch_updown,
- dbch_ver,
- dbch_virtual,
- dbch_vxd,
- dbch_wave,
- dbch_win,
- dbch_win16drv,
- dbch_win32,
- dbch_wing,
- dbch_wininet,
- dbch_winsock,
- dbch_winspool,
- dbch_wnet,
- dbch_x11,
- dbch_x11drv
-};
-
-int dbg_header_err( const char *dbg_channel, const char *func )
-{
- return dbg_printf( "err:%s:%s ", dbg_channel + 1, func );
-}
-
-int dbg_header_fixme( const char *dbg_channel, const char *func )
-{
- return dbg_printf( "fixme:%s:%s ", dbg_channel + 1, func );
-}
-
-int dbg_header_warn( const char *dbg_channel, const char *func )
-{
- return dbg_printf( "warn:%s:%s ", dbg_channel + 1, func );
-}
-
-int dbg_header_trace( const char *dbg_channel, const char *func )
-{
- return dbg_printf( "trace:%s:%s ", dbg_channel + 1, func );
-}
diff --git a/include/debugtools.h b/include/debugtools.h
index 3624b4b..01c4503 100644
--- a/include/debugtools.h
+++ b/include/debugtools.h
@@ -40,59 +40,60 @@
#endif
#define __DPRINTF(dbcl,dbch) \
- (!__GET_DEBUGGING(dbcl,(dbch)) || (dbg_header_##dbcl((dbch),__FUNCTION__),0)) ? \
- (void)0 : (void)dbg_printf
+ (!__GET_DEBUGGING(dbcl,(dbch)) || (__wine_dbg_header_##dbcl((dbch),__FUNCTION__),0)) ? \
+ (void)0 : (void)wine_dbg_printf
+
+extern int __wine_dbg_header_err( const char *dbg_channel, const char *func );
+extern int __wine_dbg_header_warn( const char *dbg_channel, const char *func );
+extern int __wine_dbg_header_fixme( const char *dbg_channel, const char *func );
+extern int __wine_dbg_header_trace( const char *dbg_channel, const char *func );
/* Exported definitions and macros */
/* These function return a printable version of a string, including
quotes. The string will be valid for some time, but not indefinitely
as strings are re-used. */
-extern LPCSTR debugstr_an (LPCSTR s, int n);
-extern LPCSTR debugstr_wn (LPCWSTR s, int n);
-extern LPCSTR debugres_a (LPCSTR res);
-extern LPCSTR debugres_w (LPCWSTR res);
-extern LPCSTR debugstr_guid( const struct _GUID *id );
-extern LPCSTR debugstr_hex_dump (const void *ptr, int len);
-extern int dbg_header_err( const char *dbg_channel, const char *func );
-extern int dbg_header_warn( const char *dbg_channel, const char *func );
-extern int dbg_header_fixme( const char *dbg_channel, const char *func );
-extern int dbg_header_trace( const char *dbg_channel, const char *func );
-extern int dbg_vprintf( const char *format, va_list args );
+extern const char *debugstr_an (const char * s, int n);
+extern const char *debugstr_wn (const WCHAR *s, int n);
+extern const char *debugstr_guid( const struct _GUID *id );
-static inline LPCSTR debugstr_a( LPCSTR s ) { return debugstr_an( s, 80 ); }
-static inline LPCSTR debugstr_w( LPCWSTR s ) { return debugstr_wn( s, 80 ); }
+extern int wine_dbg_vprintf( const char *format, va_list args );
+
+inline static const char *debugstr_a( const char *s ) { return debugstr_an( s, 80 ); }
+inline static const char *debugstr_w( const WCHAR *s ) { return debugstr_wn( s, 80 ); }
+inline static const char *debugres_a( const char *s ) { return debugstr_an( s, 80 ); }
+inline static const char *debugres_w( const WCHAR *s ) { return debugstr_wn( s, 80 ); }
#ifdef __GNUC__
-extern int dbg_printf(const char *format, ...) __attribute__((format (printf,1,2)));
+extern int wine_dbg_printf(const char *format, ...) __attribute__((format (printf,1,2)));
#else
-extern int dbg_printf(const char *format, ...);
+extern int wine_dbg_printf(const char *format, ...);
#endif
-#define TRACE __DPRINTF(trace,__dbch_default)
-#define TRACE_(ch) __DPRINTF(trace,dbch_##ch)
-#define TRACE_ON(ch) __GET_DEBUGGING(trace,dbch_##ch)
+#define TRACE __DPRINTF(trace,__wine_dbch___default)
+#define TRACE_(ch) __DPRINTF(trace,__wine_dbch_##ch)
+#define TRACE_ON(ch) __GET_DEBUGGING(trace,__wine_dbch_##ch)
-#define WARN __DPRINTF(warn,__dbch_default)
-#define WARN_(ch) __DPRINTF(warn,dbch_##ch)
-#define WARN_ON(ch) __GET_DEBUGGING(warn,dbch_##ch)
+#define WARN __DPRINTF(warn,__wine_dbch___default)
+#define WARN_(ch) __DPRINTF(warn,__wine_dbch_##ch)
+#define WARN_ON(ch) __GET_DEBUGGING(warn,__wine_dbch_##ch)
-#define FIXME __DPRINTF(fixme,__dbch_default)
-#define FIXME_(ch) __DPRINTF(fixme,dbch_##ch)
-#define FIXME_ON(ch) __GET_DEBUGGING(fixme,dbch_##ch)
+#define FIXME __DPRINTF(fixme,__wine_dbch___default)
+#define FIXME_(ch) __DPRINTF(fixme,__wine_dbch_##ch)
+#define FIXME_ON(ch) __GET_DEBUGGING(fixme,__wine_dbch_##ch)
#undef ERR /* Solaris got an 'ERR' define in <sys/reg.h> */
-#define ERR __DPRINTF(err,__dbch_default)
-#define ERR_(ch) __DPRINTF(err,dbch_##ch)
-#define ERR_ON(ch) __GET_DEBUGGING(err,dbch_##ch)
+#define ERR __DPRINTF(err,__wine_dbch___default)
+#define ERR_(ch) __DPRINTF(err,__wine_dbch_##ch)
+#define ERR_ON(ch) __GET_DEBUGGING(err,__wine_dbch_##ch)
#define DECLARE_DEBUG_CHANNEL(ch) \
- extern char dbch_##ch[];
+ extern char __wine_dbch_##ch[];
#define DEFAULT_DEBUG_CHANNEL(ch) \
- extern char dbch_##ch[]; static char * const __dbch_default = dbch_##ch;
+ extern char __wine_dbch_##ch[]; static char * const __wine_dbch___default = __wine_dbch_##ch;
-#define DPRINTF dbg_printf
-#define MESSAGE dbg_printf
+#define DPRINTF wine_dbg_printf
+#define MESSAGE wine_dbg_printf
#endif /* __WINE__ */
diff --git a/include/main.h b/include/main.h
index 4472072..3a90d17 100644
--- a/include/main.h
+++ b/include/main.h
@@ -9,7 +9,6 @@
extern BOOL MAIN_MainInit(void);
extern void MAIN_WineInit(void);
-extern void MAIN_ParseDebugOptions(const char *options);
extern BOOL RELAY_Init(void);
extern int RELAY_ShowDebugmsgRelay(const char *func);
diff --git a/library/Makefile.in b/library/Makefile.in
index a6d6883..224f1fd 100644
--- a/library/Makefile.in
+++ b/library/Makefile.in
@@ -9,6 +9,7 @@
SONAME = libwine.so
C_SRCS = \
+ debug.c \
port.c
all: libwine.$(LIBEXT)
diff --git a/library/debug.c b/library/debug.c
new file mode 100644
index 0000000..3f38487
--- /dev/null
+++ b/library/debug.c
@@ -0,0 +1,118 @@
+/*
+ * Management of the debugging channels
+ *
+ * Copyright 2000 Alexandre Julliard
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+
+struct dll
+{
+ struct dll *next; /* linked list of dlls */
+ struct dll *prev;
+ char * const *channels; /* array of channels */
+ int nb_channels; /* number of channels in array */
+};
+
+static struct dll *first_dll;
+
+struct option
+{
+ struct option *next; /* next option in list */
+ unsigned char set; /* bits to set */
+ unsigned char clear; /* bits to clear */
+ char name[14]; /* channel name, or empty for "all" */
+};
+
+static struct option *first_option;
+static struct option *last_option;
+
+
+static int cmp_name( const void *p1, const void *p2 )
+{
+ const char *name = p1;
+ const char * const *chan = p2;
+ return strcmp( name, *chan + 1 );
+}
+
+/* apply a debug option to the channels of a given dll */
+static void apply_option( struct dll *dll, const struct 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;
+ }
+ else /* all */
+ {
+ int i;
+ for (i = 0; i < dll->nb_channels; i++)
+ dll->channels[i][0] = (dll->channels[i][0] & ~opt->clear) | opt->set;
+ }
+}
+
+/* register a new set of channels for a dll */
+void *wine_dbg_register( char * const *channels, int nb )
+{
+ struct option *opt = first_option;
+ struct dll *dll = malloc( sizeof(*dll) );
+ if (dll)
+ {
+ dll->channels = channels;
+ dll->nb_channels = nb;
+ dll->prev = NULL;
+ if ((dll->next = first_dll)) dll->next->prev = dll;
+ first_dll = dll;
+
+ /* apply existing options to this dll */
+ while (opt)
+ {
+ apply_option( dll, opt );
+ opt = opt->next;
+ }
+ }
+ return dll;
+}
+
+
+/* unregister a set of channels; must pass the pointer obtained from wine_dbg_register */
+void wine_dbg_unregister( void *channel )
+{
+ struct dll *dll = channel;
+ if (dll)
+ {
+ if (dll->next) dll->next->prev = dll->prev;
+ if (dll->prev) dll->prev->next = dll->next;
+ else first_dll = dll->next;
+ free( dll );
+ }
+}
+
+
+/* add a new debug option at the end of the option list */
+void wine_dbg_add_option( const char *name, unsigned char set, unsigned char clear )
+{
+ struct dll *dll = first_dll;
+ struct option *opt;
+
+ if (!(opt = malloc( sizeof(*opt) ))) return;
+ opt->next = NULL;
+ opt->set = set;
+ opt->clear = clear;
+ strncpy( opt->name, name, sizeof(opt->name) );
+ opt->name[sizeof(opt->name)-1] = 0;
+ if (last_option) last_option->next = opt;
+ else first_option = opt;
+ last_option = opt;
+
+ /* apply option to all existing dlls */
+ while (dll)
+ {
+ apply_option( dll, opt );
+ dll = dll->next;
+ }
+}
diff --git a/misc/Makefile.in b/misc/Makefile.in
index 90f1dda..84eaf58 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -9,7 +9,6 @@
C_SRCS = \
cdrom.c \
cpu.c \
- debugstr.c \
error.c \
ext_debugger.c \
lstr.c \
diff --git a/misc/debugstr.c b/misc/debugstr.c
deleted file mode 100644
index 021007a..0000000
--- a/misc/debugstr.c
+++ /dev/null
@@ -1,332 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-
-#include "debugtools.h"
-#include "thread.h"
-#include "winbase.h"
-#include "winnt.h"
-#include "wtypes.h"
-
-/* ---------------------------------------------------------------------- */
-
-struct debug_info
-{
- char *str_pos; /* current position in strings buffer */
- char *out_pos; /* current position in output buffer */
- char strings[500]; /* buffer for temporary strings */
- char output[500]; /* current output line */
-};
-
-static struct debug_info tmp;
-
-static inline struct debug_info *get_info(void)
-{
- struct debug_info *info = NtCurrentTeb()->debug_info;
- if (!info)
- {
- /* setup the temp structure in case HeapAlloc wants to print something */
- NtCurrentTeb()->debug_info = &tmp;
- tmp.str_pos = tmp.strings;
- tmp.out_pos = tmp.output;
- info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info) );
- info->str_pos = info->strings;
- info->out_pos = info->output;
- NtCurrentTeb()->debug_info = info;
- }
- return info;
-}
-
-/* ---------------------------------------------------------------------- */
-
-static void *
-gimme1 (int n)
-{
- struct debug_info *info = get_info();
- char *res = info->str_pos;
-
- if (res + n >= &info->strings[sizeof(info->strings)]) res = info->strings;
- info->str_pos = res + n;
- return res;
-}
-
-/* ---------------------------------------------------------------------- */
-
-/* release extra space that we requested in gimme1() */
-static inline void release( void *ptr )
-{
- struct debug_info *info = NtCurrentTeb()->debug_info;
- info->str_pos = ptr;
-}
-
-/* ---------------------------------------------------------------------- */
-
-LPCSTR debugstr_an (LPCSTR src, int n)
-{
- LPSTR dst, res;
-
- if (!src) return "(null)";
- if (n < 0) n = 0;
- dst = res = gimme1 (n * 4 + 6);
- *dst++ = '"';
- while (n-- > 0 && *src)
- {
- BYTE 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++ = '0' + ((c >> 6) & 7);
- *dst++ = '0' + ((c >> 3) & 7);
- *dst++ = '0' + ((c >> 0) & 7);
- }
- }
- }
- *dst++ = '"';
- if (*src)
- {
- *dst++ = '.';
- *dst++ = '.';
- *dst++ = '.';
- }
- *dst++ = '\0';
- release( dst );
- return res;
-}
-
-/* ---------------------------------------------------------------------- */
-
-LPCSTR debugstr_wn (LPCWSTR src, int n)
-{
- LPSTR dst, res;
-
- if (!src) return "(null)";
- if (n < 0) n = 0;
- dst = res = gimme1 (n * 5 + 7);
- *dst++ = 'L';
- *dst++ = '"';
- while (n-- > 0 && *src)
- {
- WORD 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;
-}
-
-/* ---------------------------------------------------------------------- */
-/* This routine returns a nicely formated name of the resource res
- If the resource name is a string, it will return '<res-name>'
- If it is a number, it will return #<4-digit-hex-number> */
-LPCSTR debugres_a( LPCSTR res )
-{
- char *resname;
- if (HIWORD(res)) return debugstr_a(res);
- resname = gimme1(6);
- sprintf(resname, "#%04x", LOWORD(res) );
- return resname;
-}
-
-LPCSTR debugres_w( LPCWSTR res )
-{
- char *resname;
- if (HIWORD(res)) return debugstr_w(res);
- resname = gimme1(6);
- sprintf( resname, "#%04x", LOWORD(res) );
- return resname;
-}
-
-/* ---------------------------------------------------------------------- */
-
-LPCSTR debugstr_guid( const GUID *id )
-{
- LPSTR str;
-
- if (!id) return "(null)";
- if (!HIWORD(id))
- {
- str = gimme1(12);
- sprintf( str, "<guid-0x%04x>", LOWORD(id) );
- }
- else
- {
- str = gimme1(40);
- sprintf( str, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
- id->Data1, id->Data2, id->Data3,
- id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
- id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] );
- }
- return str;
-}
-
-/* ---------------------------------------------------------------------- */
-
-int dbg_vprintf( const char *format, va_list args )
-{
- struct debug_info *info = get_info();
-
- int ret = vsprintf( info->out_pos, format, args );
- char *p = strrchr( info->out_pos, '\n' );
- if (!p) info->out_pos += ret;
- else
- {
- char *pos = info->output;
- p++;
- write( 2, pos, p - pos );
- /* move beginning of next line to start of buffer */
- while ((*pos = *p++)) pos++;
- info->out_pos = pos;
- }
- return ret;
-}
-
-/* ---------------------------------------------------------------------- */
-
-int dbg_printf(const char *format, ...)
-{
- int ret;
- va_list valist;
-
- va_start(valist, format);
- ret = dbg_vprintf( format, valist);
- va_end(valist);
- return ret;
-}
-
-
-/*--< Function >---------------------------------------------------------
-**
-** debugstr_hex_dump
-**
-** Description:
-** This function creates a hex dump, with a readable ascii
-** section, for displaying memory.
-**
-** Parameters:
-** 1. ptr Pointer to memory
-** 2. len How much to dump.
-**
-** Returns:
-** Temporarily allocated buffer, with the hex dump in it.
-** Don't rely on this pointer being around for very long, just
-** long enough to use it in a TRACE statement; e.g.:
-** TRACE("struct dump is \n%s", debugstr_hex_dump(&x, sizeof(x)));
-**
-**-------------------------------------------------------------------------*/
-LPCSTR debugstr_hex_dump (const void *ptr, int len)
-{
- /* Locals */
- char dumpbuf[59];
- char charbuf[20];
- char tempbuf[8];
- const char *p;
- int i;
- unsigned int nosign;
- LPSTR dst;
- LPSTR outptr;
-
-/* Begin function dbg_hex_dump */
-
- /*-----------------------------------------------------------------------
- ** Allocate an output buffer
- ** A reasonable value is one line overhand (80 chars), and
- ** then one line (80) for every 16 bytes.
- **---------------------------------------------------------------------*/
- outptr = dst = gimme1 ((len * (80 / 16)) + 80);
-
- /*-----------------------------------------------------------------------
- ** Loop throught the input buffer, one character at a time
- **---------------------------------------------------------------------*/
- for (i = 0, p = ptr; (i < len); i++, p++)
- {
-
- /*-------------------------------------------------------------------
- ** If we're just starting a line,
- ** we need to possibly flush the old line, and then
- ** intialize the line buffer.
- **-----------------------------------------------------------------*/
- if ((i % 16) == 0)
- {
- if (i)
- {
- sprintf(outptr, " %-43.43s %-16.16s\n", dumpbuf, charbuf);
- outptr += strlen(outptr);
- }
- sprintf (dumpbuf, "%04x: ", i);
- strcpy (charbuf, "");
- }
-
- /*-------------------------------------------------------------------
- ** Add the current data byte to the dump section.
- **-----------------------------------------------------------------*/
- nosign = (unsigned char) *p;
- sprintf (tempbuf, "%02X", nosign);
-
- /*-------------------------------------------------------------------
- ** If we're two DWORDS through, add a hyphen for readability,
- ** if it's a DWORD boundary, add a space for more
- ** readability.
- **-----------------------------------------------------------------*/
- if ((i % 16) == 7)
- strcat(tempbuf, " - ");
- else if ( (i % 4) == 3)
- strcat(tempbuf, " ");
- strcat (dumpbuf, tempbuf);
-
- /*-------------------------------------------------------------------
- ** Add the current byte to the character display part of the
- ** hex dump
- **-----------------------------------------------------------------*/
- sprintf (tempbuf, "%c", isprint(*p) ? *p : '.');
- strcat (charbuf, tempbuf);
- }
-
- /*-----------------------------------------------------------------------
- ** Flush the last line, if any
- **---------------------------------------------------------------------*/
- if (i > 0)
- {
- sprintf(outptr, " %-43.43s %-16.16s\n", dumpbuf, charbuf);
- outptr += strlen(outptr);
- }
-
- return(dst);
-} /* End function dbg_hex_dump */
-
-
-
diff --git a/misc/main.c b/misc/main.c
index 6233840..357db38 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -27,11 +27,13 @@
#include "msdos.h"
#include "options.h"
#include "debugtools.h"
-#include "debugdefs.h"
#include "module.h"
#include "tweak.h"
+DECLARE_DEBUG_CHANNEL(file);
+
+#if 0
/***********************************************************************
* MAIN_ParseDebugOptions
*
@@ -176,6 +178,7 @@
MESSAGE("\n\n");
ExitProcess(1);
}
+#endif
/***********************************************************************
* MAIN_WineInit
diff --git a/misc/options.c b/misc/options.c
index e1e7154..575067f 100644
--- a/misc/options.c
+++ b/misc/options.c
@@ -60,6 +60,7 @@
}
static void do_config( const char *arg );
+static void do_debugmsg( const char *arg );
static void do_desktop( const char *arg );
static void do_display( const char *arg );
static void do_dll( const char *arg );
@@ -73,7 +74,7 @@
{
{ "config", 0, 1, 0, do_config,
"--config name Specify config file to use" },
- { "debugmsg", 0, 1, 1, MAIN_ParseDebugOptions,
+ { "debugmsg", 0, 1, 1, do_debugmsg,
"--debugmsg name Turn debugging-messages on or off" },
{ "desktop", 0, 1, 1, do_desktop,
"--desktop geom Use a desktop window of the given geometry" },
@@ -157,6 +158,62 @@
Options.configFileName = xstrdup( arg );
}
+static void do_debugmsg( const char *arg )
+{
+ extern void wine_dbg_add_option( const char *name, unsigned char set, unsigned char clear );
+ static const char * const debug_class_names[__DBCL_COUNT] = { "fixme", "err", "warn", "trace" };
+
+ char *opt, *options = strdup(arg);
+ int i;
+
+ if (!(opt = strtok( options, "," ))) goto error;
+ do
+ {
+ unsigned char set = 0, clear = 0;
+ char *p = strchr( opt, '+' );
+ if (!p) p = strchr( opt, '-' );
+ if (!p || !p[1]) goto error;
+ if (p > opt)
+ {
+ for (i = 0; i < __DBCL_COUNT; i++)
+ {
+ int len = strlen(debug_class_names[i]);
+ if (len != (p - opt)) continue;
+ if (!memcmp( opt, debug_class_names[i], len )) /* found it */
+ {
+ if (*p == '+') set |= 1 << i;
+ else clear |= 1 << i;
+ break;
+ }
+ }
+ if (i == __DBCL_COUNT) goto error; /* class name not found */
+ }
+ else
+ {
+ if (*p == '+') set = ~0;
+ else clear = ~0;
+ }
+ p++;
+ if (!strcmp( p, "all" )) p = ""; /* empty string means all */
+ wine_dbg_add_option( p, set, clear );
+ opt = strtok( NULL, "," );
+ } while(opt);
+
+ free( options );
+ return;
+
+ error:
+ MESSAGE("wine: Syntax: --debugmsg [class]+xxx,... or "
+ "-debugmsg [class]-xxx,...\n");
+ MESSAGE("Example: --debugmsg +all,warn-heap\n"
+ " turn on all messages except warning heap messages\n");
+ MESSAGE("Available message classes:\n");
+ for( i = 0; i < __DBCL_COUNT; i++) MESSAGE( "%-9s", debug_class_names[i] );
+ MESSAGE("\n\n");
+ ExitProcess(1);
+}
+
+
static void remove_options( char *argv[], int pos, int count, int inherit )
{
if (inherit)
diff --git a/relay32/builtin32.c b/relay32/builtin32.c
index cdb288c..e741bc9 100644
--- a/relay32/builtin32.c
+++ b/relay32/builtin32.c
@@ -249,7 +249,7 @@
fixup_rva_ptrs( &exports->AddressOfNameOrdinals, addr, 1 );
/* Setup relay debugging entry points */
- if (WARN_ON(relay) || TRACE_ON(relay)) RELAY_SetupDLL( addr );
+ if (TRACE_ON(relay)) RELAY_SetupDLL( addr );
}
return (HMODULE)addr;
diff --git a/tools/find_debug_channels b/tools/find_debug_channels
deleted file mode 100755
index 05377e8..0000000
--- a/tools/find_debug_channels
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh
-#
-# This script scans the whole source code for symbols of the form
-# 'xxx(yyy' where:
-# xxx is either DECLARE_DEBUG_CHANNEL or DEFAULT_DEBUG_CHANNEL
-# yyy is a C identifier
-# It outputs on the standard output a sorted list of the
-# yyy identifiers found in the .c files.
-# Each identifier is reported once. Header files are not scanned.
-#
-# The script can be given an argument that specifies the files to be
-# searched according to the following scheme:
-# - if the argument does not contain a slash (/), the script
-# will search the tree rooted in the current directory for
-# files that match that description. You can also pass
-# wildcard arguments, but remember to quote them to prevent
-# expansion by the shell
-# - if the argument does contain a slash, only that file is
-# searched
-# - if no argument is given, the argument defaults to "*.c"
-# that is, all C files are searched.
-# - if more than one argument is given, only the listed files are
-# searched. Note that in this case, the script will not
-# attempt to find them in some subdirectories, but rather
-# it will try to open them in the current directory.
-# Thus, if you want to disable the automatic searching when the file
-# name does not contain a /, either prefix the filename with ./
-# or add /dev/null as another argument.
-#
-# Dimitrie O. Paun <dimi@cs.toronto.edu>
-# Patrik Stridvall <ps@leissner.se>
-#
-
-case "$#" in
- 0 | 1) files="${1:-*.c}"
- if [ "`echo "$files" | sed 's/^\(.*\)\/$/\1/g'`" = "$files" ]; then
- files=`find . -name "$files" -print`
- fi;;
- * ) files="$@";;
-esac
-
-(
-grep -h "DECLARE_DEBUG_CHANNEL *(" $files /dev/null | \
- sed 's/.*DECLARE_DEBUG_CHANNEL( *\([A-Za-z0-9_]*\) *).*/\1/g'
-grep -h "DEFAULT_DEBUG_CHANNEL *(" $files /dev/null | \
- sed 's/.*DEFAULT_DEBUG_CHANNEL( *\([A-Za-z0-9_]*\) *).*/\1/g'
-) | sort | uniq
diff --git a/tools/make_debug b/tools/make_debug
index e5a59f0..7916f8e 100755
--- a/tools/make_debug
+++ b/tools/make_debug
@@ -1,60 +1,56 @@
-#!/bin/sh
+#!/usr/bin/perl
#
-# This script generates the required file for supporting the debug
-# channels used throught the code.
-# The generated file is
-# include/debugdefs.h
-# The script must be run in the root directory of the project.
+# Update the list of debug channels of a given spec file
#
-# Dimitrie O. Paun <dimi@cs.toronto.edu>
-# Patrik Stridvall <ps@leissner.se>
+# Copyright 2000 Alexandre Julliard
+#
+# Usage: make_debug spec_file [source_files...]
#
-DEBUG_CHANNELS=`tools/find_debug_channels`
+die "Usage: make_debug spec_file [source]\n" unless @ARGV;
-exec > include/debugdefs.h
+$SPEC = shift @ARGV;
-cat <<EOF
-/* Do not modify this file -- it is automatically generated! */
-
-#include "debugtools.h"
-
-#define DEBUG_CLASS_COUNT __DBCL_COUNT
-
-static const char * const debug_cl_name[] = { "fixme", "err", "warn", "trace" };
-
-EOF
-
-chno=0
-for ch in $DEBUG_CHANNELS
-do
- echo "char dbch_$ch[] = \"\\003$ch\";"
- chno=`expr $chno + 1`
-done
-echo
-echo "#define DEBUG_CHANNEL_COUNT $chno"
-
-count=1
-echo
-echo 'static char * const debug_channels[DEBUG_CHANNEL_COUNT] = {'
-for ch in $DEBUG_CHANNELS
-do
- if [ "${count}" != "${chno}" ]; then
- echo " dbch_${ch},"
- else
- echo " dbch_${ch}"
- fi
- count=`expr $count + 1`
-done
-echo '};'
-
-for cls in err fixme warn trace
-do
- cat <<EOF
-
-int dbg_header_$cls( const char *dbg_channel, const char *func )
+# read in all the source files
+if (@ARGV)
{
- return dbg_printf( "$cls:%s:%s ", dbg_channel + 1, func );
+ while (<>)
+ {
+ if (/DECLARE_DEBUG_CHANNEL\s*\(\s*([A-Za-z0-9_]+)\s*\)/) { $channels{$1} = 1; }
+ if (/DEFAULT_DEBUG_CHANNEL\s*\(\s*([A-Za-z0-9_]+)\s*\)/) { $channels{$1} = 1; }
+ }
}
-EOF
-done
+@dbg_channels = sort keys %channels;
+
+# read the whole spec file
+undef $/;
+open SPEC or die "Cannot open $SPEC\n";
+$spec = <SPEC>;
+close SPEC;
+
+# build the new channel list
+$channel_str = "debug_channels (";
+$pos = length($channel_str);
+for ($i = 0; $i <= $#dbg_channels; $i++)
+{
+ $channel_str .= $dbg_channels[$i];
+ $pos += length($dbg_channels[$i]);
+ if ($i < $#dbg_channels)
+ {
+ if ($pos >= 75) { $pos = 16; $channel_str .= "\n" . (" " x $pos); }
+ else { $channel_str .= " "; $pos++; }
+ }
+}
+$channel_str .= ")";
+
+# replace the list in the spec file
+if (!($spec =~ s/debug_channels\s*\(([^)]*)\)/$channel_str/))
+{
+ die "Could not replace debug_channels\n" if @dbg_channels;
+ exit 0;
+}
+
+# output the modified spec file
+open OUTPUT, ">$SPEC" or die "Cannot modify $SPEC\n";
+print OUTPUT $spec;
+close OUTPUT;