diff options
Diffstat (limited to 'src/shared/format-table.c')
-rw-r--r-- | src/shared/format-table.c | 133 |
1 files changed, 115 insertions, 18 deletions
diff --git a/src/shared/format-table.c b/src/shared/format-table.c index 9a19177..9146444 100644 --- a/src/shared/format-table.c +++ b/src/shared/format-table.c @@ -77,7 +77,9 @@ typedef struct TableData { unsigned ellipsize_percent; /* 0 … 100, where to place the ellipsis when compression is needed */ unsigned align_percent; /* 0 … 100, where to pad with spaces when expanding is needed. 0: left-aligned, 100: right-aligned */ - bool uppercase; /* Uppercase string on display */ + bool uppercase:1; /* Uppercase string on display */ + bool underline:1; + bool rgap_underline:1; const char *color; /* ANSI color string to use for this cell. When written to terminal should not move cursor. Will automatically be reset after the cell */ const char *rgap_color; /* The ANSI color to use for the gap right of this cell. Usually used to underline entire rows in a gapless fashion */ @@ -401,7 +403,7 @@ static bool table_data_matches( return false; /* If a color/url is set, refuse to merge */ - if (d->color || d->rgap_color) + if (d->color || d->rgap_color || d->underline || d->rgap_underline) return false; if (d->url) return false; @@ -617,6 +619,8 @@ static int table_dedup_cell(Table *t, TableCell *cell) { nd->color = od->color; nd->rgap_color = od->rgap_color; + nd->underline = od->underline; + nd->rgap_underline = od->rgap_underline; nd->url = TAKE_PTR(curl); table_data_unref(od); @@ -759,6 +763,46 @@ int table_set_rgap_color(Table *t, TableCell *cell, const char *color) { return 0; } +int table_set_underline(Table *t, TableCell *cell, bool b) { + TableData *d; + int r; + + assert(t); + assert(cell); + + r = table_dedup_cell(t, cell); + if (r < 0) + return r; + + assert_se(d = table_get_data(t, cell)); + + if (d->underline == b) + return 0; + + d->underline = b; + return 1; +} + +int table_set_rgap_underline(Table *t, TableCell *cell, bool b) { + TableData *d; + int r; + + assert(t); + assert(cell); + + r = table_dedup_cell(t, cell); + if (r < 0) + return r; + + assert_se(d = table_get_data(t, cell)); + + if (d->rgap_underline == b) + return 0; + + d->rgap_underline = b; + return 1; +} + int table_set_url(Table *t, TableCell *cell, const char *url) { _cleanup_free_ char *copy = NULL; int r; @@ -834,6 +878,8 @@ int table_update(Table *t, TableCell *cell, TableDataType type, const void *data nd->color = od->color; nd->rgap_color = od->rgap_color; + nd->underline = od->underline; + nd->rgap_underline = od->rgap_underline; nd->url = TAKE_PTR(curl); table_data_unref(od); @@ -1101,6 +1147,31 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) { goto check; } + case TABLE_SET_UNDERLINE: { + int u = va_arg(ap, int); + r = table_set_underline(t, last_cell, u); + goto check; + } + + case TABLE_SET_RGAP_UNDERLINE: { + int u = va_arg(ap, int); + r = table_set_rgap_underline(t, last_cell, u); + goto check; + } + + case TABLE_SET_BOTH_UNDERLINES: { + int u = va_arg(ap, int); + + r = table_set_underline(t, last_cell, u); + if (r < 0) { + va_end(ap); + return r; + } + + r = table_set_rgap_underline(t, last_cell, u); + goto check; + } + case TABLE_SET_URL: { const char *u = va_arg(ap, const char*); r = table_set_url(t, last_cell, u); @@ -1641,7 +1712,7 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas if (!p) return NULL; - if (!format_bytes_full(p, FORMAT_BYTES_MAX, d->size, 0)) + if (!format_bytes_full(p, FORMAT_BYTES_MAX, d->size, FORMAT_BYTES_BELOW_POINT)) return table_ersatz_string(t); n = strlen(p); @@ -1932,7 +2003,7 @@ static const char *table_data_format(Table *t, TableData *d, bool avoid_uppercas if (d->mode == MODE_INVALID) return table_ersatz_string(t); - return inode_type_to_string(d->mode); + return inode_type_to_string(d->mode) ?: table_ersatz_string(t); case TABLE_DEVNUM: if (devnum_is_zero(d->devnum)) @@ -2130,8 +2201,6 @@ static const char* table_data_color(TableData *d) { if (d->type == TABLE_FIELD) return ansi_bright_blue(); - if (d->type == TABLE_HEADER) - return ansi_underline(); return NULL; } @@ -2139,11 +2208,29 @@ static const char* table_data_color(TableData *d) { static const char* table_data_rgap_color(TableData *d) { assert(d); - if (d->rgap_color) - return d->rgap_color; + return d->rgap_color ?: d->rgap_color; +} + +static const char* table_data_underline(TableData *d) { + assert(d); + + if (d->underline) + return /* cescape( */ansi_add_underline_grey()/* ) */; if (d->type == TABLE_HEADER) - return ansi_underline(); + return ansi_add_underline(); + + return NULL; +} + +static const char* table_data_rgap_underline(TableData *d) { + assert(d); + + if (d->rgap_underline) + return ansi_add_underline_grey(); + + if (d->type == TABLE_HEADER) + return ansi_add_underline(); return NULL; } @@ -2418,13 +2505,13 @@ int table_print(Table *t, FILE *f) { row = t->data + i * t->n_columns; do { - const char *gap_color = NULL; + const char *gap_color = NULL, *gap_underline = NULL; more_sublines = false; for (size_t j = 0; j < display_columns; j++) { _cleanup_free_ char *buffer = NULL, *extracted = NULL; bool lines_truncated = false; - const char *field, *color = NULL; + const char *field, *color = NULL, *underline = NULL; TableData *d; size_t l; @@ -2490,6 +2577,7 @@ int table_print(Table *t, FILE *f) { /* Drop trailing white spaces of last column when no cosmetics is set. */ if (j == display_columns - 1 && (!colors_enabled() || !table_data_color(d)) && + (!underline_enabled() || !table_data_underline(d)) && (!urlify_enabled() || !d->url)) delete_trailing_chars(aligned, NULL); @@ -2511,31 +2599,40 @@ int table_print(Table *t, FILE *f) { if (colors_enabled() && gap_color) fputs(gap_color, f); + if (underline_enabled() && gap_underline) + fputs(gap_underline, f); if (j > 0) fputc(' ', f); /* column separator left of cell */ + /* Undo gap color/underline */ + if ((colors_enabled() && gap_color) || + (underline_enabled() && gap_underline)) + fputs(ANSI_NORMAL, f); + if (colors_enabled()) { color = table_data_color(d); - - /* Undo gap color */ - if (gap_color) - fputs(ANSI_NORMAL, f); - if (color) fputs(color, f); } + if (underline_enabled()) { + underline = table_data_underline(d); + if (underline) + fputs(underline, f); + } + fputs(field, f); - if (colors_enabled() && color) + if (color || underline) fputs(ANSI_NORMAL, f); gap_color = table_data_rgap_color(d); + gap_underline = table_data_rgap_underline(d); } fputc('\n', f); - n_subline ++; + n_subline++; } while (more_sublines); } |