new_inst->pool = pool;
// initialize column definitions
- int col_count = 0; // count the number of columns in the struct table
+ uint col_count = 0; // count the number of columns in the struct table
for(;;) {
if(tbl_template->columns[col_count].name == NULL &&
tbl_template->columns[col_count].width == 0 &&
}
new_inst->column_count = col_count;
- new_inst->columns = mp_alloc_zero(new_inst->pool, sizeof(struct table_column) * new_inst->column_count);
- memcpy(new_inst->columns, tbl_template->columns, sizeof(struct table_column) * new_inst->column_count);
+ new_inst->columns = tbl_template->columns;
+ new_inst->ll_headers = mp_alloc(new_inst->pool, sizeof(int) * col_count);
+ for(uint i = 0; i < col_count; i++) {
+ new_inst->ll_headers[i] = -1;
+ }
// initialize column_order
if(tbl_template->column_order) {
int cols_to_output = tbl->cols_to_output;
for(int i = 0; i < tbl->column_count; i++) {
- tbl->columns[i].first_column = -1;
+ tbl->ll_headers[i] = -1;
}
for(int i = 0; i < cols_to_output; i++) {
}
for(int i = 0; i < cols_to_output; i++) {
- int first = tbl->column_order[i].col_def->first_column;
- tbl->column_order[i].col_def->first_column = i;
-
- if(first != -1) {
- tbl->column_order[i].next_column = first;
- } else {
- tbl->column_order[i].next_column = -1;
- }
+ int col_def_idx = tbl->column_order[i].col_def - tbl->columns;
+ int first = tbl->ll_headers[col_def_idx];
+ tbl->ll_headers[col_def_idx] = i;
+ tbl->column_order[i].next_column = first;
}
}
bool table_col_is_printed(struct table *tbl, uint col_idx)
{
- if(tbl->columns[col_idx].first_column == -1) return 0;
+ if(tbl->ll_headers[col_idx] == -1) return 0;
return 1;
}
**/
bool table_set_col_opt_default(struct table *tbl, int col_idx, const char *col_arg, char **err)
{
- struct table_column *col_def = tbl->column_order[col_idx].col_def;
+ const struct table_column *col_def = tbl->column_order[col_idx].col_def;
if(col_def->type_def == COL_TYPE_DOUBLE) {
uint precision = 0;
static void table_row_human_readable(struct table *tbl)
{
for(uint i = 0; i < tbl->cols_to_output; i++) {
- struct table_column *col_def = tbl->column_order[i].col_def;
+ const struct table_column *col_def = tbl->column_order[i].col_def;
if(i) {
bputs(tbl->out, tbl->col_delimiter);
}
static void table_write_header(struct table *tbl)
{
for(uint i = 0; i < tbl->cols_to_output; i++) {
- struct table_column *col_def = tbl->column_order[i].col_def;
+ const struct table_column *col_def = tbl->column_order[i].col_def;
if(i) {
bputs(tbl->out, tbl->col_delimiter);
}
static void table_row_blockline_output(struct table *tbl)
{
for(uint i = 0; i < tbl->cols_to_output; i++) {
- struct table_column *col_def = tbl->column_order[i].col_def;
+ const struct table_column *col_def = tbl->column_order[i].col_def;
bprintf(tbl->out, "%s: %s\n", col_def->name, tbl->column_order[i].cell_content);
}
bputc(tbl->out, '\n');
{
struct table *tbl = table_init(&test_any_tbl);
- tbl->columns[TEST_ANY_COL1_ANY].fmt = XTYPE_FMT_PRETTY;
-
table_start(tbl, out);
table_col_int(tbl, TEST_ANY_COL0_INT, -10);
const char *name; // [*] Name of the column displayed in table header
int width; // [*] Width of the column (in characters) OR'ed with column flags
enum xtype_fmt fmt;
- int first_column; // head of linked list of columns of this type
const struct xtype *type_def;
bool (*set_col_instance_option)(struct table *tbl, uint col, const char *value, char **err);
// idx is used only for initialization and col_def is used in other cases
struct table_col_instance {
uint idx; // idx is a index into struct table::columns
- struct table_column *col_def; // this is pointer to the column definition, located in the array struct table::columns
+ const struct table_column *col_def; // this is pointer to the column definition, located in the array struct table::columns
const char *cell_content; // content of the cell of the current row
int next_column; // index of next column in linked list of columns of the same type
enum xtype_fmt output_type; // format of this column
* Please use only fields marked with `[*]`.
**/
struct table_template {
- struct table_column *columns; // [*] Definition of columns
+ const struct table_column *columns; // [*] Definition of columns
struct table_col_instance *column_order; // [*] Order of the columns in the print-out of the table
uint cols_to_output; // [*] Number of columns that are printed
const char *col_delimiter; // [*] Delimiter that is placed between columns
* fields marked with `[*]`.
**/
struct table {
- struct table_column *columns; // [*] Definition of columns
+ const struct table_column *columns; // [*] Definition of columns
int column_count; // [*] Number of columns (calculated by table_init())
+ int *ll_headers; // headers of linked lists that connects column instances
struct mempool *pool; // Memory pool used for storing table data. Contains global state
// and data of the current row.
struct mempool_state pool_state; // State of the pool after the table is initialized, i.e., before
*
***/
-#define TBL_COL_LIST_INIT .first_column = -1
-#define TBL_COL_STR(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_STR, TBL_COL_LIST_INIT }
-#define TBL_COL_INT(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_INT, TBL_COL_LIST_INIT }
-#define TBL_COL_S64(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_S64, TBL_COL_LIST_INIT }
-#define TBL_COL_UINT(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_UINT, TBL_COL_LIST_INIT }
-#define TBL_COL_U64(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_U64, TBL_COL_LIST_INIT }
-#define TBL_COL_INTMAX(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_INTMAX, TBL_COL_LIST_INIT }
-#define TBL_COL_UINTMAX(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_UINTMAX, TBL_COL_LIST_INIT }
-#define TBL_COL_HEXUINT(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_UINT, TBL_COL_LIST_INIT }
-#define TBL_COL_DOUBLE(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_DOUBLE, TBL_COL_LIST_INIT }
-#define TBL_COL_BOOL(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_BOOL, TBL_COL_LIST_INIT }
-#define TBL_COL_ANY(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_ANY, TBL_COL_LIST_INIT }
-#define TBL_COL_CUSTOM(_name, _width, _xtype) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = _xtype, TBL_COL_LIST_INIT }
-
-#define TBL_COL_STR_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_STR, TBL_COL_LIST_INIT }
-#define TBL_COL_INT_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_INT, TBL_COL_LIST_INIT }
-#define TBL_COL_S64_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_S64, TBL_COL_LIST_INIT }
-#define TBL_COL_UINT_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_UINT, TBL_COL_LIST_INIT }
-#define TBL_COL_U64_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_U64, TBL_COL_LIST_INIT }
-#define TBL_COL_INTMAX_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_INTMAX, TBL_COL_LIST_INIT }
-#define TBL_COL_UINTMAX_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_UINTMAX, TBL_COL_LIST_INIT }
-#define TBL_COL_HEXUINT_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_UINT, TBL_COL_LIST_INIT }
-#define TBL_COL_BOOL_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_BOOL, TBL_COL_LIST_INIT }
-#define TBL_COL_ANY_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_ANY, TBL_COL_LIST_INIT }
-#define TBL_COL_DOUBLE_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_DOUBLE, TBL_COL_LIST_INIT }
+//#define TBL_COL_LIST_INIT .first_column = -1
+#define TBL_COL_STR(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_STR }
+#define TBL_COL_INT(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_INT }
+#define TBL_COL_S64(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_S64 }
+#define TBL_COL_UINT(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_UINT }
+#define TBL_COL_U64(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_U64 }
+#define TBL_COL_INTMAX(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_INTMAX }
+#define TBL_COL_UINTMAX(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_UINTMAX }
+#define TBL_COL_HEXUINT(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_UINT }
+#define TBL_COL_DOUBLE(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_DOUBLE }
+#define TBL_COL_BOOL(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_BOOL }
+#define TBL_COL_ANY(_name, _width) { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_ANY }
+#define TBL_COL_CUSTOM(_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 = COL_TYPE_STR }
+#define TBL_COL_INT_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_INT }
+#define TBL_COL_S64_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_S64 }
+#define TBL_COL_UINT_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_UINT }
+#define TBL_COL_U64_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_U64 }
+#define TBL_COL_INTMAX_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_INTMAX }
+#define TBL_COL_UINTMAX_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_UINTMAX }
+#define TBL_COL_HEXUINT_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_UINT }
+#define TBL_COL_BOOL_FMT(_name, _width, _fmt) { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_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 = COL_TYPE_DOUBLE }
#define TBL_COL_END { .name = 0, .width = 0, .fmt = 0, .type_def = NULL }
#define TBL_OUTPUT_BLOCKLINE .formatter = &table_fmt_blockline
#define TBL_OUTPUT_MACHINE_READABLE .formatter = &table_fmt_machine_readable
-#define TBL_COL_ITER_START(_tbl, _colidx, _var, _idxval) { struct table_col_instance *_var = NULL; int _idxval = _tbl->columns[_colidx].first_column; \
- for(_idxval = _tbl->columns[_colidx].first_column, _var = _tbl->column_order + _idxval; _idxval != -1; _idxval = _tbl->column_order[_idxval].next_column, _var = _tbl->column_order + _idxval)
+#define TBL_COL_ITER_START(_tbl, _colidx, _var, _idxval) { struct table_col_instance *_var = NULL; int _idxval = _tbl->ll_headers[_colidx]; \
+ for(_idxval = _tbl->ll_headers[_colidx], _var = _tbl->column_order + _idxval; _idxval != -1; _idxval = _tbl->column_order[_idxval].next_column, _var = _tbl->column_order + _idxval)
#define TBL_COL_ITER_END }