mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:43:04 +00:00
[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.
This commit is contained in:
parent
ff445ca184
commit
aff90f530c
1 changed files with 132 additions and 92 deletions
|
@ -74,7 +74,7 @@ ConPagerWorker(IN PCON_PAGER Pager)
|
||||||
{
|
{
|
||||||
const DWORD PageColumns = Pager->PageColumns;
|
const DWORD PageColumns = Pager->PageColumns;
|
||||||
const DWORD ScrollRows = Pager->ScrollRows;
|
const DWORD ScrollRows = Pager->ScrollRows;
|
||||||
const PCTCH TextBuff = Pager->TextBuff;
|
const PCTCH Line = Pager->TextBuff;
|
||||||
const DWORD cch = Pager->cch;
|
const DWORD cch = Pager->cch;
|
||||||
|
|
||||||
BOOL bFinitePaging = ((PageColumns > 0) && (Pager->PageRows > 0));
|
BOOL bFinitePaging = ((PageColumns > 0) && (Pager->PageRows > 0));
|
||||||
|
@ -83,9 +83,8 @@ ConPagerWorker(IN PCON_PAGER Pager)
|
||||||
DWORD ich = Pager->ich;
|
DWORD ich = Pager->ich;
|
||||||
DWORD iColumn = Pager->iColumn;
|
DWORD iColumn = Pager->iColumn;
|
||||||
DWORD iLine = Pager->iLine;
|
DWORD iLine = Pager->iLine;
|
||||||
DWORD lineno = Pager->lineno;
|
|
||||||
|
|
||||||
DWORD ichStart = ich;
|
DWORD ichStart = ich;
|
||||||
|
|
||||||
UINT nCodePage;
|
UINT nCodePage;
|
||||||
BOOL IsCJK;
|
BOOL IsCJK;
|
||||||
UINT nWidthOfChar = 1;
|
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 */
|
/* Loop over each character in the buffer */
|
||||||
for (; ich < cch; ++ich)
|
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 */
|
/* NEWLINE character */
|
||||||
if (TextBuff[ich] == TEXT('\n'))
|
if (Line[ich] == TEXT('\n'))
|
||||||
{
|
{
|
||||||
/* Output the pending text, including the newline */
|
/* We should stop now */
|
||||||
ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart + 1);
|
break;
|
||||||
ichStart = ich + 1;
|
|
||||||
if (!(Pager->dwFlags & CON_PAGER_DONT_OUTPUT))
|
|
||||||
++iLine;
|
|
||||||
iColumn = 0;
|
|
||||||
|
|
||||||
/* Done with this line; start a new one */
|
|
||||||
++lineno;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TAB character */
|
/* TAB character */
|
||||||
if (TextBuff[ich] == TEXT('\t') &&
|
if (Line[ich] == TEXT('\t') &&
|
||||||
(Pager->dwFlags & CON_PAGER_EXPAND_TABS))
|
(Pager->dwFlags & CON_PAGER_EXPAND_TABS))
|
||||||
{
|
{
|
||||||
/* Output the pending text */
|
/* We should stop now */
|
||||||
ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart);
|
break;
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FORM-FEED character */
|
/* FORM-FEED character */
|
||||||
if (TextBuff[ich] == TEXT('\f') &&
|
if (Line[ich] == TEXT('\f') &&
|
||||||
(Pager->dwFlags & CON_PAGER_EXPAND_FF))
|
(Pager->dwFlags & CON_PAGER_EXPAND_FF))
|
||||||
{
|
{
|
||||||
/* Output the pending text, skipping the form-feed */
|
/* We should stop now */
|
||||||
ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart);
|
break;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Other character - Handle double-width for CJK */
|
/* Other character - Handle double-width for CJK */
|
||||||
|
|
||||||
if (IsCJK)
|
if (IsCJK)
|
||||||
{
|
nWidthOfChar = GetWidthOfCharCJK(nCodePage, Line[ich]);
|
||||||
nWidthOfChar = GetWidthOfCharCJK(nCodePage, TextBuff[ich]);
|
|
||||||
if (PageColumns > 0)
|
|
||||||
{
|
|
||||||
IsDoubleWidthCharTrailing = (nWidthOfChar == 2) &&
|
|
||||||
((iColumn + 1) % PageColumns == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Care about CJK character presentation only when outputting
|
/* Care about CJK character presentation only when outputting
|
||||||
* to a device where the number of columns is known. */
|
* to a device where the number of columns is known. */
|
||||||
if (PageColumns > 0)
|
if ((PageColumns > 0) && IsCJK)
|
||||||
{
|
{
|
||||||
if ((iColumn + nWidthOfChar) % PageColumns == 0)
|
IsDoubleWidthCharTrailing = (nWidthOfChar == 2) &&
|
||||||
{
|
((iColumn + 1) % 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDoubleWidthCharTrailing)
|
if (IsDoubleWidthCharTrailing)
|
||||||
{
|
{
|
||||||
/* Output the pending text, excluding the last double-width character */
|
/* Reserve this character for the next line */
|
||||||
ConCallPagerLine(Pager, &TextBuff[ichStart], ich - ichStart);
|
++iColumn; // Count a blank instead.
|
||||||
ichStart = ich;
|
/* We should stop now */
|
||||||
if (!(Pager->dwFlags & CON_PAGER_DONT_OUTPUT))
|
break;
|
||||||
CON_STREAM_WRITE(Pager->Screen->Stream, TEXT(" "), 1);
|
|
||||||
--ich;
|
|
||||||
if (!(Pager->dwFlags & CON_PAGER_DONT_OUTPUT))
|
|
||||||
++iLine;
|
|
||||||
++iColumn;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iColumn += nWidthOfChar;
|
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)
|
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)
|
if (iLine >= ScrollRows)
|
||||||
iLine = 0; /* Reset the count of lines being printed */
|
iLine = 0; /* Reset the count of lines being printed */
|
||||||
|
|
||||||
Pager->ich = ich;
|
Pager->ich = ich;
|
||||||
Pager->iColumn = iColumn;
|
Pager->iColumn = iColumn;
|
||||||
Pager->iLine = iLine;
|
Pager->iLine = iLine;
|
||||||
Pager->lineno = lineno;
|
|
||||||
|
|
||||||
return (ich < cch);
|
return (ich < cch);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue