libtabular-c

C tabular formatting library
git clone https://git.sinitax.com/sinitax/libtabular-c
Log | Files | Refs | Submodules | sfeed.txt

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:
Msrc/tabular.c | 34++++++++++++++++------------------
Msrc/test.c | 8++++----
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);