From: Omar Polo Subject: simplify scroll_wline/format_line To: gameoftrees@openbsd.org Date: Thu, 16 Jun 2022 20:23:57 +0200 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