diff --git a/base/shell/cmd/CMakeLists.txt b/base/shell/cmd/CMakeLists.txt index b1cf669c03a..a2f741414b4 100644 --- a/base/shell/cmd/CMakeLists.txt +++ b/base/shell/cmd/CMakeLists.txt @@ -54,6 +54,7 @@ list(APPEND SOURCE time.c timer.c title.c + trace.c type.c ver.c verify.c diff --git a/base/shell/cmd/config.h b/base/shell/cmd/config.h index 3a5b70b221a..09fb65d7e8e 100644 --- a/base/shell/cmd/config.h +++ b/base/shell/cmd/config.h @@ -18,26 +18,24 @@ /* Define to enable the alias command, and aliases.*/ #define FEATURE_ALIASES - /* Define to enable history */ #define FEATURE_HISTORY /*Define to enable history wrap (4nt's style)*/ #define WRAP_HISTORY - /* Define one of these to enable filename completion */ //#define FEATURE_UNIX_FILENAME_COMPLETION #define FEATURE_4NT_FILENAME_COMPLETION - /* Define to enable the directory stack */ #define FEATURE_DIRECTORY_STACK - /* Define to activate redirections and piping */ #define FEATURE_REDIRECTION +/* Define to enable dynamic switching of TRACE output in console */ +#define FEATURE_DYNAMIC_TRACE /* Define one of these to select the used locale. */ /* (date and time formats etc.) used in DATE, TIME, */ diff --git a/base/shell/cmd/precomp.h b/base/shell/cmd/precomp.h index 7c0e76dc3da..f2c663c712e 100644 --- a/base/shell/cmd/precomp.h +++ b/base/shell/cmd/precomp.h @@ -37,10 +37,34 @@ #include WINE_DEFAULT_DEBUG_CHANNEL(cmd); + #ifdef UNICODE #define debugstr_aw debugstr_w #else #define debugstr_aw debugstr_a #endif +#ifdef FEATURE_DYNAMIC_TRACE + +extern BOOL g_bDynamicTrace; +void CmdTrace(INT type, LPCSTR file, INT line, LPCSTR func, LPCSTR fmt, ...); + +#undef FIXME +#define FIXME(fmt, ...) \ + CmdTrace(__WINE_DBCL_FIXME, __FILE__, __LINE__, __FUNCTION__, fmt, ## __VA_ARGS__) + +#undef ERR +#define ERR(fmt, ...) \ + CmdTrace(__WINE_DBCL_ERR, __FILE__, __LINE__, __FUNCTION__, fmt, ## __VA_ARGS__) + +#undef WARN +#define WARN(fmt, ...) \ + CmdTrace(__WINE_DBCL_WARN, __FILE__, __LINE__, __FUNCTION__, fmt, ## __VA_ARGS__) + +#undef TRACE +#define TRACE(fmt, ...) \ + CmdTrace(__WINE_DBCL_TRACE, __FILE__, __LINE__, __FUNCTION__, fmt, ## __VA_ARGS__) + +#endif /* def FEATURE_DYNAMIC_TRACE */ + #endif /* __CMD_PRECOMP_H */ diff --git a/base/shell/cmd/set.c b/base/shell/cmd/set.c index 1adf091ad84..9028a181a96 100644 --- a/base/shell/cmd/set.c +++ b/base/shell/cmd/set.c @@ -175,6 +175,13 @@ INT cmd_set(LPTSTR param) } *p++ = _T('\0'); + +#ifdef FEATURE_DYNAMIC_TRACE + /* Check for dynamic TRACE ON/OFF */ + if (!_tcsicmp(param, _T("CMDTRACE"))) + g_bDynamicTrace = !_tcsicmp(p, _T("ON")); +#endif + if (!SetEnvironmentVariable(param, *p ? p : NULL)) { retval = 1; diff --git a/base/shell/cmd/trace.c b/base/shell/cmd/trace.c new file mode 100644 index 00000000000..92eb740c087 --- /dev/null +++ b/base/shell/cmd/trace.c @@ -0,0 +1,72 @@ +/* + * PROJECT: ReactOS Command Shell + * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) + * PURPOSE: Dynamic trace (generates debugging output to console output) + * COPYRIGHT: Copyright 2011 Hans Harder + * Copyright 2024 Katayama Hirofumi MZ + */ + +#include "precomp.h" + +#ifdef FEATURE_DYNAMIC_TRACE + +BOOL g_bDynamicTrace = FALSE; + +VOID CmdTrace(INT type, LPCSTR file, INT line, LPCSTR func, LPCSTR fmt, ...) +{ + va_list va; + int cch; + char szTextA[800]; +#ifdef _UNICODE + wchar_t szTextW[800]; +#endif + static struct __wine_debug_functions s_Debug; + + va_start(va, fmt); + + /* Console output */ + if (g_bDynamicTrace) + { + StringCchPrintfA(szTextA, _countof(szTextA), "%s (%d): ", file, line); + cch = lstrlenA(szTextA); + StringCchVPrintfA(&szTextA[cch], _countof(szTextA) - cch, fmt, va); + +#ifdef _UNICODE + MultiByteToWideChar(OutputCodePage, 0, szTextA, -1, szTextW, _countof(szTextW)); + szTextW[_countof(szTextW) - 1] = UNICODE_NULL; /* Avoid buffer overrun */ + ConOutPuts(szTextW); +#else + ConOutPuts(szTextA); +#endif + } + + if (!s_Debug.dbg_vlog) + __wine_dbg_set_functions(NULL, &s_Debug, sizeof(s_Debug)); + + /* Debug logging */ + switch (type) + { + case __WINE_DBCL_FIXME: + if (__WINE_IS_DEBUG_ON(_FIXME, __wine_dbch___default)) + s_Debug.dbg_vlog(__WINE_DBCL_FIXME, __wine_dbch___default, file, func, line, fmt, va); + break; + case __WINE_DBCL_ERR: + if (__WINE_IS_DEBUG_ON(_ERR, __wine_dbch___default)) + s_Debug.dbg_vlog(__WINE_DBCL_ERR, __wine_dbch___default, file, func, line, fmt, va); + break; + case __WINE_DBCL_WARN: + if (__WINE_IS_DEBUG_ON(_WARN, __wine_dbch___default)) + s_Debug.dbg_vlog(__WINE_DBCL_WARN, __wine_dbch___default, file, func, line, fmt, va); + break; + case __WINE_DBCL_TRACE: + if (__WINE_IS_DEBUG_ON(_TRACE, __wine_dbch___default)) + s_Debug.dbg_vlog(__WINE_DBCL_TRACE, __wine_dbch___default, file, func, line, fmt, va); + break; + default: + break; + } + + va_end(va); +} + +#endif /* def FEATURE_DYNAMIC_TRACE */