From 7a9b4bb0507b815fa29eb8a19b50f0fcef93f39c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 29 Jul 2019 18:36:19 +0200 Subject: format-table: optionally show a specific string in empty cells For some cases it might make sense to show "-" instead of just spaces for empty cells. --- src/shared/format-table.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'src/shared/format-table.c') diff --git a/src/shared/format-table.c b/src/shared/format-table.c index aede59bf34..51ddd1ac51 100644 --- a/src/shared/format-table.c +++ b/src/shared/format-table.c @@ -121,6 +121,8 @@ struct Table { size_t n_sort_map; bool *reverse_map; + + char *empty_string; }; Table *table_new_raw(size_t n_columns) { @@ -212,6 +214,7 @@ Table *table_unref(Table *t) { free(t->display_map); free(t->sort_map); free(t->reverse_map); + free(t->empty_string); return mfree(t); } @@ -859,6 +862,12 @@ void table_set_width(Table *t, size_t width) { t->width = width; } +int table_set_empty_string(Table *t, const char *empty) { + assert(t); + + return free_and_strdup(&t->empty_string, empty); +} + int table_set_display(Table *t, size_t first_column, ...) { size_t allocated, column; va_list ap; @@ -1016,7 +1025,7 @@ static int table_data_compare(const size_t *a, const size_t *b, Table *t) { return CMP(*a, *b); } -static const char *table_data_format(TableData *d) { +static const char *table_data_format(Table *t, TableData *d) { assert(d); if (d->formatted) @@ -1024,7 +1033,7 @@ static const char *table_data_format(TableData *d) { switch (d->type) { case TABLE_EMPTY: - return ""; + return strempty(t->empty_string); case TABLE_STRING: if (d->uppercase) { @@ -1225,11 +1234,11 @@ static const char *table_data_format(TableData *d) { return d->formatted; } -static int table_data_requested_width(TableData *d, size_t *ret) { +static int table_data_requested_width(Table *table, TableData *d, size_t *ret) { const char *t; size_t l; - t = table_data_format(d); + t = table_data_format(table, d); if (!t) return -ENOMEM; @@ -1372,7 +1381,7 @@ int table_print(Table *t, FILE *f) { assert_se(d = row[t->display_map ? t->display_map[j] : j]); - r = table_data_requested_width(d, &req); + r = table_data_requested_width(t, d, &req); if (r < 0) return r; @@ -1539,7 +1548,7 @@ int table_print(Table *t, FILE *f) { assert_se(d = row[t->display_map ? t->display_map[j] : j]); - field = table_data_format(d); + field = table_data_format(t, d); if (!field) return -ENOMEM; -- cgit v1.2.3 From 4ea710eaf44132fbc10634dad3a4ac1e24432b6a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 29 Jul 2019 18:36:59 +0200 Subject: format-table: if NULL is spcified as data, let's patch to an empty cell This should make various calls easier that currently generate either an empty cell or a regular cell depending on whether they have data to show. --- src/shared/format-table.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/shared/format-table.c') diff --git a/src/shared/format-table.c b/src/shared/format-table.c index 51ddd1ac51..d2764eebbd 100644 --- a/src/shared/format-table.c +++ b/src/shared/format-table.c @@ -356,6 +356,10 @@ int table_add_cell_full( assert(type >= 0); assert(type < _TABLE_DATA_TYPE_MAX); + /* Special rule: patch NULL data fields to the empty field */ + if (!data) + type = TABLE_EMPTY; + /* Determine the cell adjacent to the current one, but one row up */ if (t->n_cells >= t->n_columns) assert_se(p = t->data[t->n_cells - t->n_columns]); -- cgit v1.2.3 From 728a22d3b13b3fb76ebbf4e9fb5bde74001bcac4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 29 Jul 2019 18:38:13 +0200 Subject: format-table: add table_fill_empty() to fill in empty cells until the specified column is reached --- src/shared/format-table.c | 21 +++++++++++++++++++++ src/shared/format-table.h | 2 ++ 2 files changed, 23 insertions(+) (limited to 'src/shared/format-table.c') diff --git a/src/shared/format-table.c b/src/shared/format-table.c index d2764eebbd..39fc80571e 100644 --- a/src/shared/format-table.c +++ b/src/shared/format-table.c @@ -418,6 +418,27 @@ int table_add_cell_stringf(Table *t, TableCell **ret_cell, const char *format, . return table_add_cell(t, ret_cell, TABLE_STRING, buffer); } +int table_fill_empty(Table *t, size_t until_column) { + int r; + + assert(t); + + /* Fill the rest of the current line with empty cells until we reach the specified column. Will add + * at least one cell. Pass 0 in order to fill a line to the end or insert an empty line. */ + + if (until_column >= t->n_columns) + return -EINVAL; + + do { + r = table_add_cell(t, NULL, TABLE_EMPTY, NULL); + if (r < 0) + return r; + + } while ((t->n_cells % t->n_columns) != until_column); + + return 0; +} + int table_dup_cell(Table *t, TableCell *cell) { size_t i; diff --git a/src/shared/format-table.h b/src/shared/format-table.h index 8afb4257a8..0942fd7248 100644 --- a/src/shared/format-table.h +++ b/src/shared/format-table.h @@ -59,6 +59,8 @@ static inline int table_add_cell(Table *t, TableCell **ret_cell, TableDataType t } int table_add_cell_stringf(Table *t, TableCell **ret_cell, const char *format, ...) _printf_(3, 4); +int table_fill_empty(Table *t, size_t until_column); + int table_dup_cell(Table *t, TableCell *cell); int table_set_minimum_width(Table *t, TableCell *cell, size_t minimum_width); -- cgit v1.2.3 From 2cb86a3e16064517340b1e3a923d18b764bb00e2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 29 Jul 2019 18:39:05 +0200 Subject: format-table: automatically show empty cells in grey --- src/shared/format-table.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src/shared/format-table.c') diff --git a/src/shared/format-table.c b/src/shared/format-table.c index 39fc80571e..54e8f68ab0 100644 --- a/src/shared/format-table.c +++ b/src/shared/format-table.c @@ -1341,6 +1341,19 @@ static char *align_string_mem(const char *str, const char *url, size_t new_lengt return ret; } +static const char* table_data_color(TableData *d) { + assert(d); + + if (d->color) + return d->color; + + /* Let's implicitly color all "empty" cells in grey, in case an "empty_string" is set that is not empty */ + if (d->type == TABLE_EMPTY) + return ansi_grey(); + + return NULL; +} + int table_print(Table *t, FILE *f) { size_t n_rows, *minimum_width, *maximum_width, display_columns, *requested_width, i, j, table_minimum_width, table_maximum_width, table_requested_width, table_effective_width, @@ -1614,16 +1627,16 @@ int table_print(Table *t, FILE *f) { if (j > 0) fputc(' ', f); /* column separator */ - if (d->color && colors_enabled()) { + if (table_data_color(d) && colors_enabled()) { if (row == t->data) /* first undo header underliner */ fputs(ANSI_NORMAL, f); - fputs(d->color, f); + fputs(table_data_color(d), f); } fputs(field, f); - if (colors_enabled() && (d->color || row == t->data)) + if (colors_enabled() && (table_data_color(d) || row == t->data)) fputs(ANSI_NORMAL, f); } -- cgit v1.2.3