1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
12 typedef enum TableDataType
{
15 TABLE_HEADER
, /* in regular mode: the cells in the first row, that carry the column names */
16 TABLE_FIELD
, /* in vertical mode: the cells in the first column, that carry the field names */
20 TABLE_PATH_BASENAME
, /* like TABLE_PATH, but display only last path element (i.e. the "basename") in regular output */
22 TABLE_BOOLEAN_CHECKMARK
,
25 TABLE_TIMESTAMP_RELATIVE
,
26 TABLE_TIMESTAMP_RELATIVE_MONOTONIC
,
48 TABLE_IN_ADDR
, /* Takes a union in_addr_union (or a struct in_addr) */
49 TABLE_IN6_ADDR
, /* Takes a union in_addr_union (or a struct in6_addr) */
56 TABLE_MODE
, /* as in UNIX file mode (mode_t), in typical octal output */
57 TABLE_MODE_INODE_TYPE
, /* also mode_t, but displays only the inode type as string */
58 TABLE_DEVNUM
, /* a dev_t, displayed in the usual major:minor way */
61 /* The following are not really data types, but commands for table_add_cell_many() to make changes to
62 * a cell just added. */
63 TABLE_SET_MINIMUM_WIDTH
,
64 TABLE_SET_MAXIMUM_WIDTH
,
66 TABLE_SET_ALIGN_PERCENT
,
67 TABLE_SET_ELLIPSIZE_PERCENT
,
70 TABLE_SET_BOTH_COLORS
,
72 TABLE_SET_RGAP_UNDERLINE
,
73 TABLE_SET_BOTH_UNDERLINES
,
77 _TABLE_DATA_TYPE_INVALID
= -EINVAL
,
80 typedef enum TableErsatz
{
88 typedef struct Table Table
;
89 typedef struct TableCell TableCell
;
91 Table
*table_new_internal(const char *first_header
, ...) _sentinel_
;
92 #define table_new(...) table_new_internal(__VA_ARGS__, NULL)
93 Table
*table_new_raw(size_t n_columns
);
94 Table
*table_new_vertical(void);
95 Table
*table_unref(Table
*t
);
97 DEFINE_TRIVIAL_CLEANUP_FUNC(Table
*, table_unref
);
99 int table_add_cell_full(Table
*t
, TableCell
**ret_cell
, TableDataType type
, const void *data
, size_t minimum_width
, size_t maximum_width
, unsigned weight
, unsigned align_percent
, unsigned ellipsize_percent
);
100 static inline int table_add_cell(Table
*t
, TableCell
**ret_cell
, TableDataType type
, const void *data
) {
101 return table_add_cell_full(t
, ret_cell
, type
, data
, SIZE_MAX
, SIZE_MAX
, UINT_MAX
, UINT_MAX
, UINT_MAX
);
103 int table_add_cell_stringf_full(Table
*t
, TableCell
**ret_cell
, TableDataType type
, const char *format
, ...) _printf_(4, 5);
104 #define table_add_cell_stringf(t, ret_cell, format, ...) table_add_cell_stringf_full(t, ret_cell, TABLE_STRING, format, __VA_ARGS__)
106 int table_fill_empty(Table
*t
, size_t until_column
);
108 int table_dup_cell(Table
*t
, TableCell
*cell
);
110 int table_set_minimum_width(Table
*t
, TableCell
*cell
, size_t minimum_width
);
111 int table_set_maximum_width(Table
*t
, TableCell
*cell
, size_t maximum_width
);
112 int table_set_weight(Table
*t
, TableCell
*cell
, unsigned weight
);
113 int table_set_align_percent(Table
*t
, TableCell
*cell
, unsigned percent
);
114 int table_set_ellipsize_percent(Table
*t
, TableCell
*cell
, unsigned percent
);
115 int table_set_color(Table
*t
, TableCell
*cell
, const char *color
);
116 int table_set_rgap_color(Table
*t
, TableCell
*cell
, const char *color
);
117 int table_set_underline(Table
*t
, TableCell
*cell
, bool b
);
118 int table_set_rgap_underline(Table
*t
, TableCell
*cell
, bool b
);
119 int table_set_url(Table
*t
, TableCell
*cell
, const char *url
);
120 int table_set_uppercase(Table
*t
, TableCell
*cell
, bool b
);
122 int table_update(Table
*t
, TableCell
*cell
, TableDataType type
, const void *data
);
124 int table_add_many_internal(Table
*t
, TableDataType first_type
, ...);
125 #define table_add_many(t, ...) table_add_many_internal(t, __VA_ARGS__, _TABLE_DATA_TYPE_MAX)
127 void table_set_header(Table
*table
, bool b
);
128 void table_set_width(Table
*t
, size_t width
);
129 void table_set_cell_height_max(Table
*t
, size_t height
);
130 void table_set_ersatz_string(Table
*t
, TableErsatz ersatz
);
131 int table_set_display_internal(Table
*t
, size_t first_column
, ...);
132 #define table_set_display(...) table_set_display_internal(__VA_ARGS__, SIZE_MAX)
133 int table_set_sort_internal(Table
*t
, size_t first_column
, ...);
134 #define table_set_sort(...) table_set_sort_internal(__VA_ARGS__, SIZE_MAX)
135 int table_set_reverse(Table
*t
, size_t column
, bool b
);
136 int table_hide_column_from_display_internal(Table
*t
, ...);
137 #define table_hide_column_from_display(t, ...) table_hide_column_from_display_internal(t, __VA_ARGS__, SIZE_MAX)
139 int table_print(Table
*t
, FILE *f
);
140 int table_format(Table
*t
, char **ret
);
142 static inline TableCell
* TABLE_HEADER_CELL(size_t i
) {
143 return SIZE_TO_PTR(i
+ 1);
146 size_t table_get_rows(Table
*t
);
147 static inline bool table_isempty(Table
*t
) {
151 return table_get_rows(t
) <= 1;
153 size_t table_get_columns(Table
*t
);
155 size_t table_get_current_column(Table
*t
);
157 TableCell
*table_get_cell(Table
*t
, size_t row
, size_t column
);
159 const void *table_get(Table
*t
, TableCell
*cell
);
160 const void *table_get_at(Table
*t
, size_t row
, size_t column
);
162 int table_to_json(Table
*t
, JsonVariant
**ret
);
163 int table_print_json(Table
*t
, FILE *f
, JsonFormatFlags json_flags
);
165 int table_print_with_pager(Table
*t
, JsonFormatFlags json_format_flags
, PagerFlags pager_flags
, bool show_header
);
167 int table_set_json_field_name(Table
*t
, size_t idx
, const char *name
);
169 #define table_log_add_error(r) \
170 log_error_errno(r, "Failed to add cells to table: %m")
172 #define table_log_print_error(r) \
173 log_error_errno(r, "Failed to print table: %m")
175 #define table_log_sort_error(r) \
176 log_error_errno(r, "Failed to sort table: %m")