Download raw body.
simplify scroll_wline/format_line
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
simplify scroll_wline/format_line