https://git.reactos.org/?p=reactos.git;a=commitdiff;h=aff90f530cbbbabbc6c1e…
commit aff90f530cbbbabbc6c1e54a04b38e4bfb631c2b
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Mon Jun 28 00:49:48 2021 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Mon Jun 28 21:26:32 2021 +0200
[CONUTILS:PAGER] Extract the character-specific handling out of the character-loop.
This also allows to factor out the ConCallPagerLine() call for outputting the pending
text.
---
sdk/lib/conutils/pager.c | 224 ++++++++++++++++++++++++++++-------------------
1 file changed, 132 insertions(+), 92 deletions(-)
diff --git a/sdk/lib/conutils/pager.c b/sdk/lib/conutils/pager.c
index db7e17eb883..4005e455410 100644
--- a/sdk/lib/conutils/pager.c
+++ b/sdk/lib/conutils/pager.c
@@ -74,7 +74,7 @@ ConPagerWorker(IN PCON_PAGER Pager)
{
const DWORD PageColumns = Pager->PageColumns;
const DWORD ScrollRows = Pager->ScrollRows;
- const PCTCH TextBuff = Pager->TextBuff;
+ const PCTCH Line = Pager->TextBuff;
const DWORD cch = Pager->cch;
BOOL bFinitePaging = ((PageColumns > 0) && (Pager->PageRows > 0));
@@ -83,9 +83,8 @@ ConPagerWorker(IN PCON_PAGER Pager)
DWORD ich = Pager->ich;
DWORD iColumn = Pager->iColumn;
DWORD iLine = Pager->iLine;
- DWORD lineno = Pager->lineno;
-
DWORD ichStart = ich;
+
UINT nCodePage;
BOOL IsCJK;
UINT nWidthOfChar = 1;
@@ -134,135 +133,176 @@ ExpandTab:
}
}
+ProcessLine:
+ /* Stop now if we have displayed more screen lines than requested */
+ if (bFinitePaging && (iLine >= ScrollRows))
+ goto End;
+
/* Loop over each character in the buffer */
for (; ich < cch; ++ich)
{
- /* Stop now if we have displayed more screen lines than requested */
- if (bFinitePaging && (iLine >= ScrollRows))
- break;
-
- Pager->lineno = lineno;
-
/* NEWLINE character */
- if (TextBuff[ich] == TEXT('\n'))
+ if (Line[ich] == TEXT('\n'))
{
- /* Output the pending text, including the newline */
- ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart + 1);
- ichStart = ich + 1;
- if (!(Pager->dwFlags & CON_PAGER_DONT_OUTPUT))
- ++iLine;
- iColumn = 0;
-
- /* Done with this line; start a new one */
- ++lineno;
- continue;
+ /* We should stop now */
+ break;
}
/* TAB character */
- if (TextBuff[ich] == TEXT('\t') &&
+ if (Line[ich] == TEXT('\t') &&
(Pager->dwFlags & CON_PAGER_EXPAND_TABS))
{
- /* Output the pending text */
- ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart);
-
- /* Perform tab expansion, unless the tab width is zero */
- if (nTabWidth == 0)
- {
- ichStart = ich + 1;
- continue;
- }
- ichStart = ++ich;
- Pager->nSpacePending += nTabWidth - (iColumn % nTabWidth);
- goto ExpandTab;
+ /* We should stop now */
+ break;
}
/* FORM-FEED character */
- if (TextBuff[ich] == TEXT('\f') &&
+ if (Line[ich] == TEXT('\f') &&
(Pager->dwFlags & CON_PAGER_EXPAND_FF))
{
- /* Output the pending text, skipping the form-feed */
- ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart);
- ichStart = ich + 1;
- // FIXME: Should we handle CON_PAGER_DONT_OUTPUT ?
-
- if (bFinitePaging)
- {
- /* Clear until the end of the screen */
- while (iLine < ScrollRows)
- {
- ConCallPagerLine(Pager, L"\n", 1);
- // CON_STREAM_WRITE(Pager->Screen->Stream,
TEXT("\n"), 1);
- // if (!(Pager->dwFlags & CON_PAGER_DONT_OUTPUT))
- ++iLine;
- }
- }
- else
- {
- /* Just output a FORM-FEED character */
- ConCallPagerLine(Pager, L"\f", 1);
- // CON_STREAM_WRITE(Pager->Screen->Stream, L"\f", 1);
- }
-
- iColumn = 0;
- continue;
+ /* We should stop now */
+ break;
}
/* Other character - Handle double-width for CJK */
if (IsCJK)
- {
- nWidthOfChar = GetWidthOfCharCJK(nCodePage, TextBuff[ich]);
- if (PageColumns > 0)
- {
- IsDoubleWidthCharTrailing = (nWidthOfChar == 2) &&
- ((iColumn + 1) % PageColumns == 0);
- }
- }
+ nWidthOfChar = GetWidthOfCharCJK(nCodePage, Line[ich]);
/* Care about CJK character presentation only when outputting
* to a device where the number of columns is known. */
- if (PageColumns > 0)
+ if ((PageColumns > 0) && IsCJK)
{
- if ((iColumn + nWidthOfChar) % PageColumns == 0)
- {
- /* Output the pending text, including the last double-width character */
- ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart + 1);
- ichStart = ich + 1;
- if (!(Pager->dwFlags & CON_PAGER_DONT_OUTPUT))
- ++iLine;
- iColumn += nWidthOfChar;
- continue;
- }
-
+ IsDoubleWidthCharTrailing = (nWidthOfChar == 2) &&
+ ((iColumn + 1) % PageColumns == 0);
if (IsDoubleWidthCharTrailing)
{
- /* Output the pending text, excluding the last double-width character */
- ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart);
- ichStart = ich;
- if (!(Pager->dwFlags & CON_PAGER_DONT_OUTPUT))
- CON_STREAM_WRITE(Pager->Screen->Stream, TEXT(" "),
1);
- --ich;
- if (!(Pager->dwFlags & CON_PAGER_DONT_OUTPUT))
- ++iLine;
- ++iColumn;
- continue;
+ /* Reserve this character for the next line */
+ ++iColumn; // Count a blank instead.
+ /* We should stop now */
+ break;
}
}
iColumn += nWidthOfChar;
+
+ /* Check whether we are going across the column */
+ if ((PageColumns > 0) && (iColumn % PageColumns == 0))
+ {
+ ++ich;
+ break;
+ }
}
- /* Output the remaining text */
+ /* Output the pending text */
+ Pager->dwFlags &= ~CON_PAGER_DONT_OUTPUT;
if (ich - ichStart > 0)
- ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart);
+ ConCallPagerLine(Pager, &Line[ichStart], ich - ichStart);
+
+ /* Have we finished the buffer? */
+ if (ich >= cch)
+ goto End;
+
+ /* Handle special characters */
+
+ /* NEWLINE character */
+ if (Line[ich] == TEXT('\n'))
+ {
+ /* Output the newline */
+ if (!(Pager->dwFlags & CON_PAGER_DONT_OUTPUT))
+ {
+ // ConCallPagerLine(Pager, L"\n", 1);
+ CON_STREAM_WRITE(Pager->Screen->Stream, TEXT("\n"), 1);
+ ++iLine;
+ }
+ iColumn = 0;
+
+ /* Done with this line; start a new one */
+ Pager->nSpacePending = 0; // And reset any pending space.
+ Pager->lineno++;
+ ichStart = ++ich;
+ goto ProcessLine;
+ }
+
+ /* TAB character */
+ if (Line[ich] == TEXT('\t') &&
+ (Pager->dwFlags & CON_PAGER_EXPAND_TABS))
+ {
+ /* Perform TAB expansion, unless the tab width is zero */
+ if (nTabWidth == 0)
+ {
+ ichStart = ++ich;
+ goto ProcessLine;
+ }
+
+ ichStart = ++ich;
+ /* Reset the number of spaces needed to develop this TAB character */
+ Pager->nSpacePending = nTabWidth - (iColumn % nTabWidth);
+ goto ExpandTab;
+ }
+
+ /* FORM-FEED character */
+ if (Line[ich] == TEXT('\f') &&
+ (Pager->dwFlags & CON_PAGER_EXPAND_FF))
+ {
+ // FIXME: Should we handle CON_PAGER_DONT_OUTPUT ?
+ if (bFinitePaging)
+ {
+ /* Clear until the end of the screen */
+ while (iLine < ScrollRows)
+ {
+ ConCallPagerLine(Pager, L"\n", 1);
+ // CON_STREAM_WRITE(Pager->Screen->Stream, TEXT("\n"),
1);
+ // if (!(Pager->dwFlags & CON_PAGER_DONT_OUTPUT))
+ ++iLine;
+ }
+ }
+ else
+ {
+ /* Just output a FORM-FEED character */
+ ConCallPagerLine(Pager, L"\f", 1);
+ // CON_STREAM_WRITE(Pager->Screen->Stream, L"\f", 1);
+ }
+
+ iColumn = 0;
+ Pager->nSpacePending = 0; // And reset any pending space.
+
+ ichStart = ++ich;
+ goto ProcessLine;
+ }
+
+ /* If we output a double-width character that goes across the column,
+ * fill with blank and display the character on the next line. */
+ if (IsDoubleWidthCharTrailing)
+ {
+ IsDoubleWidthCharTrailing = FALSE; // Reset the flag.
+
+ if (!(Pager->dwFlags & CON_PAGER_DONT_OUTPUT))
+ CON_STREAM_WRITE(Pager->Screen->Stream, TEXT(" "), 1);
+ // ++iLine;
+
+ /* Fall back below */
+ }
+
+ /* Are we wrapping the line? */
+ if ((PageColumns > 0) && (iColumn % PageColumns == 0))
+ {
+ if (!(Pager->dwFlags & CON_PAGER_DONT_OUTPUT))
+ ++iLine;
+ }
+
+ /* Restart at the character */
+ ichStart = ich;
+ goto ProcessLine;
+
+End:
if (iLine >= ScrollRows)
iLine = 0; /* Reset the count of lines being printed */
Pager->ich = ich;
Pager->iColumn = iColumn;
Pager->iLine = iLine;
- Pager->lineno = lineno;
return (ich < cch);
}