Merge pull request #14555 from poettering/table-multine
format-table: proper multi-line support
This commit is contained in:
@@ -31,6 +31,118 @@ static void test_issue_9549(void) {
|
||||
));
|
||||
}
|
||||
|
||||
static void test_multiline(void) {
|
||||
_cleanup_(table_unrefp) Table *table = NULL;
|
||||
_cleanup_free_ char *formatted = NULL;
|
||||
|
||||
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_STRING, "three\ndifferent\nlines",
|
||||
TABLE_STRING, "two\nlines\n") >= 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… two…\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 two\n"
|
||||
"different… 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 two\n"
|
||||
"different lines\n"
|
||||
"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 two\n"
|
||||
"different lines\n"
|
||||
"lines \n"));
|
||||
formatted = mfree(formatted);
|
||||
|
||||
assert_se(table_add_many(table,
|
||||
TABLE_STRING, "short",
|
||||
TABLE_STRING, "a\npair") >= 0);
|
||||
|
||||
assert_se(table_add_many(table,
|
||||
TABLE_STRING, "short2\n",
|
||||
TABLE_STRING, "a\nfour\nline\ncell") >= 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… two…\n"
|
||||
"short a…\n"
|
||||
"short2 a…\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 two\n"
|
||||
"different… lines\n"
|
||||
"short a\n"
|
||||
" pair\n"
|
||||
"short2 a\n"
|
||||
" four…\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 two\n"
|
||||
"different lines\n"
|
||||
"lines \n"
|
||||
"short a\n"
|
||||
" pair\n"
|
||||
"short2 a\n"
|
||||
" four\n"
|
||||
" line…\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 two\n"
|
||||
"different lines\n"
|
||||
"lines \n"
|
||||
"short a\n"
|
||||
" pair\n"
|
||||
"short2 a\n"
|
||||
" four\n"
|
||||
" line\n"
|
||||
" cell\n"));
|
||||
formatted = mfree(formatted);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
_cleanup_(table_unrefp) Table *t = NULL;
|
||||
@@ -172,6 +284,7 @@ int main(int argc, char *argv[]) {
|
||||
"5min 5min \n"));
|
||||
|
||||
test_issue_9549();
|
||||
test_multiline();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -563,6 +563,153 @@ static void test_memory_startswith_no_case(void) {
|
||||
assert_se(memory_startswith_no_case((char[2]){'X', 'X'}, 2, "XX"));
|
||||
}
|
||||
|
||||
static void test_string_truncate_lines_one(const char *input, size_t n_lines, const char *output, bool truncation) {
|
||||
_cleanup_free_ char *b = NULL;
|
||||
int k;
|
||||
|
||||
assert_se((k = string_truncate_lines(input, n_lines, &b)) >= 0);
|
||||
assert_se(streq(b, output));
|
||||
assert_se(!!k == truncation);
|
||||
}
|
||||
|
||||
static void test_string_truncate_lines(void) {
|
||||
test_string_truncate_lines_one("", 0, "", false);
|
||||
test_string_truncate_lines_one("", 1, "", false);
|
||||
test_string_truncate_lines_one("", 2, "", false);
|
||||
test_string_truncate_lines_one("", 3, "", false);
|
||||
|
||||
test_string_truncate_lines_one("x", 0, "", true);
|
||||
test_string_truncate_lines_one("x", 1, "x", false);
|
||||
test_string_truncate_lines_one("x", 2, "x", false);
|
||||
test_string_truncate_lines_one("x", 3, "x", false);
|
||||
|
||||
test_string_truncate_lines_one("x\n", 0, "", true);
|
||||
test_string_truncate_lines_one("x\n", 1, "x", false);
|
||||
test_string_truncate_lines_one("x\n", 2, "x", false);
|
||||
test_string_truncate_lines_one("x\n", 3, "x", false);
|
||||
|
||||
test_string_truncate_lines_one("x\ny", 0, "", true);
|
||||
test_string_truncate_lines_one("x\ny", 1, "x", true);
|
||||
test_string_truncate_lines_one("x\ny", 2, "x\ny", false);
|
||||
test_string_truncate_lines_one("x\ny", 3, "x\ny", false);
|
||||
|
||||
test_string_truncate_lines_one("x\ny\n", 0, "", true);
|
||||
test_string_truncate_lines_one("x\ny\n", 1, "x", true);
|
||||
test_string_truncate_lines_one("x\ny\n", 2, "x\ny", false);
|
||||
test_string_truncate_lines_one("x\ny\n", 3, "x\ny", false);
|
||||
|
||||
test_string_truncate_lines_one("x\ny\nz", 0, "", true);
|
||||
test_string_truncate_lines_one("x\ny\nz", 1, "x", true);
|
||||
test_string_truncate_lines_one("x\ny\nz", 2, "x\ny", true);
|
||||
test_string_truncate_lines_one("x\ny\nz", 3, "x\ny\nz", false);
|
||||
|
||||
test_string_truncate_lines_one("x\ny\nz\n", 0, "", true);
|
||||
test_string_truncate_lines_one("x\ny\nz\n", 1, "x", true);
|
||||
test_string_truncate_lines_one("x\ny\nz\n", 2, "x\ny", true);
|
||||
test_string_truncate_lines_one("x\ny\nz\n", 3, "x\ny\nz", false);
|
||||
|
||||
test_string_truncate_lines_one("\n", 0, "", false);
|
||||
test_string_truncate_lines_one("\n", 1, "", false);
|
||||
test_string_truncate_lines_one("\n", 2, "", false);
|
||||
test_string_truncate_lines_one("\n", 3, "", false);
|
||||
|
||||
test_string_truncate_lines_one("\n\n", 0, "", false);
|
||||
test_string_truncate_lines_one("\n\n", 1, "", false);
|
||||
test_string_truncate_lines_one("\n\n", 2, "", false);
|
||||
test_string_truncate_lines_one("\n\n", 3, "", false);
|
||||
|
||||
test_string_truncate_lines_one("\n\n\n", 0, "", false);
|
||||
test_string_truncate_lines_one("\n\n\n", 1, "", false);
|
||||
test_string_truncate_lines_one("\n\n\n", 2, "", false);
|
||||
test_string_truncate_lines_one("\n\n\n", 3, "", false);
|
||||
|
||||
test_string_truncate_lines_one("\nx\n\n", 0, "", true);
|
||||
test_string_truncate_lines_one("\nx\n\n", 1, "", true);
|
||||
test_string_truncate_lines_one("\nx\n\n", 2, "\nx", false);
|
||||
test_string_truncate_lines_one("\nx\n\n", 3, "\nx", false);
|
||||
|
||||
test_string_truncate_lines_one("\n\nx\n", 0, "", true);
|
||||
test_string_truncate_lines_one("\n\nx\n", 1, "", true);
|
||||
test_string_truncate_lines_one("\n\nx\n", 2, "", true);
|
||||
test_string_truncate_lines_one("\n\nx\n", 3, "\n\nx", false);
|
||||
}
|
||||
|
||||
static void test_string_extract_lines_one(const char *input, size_t i, const char *output, bool more) {
|
||||
_cleanup_free_ char *b = NULL;
|
||||
int k;
|
||||
|
||||
assert_se((k = string_extract_line(input, i, &b)) >= 0);
|
||||
assert_se(streq(b ?: input, output));
|
||||
assert_se(!!k == more);
|
||||
}
|
||||
|
||||
static void test_string_extract_line(void) {
|
||||
test_string_extract_lines_one("", 0, "", false);
|
||||
test_string_extract_lines_one("", 1, "", false);
|
||||
test_string_extract_lines_one("", 2, "", false);
|
||||
test_string_extract_lines_one("", 3, "", false);
|
||||
|
||||
test_string_extract_lines_one("x", 0, "x", false);
|
||||
test_string_extract_lines_one("x", 1, "", false);
|
||||
test_string_extract_lines_one("x", 2, "", false);
|
||||
test_string_extract_lines_one("x", 3, "", false);
|
||||
|
||||
test_string_extract_lines_one("x\n", 0, "x", false);
|
||||
test_string_extract_lines_one("x\n", 1, "", false);
|
||||
test_string_extract_lines_one("x\n", 2, "", false);
|
||||
test_string_extract_lines_one("x\n", 3, "", false);
|
||||
|
||||
test_string_extract_lines_one("x\ny", 0, "x", true);
|
||||
test_string_extract_lines_one("x\ny", 1, "y", false);
|
||||
test_string_extract_lines_one("x\ny", 2, "", false);
|
||||
test_string_extract_lines_one("x\ny", 3, "", false);
|
||||
|
||||
test_string_extract_lines_one("x\ny\n", 0, "x", true);
|
||||
test_string_extract_lines_one("x\ny\n", 1, "y", false);
|
||||
test_string_extract_lines_one("x\ny\n", 2, "", false);
|
||||
test_string_extract_lines_one("x\ny\n", 3, "", false);
|
||||
|
||||
test_string_extract_lines_one("x\ny\nz", 0, "x", true);
|
||||
test_string_extract_lines_one("x\ny\nz", 1, "y", true);
|
||||
test_string_extract_lines_one("x\ny\nz", 2, "z", false);
|
||||
test_string_extract_lines_one("x\ny\nz", 3, "", false);
|
||||
|
||||
test_string_extract_lines_one("\n", 0, "", false);
|
||||
test_string_extract_lines_one("\n", 1, "", false);
|
||||
test_string_extract_lines_one("\n", 2, "", false);
|
||||
test_string_extract_lines_one("\n", 3, "", false);
|
||||
|
||||
test_string_extract_lines_one("\n\n", 0, "", true);
|
||||
test_string_extract_lines_one("\n\n", 1, "", false);
|
||||
test_string_extract_lines_one("\n\n", 2, "", false);
|
||||
test_string_extract_lines_one("\n\n", 3, "", false);
|
||||
|
||||
test_string_extract_lines_one("\n\n\n", 0, "", true);
|
||||
test_string_extract_lines_one("\n\n\n", 1, "", true);
|
||||
test_string_extract_lines_one("\n\n\n", 2, "", false);
|
||||
test_string_extract_lines_one("\n\n\n", 3, "", false);
|
||||
|
||||
test_string_extract_lines_one("\n\n\n\n", 0, "", true);
|
||||
test_string_extract_lines_one("\n\n\n\n", 1, "", true);
|
||||
test_string_extract_lines_one("\n\n\n\n", 2, "", true);
|
||||
test_string_extract_lines_one("\n\n\n\n", 3, "", false);
|
||||
|
||||
test_string_extract_lines_one("\nx\n\n\n", 0, "", true);
|
||||
test_string_extract_lines_one("\nx\n\n\n", 1, "x", true);
|
||||
test_string_extract_lines_one("\nx\n\n\n", 2, "", true);
|
||||
test_string_extract_lines_one("\nx\n\n\n", 3, "", false);
|
||||
|
||||
test_string_extract_lines_one("\n\nx\n\n", 0, "", true);
|
||||
test_string_extract_lines_one("\n\nx\n\n", 1, "", true);
|
||||
test_string_extract_lines_one("\n\nx\n\n", 2, "x", true);
|
||||
test_string_extract_lines_one("\n\nx\n\n", 3, "", false);
|
||||
|
||||
test_string_extract_lines_one("\n\n\nx\n", 0, "", true);
|
||||
test_string_extract_lines_one("\n\n\nx\n", 1, "", true);
|
||||
test_string_extract_lines_one("\n\n\nx\n", 2, "", true);
|
||||
test_string_extract_lines_one("\n\n\nx\n", 3, "x", false);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_setup_logging(LOG_DEBUG);
|
||||
|
||||
@@ -595,6 +742,8 @@ int main(int argc, char *argv[]) {
|
||||
test_strlen_ptr();
|
||||
test_memory_startswith();
|
||||
test_memory_startswith_no_case();
|
||||
test_string_truncate_lines();
|
||||
test_string_extract_line();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user