https://git.reactos.org/?p=reactos.git;a=commitdiff;h=aff90f530cbbbabbc6c1e54a04b38e4bfb631c2b

commit aff90f530cbbbabbc6c1e54a04b38e4bfb631c2b
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Mon Jun 28 00:49:48 2021 +0200
Commit:     Hermès Bélusca-Maïto <[email protected]>
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);
 }

Reply via email to