commit af0a6916407b3f1549416e6bb4b7a9bec5ea2978
parent 46972dd2694b2b7ba4395861787c6a63d6dd4d53
Author: Louis Burda <quent.burda@gmail.com>
Date: Mon, 20 Mar 2023 00:40:39 +0100
Fix wordaware column width calculation
Diffstat:
2 files changed, 20 insertions(+), 22 deletions(-)
diff --git a/src/tabular.c b/src/tabular.c
@@ -67,7 +67,7 @@ const char *
calc_word_aware_line(const char *str, size_t maxwidth,
size_t *out_offset, size_t *out_width)
{
- const char *sep;
+ const char *sep, *nstr;
size_t width, nwidth;
size_t offset, wlen;
@@ -77,19 +77,22 @@ calc_word_aware_line(const char *str, size_t maxwidth,
return NULL;
}
- offset = strspn(str, " ");
+ offset = strspn(str, " \v\t\r\n");
str += offset;
+ nstr = str;
nwidth = width = 0;
while (nwidth <= maxwidth) {
+ width = nwidth;
+ str = nstr;
if (!str) break;
sep = strchr(str, ' ');
if (!sep) {
wlen = u8strlen(str);
- str = NULL;
+ nstr = NULL;
} else {
wlen = u8strnlen(str, (size_t) (sep - str));
- str = sep + 1;
+ nstr = sep + 1;
}
nwidth = width + (width > 0) + wlen;
}
@@ -97,10 +100,12 @@ calc_word_aware_line(const char *str, size_t maxwidth,
if (out_offset) *out_offset = offset;
if (out_width) {
/* single word > maxwidth */
- if (!width && nwidth)
+ if (!width && nwidth) {
*out_width = maxwidth;
- else
- *out_offset = offset;
+ str = nstr; /* skip single word */
+ } else {
+ *out_width = width;
+ }
}
return str;
@@ -116,12 +121,6 @@ calc_word_aware(struct tabular_entry *entry, size_t maxwidth,
if (out_offset) *out_offset = 0;
- if (!entry->str) {
- if (out_width) *out_width = 0;
- if (out_lines) *out_lines = 1;
- return;
- }
-
lines = 0;
mwidth = 0;
str = entry->str;
@@ -147,13 +146,11 @@ recalc_col_word_aware(const struct tabular_cfg *cfg,
max_wwidth = cfg->columns[col].minwidth;
rowcnt = 0;
- for (row = rows; row; row = row->next) {
+ for (row = rows; row && rowcnt < limit; row = row->next) {
calc_word_aware(&row->entries[col],
maxwidth, &off, &wwidth, NULL);
max_wwidth = MAX(max_wwidth, wwidth);
-
rowcnt += 1;
- if (rowcnt == limit) break;
}
return max_wwidth;
@@ -519,7 +516,7 @@ output_row(FILE *file, const struct tabular_cfg *cfg,
/* check if anything other than whitespace left */
entry += u8rawlen(entry, outlen);
- if (strspn(entry, " \t\v\n") != u8strlen(entry))
+ if (strspn(entry, " \t\v\r\n") != u8strlen(entry))
done = false;
}
fprintf(file, "\n");
@@ -577,7 +574,8 @@ tabular_format(FILE *file, const struct tabular_cfg *cfg,
>= cfg->columns[i].minwidth)
return 1;
if (cfg->columns[i].strategy != TABULAR_TRUNC
- && cfg->columns[i].strategy != TABULAR_SQUASH)
+ && cfg->columns[i].strategy != TABULAR_SQUASH
+ && cfg->columns[i].strategy != TABULAR_SQUASH_WORDAWARE)
return 1;
}
diff --git a/src/test.c b/src/test.c
@@ -44,13 +44,13 @@ static struct tabular_col columns[] = {
.is_hidden = NULL,
.minwidth = 5,
- .maxwidth = 20,
+ .maxwidth = 80,
.lpad = 0,
.rpad = 0,
.align = TABULAR_ALIGN_LEFT,
- .strategy = TABULAR_SQUASH,
+ .strategy = TABULAR_SQUASH_WORDAWARE,
.essential = true,
},
};
@@ -140,11 +140,11 @@ main(int argc, const char **_argv)
for (i = 0; i < argc; i++) {
end = tabular_alloc_row(&cfg, &rc, end,
(struct tabular_user) { .id = (size_t) i });
- if (!end) errx(1, "tabular_append_row");
+ if (!end) errx(1, "tabular_append_row %i", rc);
}
rc = tabular_format(stdout, &cfg, &stats, rows);
- if (rc) errx(1, "tabular_format");
+ if (rc) errx(1, "tabular_format %i", rc);
printf("\n%lu lines, %lu rows\n",
stats.lines_used, stats.rows_displayed);