Merge branch 'obsd-master' into master

This commit is contained in:
Thomas Adam 2021-08-22 18:01:18 +01:00
commit 1dec1ca146

View File

@ -632,6 +632,36 @@ format_draw_absolute_centre(struct screen_write_ctx *octx, u_int available,
width_after); width_after);
} }
/* Get width and count of any leading #s. */
static const char *
format_leading_hashes(const char *cp, u_int *n, u_int *width)
{
for (*n = 0; cp[*n] == '#'; (*n)++)
/* nothing */;
if (*n == 0) {
*width = 0;
return (cp);
}
if (cp[*n] != '[') {
if ((*n % 2) == 0)
*width = (*n / 2);
else
*width = (*n / 2) + 1;
return (cp + *n);
}
*width = (*n / 2);
if ((*n % 2) == 0) {
/*
* An even number of #s means that all #s are escaped, so not a
* style. The caller should not skip this. Return pointing to
* the [.
*/
return (cp + *n);
}
/* This is a style, so return pointing to the #. */
return (cp + *n - 1);
}
/* Draw multiple characters. */ /* Draw multiple characters. */
static void static void
format_draw_many(struct screen_write_ctx *ctx, struct style *sy, char ch, format_draw_many(struct screen_write_ctx *ctx, struct style *sy, char ch,
@ -1002,37 +1032,22 @@ u_int
format_width(const char *expanded) format_width(const char *expanded)
{ {
const char *cp, *end; const char *cp, *end;
u_int n, width = 0; u_int n, leading_width, width = 0;
struct utf8_data ud; struct utf8_data ud;
enum utf8_state more; enum utf8_state more;
cp = expanded; cp = expanded;
while (*cp != '\0') { while (*cp != '\0') {
if (*cp == '#') { if (*cp == '#') {
for (n = 1; cp[n] == '#'; n++) end = format_leading_hashes(cp, &n, &leading_width);
/* nothing */; width += leading_width;
if (cp[n] != '[') { cp = end;
width += n; if (*cp == '#') {
cp += n;
continue;
}
width += (n / 2); /* one for each ## */
if ((n % 2) == 0) {
/*
* An even number of #s means that all #s are
* escaped, so not a style.
*/
width++; /* one for the [ */
cp += (n + 1);
continue;
}
cp += (n - 1); /* point to the [ */
end = format_skip(cp + 2, "]"); end = format_skip(cp + 2, "]");
if (end == NULL) if (end == NULL)
return (0); return (0);
cp = end + 1; cp = end + 1;
}
} else if ((more = utf8_open(&ud, *cp)) == UTF8_MORE) { } else if ((more = utf8_open(&ud, *cp)) == UTF8_MORE) {
while (*++cp != '\0' && more == UTF8_MORE) while (*++cp != '\0' && more == UTF8_MORE)
more = utf8_append(&ud, *cp); more = utf8_append(&ud, *cp);
@ -1059,7 +1074,7 @@ format_trim_left(const char *expanded, u_int limit)
{ {
char *copy, *out; char *copy, *out;
const char *cp = expanded, *end; const char *cp = expanded, *end;
u_int even, n, width = 0; u_int n, width = 0, leading_width;
struct utf8_data ud; struct utf8_data ud;
enum utf8_state more; enum utf8_state more;
@ -1068,44 +1083,27 @@ format_trim_left(const char *expanded, u_int limit)
if (width >= limit) if (width >= limit)
break; break;
if (*cp == '#') { if (*cp == '#') {
for (end = cp + 1; *end == '#'; end++) end = format_leading_hashes(cp, &n, &leading_width);
/* nothing */; if (leading_width > limit - width)
n = end - cp; leading_width = limit - width;
if (*end != '[') { if (leading_width != 0) {
if (n > limit - width) if (n == 1)
n = limit - width; *out++ = '#';
memcpy(out, cp, n); else {
out += n; memset(out, '#', 2 * leading_width);
width += n; out += 2 * leading_width;
}
width += leading_width;
}
cp = end; cp = end;
continue; if (*cp == '#') {
}
even = ((n % 2) == 0);
n /= 2;
if (n > limit - width)
n = limit - width;
width += n;
n *= 2;
memcpy(out, cp, n);
out += n;
if (even) {
if (width + 1 <= limit) {
*out++ = '[';
width++;
}
cp = end + 1;
continue;
}
cp = end - 1;
end = format_skip(cp + 2, "]"); end = format_skip(cp + 2, "]");
if (end == NULL) if (end == NULL)
break; break;
memcpy(out, cp, end + 1 - cp); memcpy(out, cp, end + 1 - cp);
out += (end + 1 - cp); out += (end + 1 - cp);
cp = end + 1; cp = end + 1;
}
} else if ((more = utf8_open(&ud, *cp)) == UTF8_MORE) { } else if ((more = utf8_open(&ud, *cp)) == UTF8_MORE) {
while (*++cp != '\0' && more == UTF8_MORE) while (*++cp != '\0' && more == UTF8_MORE)
more = utf8_append(&ud, *cp); more = utf8_append(&ud, *cp);
@ -1137,7 +1135,8 @@ format_trim_right(const char *expanded, u_int limit)
{ {
char *copy, *out; char *copy, *out;
const char *cp = expanded, *end; const char *cp = expanded, *end;
u_int width = 0, total_width, skip, old_n, even, n; u_int width = 0, total_width, skip, n;
u_int leading_width, copy_width;
struct utf8_data ud; struct utf8_data ud;
enum utf8_state more; enum utf8_state more;
@ -1149,64 +1148,32 @@ format_trim_right(const char *expanded, u_int limit)
out = copy = xcalloc(1, strlen(expanded) + 1); out = copy = xcalloc(1, strlen(expanded) + 1);
while (*cp != '\0') { while (*cp != '\0') {
if (*cp == '#') { if (*cp == '#') {
for (end = cp + 1; *end == '#'; end++) end = format_leading_hashes(cp, &n, &leading_width);
/* nothing */;
old_n = n = end - cp;
if (*end != '[') {
if (width <= skip) { if (width <= skip) {
if (skip - width >= n) if (skip - width >= leading_width)
n = 0; copy_width = 0;
else else
n -= (skip - width); copy_width -= (skip - width);
} else
copy_width = leading_width;
if (copy_width != 0) {
if (n == 1)
*out++ = '#';
else {
memset(out, '#', 2 * copy_width);
out += 2 * copy_width;
} }
if (n != 0) {
memcpy(out, cp, n);
out += n;
} }
width += leading_width;
/*
* The width always increases by the full
* amount even if we can't copy anything yet.
*/
width += old_n;
cp = end; cp = end;
continue; if (*cp == '#') {
}
even = ((n % 2) == 0);
n /= 2;
if (width <= skip) {
if (skip - width >= n)
n = 0;
else
n -= (skip - width);
}
if (n != 0) {
/*
* Copy the full amount because it hasn't been
* escaped yet.
*/
memcpy(out, cp, old_n);
out += old_n;
}
cp += old_n;
width += (old_n / 2) - even;
if (even) {
if (width > skip)
*out++ = '[';
width++;
continue;
}
cp = end - 1;
end = format_skip(cp + 2, "]"); end = format_skip(cp + 2, "]");
if (end == NULL) { if (end == NULL)
break; break;
}
memcpy(out, cp, end + 1 - cp); memcpy(out, cp, end + 1 - cp);
out += (end + 1 - cp); out += (end + 1 - cp);
cp = end + 1; cp = end + 1;
}
} else if ((more = utf8_open(&ud, *cp)) == UTF8_MORE) { } else if ((more = utf8_open(&ud, *cp)) == UTF8_MORE) {
while (*++cp != '\0' && more == UTF8_MORE) while (*++cp != '\0' && more == UTF8_MORE)
more = utf8_append(&ud, *cp); more = utf8_append(&ud, *cp);