format-table: add TABLE_STRV_WRAPPED
The idea is that we have strvs like list of server names or addresses, where the majority of strings is rather short, but some are long and there can potentially be many strings. So formattting them either all on one line or all in separate lines leads to output that is either hard to read or uses way too many rows. We want to wrap them, but relying on the pager to do the wrapping is not nice. Normal text has a lot of redundancy, so when the pager wraps a line in the middle of a word the read can understand what is going on without any trouble. But for a high-density zero-redundancy text like an IP address it is much nicer to wrap between words. This also makes c&p easier. This adds a variant of TABLE_STRV which is wrapped on output (with line breaks inserted between different strv entries). The change table_print() is quite ugly. A second pass is added to re-calculate column widths. Since column size is now "soft", i.e. it can adjust based on available columns, we need to two passes: - first we figure out how much space we want - in the second pass we figure out what the actual wrapped columns widths will be. To avoid unnessary work, the second pass is only done when we actually have wrappable fields. A test is added in test-format-table.
This commit is contained in:
@@ -12,6 +12,8 @@ static void test_issue_9549(void) {
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
_cleanup_free_ char *formatted = NULL;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(table = table_new("name", "type", "ro", "usage", "created", "modified"));
|
||||
assert_se(table_set_align_percent(table, TABLE_HEADER_CELL(3), 100) >= 0);
|
||||
assert_se(table_add_many(table,
|
||||
@@ -36,6 +38,8 @@ static void test_multiline(void) {
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
_cleanup_free_ char *formatted = NULL;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(table = table_new("foo", "bar"));
|
||||
|
||||
assert_se(table_set_align_percent(table, TABLE_HEADER_CELL(1), 100) >= 0);
|
||||
@@ -148,6 +152,8 @@ static void test_strv(void) {
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
_cleanup_free_ char *formatted = NULL;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(table = table_new("foo", "bar"));
|
||||
|
||||
assert_se(table_set_align_percent(table, TABLE_HEADER_CELL(1), 100) >= 0);
|
||||
@@ -256,8 +262,111 @@ static void test_strv(void) {
|
||||
formatted = mfree(formatted);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
static void test_strv_wrapped(void) {
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
_cleanup_free_ char *formatted = NULL;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
assert_se(table = table_new("foo", "bar"));
|
||||
|
||||
assert_se(table_set_align_percent(table, TABLE_HEADER_CELL(1), 100) >= 0);
|
||||
|
||||
assert_se(table_add_many(table,
|
||||
TABLE_STRV_WRAPPED, STRV_MAKE("three", "different", "lines"),
|
||||
TABLE_STRV_WRAPPED, STRV_MAKE("two", "lines")) >= 0);
|
||||
|
||||
table_set_cell_height_max(table, 1);
|
||||
assert_se(table_format(table, &formatted) >= 0);
|
||||
fputs(formatted, stdout);
|
||||
assert_se(streq(formatted,
|
||||
"FOO BAR\n"
|
||||
"three different lines two lines\n"));
|
||||
formatted = mfree(formatted);
|
||||
|
||||
table_set_cell_height_max(table, 2);
|
||||
assert_se(table_format(table, &formatted) >= 0);
|
||||
fputs(formatted, stdout);
|
||||
assert_se(streq(formatted,
|
||||
"FOO BAR\n"
|
||||
"three different lines two lines\n"));
|
||||
formatted = mfree(formatted);
|
||||
|
||||
table_set_cell_height_max(table, 3);
|
||||
assert_se(table_format(table, &formatted) >= 0);
|
||||
fputs(formatted, stdout);
|
||||
assert_se(streq(formatted,
|
||||
"FOO BAR\n"
|
||||
"three different lines two lines\n"));
|
||||
formatted = mfree(formatted);
|
||||
|
||||
table_set_cell_height_max(table, (size_t) -1);
|
||||
assert_se(table_format(table, &formatted) >= 0);
|
||||
fputs(formatted, stdout);
|
||||
assert_se(streq(formatted,
|
||||
"FOO BAR\n"
|
||||
"three different lines two lines\n"));
|
||||
formatted = mfree(formatted);
|
||||
|
||||
assert_se(table_add_many(table,
|
||||
TABLE_STRING, "short",
|
||||
TABLE_STRV_WRAPPED, STRV_MAKE("a", "pair")) >= 0);
|
||||
|
||||
assert_se(table_add_many(table,
|
||||
TABLE_STRV_WRAPPED, STRV_MAKE("short2"),
|
||||
TABLE_STRV_WRAPPED, STRV_MAKE("a", "eight", "line", "ćęłł",
|
||||
"___5___", "___6___", "___7___", "___8___")) >= 0);
|
||||
|
||||
table_set_cell_height_max(table, 1);
|
||||
assert_se(table_format(table, &formatted) >= 0);
|
||||
fputs(formatted, stdout);
|
||||
assert_se(streq(formatted,
|
||||
"FOO BAR\n"
|
||||
"three different… two lines\n"
|
||||
"short a pair\n"
|
||||
"short2 a eight line ćęłł…\n"));
|
||||
formatted = mfree(formatted);
|
||||
|
||||
table_set_cell_height_max(table, 2);
|
||||
assert_se(table_format(table, &formatted) >= 0);
|
||||
fputs(formatted, stdout);
|
||||
assert_se(streq(formatted,
|
||||
"FOO BAR\n"
|
||||
"three different two lines\n"
|
||||
"lines \n"
|
||||
"short a pair\n"
|
||||
"short2 a eight line ćęłł\n"
|
||||
" ___5___ ___6___…\n"));
|
||||
formatted = mfree(formatted);
|
||||
|
||||
table_set_cell_height_max(table, 3);
|
||||
assert_se(table_format(table, &formatted) >= 0);
|
||||
fputs(formatted, stdout);
|
||||
assert_se(streq(formatted,
|
||||
"FOO BAR\n"
|
||||
"three different two lines\n"
|
||||
"lines \n"
|
||||
"short a pair\n"
|
||||
"short2 a eight line ćęłł\n"
|
||||
" ___5___ ___6___\n"
|
||||
" ___7___ ___8___\n"));
|
||||
formatted = mfree(formatted);
|
||||
|
||||
table_set_cell_height_max(table, (size_t) -1);
|
||||
assert_se(table_format(table, &formatted) >= 0);
|
||||
fputs(formatted, stdout);
|
||||
assert_se(streq(formatted,
|
||||
"FOO BAR\n"
|
||||
"three different two lines\n"
|
||||
"lines \n"
|
||||
"short a pair\n"
|
||||
"short2 a eight line ćęłł\n"
|
||||
" ___5___ ___6___\n"
|
||||
" ___7___ ___8___\n"));
|
||||
formatted = mfree(formatted);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
_cleanup_(table_unrefp) Table *t = NULL;
|
||||
_cleanup_free_ char *formatted = NULL;
|
||||
|
||||
@@ -399,6 +508,7 @@ int main(int argc, char *argv[]) {
|
||||
test_issue_9549();
|
||||
test_multiline();
|
||||
test_strv();
|
||||
test_strv_wrapped();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user