https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6084da8c848839a1dc1a7…
commit 6084da8c848839a1dc1a7384d02672c687b55429
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon Mar 27 22:40:09 2023 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Mon Mar 27 23:31:34 2023 +0200
[NTOS:KDBG] Move command history management in a separate file. Simplify duplicated
code in KdbpReadCommand.
---
ntoskrnl/kdbg/kdb.h | 9 +++
ntoskrnl/kdbg/kdb_cli.c | 140 +++-----------------------------------
ntoskrnl/kdbg/kdb_cmdhist.c | 162 ++++++++++++++++++++++++++++++++++++++++++++
ntoskrnl/ntos.cmake | 1 +
4 files changed, 182 insertions(+), 130 deletions(-)
diff --git a/ntoskrnl/kdbg/kdb.h b/ntoskrnl/kdbg/kdb.h
index cd7a0b5bec6..ac3f8b13004 100644
--- a/ntoskrnl/kdbg/kdb.h
+++ b/ntoskrnl/kdbg/kdb.h
@@ -104,6 +104,15 @@ KdbpCliMainLoop(
VOID
KdbpCliInterpretInitFile(VOID);
+VOID
+KdbpCommandHistoryAppend(
+ _In_ PCSTR Command);
+
+PCSTR
+KdbGetHistoryEntry(
+ _Inout_ PLONG NextIndex,
+ _In_ BOOLEAN Next);
+
SIZE_T
KdbpReadCommand(
_Out_ PCHAR Buffer,
diff --git a/ntoskrnl/kdbg/kdb_cli.c b/ntoskrnl/kdbg/kdb_cli.c
index f114a862958..b50d18b692f 100644
--- a/ntoskrnl/kdbg/kdb_cli.c
+++ b/ntoskrnl/kdbg/kdb_cli.c
@@ -140,11 +140,6 @@ static PKDBG_CLI_ROUTINE KdbCliCallbacks[10];
static BOOLEAN KdbUseIntelSyntax = FALSE; /* Set to TRUE for intel syntax */
static BOOLEAN KdbBreakOnModuleLoad = FALSE; /* Set to TRUE to break into KDB when a
module is loaded */
-static CHAR KdbCommandHistoryBuffer[2048]; /* Command history string ringbuffer */
-static PCHAR KdbCommandHistory[sizeof(KdbCommandHistoryBuffer) / 8] = { NULL }; /*
Command history ringbuffer */
-static LONG KdbCommandHistoryBufferIndex = 0;
-static LONG KdbCommandHistoryIndex = 0;
-
static ULONG KdbNumberOfRowsPrinted = 0;
static ULONG KdbNumberOfColsPrinted = 0;
static BOOLEAN KdbOutputAborted = FALSE;
@@ -3262,77 +3257,6 @@ KdbpPrintUnicodeString(
}
-/*!\brief Appends a command to the command history
- *
- * \param Command Pointer to the command to append to the history.
- */
-static VOID
-KdbpCommandHistoryAppend(
- IN PCHAR Command)
-{
- SIZE_T Length1 = strlen(Command) + 1;
- SIZE_T Length2 = 0;
- INT i;
- PCHAR Buffer;
-
- ASSERT(Length1 <= RTL_NUMBER_OF(KdbCommandHistoryBuffer));
-
- if (Length1 <= 1 ||
- (KdbCommandHistory[KdbCommandHistoryIndex] &&
- strcmp(KdbCommandHistory[KdbCommandHistoryIndex], Command) == 0))
- {
- return;
- }
-
- /* Calculate Length1 and Length2 */
- Buffer = KdbCommandHistoryBuffer + KdbCommandHistoryBufferIndex;
- KdbCommandHistoryBufferIndex += Length1;
- if (KdbCommandHistoryBufferIndex >=
(LONG)RTL_NUMBER_OF(KdbCommandHistoryBuffer))
- {
- KdbCommandHistoryBufferIndex -= RTL_NUMBER_OF(KdbCommandHistoryBuffer);
- Length2 = KdbCommandHistoryBufferIndex;
- Length1 -= Length2;
- }
-
- /* Remove previous commands until there is enough space to append the new command
*/
- for (i = KdbCommandHistoryIndex; KdbCommandHistory[i];)
- {
- if ((Length2 > 0 &&
- (KdbCommandHistory[i] >= Buffer ||
- KdbCommandHistory[i] < (KdbCommandHistoryBuffer +
KdbCommandHistoryBufferIndex))) ||
- (Length2 <= 0 &&
- (KdbCommandHistory[i] >= Buffer &&
- KdbCommandHistory[i] < (KdbCommandHistoryBuffer +
KdbCommandHistoryBufferIndex))))
- {
- KdbCommandHistory[i] = NULL;
- }
-
- i--;
- if (i < 0)
- i = RTL_NUMBER_OF(KdbCommandHistory) - 1;
-
- if (i == KdbCommandHistoryIndex)
- break;
- }
-
- /* Make sure the new command history entry is free */
- KdbCommandHistoryIndex++;
- KdbCommandHistoryIndex %= RTL_NUMBER_OF(KdbCommandHistory);
- if (KdbCommandHistory[KdbCommandHistoryIndex])
- {
- KdbCommandHistory[KdbCommandHistoryIndex] = NULL;
- }
-
- /* Append command */
- KdbCommandHistory[KdbCommandHistoryIndex] = Buffer;
- ASSERT((KdbCommandHistory[KdbCommandHistoryIndex] + Length1) <=
KdbCommandHistoryBuffer + RTL_NUMBER_OF(KdbCommandHistoryBuffer));
- memcpy(KdbCommandHistory[KdbCommandHistoryIndex], Command, Length1);
- if (Length2 > 0)
- {
- memcpy(KdbCommandHistoryBuffer, Command + Length1, Length2);
- }
-}
-
/**
* @brief Reads a line of user input from the terminal.
*
@@ -3358,8 +3282,7 @@ KdbpReadCommand(
BOOLEAN EchoOn;
static CHAR LastCommand[1024];
static CHAR NextKey = '\0';
- INT CmdHistIndex = -1;
- INT_PTR i;
+ LONG CmdHistIndex = -1; // Start at end of history.
/* Bail out if the buffer is zero-sized */
if (Size == 0)
@@ -3445,6 +3368,7 @@ KdbpReadCommand(
}
else if (Key == KEY_BS || Key == KEY_DEL)
{
+ /* Erase the last character */
if (Buffer > Orig)
{
Buffer--;
@@ -3456,29 +3380,15 @@ KdbpReadCommand(
KdpDprintf(" %c", KEY_BS);
}
}
- else if (ScanCode == KEY_SCAN_UP)
+ else if (ScanCode == KEY_SCAN_UP || ScanCode == KEY_SCAN_DOWN)
{
- BOOLEAN Print = TRUE;
-
- if (CmdHistIndex < 0)
+ PCSTR CmdHistory = KdbGetHistoryEntry(&CmdHistIndex,
+ (ScanCode == KEY_SCAN_DOWN));
+ if (CmdHistory)
{
- CmdHistIndex = KdbCommandHistoryIndex;
- }
- else
- {
- i = CmdHistIndex - 1;
-
- if (i < 0)
- CmdHistIndex = RTL_NUMBER_OF(KdbCommandHistory) - 1;
-
- if (KdbCommandHistory[i] && i != KdbCommandHistoryIndex)
- CmdHistIndex = i;
- else
- Print = FALSE;
- }
+ SIZE_T i;
- if (Print && KdbCommandHistory[CmdHistIndex])
- {
+ /* Erase the whole line */
while (Buffer > Orig)
{
Buffer--;
@@ -3490,43 +3400,13 @@ KdbpReadCommand(
KdpDprintf(" %c", KEY_BS);
}
- i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
- memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
+ i = min(strlen(CmdHistory), Size - 1);
+ memcpy(Orig, CmdHistory, i);
Orig[i] = '\0';
Buffer = Orig + i;
KdpDprintf("%s", Orig);
}
}
- else if (ScanCode == KEY_SCAN_DOWN)
- {
- if (CmdHistIndex > 0 && CmdHistIndex != KdbCommandHistoryIndex)
- {
- i = CmdHistIndex + 1;
- if (i >= (INT)RTL_NUMBER_OF(KdbCommandHistory))
- i = 0;
-
- if (KdbCommandHistory[i])
- {
- CmdHistIndex = i;
- while (Buffer > Orig)
- {
- Buffer--;
- *Buffer = '\0';
-
- if (EchoOn)
- KdpDprintf("%c %c", KEY_BS, KEY_BS);
- else
- KdpDprintf(" %c", KEY_BS);
- }
-
- i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
- memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
- Orig[i] = '\0';
- Buffer = Orig + i;
- KdpDprintf("%s", Orig);
- }
- }
- }
else
{
/* Don't accept any key if the buffer is full */
diff --git a/ntoskrnl/kdbg/kdb_cmdhist.c b/ntoskrnl/kdbg/kdb_cmdhist.c
new file mode 100644
index 00000000000..c1f1fcb1eae
--- /dev/null
+++ b/ntoskrnl/kdbg/kdb_cmdhist.c
@@ -0,0 +1,162 @@
+/*
+ * PROJECT: ReactOS KDBG Kernel Debugger
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Command History helpers
+ * COPYRIGHT: Copyright 2005 Gregor Anich <blight(a)blight.eu.org>
+ * Copyright 2023 Hermès Bélusca-Maïto
<hermes.belusca-maito(a)reactos.org>
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+
+/* GLOBALS *******************************************************************/
+
+/**
+ * History range in ring buffer:
+ * (KdbCommandHistoryIndex; RTL_NUMBER_OF(KdbCommandHistory) - 1]
+ * and [0; KdbCommandHistoryIndex].
+ **/
+
+/* Command history string ring buffer */
+static CHAR KdbCommandHistoryBuffer[2048];
+/* Command history ring buffer */
+static PCHAR KdbCommandHistory[sizeof(KdbCommandHistoryBuffer) / 8] = { NULL };
+static LONG KdbCommandHistoryBufferIndex = 0;
+static LONG KdbCommandHistoryIndex = 0;
+
+/* FUNCTIONS *****************************************************************/
+
+/**
+ * @brief Appends a command to the command history.
+ *
+ * @param[in] Command
+ * Pointer to the command to append to the history.
+ **/
+VOID
+KdbpCommandHistoryAppend(
+ _In_ PCSTR Command)
+{
+ SIZE_T Length1 = strlen(Command) + 1;
+ SIZE_T Length2 = 0;
+ LONG i;
+ PCHAR Buffer;
+
+ ASSERT(Length1 <= RTL_NUMBER_OF(KdbCommandHistoryBuffer));
+
+ /*
+ * Do not append the string if:
+ * - it is empty (just the NULL terminator);
+ * - or the last command is the same.
+ */
+ if (Length1 <= 1 ||
+ (KdbCommandHistory[KdbCommandHistoryIndex] &&
+ strcmp(KdbCommandHistory[KdbCommandHistoryIndex], Command) == 0))
+ {
+ return;
+ }
+
+ /* Calculate Length1 and Length2 */
+ Buffer = KdbCommandHistoryBuffer + KdbCommandHistoryBufferIndex;
+ KdbCommandHistoryBufferIndex += Length1;
+ if (KdbCommandHistoryBufferIndex >=
(LONG)RTL_NUMBER_OF(KdbCommandHistoryBuffer))
+ {
+ KdbCommandHistoryBufferIndex -= RTL_NUMBER_OF(KdbCommandHistoryBuffer);
+ Length2 = KdbCommandHistoryBufferIndex;
+ Length1 -= Length2;
+ }
+
+ /* Remove previous commands until there is enough space to append the new command
*/
+ for (i = KdbCommandHistoryIndex; KdbCommandHistory[i];)
+ {
+ if ((Length2 > 0 &&
+ (KdbCommandHistory[i] >= Buffer ||
+ KdbCommandHistory[i] < (KdbCommandHistoryBuffer +
KdbCommandHistoryBufferIndex))) ||
+ (Length2 <= 0 &&
+ (KdbCommandHistory[i] >= Buffer &&
+ KdbCommandHistory[i] < (KdbCommandHistoryBuffer +
KdbCommandHistoryBufferIndex))))
+ {
+ KdbCommandHistory[i] = NULL;
+ }
+
+ i--;
+ if (i < 0)
+ i = RTL_NUMBER_OF(KdbCommandHistory) - 1;
+
+ if (i == KdbCommandHistoryIndex)
+ break;
+ }
+
+ /* Make sure the new command history entry is free */
+ KdbCommandHistoryIndex++;
+ KdbCommandHistoryIndex %= RTL_NUMBER_OF(KdbCommandHistory);
+ if (KdbCommandHistory[KdbCommandHistoryIndex])
+ {
+ KdbCommandHistory[KdbCommandHistoryIndex] = NULL;
+ }
+
+ /* Append command */
+ KdbCommandHistory[KdbCommandHistoryIndex] = Buffer;
+ ASSERT((KdbCommandHistory[KdbCommandHistoryIndex] + Length1) <=
KdbCommandHistoryBuffer + RTL_NUMBER_OF(KdbCommandHistoryBuffer));
+ memcpy(KdbCommandHistory[KdbCommandHistoryIndex], Command, Length1);
+ if (Length2 > 0)
+ {
+ memcpy(KdbCommandHistoryBuffer, Command + Length1, Length2);
+ }
+}
+
+static PCSTR
+KdbpGetPrevHistoryEntry(
+ _Inout_ PLONG NextIndex)
+{
+ if (*NextIndex < 0)
+ {
+ /* Start at the end of the history */
+ *NextIndex = KdbCommandHistoryIndex;
+ }
+ else
+ {
+ LONG i = *NextIndex - 1;
+ if (i < 0)
+ *NextIndex = RTL_NUMBER_OF(KdbCommandHistory) - 1;
+
+ if (KdbCommandHistory[i] && i != KdbCommandHistoryIndex)
+ *NextIndex = i;
+ else
+ return NULL;
+ }
+
+ return KdbCommandHistory[*NextIndex];
+}
+
+static PCSTR
+KdbpGetNextHistoryEntry(
+ _Inout_ PLONG NextIndex)
+{
+ LONG i;
+
+ if (!(*NextIndex > 0 && *NextIndex != KdbCommandHistoryIndex))
+ return NULL;
+
+ i = *NextIndex + 1;
+ if (i >= (LONG)RTL_NUMBER_OF(KdbCommandHistory))
+ i = 0;
+
+ if (KdbCommandHistory[i])
+ *NextIndex = i;
+
+ return KdbCommandHistory[i];
+}
+
+PCSTR
+KdbGetHistoryEntry(
+ _Inout_ PLONG NextIndex,
+ _In_ BOOLEAN Next)
+{
+ if (Next)
+ return KdbpGetNextHistoryEntry(NextIndex);
+ else
+ return KdbpGetPrevHistoryEntry(NextIndex);
+}
+
+/* EOF */
diff --git a/ntoskrnl/ntos.cmake b/ntoskrnl/ntos.cmake
index 6816452fab4..648de8faf6b 100644
--- a/ntoskrnl/ntos.cmake
+++ b/ntoskrnl/ntos.cmake
@@ -405,6 +405,7 @@ if(NOT _WINKD_)
list(APPEND SOURCE
${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdb.c
${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdb_cli.c
+ ${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdb_cmdhist.c
${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdb_expr.c
${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdb_symbols.c)
endif()