mirror of
https://github.com/reactos/reactos.git
synced 2025-05-30 22:49:12 +00:00
[NTOS:KDBG] Move command history management in a separate file. Simplify duplicated code in KdbpReadCommand.
This commit is contained in:
parent
eb02a85214
commit
6084da8c84
4 changed files with 182 additions and 130 deletions
|
@ -104,6 +104,15 @@ KdbpCliMainLoop(
|
||||||
VOID
|
VOID
|
||||||
KdbpCliInterpretInitFile(VOID);
|
KdbpCliInterpretInitFile(VOID);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
KdbpCommandHistoryAppend(
|
||||||
|
_In_ PCSTR Command);
|
||||||
|
|
||||||
|
PCSTR
|
||||||
|
KdbGetHistoryEntry(
|
||||||
|
_Inout_ PLONG NextIndex,
|
||||||
|
_In_ BOOLEAN Next);
|
||||||
|
|
||||||
SIZE_T
|
SIZE_T
|
||||||
KdbpReadCommand(
|
KdbpReadCommand(
|
||||||
_Out_ PCHAR Buffer,
|
_Out_ PCHAR Buffer,
|
||||||
|
|
|
@ -140,11 +140,6 @@ static PKDBG_CLI_ROUTINE KdbCliCallbacks[10];
|
||||||
static BOOLEAN KdbUseIntelSyntax = FALSE; /* Set to TRUE for intel syntax */
|
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 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 KdbNumberOfRowsPrinted = 0;
|
||||||
static ULONG KdbNumberOfColsPrinted = 0;
|
static ULONG KdbNumberOfColsPrinted = 0;
|
||||||
static BOOLEAN KdbOutputAborted = FALSE;
|
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.
|
* @brief Reads a line of user input from the terminal.
|
||||||
*
|
*
|
||||||
|
@ -3358,8 +3282,7 @@ KdbpReadCommand(
|
||||||
BOOLEAN EchoOn;
|
BOOLEAN EchoOn;
|
||||||
static CHAR LastCommand[1024];
|
static CHAR LastCommand[1024];
|
||||||
static CHAR NextKey = '\0';
|
static CHAR NextKey = '\0';
|
||||||
INT CmdHistIndex = -1;
|
LONG CmdHistIndex = -1; // Start at end of history.
|
||||||
INT_PTR i;
|
|
||||||
|
|
||||||
/* Bail out if the buffer is zero-sized */
|
/* Bail out if the buffer is zero-sized */
|
||||||
if (Size == 0)
|
if (Size == 0)
|
||||||
|
@ -3445,6 +3368,7 @@ KdbpReadCommand(
|
||||||
}
|
}
|
||||||
else if (Key == KEY_BS || Key == KEY_DEL)
|
else if (Key == KEY_BS || Key == KEY_DEL)
|
||||||
{
|
{
|
||||||
|
/* Erase the last character */
|
||||||
if (Buffer > Orig)
|
if (Buffer > Orig)
|
||||||
{
|
{
|
||||||
Buffer--;
|
Buffer--;
|
||||||
|
@ -3456,29 +3380,15 @@ KdbpReadCommand(
|
||||||
KdpDprintf(" %c", KEY_BS);
|
KdpDprintf(" %c", KEY_BS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ScanCode == KEY_SCAN_UP)
|
else if (ScanCode == KEY_SCAN_UP || ScanCode == KEY_SCAN_DOWN)
|
||||||
{
|
{
|
||||||
BOOLEAN Print = TRUE;
|
PCSTR CmdHistory = KdbGetHistoryEntry(&CmdHistIndex,
|
||||||
|
(ScanCode == KEY_SCAN_DOWN));
|
||||||
if (CmdHistIndex < 0)
|
if (CmdHistory)
|
||||||
{
|
{
|
||||||
CmdHistIndex = KdbCommandHistoryIndex;
|
SIZE_T i;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i = CmdHistIndex - 1;
|
|
||||||
|
|
||||||
if (i < 0)
|
/* Erase the whole line */
|
||||||
CmdHistIndex = RTL_NUMBER_OF(KdbCommandHistory) - 1;
|
|
||||||
|
|
||||||
if (KdbCommandHistory[i] && i != KdbCommandHistoryIndex)
|
|
||||||
CmdHistIndex = i;
|
|
||||||
else
|
|
||||||
Print = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Print && KdbCommandHistory[CmdHistIndex])
|
|
||||||
{
|
|
||||||
while (Buffer > Orig)
|
while (Buffer > Orig)
|
||||||
{
|
{
|
||||||
Buffer--;
|
Buffer--;
|
||||||
|
@ -3490,43 +3400,13 @@ KdbpReadCommand(
|
||||||
KdpDprintf(" %c", KEY_BS);
|
KdpDprintf(" %c", KEY_BS);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
|
i = min(strlen(CmdHistory), Size - 1);
|
||||||
memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
|
memcpy(Orig, CmdHistory, i);
|
||||||
Orig[i] = '\0';
|
Orig[i] = '\0';
|
||||||
Buffer = Orig + i;
|
Buffer = Orig + i;
|
||||||
KdpDprintf("%s", Orig);
|
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
|
else
|
||||||
{
|
{
|
||||||
/* Don't accept any key if the buffer is full */
|
/* Don't accept any key if the buffer is full */
|
||||||
|
|
162
ntoskrnl/kdbg/kdb_cmdhist.c
Normal file
162
ntoskrnl/kdbg/kdb_cmdhist.c
Normal file
|
@ -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 */
|
|
@ -405,6 +405,7 @@ if(NOT _WINKD_)
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdb.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdb.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdb_cli.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_expr.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdb_symbols.c)
|
${REACTOS_SOURCE_DIR}/ntoskrnl/kdbg/kdb_symbols.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
Loading…
Reference in a new issue