From 0efb089d44b263d9f39aee96f22e74534da5cc60 Mon Sep 17 00:00:00 2001 From: Robert Kessl Date: Tue, 29 Jul 2014 09:32:33 +0200 Subject: [PATCH] tableprinter: update of column order - setting column order (table_set_col_order) now does not need length of the array. Instead it uses special stop element. - table_set_col_opt now uses ASSERT instead of die. --- ucw/table-test.c | 3 ++- ucw/table.c | 39 ++++++++++++++++++++++++--------------- ucw/table.h | 17 ++++++++--------- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/ucw/table-test.c b/ucw/table-test.c index 480a7a33..64acedb8 100644 --- a/ucw/table-test.c +++ b/ucw/table-test.c @@ -14,7 +14,8 @@ enum test_table_cols { TEST_COL0_STR, TEST_COL1_INT, TEST_COL2_UINT, TEST_COL3_BOOL, TEST_COL4_DOUBLE, TEST_COL5_SIZE, TEST_COL6_TIME }; -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 { diff --git a/ucw/table.c b/ucw/table.c index 6a541d3b..30c7e64a 100644 --- a/ucw/table.c +++ b/ucw/table.c @@ -49,8 +49,13 @@ struct table *table_init(const struct table_template *tbl_template) // 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; @@ -58,7 +63,7 @@ struct table *table_init(const struct table_template *tbl_template) 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; @@ -82,7 +87,7 @@ void table_cleanup(struct table *tbl) // 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++) { @@ -90,8 +95,10 @@ static void table_make_default_column_order(struct table *tbl) // 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) @@ -169,10 +176,13 @@ static void table_update_ll(struct table *tbl) } } -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; @@ -213,9 +223,7 @@ const char *table_set_col_opt(struct table *tbl, uint col_inst_idx, const char * // 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); } @@ -586,7 +594,8 @@ enum test_table_cols { 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 { @@ -675,8 +684,8 @@ static void test_simple1(struct fastbuf *out) // 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"); @@ -696,7 +705,7 @@ enum test_any_table_cols { 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 { diff --git a/ucw/table.h b/ucw/table.h index 04abd1f3..3338b47d 100644 --- a/ucw/table.h +++ b/ucw/table.h @@ -103,7 +103,6 @@ struct table_col_instance { 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; @@ -182,7 +181,7 @@ struct table { #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 /** @@ -190,6 +189,7 @@ struct table { **/ #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. @@ -323,16 +323,15 @@ const char *table_set_col_opt(struct table *tbl, uint col_inst_idx, const char * 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 -- 2.39.2