mirror of
https://github.com/reactos/reactos.git
synced 2025-04-02 19:53:19 +00:00
[NTOS:KDBG] Deduplicate code between KdbpPrint() and KdbpPager().
This commit is contained in:
parent
8940614a78
commit
9337ea6a3c
2 changed files with 208 additions and 351 deletions
|
@ -98,10 +98,15 @@ KdbpCliMainLoop(
|
|||
VOID
|
||||
KdbpCliInterpretInitFile(VOID);
|
||||
|
||||
VOID
|
||||
KdbpPager(
|
||||
_In_ PCHAR Buffer,
|
||||
_In_ ULONG BufLength);
|
||||
|
||||
VOID
|
||||
KdbpPrint(
|
||||
IN PCHAR Format,
|
||||
IN ... OPTIONAL);
|
||||
_In_ PSTR Format,
|
||||
_In_ ...);
|
||||
|
||||
VOID
|
||||
KdbpPrintUnicodeString(
|
||||
|
|
|
@ -2526,12 +2526,6 @@ KdbpCmdReboot(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
KdbpPager(
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufLength);
|
||||
|
||||
/*!\brief Display debug messages on screen, with paging.
|
||||
*
|
||||
* Keys for per-page view: Home, End, PageUp, Arrow Up, PageDown,
|
||||
|
@ -2787,266 +2781,9 @@ KdbpCmdHelp(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*!\brief Prints the given string with printf-like formatting.
|
||||
*
|
||||
* \param Format Format of the string/arguments.
|
||||
* \param ... Variable number of arguments matching the format specified in \a Format.
|
||||
*
|
||||
* \note Doesn't correctly handle \\t and terminal escape sequences when calculating the
|
||||
* number of lines required to print a single line from the Buffer in the terminal.
|
||||
* Prints maximum 4096 chars, because of its buffer size.
|
||||
* Uses KdpDPrintf internally (NOT DbgPrint!). Callers must already hold the debugger lock.
|
||||
*/
|
||||
VOID
|
||||
KdbpPrint(
|
||||
IN PCHAR Format,
|
||||
IN ... OPTIONAL)
|
||||
{
|
||||
static CHAR Buffer[4096];
|
||||
static BOOLEAN TerminalInitialized = FALSE;
|
||||
static BOOLEAN TerminalConnected = FALSE;
|
||||
static BOOLEAN TerminalReportsSize = TRUE;
|
||||
CHAR c = '\0';
|
||||
PCHAR p, p2;
|
||||
ULONG Length;
|
||||
SIZE_T i, j;
|
||||
LONG RowsPrintedByTerminal;
|
||||
ULONG ScanCode;
|
||||
va_list ap;
|
||||
|
||||
/* Check if the user has aborted output of the current command */
|
||||
if (KdbOutputAborted)
|
||||
return;
|
||||
|
||||
/* Initialize the terminal */
|
||||
if (!TerminalInitialized)
|
||||
{
|
||||
KdpDprintf("\x1b[7h"); /* Enable linewrap */
|
||||
|
||||
/* Query terminal type */
|
||||
/*DbgPrint("\x1b[Z");*/
|
||||
KdpDprintf("\x05");
|
||||
|
||||
TerminalInitialized = TRUE;
|
||||
Length = 0;
|
||||
KeStallExecutionProcessor(100000);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
c = KdbpTryGetCharSerial(5000);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
Buffer[Length++] = c;
|
||||
if (Length >= (sizeof(Buffer) - 1))
|
||||
break;
|
||||
}
|
||||
|
||||
Buffer[Length] = '\0';
|
||||
if (Length > 0)
|
||||
TerminalConnected = TRUE;
|
||||
}
|
||||
|
||||
/* Get number of rows and columns in terminal */
|
||||
if ((KdbNumberOfRowsTerminal < 0) || (KdbNumberOfColsTerminal < 0) ||
|
||||
(KdbNumberOfRowsPrinted) == 0) /* Refresh terminal size each time when number of rows printed is 0 */
|
||||
{
|
||||
if ((KdbDebugState & KD_DEBUG_KDSERIAL) && TerminalConnected && TerminalReportsSize)
|
||||
{
|
||||
/* Try to query number of rows from terminal. A reply looks like "\x1b[8;24;80t" */
|
||||
TerminalReportsSize = FALSE;
|
||||
KeStallExecutionProcessor(100000);
|
||||
KdpDprintf("\x1b[18t");
|
||||
c = KdbpTryGetCharSerial(5000);
|
||||
|
||||
if (c == KEY_ESC)
|
||||
{
|
||||
c = KdbpTryGetCharSerial(5000);
|
||||
if (c == '[')
|
||||
{
|
||||
Length = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
c = KdbpTryGetCharSerial(5000);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
Buffer[Length++] = c;
|
||||
if (isalpha(c) || Length >= (sizeof(Buffer) - 1))
|
||||
break;
|
||||
}
|
||||
|
||||
Buffer[Length] = '\0';
|
||||
if (Buffer[0] == '8' && Buffer[1] == ';')
|
||||
{
|
||||
for (i = 2; (i < Length) && (Buffer[i] != ';'); i++);
|
||||
|
||||
if (Buffer[i] == ';')
|
||||
{
|
||||
Buffer[i++] = '\0';
|
||||
|
||||
/* Number of rows is now at Buffer + 2 and number of cols at Buffer + i */
|
||||
KdbNumberOfRowsTerminal = strtoul(Buffer + 2, NULL, 0);
|
||||
KdbNumberOfColsTerminal = strtoul(Buffer + i, NULL, 0);
|
||||
TerminalReportsSize = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Clear further characters */
|
||||
while ((c = KdbpTryGetCharSerial(5000)) != -1);
|
||||
}
|
||||
}
|
||||
|
||||
if (KdbNumberOfRowsTerminal <= 0)
|
||||
{
|
||||
/* Set number of rows to the default. */
|
||||
KdbNumberOfRowsTerminal = 23; //24; //Mna.: 23 for SCREEN debugport
|
||||
}
|
||||
else if (KdbNumberOfColsTerminal <= 0)
|
||||
{
|
||||
/* Set number of cols to the default. */
|
||||
KdbNumberOfColsTerminal = 75; //80; //Mna.: 75 for SCREEN debugport
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the string */
|
||||
va_start(ap, Format);
|
||||
Length = _vsnprintf(Buffer, sizeof(Buffer) - 1, Format, ap);
|
||||
Buffer[Length] = '\0';
|
||||
va_end(ap);
|
||||
|
||||
p = Buffer;
|
||||
while (p[0] != '\0')
|
||||
{
|
||||
i = strcspn(p, "\n");
|
||||
|
||||
/* Calculate the number of lines which will be printed in the terminal
|
||||
* when outputting the current line
|
||||
*/
|
||||
if (i > 0)
|
||||
RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) / KdbNumberOfColsTerminal;
|
||||
else
|
||||
RowsPrintedByTerminal = 0;
|
||||
|
||||
if (p[i] == '\n')
|
||||
RowsPrintedByTerminal++;
|
||||
|
||||
/*DbgPrint("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);*/
|
||||
|
||||
/* Display a prompt if we printed one screen full of text */
|
||||
if (KdbNumberOfRowsTerminal > 0 &&
|
||||
(LONG)(KdbNumberOfRowsPrinted + RowsPrintedByTerminal) >= KdbNumberOfRowsTerminal)
|
||||
{
|
||||
KdbRepeatLastCommand = FALSE;
|
||||
|
||||
if (KdbNumberOfColsPrinted > 0)
|
||||
KdpDprintf("\n");
|
||||
|
||||
KdpDprintf("--- Press q to abort, any other key to continue ---");
|
||||
RowsPrintedByTerminal++; /* added by Mna. */
|
||||
|
||||
if (KdbDebugState & KD_DEBUG_KDSERIAL)
|
||||
c = KdbpGetCharSerial();
|
||||
else
|
||||
c = KdbpGetCharKeyboard(&ScanCode);
|
||||
|
||||
if (c == '\r')
|
||||
{
|
||||
/* Try to read '\n' which might follow '\r' - if \n is not received here
|
||||
* it will be interpreted as "return" when the next command should be read.
|
||||
*/
|
||||
if (KdbDebugState & KD_DEBUG_KDSERIAL)
|
||||
c = KdbpTryGetCharSerial(5);
|
||||
else
|
||||
c = KdbpTryGetCharKeyboard(&ScanCode, 5);
|
||||
}
|
||||
|
||||
KdpDprintf("\n");
|
||||
if (c == 'q')
|
||||
{
|
||||
KdbOutputAborted = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
KdbNumberOfRowsPrinted = 0;
|
||||
KdbNumberOfColsPrinted = 0;
|
||||
}
|
||||
|
||||
/* Insert a NUL after the line and print only the current line. */
|
||||
if (p[i] == '\n' && p[i + 1] != '\0')
|
||||
{
|
||||
c = p[i + 1];
|
||||
p[i + 1] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
c = '\0';
|
||||
}
|
||||
|
||||
/* Remove escape sequences from the line if there's no terminal connected */
|
||||
if (!TerminalConnected)
|
||||
{
|
||||
while ((p2 = strrchr(p, '\x1b'))) /* Look for escape character */
|
||||
{
|
||||
size_t len = strlen(p2);
|
||||
if (p2[1] == '[')
|
||||
{
|
||||
j = 2;
|
||||
while (!isalpha(p2[j++]));
|
||||
memmove(p2, p2 + j, len + 1 - j);
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(p2, p2 + 1, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
KdpDprintf("%s", p);
|
||||
|
||||
if (c != '\0')
|
||||
p[i + 1] = c;
|
||||
|
||||
/* Set p to the start of the next line and
|
||||
* remember the number of rows/cols printed
|
||||
*/
|
||||
p += i;
|
||||
if (p[0] == '\n')
|
||||
{
|
||||
p++;
|
||||
KdbNumberOfColsPrinted = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(p[0] == '\0');
|
||||
KdbNumberOfColsPrinted += i;
|
||||
}
|
||||
|
||||
KdbNumberOfRowsPrinted += RowsPrintedByTerminal;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
KdbpPrintUnicodeString(
|
||||
_In_ PCUNICODE_STRING String)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
if ((String == NULL) || (String->Buffer == NULL))
|
||||
{
|
||||
KdbpPrint("<NULL>");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < String->Length / sizeof(WCHAR); i++)
|
||||
{
|
||||
KdbpPrint("%c", (CHAR)String->Buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** memrchr(), explicitly defined, since was absent in MinGW of RosBE. */
|
||||
/*
|
||||
* memrchr(), explicitly defined, since absent in the CRT.
|
||||
* Reverse memchr()
|
||||
* Find the last occurrence of 'c' in the buffer 's' of size 'n'.
|
||||
*/
|
||||
|
@ -3078,14 +2815,17 @@ memrchr(const void *s, int c, size_t n)
|
|||
* Used by KdbpPager().
|
||||
* Now N lines count is hardcoded to KdbNumberOfRowsTerminal.
|
||||
*/
|
||||
PCHAR
|
||||
CountOnePageUp(PCHAR Buffer, ULONG BufLength, PCHAR pCurPos)
|
||||
static PCHAR
|
||||
CountOnePageUp(
|
||||
_In_ PCCH Buffer,
|
||||
_In_ ULONG BufLength,
|
||||
_In_ PCCH pCurPos)
|
||||
{
|
||||
PCHAR p;
|
||||
PCCH p;
|
||||
// p0 is initial guess of Page Start
|
||||
ULONG p0len = KdbNumberOfRowsTerminal * KdbNumberOfColsTerminal;
|
||||
PCHAR p0 = pCurPos - p0len;
|
||||
PCHAR prev_p = p0, p1;
|
||||
PCCH p0 = pCurPos - p0len;
|
||||
PCCH prev_p = p0, p1;
|
||||
ULONG j;
|
||||
|
||||
if (pCurPos < Buffer)
|
||||
|
@ -3093,7 +2833,7 @@ CountOnePageUp(PCHAR Buffer, ULONG BufLength, PCHAR pCurPos)
|
|||
ASSERT(pCurPos <= Buffer + BufLength);
|
||||
|
||||
p = memrchr(p0, '\n', p0len);
|
||||
if (NULL == p)
|
||||
if (!p)
|
||||
p = p0;
|
||||
for (j = KdbNumberOfRowsTerminal; j--; )
|
||||
{
|
||||
|
@ -3101,10 +2841,10 @@ CountOnePageUp(PCHAR Buffer, ULONG BufLength, PCHAR pCurPos)
|
|||
p1 = memrchr(p0, '\n', p-p0);
|
||||
prev_p = p;
|
||||
p = p1;
|
||||
if (NULL == p)
|
||||
if (!p)
|
||||
{
|
||||
p = prev_p;
|
||||
if (NULL == p)
|
||||
if (!p)
|
||||
p = p0;
|
||||
break;
|
||||
}
|
||||
|
@ -3113,9 +2853,33 @@ CountOnePageUp(PCHAR Buffer, ULONG BufLength, PCHAR pCurPos)
|
|||
j -= linesCnt-1;
|
||||
}
|
||||
|
||||
ASSERT(p != 0);
|
||||
ASSERT(p != NULL);
|
||||
++p;
|
||||
return p;
|
||||
return (PCHAR)p;
|
||||
}
|
||||
|
||||
static VOID
|
||||
KdpFilterEscapes(
|
||||
_Inout_ PSTR String)
|
||||
{
|
||||
PCHAR p;
|
||||
SIZE_T i;
|
||||
size_t len;
|
||||
|
||||
while ((p = strrchr(String, '\x1b'))) /* Look for escape character */
|
||||
{
|
||||
len = strlen(p);
|
||||
if (p[1] == '[')
|
||||
{
|
||||
i = 2;
|
||||
while (!isalpha(p[i++]));
|
||||
memmove(p, p + i, len + 1 - i);
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(p, p + 1, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!\brief Prints the given string with, page by page.
|
||||
|
@ -3126,27 +2890,28 @@ CountOnePageUp(PCHAR Buffer, ULONG BufLength, PCHAR pCurPos)
|
|||
* \note Doesn't correctly handle \\t and terminal escape sequences when calculating the
|
||||
* number of lines required to print a single line from the Buffer in the terminal.
|
||||
* Maximum length of buffer is limited only by memory size.
|
||||
* Uses KdpDprintf internally (NOT DbgPrint!). Callers must already hold the debugger lock.
|
||||
*
|
||||
* Note: BufLength should be greater then (KdbNumberOfRowsTerminal * KdbNumberOfColsTerminal).
|
||||
*
|
||||
*/
|
||||
VOID
|
||||
KdbpPager(
|
||||
IN PCHAR Buffer,
|
||||
IN ULONG BufLength)
|
||||
KdbpPagerInternal(
|
||||
_In_ PCHAR Buffer,
|
||||
_In_ ULONG BufLength,
|
||||
_In_ BOOLEAN DoPage)
|
||||
{
|
||||
static CHAR InBuffer[4096];
|
||||
static CHAR InBuffer[128];
|
||||
static BOOLEAN TerminalInitialized = FALSE;
|
||||
static BOOLEAN TerminalConnected = FALSE;
|
||||
static BOOLEAN TerminalReportsSize = TRUE;
|
||||
CHAR c = '\0';
|
||||
PCHAR p, p2;
|
||||
ULONG Length;
|
||||
SIZE_T i, j;
|
||||
LONG RowsPrintedByTerminal;
|
||||
CHAR c;
|
||||
ULONG ScanCode;
|
||||
PCHAR p;
|
||||
ULONG Length;
|
||||
SIZE_T i;
|
||||
LONG RowsPrintedByTerminal;
|
||||
|
||||
if( BufLength == 0)
|
||||
if (BufLength == 0)
|
||||
return;
|
||||
|
||||
/* Check if the user has aborted output of the current command */
|
||||
|
@ -3156,13 +2921,14 @@ KdbpPager(
|
|||
/* Initialize the terminal */
|
||||
if (!TerminalInitialized)
|
||||
{
|
||||
TerminalInitialized = TRUE;
|
||||
|
||||
KdpDprintf("\x1b[7h"); /* Enable linewrap */
|
||||
|
||||
/* Query terminal type */
|
||||
/*DbgPrint("\x1b[Z");*/
|
||||
KdpDprintf("\x05");
|
||||
|
||||
TerminalInitialized = TRUE;
|
||||
Length = 0;
|
||||
KeStallExecutionProcessor(100000);
|
||||
|
||||
|
@ -3184,7 +2950,8 @@ KdbpPager(
|
|||
|
||||
/* Get number of rows and columns in terminal */
|
||||
if ((KdbNumberOfRowsTerminal < 0) || (KdbNumberOfColsTerminal < 0) ||
|
||||
(KdbNumberOfRowsPrinted) == 0) /* Refresh terminal size each time when number of rows printed is 0 */
|
||||
/* Refresh terminal size each time when number of rows printed is 0 */
|
||||
(KdbNumberOfRowsPrinted) == 0)
|
||||
{
|
||||
if ((KdbDebugState & KD_DEBUG_KDSERIAL) && TerminalConnected && TerminalReportsSize)
|
||||
{
|
||||
|
@ -3235,36 +3002,45 @@ KdbpPager(
|
|||
|
||||
if (KdbNumberOfRowsTerminal <= 0)
|
||||
{
|
||||
/* Set number of rows to the default. */
|
||||
KdbNumberOfRowsTerminal = 24;
|
||||
/* Set number of rows to the default */
|
||||
if (!DoPage)
|
||||
KdbNumberOfRowsTerminal = 23; //Mna.: for SCREEN debugport
|
||||
else
|
||||
KdbNumberOfRowsTerminal = 24;
|
||||
}
|
||||
else if (KdbNumberOfColsTerminal <= 0)
|
||||
{
|
||||
/* Set number of cols to the default. */
|
||||
KdbNumberOfColsTerminal = 80;
|
||||
/* Set number of cols to the default */
|
||||
if (!DoPage)
|
||||
KdbNumberOfColsTerminal = 75; //Mna.: for SCREEN debugport
|
||||
else
|
||||
KdbNumberOfColsTerminal = 80;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the string */
|
||||
/* Loop through the strings */
|
||||
p = Buffer;
|
||||
|
||||
while (p[0] != '\0')
|
||||
{
|
||||
if ( p > Buffer+BufLength)
|
||||
if (DoPage)
|
||||
{
|
||||
KdpDprintf("Dmesg: error, p > Buffer+BufLength,d=%d", p - (Buffer+BufLength));
|
||||
return;
|
||||
if (p > Buffer + BufLength)
|
||||
{
|
||||
KdpDprintf("Dmesg: error, p > Buffer+BufLength,d=%d", p - (Buffer + BufLength));
|
||||
return;
|
||||
}
|
||||
}
|
||||
i = strcspn(p, "\n");
|
||||
|
||||
// Are we out of buffer?
|
||||
if (p + i > Buffer + BufLength)
|
||||
// Leaving pager function:
|
||||
break;
|
||||
if (DoPage)
|
||||
{
|
||||
/* Are we out of buffer? */
|
||||
if (p + i > Buffer + BufLength)
|
||||
break; // Leaving pager function
|
||||
}
|
||||
|
||||
/* Calculate the number of lines which will be printed in the terminal
|
||||
* when outputting the current line.
|
||||
*/
|
||||
/* Calculate the number of lines which will be printed in
|
||||
* the terminal when outputting the current line. */
|
||||
if (i > 0)
|
||||
RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) / KdbNumberOfColsTerminal;
|
||||
else
|
||||
|
@ -3273,7 +3049,7 @@ KdbpPager(
|
|||
if (p[i] == '\n')
|
||||
RowsPrintedByTerminal++;
|
||||
|
||||
/*DbgPrint("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);*/
|
||||
//KdpDprintf("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);
|
||||
|
||||
/* Display a prompt if we printed one screen full of text */
|
||||
if (KdbNumberOfRowsTerminal > 0 &&
|
||||
|
@ -3284,7 +3060,14 @@ KdbpPager(
|
|||
if (KdbNumberOfColsPrinted > 0)
|
||||
KdpDprintf("\n");
|
||||
|
||||
KdpDprintf("--- Press q to abort, e/End,h/Home,u/PgUp, other key/PgDn ---");
|
||||
if (DoPage)
|
||||
{
|
||||
KdpDprintf("--- Press q to abort, e/End,h/Home,u/PgUp, other key/PgDn ---");
|
||||
}
|
||||
else
|
||||
{
|
||||
KdpDprintf("--- Press q to abort, any other key to continue ---");
|
||||
}
|
||||
RowsPrintedByTerminal++;
|
||||
|
||||
if (KdbDebugState & KD_DEBUG_KDSERIAL)
|
||||
|
@ -3303,41 +3086,52 @@ KdbpPager(
|
|||
c = KdbpTryGetCharKeyboard(&ScanCode, 5);
|
||||
}
|
||||
|
||||
//DbgPrint("\n"); //Consize version: don't show pressed key
|
||||
KdpDprintf(" '%c'/scan=%04x\n", c, ScanCode); // Shows pressed key
|
||||
if (DoPage)
|
||||
{
|
||||
//KdpDprintf("\n"); // Concise version: don't show pressed key
|
||||
KdpDprintf(" '%c'/scan=%04x\n", c, ScanCode); // Shows pressed key
|
||||
}
|
||||
else
|
||||
{
|
||||
KdpDprintf("\n");
|
||||
}
|
||||
|
||||
if (c == 'q')
|
||||
{
|
||||
KdbOutputAborted = TRUE;
|
||||
return;
|
||||
}
|
||||
if ( ScanCode == KEYSC_END || c=='e')
|
||||
|
||||
if (DoPage)
|
||||
{
|
||||
PCHAR pBufEnd = Buffer + BufLength;
|
||||
p = CountOnePageUp(Buffer, BufLength, pBufEnd);
|
||||
i = strcspn(p, "\n");
|
||||
}
|
||||
else if (ScanCode == KEYSC_PAGEUP || c=='u')
|
||||
{
|
||||
p = CountOnePageUp(Buffer, BufLength, p);
|
||||
i = strcspn(p, "\n");
|
||||
}
|
||||
else if (ScanCode == KEYSC_HOME || c=='h')
|
||||
{
|
||||
p = Buffer;
|
||||
i = strcspn(p, "\n");
|
||||
}
|
||||
else if (ScanCode == KEYSC_ARROWUP)
|
||||
{
|
||||
p = CountOnePageUp(Buffer, BufLength, p);
|
||||
i = strcspn(p, "\n");
|
||||
if (ScanCode == KEYSC_END || c == 'e')
|
||||
{
|
||||
PCHAR pBufEnd = Buffer + BufLength;
|
||||
p = CountOnePageUp(Buffer, BufLength, pBufEnd);
|
||||
i = strcspn(p, "\n");
|
||||
}
|
||||
else if (ScanCode == KEYSC_PAGEUP || c == 'u')
|
||||
{
|
||||
p = CountOnePageUp(Buffer, BufLength, p);
|
||||
i = strcspn(p, "\n");
|
||||
}
|
||||
else if (ScanCode == KEYSC_HOME || c == 'h')
|
||||
{
|
||||
p = Buffer;
|
||||
i = strcspn(p, "\n");
|
||||
}
|
||||
else if (ScanCode == KEYSC_ARROWUP)
|
||||
{
|
||||
p = CountOnePageUp(Buffer, BufLength, p);
|
||||
i = strcspn(p, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
KdbNumberOfRowsPrinted = 0;
|
||||
KdbNumberOfColsPrinted = 0;
|
||||
}
|
||||
|
||||
/* Insert a NUL after the line and print only the current line. */
|
||||
/* Insert a NUL after the line and print only the current line */
|
||||
if (p[i] == '\n' && p[i + 1] != '\0')
|
||||
{
|
||||
c = p[i + 1];
|
||||
|
@ -3348,35 +3142,21 @@ KdbpPager(
|
|||
c = '\0';
|
||||
}
|
||||
|
||||
/* Remove escape sequences from the line if there's no terminal connected */
|
||||
/* Remove escape sequences from the line if there is no terminal connected */
|
||||
// FIXME: Dangerous operation since we modify the source string!!
|
||||
if (!TerminalConnected)
|
||||
{
|
||||
while ((p2 = strrchr(p, '\x1b'))) /* Look for escape character */
|
||||
{
|
||||
size_t len = strlen(p2);
|
||||
if (p2[1] == '[')
|
||||
{
|
||||
j = 2;
|
||||
while (!isalpha(p2[j++]));
|
||||
memmove(p2, p2 + j, len + 1 - j);
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(p2, p2 + 1, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
KdpFilterEscapes(p);
|
||||
|
||||
// The main printing of the current line:
|
||||
KdpDprintf(p);
|
||||
/* Print the current line */
|
||||
// KdpDprintf(p);
|
||||
KdpDprintf("%s", p);
|
||||
|
||||
// restore not null char with saved:
|
||||
/* Restore not null char with saved */
|
||||
if (c != '\0')
|
||||
p[i + 1] = c;
|
||||
|
||||
/* Set p to the start of the next line and
|
||||
* remember the number of rows/cols printed
|
||||
*/
|
||||
* remember the number of rows/cols printed */
|
||||
p += i;
|
||||
if (p[0] == '\n')
|
||||
{
|
||||
|
@ -3393,6 +3173,78 @@ KdbpPager(
|
|||
}
|
||||
}
|
||||
|
||||
/*!\brief Prints the given string with, page by page.
|
||||
*
|
||||
* \param Buffer Characters buffer to print.
|
||||
* \param BufferLen Buffer size.
|
||||
*
|
||||
* \note Doesn't correctly handle \\t and terminal escape sequences when calculating the
|
||||
* number of lines required to print a single line from the Buffer in the terminal.
|
||||
* Maximum length of buffer is limited only by memory size.
|
||||
* Uses KdpDprintf internally (NOT DbgPrint!). Callers must already hold the debugger lock.
|
||||
*
|
||||
* Note: BufLength should be greater then (KdbNumberOfRowsTerminal * KdbNumberOfColsTerminal).
|
||||
*/
|
||||
VOID
|
||||
KdbpPager(
|
||||
_In_ PCHAR Buffer,
|
||||
_In_ ULONG BufLength)
|
||||
{
|
||||
/* Call the internal function */
|
||||
KdbpPagerInternal(Buffer, BufLength, TRUE);
|
||||
}
|
||||
|
||||
/*!\brief Prints the given string with printf-like formatting.
|
||||
*
|
||||
* \param Format Format of the string/arguments.
|
||||
* \param ... Variable number of arguments matching the format specified in \a Format.
|
||||
*
|
||||
* \note Doesn't correctly handle \\t and terminal escape sequences when calculating the
|
||||
* number of lines required to print a single line from the Buffer in the terminal.
|
||||
* Prints maximum 4096 chars, because of its buffer size.
|
||||
*/
|
||||
VOID
|
||||
KdbpPrint(
|
||||
_In_ PSTR Format,
|
||||
_In_ ...)
|
||||
{
|
||||
static CHAR Buffer[4096];
|
||||
ULONG Length;
|
||||
va_list ap;
|
||||
|
||||
/* Check if the user has aborted output of the current command */
|
||||
if (KdbOutputAborted)
|
||||
return;
|
||||
|
||||
/* Build the string */
|
||||
va_start(ap, Format);
|
||||
Length = _vsnprintf(Buffer, sizeof(Buffer) - 1, Format, ap);
|
||||
Buffer[Length] = '\0';
|
||||
va_end(ap);
|
||||
|
||||
/* Actually print it */
|
||||
KdbpPagerInternal(Buffer, Length, FALSE);
|
||||
}
|
||||
|
||||
VOID
|
||||
KdbpPrintUnicodeString(
|
||||
_In_ PCUNICODE_STRING String)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
if ((String == NULL) || (String->Buffer == NULL))
|
||||
{
|
||||
KdbpPrint("<NULL>");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < String->Length / sizeof(WCHAR); i++)
|
||||
{
|
||||
KdbpPrint("%c", (CHAR)String->Buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*!\brief Appends a command to the command history
|
||||
*
|
||||
* \param Command Pointer to the command to append to the history.
|
||||
|
|
Loading…
Reference in a new issue