From 6225de5ac27f6c9b1531bdef5fe3521969777c2c Mon Sep 17 00:00:00 2001 From: Robert Kessl Date: Mon, 7 Jul 2014 15:18:05 +0200 Subject: [PATCH] tableprinter: table_init now makes a copy of its argument - tableprinter now considers the argument to table_init as a template and makes a copy of it. Copy of the template (struct table) is allocated on the table template pool. - FIXME: documentation must be updated --- ucw/table-test-2.c | 80 +++++++++++----------- ucw/table-test-align.c | 8 +-- ucw/table-test.c | 40 +++++------ ucw/table.c | 146 ++++++++++++++++++++++++++--------------- ucw/table.h | 4 +- 5 files changed, 161 insertions(+), 117 deletions(-) diff --git a/ucw/table-test-2.c b/ucw/table-test-2.c index f46427c0..78116d84 100644 --- a/ucw/table-test-2.c +++ b/ucw/table-test-2.c @@ -27,41 +27,41 @@ static void do_test(void) { struct fastbuf *out; out = bfdopen_shared(1, 4096); - table_init(&test_tbl); - table_start(&test_tbl, out); + struct table *tbl = table_init(&test_tbl); + table_start(tbl, out); u64 test_time = 1403685533; s64 test_size = 4LU*(1024LU * 1024LU * 1024LU); - table_col_size(&test_tbl, TEST_COL0_SIZE, test_size); - table_col_timestamp(&test_tbl, TEST_COL1_TS, test_time); - table_end_row(&test_tbl); + table_col_size(tbl, TEST_COL0_SIZE, test_size); + table_col_timestamp(tbl, TEST_COL1_TS, test_time); + table_end_row(tbl); - test_tbl.column_order[TEST_COL0_SIZE].output_type = UNIT_KILOBYTE; - table_col_size(&test_tbl, TEST_COL0_SIZE, test_size); - table_col_timestamp(&test_tbl, TEST_COL1_TS, test_time); - table_end_row(&test_tbl); + tbl->column_order[TEST_COL0_SIZE].output_type = UNIT_KILOBYTE; + table_col_size(tbl, TEST_COL0_SIZE, test_size); + table_col_timestamp(tbl, TEST_COL1_TS, test_time); + table_end_row(tbl); - test_tbl.column_order[TEST_COL0_SIZE].output_type = UNIT_MEGABYTE; - table_col_size(&test_tbl, TEST_COL0_SIZE, test_size); - table_col_timestamp(&test_tbl, TEST_COL1_TS, test_time); - table_end_row(&test_tbl); + tbl->column_order[TEST_COL0_SIZE].output_type = UNIT_MEGABYTE; + table_col_size(tbl, TEST_COL0_SIZE, test_size); + table_col_timestamp(tbl, TEST_COL1_TS, test_time); + table_end_row(tbl); - test_tbl.column_order[TEST_COL0_SIZE].output_type = UNIT_GIGABYTE; - test_tbl.column_order[TEST_COL1_TS].output_type = TIMESTAMP_DATETIME; - table_col_size(&test_tbl, TEST_COL0_SIZE, test_size); - table_col_timestamp(&test_tbl, TEST_COL1_TS, test_time); - table_end_row(&test_tbl); + tbl->column_order[TEST_COL0_SIZE].output_type = UNIT_GIGABYTE; + tbl->column_order[TEST_COL1_TS].output_type = TIMESTAMP_DATETIME; + table_col_size(tbl, TEST_COL0_SIZE, test_size); + table_col_timestamp(tbl, TEST_COL1_TS, test_time); + table_end_row(tbl); test_size = test_size * 1024LU; - test_tbl.column_order[TEST_COL0_SIZE].output_type = UNIT_TERABYTE; - test_tbl.column_order[TEST_COL1_TS].output_type = TIMESTAMP_DATETIME; - table_col_size(&test_tbl, TEST_COL0_SIZE, test_size); - table_col_timestamp(&test_tbl, TEST_COL1_TS, test_time); - table_end_row(&test_tbl); + tbl->column_order[TEST_COL0_SIZE].output_type = UNIT_TERABYTE; + tbl->column_order[TEST_COL1_TS].output_type = TIMESTAMP_DATETIME; + table_col_size(tbl, TEST_COL0_SIZE, test_size); + table_col_timestamp(tbl, TEST_COL1_TS, test_time); + table_end_row(tbl); - table_end(&test_tbl); - table_cleanup(&test_tbl); + table_end(tbl); + table_cleanup(tbl); bclose(out); } @@ -81,34 +81,34 @@ static void do_test2(void) { struct fastbuf *out; out = bfdopen_shared(1, 4096); - table_init(&test_tbl2); - table_set_col_order_by_name(&test_tbl2, ""); - const char *err = table_set_option_value(&test_tbl2, "cols", "size[kb],size[mb],size[gb],size[tb],ts[datetime],ts[timestamp]"); + struct table *tbl = table_init(&test_tbl2); + table_set_col_order_by_name(tbl, ""); + const char *err = table_set_option_value(tbl, "cols", "size[kb],size[mb],size[gb],size[tb],ts[datetime],ts[timestamp]"); if(err) { opt_failure("err in table_set_option_value: '%s'.", err); abort(); } - table_start(&test_tbl2, out); + table_start(tbl, out); u64 test_time = 1403685533; s64 test_size = 4LU*(1024LU * 1024LU * 1024LU); - table_col_size(&test_tbl2, TEST_COL0_SIZE, test_size); - table_col_timestamp(&test_tbl2, TEST_COL1_TS, test_time); - table_end_row(&test_tbl2); + table_col_size(tbl, TEST_COL0_SIZE, test_size); + table_col_timestamp(tbl, TEST_COL1_TS, test_time); + table_end_row(tbl); - table_col_size(&test_tbl2, TEST_COL0_SIZE, test_size); - table_col_timestamp(&test_tbl2, TEST_COL1_TS, test_time); - table_end_row(&test_tbl2); + table_col_size(tbl, TEST_COL0_SIZE, test_size); + table_col_timestamp(tbl, TEST_COL1_TS, test_time); + table_end_row(tbl); test_size = test_size * 1024LU; - table_col_size(&test_tbl2, TEST_COL0_SIZE, test_size); - table_col_timestamp(&test_tbl2, TEST_COL1_TS, test_time); - table_end_row(&test_tbl2); + table_col_size(tbl, TEST_COL0_SIZE, test_size); + table_col_timestamp(tbl, TEST_COL1_TS, test_time); + table_end_row(tbl); - table_end(&test_tbl2); - table_cleanup(&test_tbl2); + table_end(tbl); + table_cleanup(tbl); bclose(out); } diff --git a/ucw/table-test-align.c b/ucw/table-test-align.c index f0ddfaf0..ad480ad7 100644 --- a/ucw/table-test-align.c +++ b/ucw/table-test-align.c @@ -99,11 +99,11 @@ int main(int argc UNUSED, char **argv) struct fastbuf *out; out = bfdopen_shared(1, 4096); - table_init(&test_tbl); - process_command_line_opts(argv, &test_tbl); + struct table *tbl = table_init(&test_tbl); + process_command_line_opts(argv, tbl); - print_table(&test_tbl, out); - table_cleanup(&test_tbl); + print_table(tbl, out); + table_cleanup(tbl); bclose(out); return 0; diff --git a/ucw/table-test.c b/ucw/table-test.c index c13ae2e3..4e59e7e2 100644 --- a/ucw/table-test.c +++ b/ucw/table-test.c @@ -49,22 +49,22 @@ static struct table test_default_order_tbl = { static void do_default_order_test(struct fastbuf *out) { - table_init(&test_default_order_tbl); + struct table *tbl = table_init(&test_default_order_tbl); - table_start(&test_default_order_tbl, out); + table_start(tbl, out); - table_col_int(&test_default_order_tbl, test_default_order_col0_int, 0); - table_col_int(&test_default_order_tbl, test_default_order_col1_int, 1); - table_col_int(&test_default_order_tbl, test_default_order_col2_int, 2); - table_end_row(&test_default_order_tbl); + table_col_int(tbl, test_default_order_col0_int, 0); + table_col_int(tbl, test_default_order_col1_int, 1); + table_col_int(tbl, test_default_order_col2_int, 2); + table_end_row(tbl); - table_col_int(&test_default_order_tbl, test_default_order_col0_int, 10); - table_col_int(&test_default_order_tbl, test_default_order_col1_int, 11); - table_col_int(&test_default_order_tbl, test_default_order_col2_int, 12); - table_end_row(&test_default_order_tbl); + table_col_int(tbl, test_default_order_col0_int, 10); + table_col_int(tbl, test_default_order_col1_int, 11); + table_col_int(tbl, test_default_order_col2_int, 12); + table_end_row(tbl); - table_end(&test_default_order_tbl); - table_cleanup(&test_default_order_tbl); + table_end(tbl); + table_cleanup(tbl); } /** @@ -162,14 +162,14 @@ int main(int argc UNUSED, char **argv) struct fastbuf *out; out = bfdopen_shared(1, 4096); - table_init(&test_tbl); + struct table *tbl = table_init(&test_tbl); - process_command_line_opts(argv, &test_tbl); + process_command_line_opts(argv, tbl); const char *rv = NULL; switch(test_to_perform) { case TEST_INVALID_ORDER: - rv = table_set_option(&test_tbl, "cols:test_col0_str,test_col1_int,xxx"); + rv = table_set_option(tbl, "cols:test_col0_str,test_col1_int,xxx"); if(rv) printf("Tableprinter option parser returned: '%s'.\n", rv); return 0; case TEST_DEFAULT_COLUMN_ORDER: @@ -177,15 +177,15 @@ int main(int argc UNUSED, char **argv) bclose(out); return 0; case TEST_INVALID_OPTION: - test_option_parser(&test_tbl); + test_option_parser(tbl); bclose(out); return 0; }; - table_start(&test_tbl, out); - do_print1(&test_tbl); - table_end(&test_tbl); - table_cleanup(&test_tbl); + table_start(tbl, out); + do_print1(tbl); + table_end(tbl); + table_cleanup(tbl); bclose(out); diff --git a/ucw/table.c b/ucw/table.c index 94f5c528..1a26e5b3 100644 --- a/ucw/table.c +++ b/ucw/table.c @@ -20,10 +20,52 @@ static void table_update_ll(struct table *tbl); /*** Management of tables ***/ -void table_init(struct table *tbl) +static void table_template_init(struct table *tbl_template) +{ + if(!tbl_template->pool) { + tbl_template->pool = mp_new(4096); + } +} + +static struct table *table_template_copy(struct table *tbl_template) +{ + struct table *copy = mp_alloc_zero(tbl_template->pool, sizeof(struct table)); + + copy->column_count = tbl_template->column_count; + copy->pool = mp_new(4096); + if(tbl_template->column_order) { + copy->column_order = mp_alloc_zero(copy->pool, sizeof(struct table_col_info) * tbl_template->cols_to_output); //tbl_template->; // FIXME: more complicated copying + memcpy(copy->column_order, tbl_template->column_order, sizeof(struct table_col_info) * tbl_template->cols_to_output); + for(uint i = 0; i < copy->cols_to_output; i++) { + copy->column_order[i].cell_content = NULL; + copy->column_order[i].col_def = NULL; + copy->column_order[i].output_type = tbl_template->column_order[i].output_type; + } + + copy->cols_to_output = tbl_template->cols_to_output; + } + + copy->columns = tbl_template->columns; + + copy->col_delimiter = tbl_template->col_delimiter; + copy->print_header = tbl_template->print_header; + copy->out = 0; + copy->last_printed_col = -1; + copy->row_printing_started = 0; + copy->col_out = -1; + copy->formatter = tbl_template->formatter; + copy->data = NULL; + return copy; +} + +struct table *table_init(struct table *tbl_template) { int col_count = 0; // count the number of columns in the struct table + table_template_init(tbl_template); + + struct table *tbl = table_template_copy(tbl_template); + for(;;) { if(tbl->columns[col_count].name == NULL && tbl->columns[col_count].fmt == NULL && @@ -31,12 +73,11 @@ void table_init(struct table *tbl) tbl->columns[col_count].type == COL_TYPE_LAST) break; ASSERT(tbl->columns[col_count].name != NULL); - ASSERT(tbl->columns[col_count].type == COL_TYPE_ANY || tbl->columns[col_count].fmt != NULL); + ASSERT(tbl->columns[col_count].type == COL_TYPE_ANY || tbl_template->columns[col_count].fmt != NULL); ASSERT(tbl->columns[col_count].width != 0); col_count++; } - tbl->pool = mp_new(4096); tbl->column_count = col_count; @@ -45,6 +86,7 @@ void table_init(struct table *tbl) } tbl->print_header = 1; // by default, print header + return tbl; } void table_cleanup(struct table *tbl) @@ -56,7 +98,7 @@ void table_cleanup(struct table *tbl) // TODO: test default column order static void table_make_default_column_order(struct table *tbl) { - int *col_order_int = mp_alloc_zero(tbl->pool, sizeof(int) * tbl->column_count); + int *col_order_int = mp_alloc_zero(tbl->pool, sizeof(int) * tbl->column_count); // FIXME: use stack instead of memory pool for(int i = 0; i < tbl->column_count; i++) { col_order_int[i] = i; } @@ -680,53 +722,53 @@ static void do_print1(struct table *test_tbl) static void test_simple1(struct fastbuf *out) { - table_init(&test_tbl); + struct table *tbl = table_init(&test_tbl); // print table with header - table_set_col_order_by_name(&test_tbl, "col3_bool"); - table_start(&test_tbl, out); - do_print1(&test_tbl); - table_end(&test_tbl); + table_set_col_order_by_name(tbl, "col3_bool"); + table_start(tbl, out); + do_print1(tbl); + table_end(tbl); // print the same table as in the previous case without header - table_set_col_order_by_name(&test_tbl, "col0_str,col2_uint,col1_int,col3_bool"); - table_start(&test_tbl, out); - do_print1(&test_tbl); - table_end(&test_tbl); + table_set_col_order_by_name(tbl, "col0_str,col2_uint,col1_int,col3_bool"); + table_start(tbl, out); + do_print1(tbl); + table_end(tbl); // this also tests whether there is need to call table_set_col_order_by_name after table_end was called - test_tbl.print_header = 0; - table_start(&test_tbl, out); - do_print1(&test_tbl); - table_end(&test_tbl); - test_tbl.print_header = 1; + tbl->print_header = 0; + table_start(tbl, out); + do_print1(tbl); + table_end(tbl); + tbl->print_header = 1; - table_set_col_order_by_name(&test_tbl, "col3_bool"); - table_start(&test_tbl, out); - do_print1(&test_tbl); - table_end(&test_tbl); + table_set_col_order_by_name(tbl, "col3_bool"); + table_start(tbl, out); + do_print1(tbl); + table_end(tbl); - table_set_col_order_by_name(&test_tbl, "col3_bool,col0_str"); - table_start(&test_tbl, out); - do_print1(&test_tbl); - table_end(&test_tbl); + table_set_col_order_by_name(tbl, "col3_bool,col0_str"); + table_start(tbl, out); + do_print1(tbl); + table_end(tbl); - table_set_col_order_by_name(&test_tbl, "col0_str,col3_bool,col2_uint"); - table_start(&test_tbl, out); - do_print1(&test_tbl); - table_end(&test_tbl); + table_set_col_order_by_name(tbl, "col0_str,col3_bool,col2_uint"); + table_start(tbl, out); + do_print1(tbl); + table_end(tbl); - table_set_col_order_by_name(&test_tbl, "col0_str,col3_bool,col2_uint,col0_str,col3_bool,col2_uint,col0_str,col3_bool,col2_uint"); - table_start(&test_tbl, out); - do_print1(&test_tbl); - table_end(&test_tbl); + table_set_col_order_by_name(tbl, "col0_str,col3_bool,col2_uint,col0_str,col3_bool,col2_uint,col0_str,col3_bool,col2_uint"); + table_start(tbl, out); + do_print1(tbl); + table_end(tbl); - table_set_col_order_by_name(&test_tbl, "col0_str,col1_int,col2_uint,col3_bool,col4_double"); - table_start(&test_tbl, out); - do_print1(&test_tbl); - table_end(&test_tbl); + table_set_col_order_by_name(tbl, "col0_str,col1_int,col2_uint,col3_bool,col4_double"); + table_start(tbl, out); + do_print1(tbl); + table_end(tbl); - table_cleanup(&test_tbl); + table_cleanup(tbl); } enum test_any_table_cols { @@ -748,24 +790,24 @@ static struct table test_any_tbl = { static void test_any_type(struct fastbuf *out) { - table_init(&test_any_tbl); + struct table *tbl = table_init(&test_any_tbl); - table_start(&test_any_tbl, out); + table_start(tbl, out); - table_col_int(&test_any_tbl, test_any_col0_int, -10); - table_col_int(&test_any_tbl, test_any_col1_any, 10000); - table_end_row(&test_any_tbl); + table_col_int(tbl, test_any_col0_int, -10); + table_col_int(tbl, test_any_col1_any, 10000); + table_end_row(tbl); - table_col_int(&test_any_tbl, test_any_col0_int, -10); - table_col_double(&test_any_tbl, test_any_col1_any, 1.4); - table_end_row(&test_any_tbl); + table_col_int(tbl, test_any_col0_int, -10); + table_col_double(tbl, test_any_col1_any, 1.4); + table_end_row(tbl); - table_col_printf(&test_any_tbl, test_any_col0_int, "%d", 10); - table_col_double(&test_any_tbl, test_any_col1_any, 1.4); - table_end_row(&test_any_tbl); + table_col_printf(tbl, test_any_col0_int, "%d", 10); + table_col_double(tbl, test_any_col1_any, 1.4); + table_end_row(tbl); - table_end(&test_any_tbl); - table_cleanup(&test_any_tbl); + table_end(tbl); + table_cleanup(tbl); } int main(int argc UNUSED, char **argv UNUSED) diff --git a/ucw/table.h b/ucw/table.h index d1d4426c..1f0f8c2e 100644 --- a/ucw/table.h +++ b/ucw/table.h @@ -73,6 +73,8 @@ * ----------------- ***/ +// FIXME: update documentation according to the changes made in recent comments! + /** Types of columns. These are seldom used explicitly, using a column definition macro is preferred. **/ enum column_type { COL_TYPE_STR, // String @@ -224,7 +226,7 @@ struct table { * Initialize a table definition. The structure should already contain * the definitions of columns. **/ -void table_init(struct table *tbl); +struct table *table_init(struct table *tbl_template); /** Destroy a table definition, freeing all memory used by it. **/ void table_cleanup(struct table *tbl); -- 2.39.2