// initialize column_order
if(tbl_template->column_order) {
- new_inst->column_order = mp_alloc_zero(new_inst->pool, sizeof(struct table_col_instance) * tbl_template->cols_to_output);
- memcpy(new_inst->column_order, tbl_template->column_order, sizeof(struct table_col_instance) * tbl_template->cols_to_output);
+ int cols_to_output = 0;
+ for(; ; cols_to_output++) {
+ if(tbl_template->column_order[cols_to_output].idx == (uint) ~0) break;
+ }
+
+ new_inst->column_order = mp_alloc_zero(new_inst->pool, sizeof(struct table_col_instance) * cols_to_output);
+ memcpy(new_inst->column_order, tbl_template->column_order, sizeof(struct table_col_instance) * cols_to_output);
for(uint i = 0; i < new_inst->cols_to_output; i++) {
new_inst->column_order[i].cell_content = NULL;
int col_def_idx = new_inst->column_order[i].idx;
new_inst->column_order[i].fmt = tbl_template->columns[col_def_idx].fmt;
}
- new_inst->cols_to_output = tbl_template->cols_to_output;
+ new_inst->cols_to_output = cols_to_output;
}
new_inst->col_delimiter = tbl_template->col_delimiter;
// TODO: test default column order
static void table_make_default_column_order(struct table *tbl)
{
- struct table_col_instance *col_order = alloca(sizeof(struct table_col_instance) * tbl->column_count);
+ struct table_col_instance *col_order = alloca(sizeof(struct table_col_instance) * (tbl->column_count + 1));
bzero(col_order, sizeof(struct table_col_instance) * tbl->column_count);
for(int i = 0; i < tbl->column_count; i++) {
// currently, XTYPE_FMT_DEFAULT is 0, so bzero actually sets it correctly. This makes it more explicit.
col_order[i].fmt = XTYPE_FMT_DEFAULT;
}
+ struct table_col_instance tbl_col_order_end = TBL_COL_ORDER_END;
+ col_order[tbl->column_count] = tbl_col_order_end;
- table_set_col_order(tbl, col_order, tbl->column_count);
+ table_set_col_order(tbl, col_order);
}
void table_start(struct table *tbl, struct fastbuf *out)
}
}
-void table_set_col_order(struct table *tbl, const struct table_col_instance *col_order, uint cols_to_output)
+void table_set_col_order(struct table *tbl, const struct table_col_instance *col_order)
{
- for(uint i = 0; i < cols_to_output; i++) {
- ASSERT_MSG(col_order[i].idx < (uint) tbl->column_count, "Column %d does not exist; column number should be between 0 and %d(including).", col_order[i].idx, tbl->column_count - 1);
+ uint cols_to_output = 0;
+ for(; ; cols_to_output++) {
+ if(col_order[cols_to_output].idx == (uint) ~0) break;
+ ASSERT_MSG(col_order[cols_to_output].idx < (uint) tbl->column_count,
+ "Column %d does not exist; column number should be between 0 and %d(including).", col_order[cols_to_output].idx, tbl->column_count - 1);
}
tbl->cols_to_output = cols_to_output;
// Make sure that we do not call table_set_col_opt, which would
// result in an infinite recursion.
if(col_def && col_def->set_col_opt) {
- if(col_def->set_col_opt == table_set_col_opt) {
- die("table_set_col_opt should not be used as a struct table_column::set_col_opt hook");
- }
+ ASSERT_MSG(col_def->set_col_opt != table_set_col_opt,"table_set_col_opt should not be used as a struct table_column::set_col_opt hook");
return col_def->set_col_opt(tbl, col_inst_idx, col_opt);
}
TEST_COL0_STR, TEST_COL1_INT, TEST_COL2_UINT, TEST_COL3_BOOL, TEST_COL4_DOUBLE
};
-static struct table_col_instance test_column_order[] = { TBL_COL(TEST_COL3_BOOL), TBL_COL(TEST_COL4_DOUBLE), TBL_COL(TEST_COL2_UINT), TBL_COL(TEST_COL1_INT), TBL_COL(TEST_COL0_STR) };
+static struct table_col_instance test_column_order[] = { TBL_COL(TEST_COL3_BOOL), TBL_COL(TEST_COL4_DOUBLE),
+ TBL_COL(TEST_COL2_UINT), TBL_COL(TEST_COL1_INT), TBL_COL(TEST_COL0_STR), TBL_COL_ORDER_END };
static struct table_template test_tbl = {
TBL_COLUMNS {
// test table_col_order_fmt
- struct table_col_instance col_order[] = { TBL_COL(TEST_COL0_STR), TBL_COL_FMT(TEST_COL4_DOUBLE, XTYPE_FMT_PRETTY), TBL_COL_FMT(TEST_COL4_DOUBLE, XTYPE_FMT_RAW) };
- table_set_col_order(tbl, col_order, ARRAY_SIZE(col_order));
+ struct table_col_instance col_order[] = { TBL_COL(TEST_COL0_STR), TBL_COL_FMT(TEST_COL4_DOUBLE, XTYPE_FMT_PRETTY), TBL_COL_FMT(TEST_COL4_DOUBLE, XTYPE_FMT_RAW), TBL_COL_ORDER_END };
+ table_set_col_order(tbl, col_order);
table_start(tbl, out);
table_col_str(tbl, TEST_COL0_STR, "test");
TEST_ANY_COL0_INT, TEST_ANY_COL1_ANY
};
-static struct table_col_instance test_any_column_order[] = { TBL_COL(TEST_ANY_COL0_INT), TBL_COL_FMT(TEST_ANY_COL1_ANY, XTYPE_FMT_PRETTY) };
+static struct table_col_instance test_any_column_order[] = { TBL_COL(TEST_ANY_COL0_INT), TBL_COL_FMT(TEST_ANY_COL1_ANY, XTYPE_FMT_PRETTY), TBL_COL_ORDER_END };
static struct table_template test_any_tbl = {
TBL_COLUMNS {
struct table_template {
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
// Back-end used for table formatting and its private data
const struct table_formatter *formatter;
#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_ORDER(order) .column_order = (struct table_col_instance *) order
#define TBL_COL_DELIMITER(_delimiter) .col_delimiter = _delimiter
/**
**/
#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 }
+#define TBL_COL_ORDER_END { .col_def = 0, .idx = (uint) ~0, .fmt = 0, .next_column = -1 }
/**
* These macros are aliases to various kinds of table formats.
const char *table_get_col_list(struct table *tbl);
/**
- * Sets the order in which the columns are printed. The columns are specified by struct
+ * Sets the order in which the columns are printed. The columns are specified by array of struct
+ * @table_col_instance. This allows specification of format. The user should make an array of struct
+ * @table_col_instance and fill the array using the TBL_COL and TBL_COL_FMT. The array has a special
+ * last element: @TBL_COL_ORDER_END.
*
- * Sets the order in which the columns are printed.
- * The table converts the integers in @col_order into an internal representation stored
+ * The table copies content of @col_order into an internal representation stored
* in `column_order`. Options to column instances can be set using @table_set_col_opt().
- *
- * @table_col_instance. This allows specification of format. The user should make an array of struct
- * @table_col_instance and fill the array using the TBL_COL and TBL_COL_FMT.
**/
-void table_set_col_order(struct table *tbl, const struct table_col_instance *col_order, uint cols_to_output);
+void table_set_col_order(struct table *tbl, const struct table_col_instance *col_order);
/**
* Sets the order in which the columns are printed. The specification is a string with comma-separated column