https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6084da8c848839a1dc1a73...
commit 6084da8c848839a1dc1a7384d02672c687b55429 Author: Hermès Bélusca-Maïto hermes.belusca-maito@reactos.org AuthorDate: Mon Mar 27 22:40:09 2023 +0200 Commit: Hermès Bélusca-Maïto hermes.belusca-maito@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@blight.eu.org + * Copyright 2023 Hermès Bélusca-Maïto hermes.belusca-maito@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()