"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Omar Polo <op@omarpolo.com>
Subject:
simplify scroll_wline/format_line
To:
gameoftrees@openbsd.org
Date:
Thu, 16 Jun 2022 20:23:57 +0200

Download raw body.

Thread
there's a bit of duplication in span_wline.  diff below replaces
scroll_wline with a slightly generalized version: span_wline.  It
advances the given string starting at at certain offset at max by n
columns.  It's almost the same thing it did before, it's just
generalized to start at an arbitrary offset.  While here i've simplified
the implementation.

I think we can trust wcwidth to return 0, 1, 2 or -1.  (also, at least
the OpenBSD version doesn't set errno.)  If we want to be paranoid I can
add back the explicit check about the length.

With a generalized span_wline the main bulk of format_line could just
reuse it again to know how much characters to render.

ok?

diff 4cb9d869771dfcbb9e460e1f2924b289b34aff7c /home/op/w/got
blob - 6db125a8a56dececb4b421750f0f92d3644f8601
file + tog/tog.c
--- tog/tog.c
+++ tog/tog.c
@@ -1263,51 +1263,38 @@ expand_tab(char **ptr, const char *src)
 	return NULL;
 }
 
-/* 
- * Skip leading nscroll columns of a wide character string.
- * Returns the index to the first character of the scrolled string.
+/*
+ * Advance at max n columns from wline starting at offset off.  Return
+ * the index to the first character after the span operation and the
+ * reached column.
  */
-static const struct got_error *
-scroll_wline(int *scrollx , wchar_t *wline, int nscroll,
-    int col_tab_align)
+static int
+span_wline(int *rcol, int off, wchar_t *wline, int n, int col_tab_align)
 {
-	int cols = 0;
-	size_t wlen = wcslen(wline);
-	int i = 0;
+	int width, i, cols = 0;
 
-	*scrollx = 0;
+	if (n == 0) {
+		*rcol = cols;
+		return off;
+	}
 
-	while (i < wlen && cols < nscroll) {
-		int width = wcwidth(wline[i]);
+	for (i = off; wline[i] != L'\0'; ++i) {
+		width = wcwidth(wline[i]);
+		if (wline[i] == L'\t')
+			width = TABSIZE - ((cols + col_tab_align) % TABSIZE);
 
-		if (width == 0) {
-			i++;
-			continue;
+		if (width == -1) {
+			width = 1;
+			wline[i] = L'.';
 		}
 
-		if (width == 1 || width == 2) {
-			if (cols + width > nscroll)
-				break;
-			cols += width;
-			i++;
-		} else if (width == -1) {
-			if (wline[i] == L'\t') {
-				width = TABSIZE -
-				    ((cols + col_tab_align) % TABSIZE);
-			} else {
-				width = 1;
-				wline[i] = L'.';
-			}
-			if (cols + width > nscroll)
-				break;
-			cols += width;
-			i++;
-		} else
-			return got_error_from_errno("wcwidth");
+		if (cols + width > n)
+			break;
+		cols += width;
 	}
 
-	*scrollx = i;
-	return NULL;
+	*rcol = cols;
+	return i;
 }
 
 /*
@@ -1320,11 +1307,11 @@ format_line(wchar_t **wlinep, int *widthp, int *scroll
     const char *line, int nscroll, int wlimit, int col_tab_align, int expand)
 {
 	const struct got_error *err = NULL;
-	int cols = 0;
+	int cols;
 	wchar_t *wline = NULL;
 	char *exstr = NULL;
 	size_t wlen;
-	int i, scrollx = 0;
+	int i, scrollx;
 
 	*wlinep = NULL;
 	*widthp = 0;
@@ -1340,9 +1327,7 @@ format_line(wchar_t **wlinep, int *widthp, int *scroll
 	if (err)
 		return err;
 
-	err = scroll_wline(&scrollx, wline, nscroll, col_tab_align);
-	if (err)
-		goto done;
+	scrollx = span_wline(&cols, 0, wline, nscroll, col_tab_align);
 
 	if (wlen > 0 && wline[wlen - 1] == L'\n') {
 		wline[wlen - 1] = L'\0';
@@ -1353,43 +1338,13 @@ format_line(wchar_t **wlinep, int *widthp, int *scroll
 		wlen--;
 	}
 
-	i = scrollx;
-	while (i < wlen) {
-		int width = wcwidth(wline[i]);
-
-		if (width == 0) {
-			i++;
-			continue;
-		}
-
-		if (width == 1 || width == 2) {
-			if (cols + width > wlimit)
-				break;
-			cols += width;
-			i++;
-		} else if (width == -1) {
-			if (wline[i] == L'\t') {
-				width = TABSIZE -
-				    ((cols + col_tab_align) % TABSIZE);
-			} else {
-				width = 1;
-				wline[i] = L'.';
-			}
-			if (cols + width > wlimit)
-				break;
-			cols += width;
-			i++;
-		} else {
-			err = got_error_from_errno("wcwidth");
-			goto done;
-		}
-	}
+	i = span_wline(&cols, scrollx, wline, wlimit, col_tab_align);
 	wline[i] = L'\0';
+
 	if (widthp)
 		*widthp = cols;
 	if (scrollxp)
 		*scrollxp = scrollx;
-done:
 	if (err)
 		free(wline);
 	else