diff --git a/lib/fort.c b/lib/fort.c index dfec307..e54e2d9 100644 --- a/lib/fort.c +++ b/lib/fort.c @@ -712,6 +712,9 @@ separator_t *create_separator(int enabled); FT_INTERNAL void destroy_separator(separator_t *sep); +FT_INTERNAL +separator_t *copy_separator(separator_t *sep); + FT_INTERNAL fort_status_t get_table_sizes(const ft_table_t *table, size_t *rows, size_t *cols); @@ -848,7 +851,14 @@ fort_cell_options_t *get_cell_opt_and_create_if_not_exists(fort_cell_opt_contain if (opt->cell_row == row && opt->cell_col == col) return opt; } - fort_cell_options_t opt = g_default_cell_option;// DEFAULT_CELL_OPTION; + +// fort_cell_options_t opt = g_default_cell_option;// DEFAULT_CELL_OPTION; + fort_cell_options_t opt; + if (row == FT_ANY_ROW && col == FT_ANY_COLUMN) + memcpy(&opt, &g_default_cell_option, sizeof(fort_cell_options_t)); + else + memset(&opt, 0, sizeof(fort_cell_options_t)); + opt.cell_row = row; opt.cell_col = col; if (FT_IS_SUCCESS(vector_push(cont, &opt))) { @@ -868,7 +878,7 @@ int get_cell_opt_value_hierarcial(const fort_table_options_t *options, size_t ro if (options->cell_options != NULL) { while (1) { opt = cget_cell_opt(options->cell_options, row, column); - if (opt != NULL) + if (opt != NULL && OPTION_IS_SET(opt->options, option)) break; if (row != FT_ANY_ROW) { row = FT_ANY_ROW; @@ -1461,6 +1471,14 @@ void destroy_separator(separator_t *sep) } +FT_INTERNAL +separator_t *copy_separator(separator_t *sep) +{ + assert(sep); + return create_separator(sep->enabled); +} + + static fort_row_t *get_row_implementation(ft_table_t *table, size_t row, enum PolicyOnNull policy) { @@ -1832,7 +1850,17 @@ ft_table_t *ft_copy_table(ft_table_t *table) vector_push(result->rows, &new_row); } - /* todo: copy separators */ + size_t sep_sz = vector_size(table->separators); + for (size_t i = 0; i < sep_sz; ++i) { + separator_t *sep = *(separator_t **)vector_at(table->separators, i); + separator_t *new_sep = copy_separator(sep); + if (new_sep == NULL) { + ft_destroy_table(result); + return NULL; + } + vector_push(result->separators, &new_sep); + } + result->options = copy_table_options(table->options); if (result->options == NULL) { diff --git a/src/fort_impl.c b/src/fort_impl.c index 0aeaaa2..5f2e40d 100644 --- a/src/fort_impl.c +++ b/src/fort_impl.c @@ -112,7 +112,17 @@ ft_table_t *ft_copy_table(ft_table_t *table) vector_push(result->rows, &new_row); } - /* todo: copy separators */ + size_t sep_sz = vector_size(table->separators); + for (size_t i = 0; i < sep_sz; ++i) { + separator_t *sep = *(separator_t **)vector_at(table->separators, i); + separator_t *new_sep = copy_separator(sep); + if (new_sep == NULL) { + ft_destroy_table(result); + return NULL; + } + vector_push(result->separators, &new_sep); + } + result->options = copy_table_options(table->options); if (result->options == NULL) { diff --git a/src/options.c b/src/options.c index 7e333d8..22ca878 100644 --- a/src/options.c +++ b/src/options.c @@ -100,7 +100,14 @@ fort_cell_options_t *get_cell_opt_and_create_if_not_exists(fort_cell_opt_contain if (opt->cell_row == row && opt->cell_col == col) return opt; } - fort_cell_options_t opt = g_default_cell_option;// DEFAULT_CELL_OPTION; + +// fort_cell_options_t opt = g_default_cell_option;// DEFAULT_CELL_OPTION; + fort_cell_options_t opt; + if (row == FT_ANY_ROW && col == FT_ANY_COLUMN) + memcpy(&opt, &g_default_cell_option, sizeof(fort_cell_options_t)); + else + memset(&opt, 0, sizeof(fort_cell_options_t)); + opt.cell_row = row; opt.cell_col = col; if (FT_IS_SUCCESS(vector_push(cont, &opt))) { @@ -120,7 +127,7 @@ int get_cell_opt_value_hierarcial(const fort_table_options_t *options, size_t ro if (options->cell_options != NULL) { while (1) { opt = cget_cell_opt(options->cell_options, row, column); - if (opt != NULL) + if (opt != NULL && OPTION_IS_SET(opt->options, option)) break; if (row != FT_ANY_ROW) { row = FT_ANY_ROW; diff --git a/src/table.c b/src/table.c index f06d15f..6d1831f 100644 --- a/src/table.c +++ b/src/table.c @@ -22,6 +22,14 @@ void destroy_separator(separator_t *sep) } +FT_INTERNAL +separator_t *copy_separator(separator_t *sep) +{ + assert(sep); + return create_separator(sep->enabled); +} + + static fort_row_t *get_row_implementation(ft_table_t *table, size_t row, enum PolicyOnNull policy) { diff --git a/src/table.h b/src/table.h index 9db950e..9adca0b 100644 --- a/src/table.h +++ b/src/table.h @@ -18,6 +18,9 @@ separator_t *create_separator(int enabled); FT_INTERNAL void destroy_separator(separator_t *sep); +FT_INTERNAL +separator_t *copy_separator(separator_t *sep); + FT_INTERNAL fort_status_t get_table_sizes(const ft_table_t *table, size_t *rows, size_t *cols); diff --git a/tests/bb_tests/test_table_basic.c b/tests/bb_tests/test_table_basic.c index afc00f2..c965d3f 100644 --- a/tests/bb_tests/test_table_basic.c +++ b/tests/bb_tests/test_table_basic.c @@ -68,40 +68,6 @@ void test_table_basic(void) } #endif - WHEN("Test table copy") { - table = ft_create_table(); - assert_true(table != NULL); - assert_true(set_test_options_for_table(table) == FT_SUCCESS); - - ft_set_cell_option(table, 0, FT_ANY_COLUMN, FT_COPT_ROW_TYPE, FT_ROW_HEADER); - assert_true(ft_write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS); - assert_true(ft_write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS); - assert_true(ft_write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS); - - ft_table_t *table_copy = ft_copy_table(table); - assert_true(table != NULL); - const char *table_str = ft_to_string(table_copy); - assert_true(table_str != NULL); - const char *table_str_etalon = - "+---+---+-----+----------+\n" - "| | | | |\n" - "| 3 | c | 234 | 3.140000 |\n" - "| | | | |\n" - "+---+---+-----+----------+\n" - "| | | | |\n" - "| 3 | c | 234 | 3.140000 |\n" - "| | | | |\n" - "+---+---+-----+----------+\n" - "| | | | |\n" - "| 3 | c | 234 | 3.140000 |\n" - "| | | | |\n" - "+---+---+-----+----------+\n"; - assert_str_equal(table_str, table_str_etalon); - ft_destroy_table(table); - ft_destroy_table(table_copy); - } - - WHEN("All columns are not equal and not empty") { table = ft_create_table(); assert_true(table != NULL); @@ -815,3 +781,67 @@ void test_table_write(void) #endif } + + +void test_table_copy(void) +{ + ft_table_t *table = NULL; + + WHEN("Test table copy") { + table = ft_create_table(); + assert_true(table != NULL); + + assert_true(ft_set_cell_option(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_COPT_BOTTOM_PADDING, 1) == FT_SUCCESS); + assert_true(ft_set_cell_option(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_COPT_TOP_PADDING, 1) == FT_SUCCESS); + assert_true(ft_set_cell_option(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_COPT_LEFT_PADDING, 2) == FT_SUCCESS); + assert_true(ft_set_cell_option(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_COPT_RIGHT_PADDING, 2) == FT_SUCCESS); + + + ft_set_border_style(table, FT_DOUBLE2_STYLE); + + /* Set "header" type for the first row */ + ft_set_cell_option(table, 0, FT_ANY_COLUMN, FT_COPT_ROW_TYPE, FT_ROW_HEADER); + ft_write_ln(table, "Movie title", "Director", "Year", "Rating"); + + ft_write_ln(table, "The Shawshank Redemption", "Frank Darabont", "1994", "9.5"); + ft_write_ln(table, "The Godfather", "Francis Ford Coppola", "1972", "9.2"); + ft_add_separator(table); + + ft_write_ln(table, "2001: A Space Odyssey", "Stanley Kubrick", "1968", "8.5"); + + /* Set center alignment for the 1st and 3rd columns */ + ft_set_cell_option(table, FT_ANY_ROW, 1, FT_COPT_TEXT_ALIGN, FT_ALIGNED_CENTER); + ft_set_cell_option(table, FT_ANY_ROW, 3, FT_COPT_TEXT_ALIGN, FT_ALIGNED_CENTER); + + + ft_table_t *table_copy = ft_copy_table(table); + + assert_true(table != NULL); + const char *table_str = ft_to_string(table_copy); + assert_true(table_str != NULL); + const char *table_str_etalon = + "╔════════════════════════════╤════════════════════════╤════════╤══════════╗\n" + "║ │ │ │ ║\n" + "║ Movie title │ Director │ Year │ Rating ║\n" + "║ │ │ │ ║\n" + "╠════════════════════════════╪════════════════════════╪════════╪══════════╣\n" + "║ │ │ │ ║\n" + "║ The Shawshank Redemption │ Frank Darabont │ 1994 │ 9.5 ║\n" + "║ │ │ │ ║\n" + "╟────────────────────────────┼────────────────────────┼────────┼──────────╢\n" + "║ │ │ │ ║\n" + "║ The Godfather │ Francis Ford Coppola │ 1972 │ 9.2 ║\n" + "║ │ │ │ ║\n" + "╠════════════════════════════╪════════════════════════╪════════╪══════════╣\n" + "║ │ │ │ ║\n" + "║ 2001: A Space Odyssey │ Stanley Kubrick │ 1968 │ 8.5 ║\n" + "║ │ │ │ ║\n" + "╚════════════════════════════╧════════════════════════╧════════╧══════════╝\n"; + assert_str_equal(table_str, table_str_etalon); + ft_destroy_table(table); + ft_destroy_table(table_copy); + } +} + + + diff --git a/tests/bb_tests_cpp/test_table_basic.cpp b/tests/bb_tests_cpp/test_table_basic.cpp index 878d94f..d546cac 100644 --- a/tests/bb_tests_cpp/test_table_basic.cpp +++ b/tests/bb_tests_cpp/test_table_basic.cpp @@ -74,7 +74,11 @@ void test_cpp_table_basic(void) fort::Table table3; table3 = std::move(table2); - std::string table_str = table3.to_string(); + fort::Table table4(table3); + fort::Table table5; + table5 = table4; + + std::string table_str = table5.to_string(); std::string table_str_etalon = "+---+---+-----+----------+\n" "| | | | |\n" diff --git a/tests/main_test.c b/tests/main_test.c index b16fb34..5408f08 100644 --- a/tests/main_test.c +++ b/tests/main_test.c @@ -9,6 +9,7 @@ struct test_case wb_test_suit [] = { {"test_string_buffer", test_string_buffer}, {"test_table_sizes", test_table_sizes}, {"test_table_geometry", test_table_geometry}, + {"test_table_copy", test_table_copy}, }; #endif diff --git a/tests/tests.h b/tests/tests.h index d0cdca9..ebf28e5 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -25,6 +25,7 @@ void test_string_buffer(void); void test_table_sizes(void); void test_table_geometry(void); void test_table_basic(void); +void test_table_copy(void); #ifdef FT_HAVE_WCHAR void test_wcs_table_boundaries(void); #endif