commit - 95d136acd37c706e1f4874b6606e5b70917a0d79
commit + 4e4a9ac8bc1f43c6f8c14b163ee83d5a54f7a192
blob - 36dceb28705dddb875b725d732b6dea27d63158d
blob + 0a55123b6b489cb5e6153aa48023d22080daa131
--- tog/tog.c
+++ tog/tog.c
return NULL;
}
-/*
- * Skip leading nscroll columns of a wide character string.
- * Returns the index to the first character of the scrolled string.
+/*
+ * Advance at most n columns from wline starting at offset off.
+ * Return the index to the first character after the span operation.
+ * Return the combined column width of all spanned wide character in
+ * *rcol.
*/
-static const struct got_error *
-scroll_wline(int *scrollx , wchar_t *wline, int nscroll,
- int col_tab_align)
-{
- int cols = 0;
- size_t wlen = wcslen(wline);
- int i = 0;
+static int
+span_wline(int *rcol, int off, wchar_t *wline, int n, int col_tab_align)
+{
+ 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) {
+ if (wline[i] == L'\t')
+ width = TABSIZE - ((cols + col_tab_align) % TABSIZE);
+ else
+ width = wcwidth(wline[i]);
- 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;
}
/*
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;
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';
wlen--;
}
- i = scrollx;
- while (i < wlen) {
- int width = wcwidth(wline[i]);
-
- if (width == 0) {
- i++;
- continue;
- }
+ i = span_wline(&cols, scrollx, wline, wlimit, col_tab_align);
+ wline[i] = L'\0';
- 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;
- }
- }
- wline[i] = L'\0';
if (widthp)
*widthp = cols;
if (scrollxp)
*scrollxp = scrollx;
-done:
if (err)
free(wline);
else