+/****
+ * In most cases, table descriptions are constructed using the following macros.
+ * See the examples above for more details.
+ *
+ * * `TBL_COLUMNS` indicates the start of definition of columns
+ * * `TBL_COL_`'type'`(name, width)` defines a column of a given type
+ * * `TBL_COL_`'type'`_FMT(name, width, fmt)` defines a column with a custom format string
+ * * `TBL_COL_END` ends the column definitions
+ * * `TBL_COL_ORDER` specifies custom ordering of columns in the output
+ * * `TBL_COL_DELIMITER` and `TBL_APPEND_DELIMITER` override default delimiters
+ * * `TBL_FMT_HUMAN_READABLE` requests human-readable formatting (this is the default)
+ * * `TBL_FMT_MACHINE_READABLE` requests machine-readable TSV output
+ * * `TBL_FMT_BLOCKLINE` requests block formatting (each cell printed a pair of a key and value on its own line)
+ *
+ ***/
+
+#define TBL_COL_STR(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = &xt_str }
+#define TBL_COL_INT(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = &xt_int }
+#define TBL_COL_S64(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = &xt_s64 }
+#define TBL_COL_UINT(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = &xt_uint }
+#define TBL_COL_U64(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = &xt_u64 }
+#define TBL_COL_INTMAX(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = &xt_intmax }
+#define TBL_COL_UINTMAX(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = &xt_uintmax }
+#define TBL_COL_HEXUINT(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = &xt_uint }
+#define TBL_COL_DOUBLE(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = &xt_double }
+#define TBL_COL_BOOL(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = &xt_bool }
+#define TBL_COL_ANY(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_ANY }
+#define TBL_COL_XTYPE(_name, _width, _xtype) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = _xtype }
+
+#define TBL_COL_STR_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = &xt_str }
+#define TBL_COL_INT_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = &xt_int }
+#define TBL_COL_S64_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = &xt_s64 }
+#define TBL_COL_UINT_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = &xt_uint }
+#define TBL_COL_U64_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = &xt_u64 }
+#define TBL_COL_INTMAX_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = &xt_intmax }
+#define TBL_COL_UINTMAX_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = &xt_uintmax }
+#define TBL_COL_HEXUINT_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = &xt_uint }
+#define TBL_COL_BOOL_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = &xt_bool }
+#define TBL_COL_ANY_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_ANY }
+#define TBL_COL_DOUBLE_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = &xt_double }
+
+#define TBL_COL_END { .name = 0, .width = 0, .fmt = 0, .type_def = NULL }
+
+#define TBL_COLUMNS .columns = (struct table_column [])
+#define TBL_COL_ORDER(order) .column_order = (struct table_col_instance *) order, .cols_to_output = ARRAY_SIZE(order)
+#define TBL_COL_DELIMITER(_delimiter) .col_delimiter = _delimiter
+
+/**
+ * These macros are used for definition of column order
+ **/
+#define TBL_COL(_idx) { .idx = _idx, .fmt = XTYPE_FMT_DEFAULT, .next_column = -1 }
+#define TBL_COL_FMT(_idx, _fmt) { .idx = _idx, .fmt = _fmt, .next_column = -1 }
+
+/**
+ * These macros are aliases to various kinds of table formats.
+ **/
+#define TBL_FMT_HUMAN_READABLE .formatter = &table_fmt_human_readable
+#define TBL_FMT_BLOCKLINE .formatter = &table_fmt_blockline
+#define TBL_FMT_MACHINE_READABLE .formatter = &table_fmt_machine_readable
+#define TBL_FMT(_fmt) .formatter = _fmt