From cf0eed6c36e28743464b17c510778451594fdec1 Mon Sep 17 00:00:00 2001
From: Benno Schulenberg <bensberg@justemail.net>
Date: Sun, 5 Jun 2016 12:53:02 +0200
Subject: [PATCH] screen: don't check for every character whether there is
 still enough space

Just allocate ample space up front and thus discard the delaying 'if' for
each and every character.  In most cases this will allocate far too much,
but that hardly matters: it is freed again as soon as the line is printed.
---
 src/winio.c | 29 ++---------------------------
 1 file changed, 2 insertions(+), 27 deletions(-)

diff --git a/src/winio.c b/src/winio.c
index 5cf4612d..f10d2c98 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -1735,8 +1735,6 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
 	/* Index in buf of the first character shown. */
     size_t column;
 	/* Screen column that start_index corresponds to. */
-    size_t alloc_len;
-	/* The length of memory allocated for converted. */
     char *converted;
 	/* The string we return. */
     size_t index;
@@ -1759,21 +1757,8 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
 
     assert(column <= start_col);
 
-    /* Make sure there's enough room for the initial character, whether
-     * it's a multibyte control character, a non-control multibyte
-     * character, a tab character, or a null terminator.  Rationale:
-     *
-     * multibyte control character followed by a null terminator:
-     *     1 byte ('^') + mb_cur_max() bytes + 1 byte ('\0')
-     * multibyte non-control character followed by a null terminator:
-     *     mb_cur_max() bytes + 1 byte ('\0')
-     * tab character followed by a null terminator:
-     *     mb_cur_max() bytes + (tabsize - 1) bytes + 1 byte ('\0')
-     *
-     * Since tabsize has a minimum value of 1, it can substitute for 1
-     * byte above. */
-    alloc_len = (mb_cur_max() + tabsize + 1) * MAX_BUF_SIZE;
-    converted = charalloc(alloc_len);
+    /* Allocate enough space to hold the entire converted buffer. */
+    converted = charalloc(strlen(buf) * (mb_cur_max() + tabsize) + 1);
 
     index = 0;
     seen_wide = FALSE;
@@ -1812,14 +1797,6 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
 	if (mbwidth(buf + start_index) > 1)
 	    seen_wide = TRUE;
 
-	/* Make sure there's enough room for the next character, whether
-	 * it's a multibyte control character, a non-control multibyte
-	 * character, a tab character, or a null terminator. */
-	if (index + mb_cur_max() + tabsize + 1 >= alloc_len - 1) {
-	    alloc_len += (mb_cur_max() + tabsize + 1) * MAX_BUF_SIZE;
-	    converted = charealloc(converted, alloc_len);
-	}
-
 	if (*buf_mb == ' ') {
 	    /* Show a space as a visible character, or as a space. */
 #ifndef NANO_TINY
@@ -1882,8 +1859,6 @@ char *display_string(const char *buf, size_t start_col, size_t len, bool
 
     free(buf_mb);
 
-    assert(alloc_len >= index + 1);
-
     /* Null-terminate converted. */
     converted[index] = '\0';
 
-- 
GitLab