From 0440ebb931623811c248512b05e3efbaa0712d16 Mon Sep 17 00:00:00 2001 From: seleznevae Date: Sat, 12 May 2018 12:45:42 +0300 Subject: [PATCH] [F] Fixed printf errors --- README.md | 2 +- lib/fort.c | 64 ++++++++++++++++++++++++++++--- src/row.c | 59 ++++++++++++++++++++++++++-- src/vector.c | 5 ++- tests/bb_tests/test_table_basic.c | 40 +++++++++++++++++++ tests/wb_tests/test_vector.c | 33 ++++++++++++++++ 6 files changed, 192 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 0da7dd3..1e42f65 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ The following compilers are currently used in continuous integration at [Travis] | Visual Studio 2017 | Windows Server 2016 | Pease note: -- In case of clang on OS X before using libfort with ```wchar_t``` with real unicode symbols it may be necessary to set ```setlocale(LC_CTYPE, "");``` because otherwise standard function ```swprintf```, that libfort uses internally, may fail and _ft_to_string_ will return error. +- In case of clang on OS X before using **libfort** with ```wchar_t``` with real unicode symbols it may be necessary to set ```setlocale(LC_CTYPE, "");``` because otherwise standard function ```swprintf```, that libfort uses internally, may fail and ```ft_to_string``` will return error. ## License diff --git a/lib/fort.c b/lib/fort.c index de3aef7..a73ec8f 100644 --- a/lib/fort.c +++ b/lib/fort.c @@ -2713,7 +2713,7 @@ fort_status_t vector_swap(vector_t *cur_vec, vector_t *mv_vec, size_t pos) } size_t min_targ_size = pos + mv_sz; - if (cur_sz < min_targ_size) { + if (vector_capacity(cur_vec) < min_targ_size) { if (vector_reallocate_(cur_vec, min_targ_size) == -1) return FT_ERROR; cur_vec->m_capacity = min_targ_size; @@ -2732,7 +2732,7 @@ fort_status_t vector_swap(vector_t *cur_vec, vector_t *mv_vec, size_t pos) memcpy(tmp, (char *)cur_vec->m_data + deviation, - cur_vec->m_item_size * (cur_sz - pos)); + cur_vec->m_item_size * new_mv_sz); memcpy((char *)cur_vec->m_data + deviation, mv_vec->m_data, cur_vec->m_item_size * mv_sz); @@ -2740,6 +2740,7 @@ fort_status_t vector_swap(vector_t *cur_vec, vector_t *mv_vec, size_t pos) tmp, cur_vec->m_item_size * new_mv_sz); + cur_vec->m_size = MAX(cur_vec->m_size, min_targ_size); mv_vec->m_size = new_mv_sz; F_FREE(tmp); return FT_SUCCESS; @@ -4233,6 +4234,7 @@ fort_row_t *create_row_from_fmt_string(const char *fmt, va_list *va_args) #define STR_FILED cstr #define CREATE_ROW_FROM_STRING create_row_from_string #define NUMBER_OF_COLUMNS_IN_FORMAT_STRING number_of_columns_in_format_string +#define FILL_CELL_FROM_STRING fill_cell_from_string string_buffer_t *buffer = create_string_buffer(DEFAULT_STR_BUF_SIZE, CharBuf); if (buffer == NULL) @@ -4271,7 +4273,32 @@ fort_row_t *create_row_from_fmt_string(const char *fmt, va_list *va_args) return row; } - /* todo: add processing of cols != cols_origin */ + if (cols_origin == 1) { + fort_row_t *row = create_row(); + if (row == NULL) { + goto clear; + } + + fort_cell_t *cell = get_cell_and_create_if_not_exists(row, 0); + if (cell == NULL) { + destroy_row(row); + goto clear; + } + + fort_status_t result = FILL_CELL_FROM_STRING(cell, buffer->str.STR_FILED); + if (FT_IS_ERROR(result)) { + destroy_row(row); + goto clear; + } + + destroy_string_buffer(buffer); + return row; + } + + /* + * todo: add processing of cols != cols_origin in a general way + * (when cols_origin != 1). + */ clear: destroy_string_buffer(buffer); @@ -4280,6 +4307,7 @@ clear: #undef STR_FILED #undef CREATE_ROW_FROM_STRING #undef NUMBER_OF_COLUMNS_IN_FORMAT_STRING +#undef FILL_CELL_FROM_STRING } #ifdef FT_HAVE_WCHAR @@ -4289,7 +4317,7 @@ fort_row_t *create_row_from_fmt_wstring(const wchar_t *fmt, va_list *va_args) #define STR_FILED wstr #define CREATE_ROW_FROM_STRING create_row_from_wstring #define NUMBER_OF_COLUMNS_IN_FORMAT_STRING number_of_columns_in_format_wstring - +#define FILL_CELL_FROM_STRING fill_cell_from_wstring string_buffer_t *buffer = create_string_buffer(DEFAULT_STR_BUF_SIZE, CharBuf); if (buffer == NULL) @@ -4328,7 +4356,32 @@ fort_row_t *create_row_from_fmt_wstring(const wchar_t *fmt, va_list *va_args) return row; } - /* todo: add processing of cols != cols_origin */ + if (cols_origin == 1) { + fort_row_t *row = create_row(); + if (row == NULL) { + goto clear; + } + + fort_cell_t *cell = get_cell_and_create_if_not_exists(row, 0); + if (cell == NULL) { + destroy_row(row); + goto clear; + } + + fort_status_t result = FILL_CELL_FROM_STRING(cell, buffer->str.STR_FILED); + if (FT_IS_ERROR(result)) { + destroy_row(row); + goto clear; + } + + destroy_string_buffer(buffer); + return row; + } + + /* + * todo: add processing of cols != cols_origin in a general way + * (when cols_origin != 1). + */ clear: destroy_string_buffer(buffer); @@ -4337,6 +4390,7 @@ clear: #undef STR_FILED #undef CREATE_ROW_FROM_STRING #undef NUMBER_OF_COLUMNS_IN_FORMAT_STRING +#undef FILL_CELL_FROM_STRING } #endif diff --git a/src/row.c b/src/row.c index 4618ee8..b12bb7e 100644 --- a/src/row.c +++ b/src/row.c @@ -718,6 +718,7 @@ fort_row_t *create_row_from_fmt_string(const char *fmt, va_list *va_args) #define STR_FILED cstr #define CREATE_ROW_FROM_STRING create_row_from_string #define NUMBER_OF_COLUMNS_IN_FORMAT_STRING number_of_columns_in_format_string +#define FILL_CELL_FROM_STRING fill_cell_from_string string_buffer_t *buffer = create_string_buffer(DEFAULT_STR_BUF_SIZE, CharBuf); if (buffer == NULL) @@ -756,7 +757,32 @@ fort_row_t *create_row_from_fmt_string(const char *fmt, va_list *va_args) return row; } - /* todo: add processing of cols != cols_origin */ + if (cols_origin == 1) { + fort_row_t *row = create_row(); + if (row == NULL) { + goto clear; + } + + fort_cell_t *cell = get_cell_and_create_if_not_exists(row, 0); + if (cell == NULL) { + destroy_row(row); + goto clear; + } + + fort_status_t result = FILL_CELL_FROM_STRING(cell, buffer->str.STR_FILED); + if (FT_IS_ERROR(result)) { + destroy_row(row); + goto clear; + } + + destroy_string_buffer(buffer); + return row; + } + + /* + * todo: add processing of cols != cols_origin in a general way + * (when cols_origin != 1). + */ clear: destroy_string_buffer(buffer); @@ -765,6 +791,7 @@ clear: #undef STR_FILED #undef CREATE_ROW_FROM_STRING #undef NUMBER_OF_COLUMNS_IN_FORMAT_STRING +#undef FILL_CELL_FROM_STRING } #ifdef FT_HAVE_WCHAR @@ -774,7 +801,7 @@ fort_row_t *create_row_from_fmt_wstring(const wchar_t *fmt, va_list *va_args) #define STR_FILED wstr #define CREATE_ROW_FROM_STRING create_row_from_wstring #define NUMBER_OF_COLUMNS_IN_FORMAT_STRING number_of_columns_in_format_wstring - +#define FILL_CELL_FROM_STRING fill_cell_from_wstring string_buffer_t *buffer = create_string_buffer(DEFAULT_STR_BUF_SIZE, CharBuf); if (buffer == NULL) @@ -813,7 +840,32 @@ fort_row_t *create_row_from_fmt_wstring(const wchar_t *fmt, va_list *va_args) return row; } - /* todo: add processing of cols != cols_origin */ + if (cols_origin == 1) { + fort_row_t *row = create_row(); + if (row == NULL) { + goto clear; + } + + fort_cell_t *cell = get_cell_and_create_if_not_exists(row, 0); + if (cell == NULL) { + destroy_row(row); + goto clear; + } + + fort_status_t result = FILL_CELL_FROM_STRING(cell, buffer->str.STR_FILED); + if (FT_IS_ERROR(result)) { + destroy_row(row); + goto clear; + } + + destroy_string_buffer(buffer); + return row; + } + + /* + * todo: add processing of cols != cols_origin in a general way + * (when cols_origin != 1). + */ clear: destroy_string_buffer(buffer); @@ -822,6 +874,7 @@ clear: #undef STR_FILED #undef CREATE_ROW_FROM_STRING #undef NUMBER_OF_COLUMNS_IN_FORMAT_STRING +#undef FILL_CELL_FROM_STRING } #endif diff --git a/src/vector.c b/src/vector.c index 86378c4..8887998 100644 --- a/src/vector.c +++ b/src/vector.c @@ -179,7 +179,7 @@ fort_status_t vector_swap(vector_t *cur_vec, vector_t *mv_vec, size_t pos) } size_t min_targ_size = pos + mv_sz; - if (cur_sz < min_targ_size) { + if (vector_capacity(cur_vec) < min_targ_size) { if (vector_reallocate_(cur_vec, min_targ_size) == -1) return FT_ERROR; cur_vec->m_capacity = min_targ_size; @@ -198,7 +198,7 @@ fort_status_t vector_swap(vector_t *cur_vec, vector_t *mv_vec, size_t pos) memcpy(tmp, (char *)cur_vec->m_data + deviation, - cur_vec->m_item_size * (cur_sz - pos)); + cur_vec->m_item_size * new_mv_sz); memcpy((char *)cur_vec->m_data + deviation, mv_vec->m_data, cur_vec->m_item_size * mv_sz); @@ -206,6 +206,7 @@ fort_status_t vector_swap(vector_t *cur_vec, vector_t *mv_vec, size_t pos) tmp, cur_vec->m_item_size * new_mv_sz); + cur_vec->m_size = MAX(cur_vec->m_size, min_targ_size); mv_vec->m_size = new_mv_sz; F_FREE(tmp); return FT_SUCCESS; diff --git a/tests/bb_tests/test_table_basic.c b/tests/bb_tests/test_table_basic.c index 2e4ebaf..bb1f978 100644 --- a/tests/bb_tests/test_table_basic.c +++ b/tests/bb_tests/test_table_basic.c @@ -700,4 +700,44 @@ void test_table_write(void) } #endif + SCENARIO("Test printf functions with strings with separators inside them") { + 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); + int n = ft_printf_ln(table, "%d|%c|%s|%f", 3, 'c', "234", 3.14); + assert_true(n == 4); + n = ft_printf(table, "%c", 'c'); + assert_true(n == 1); + n = ft_printf(table, "%s", "234"); + assert_true(n == 1); + n = ft_printf(table, "%s", "string|with separator"); + assert_true(n == 1); + n = ft_printf(table, "3"); + assert_true(n == 1); + ft_ln(table); + n = ft_printf_ln(table, "%s|%f|%d|%c", "234", 3.14, 3, 'c'); + assert_true(n == 4); + + const char *table_str = ft_to_string(table); + assert_true(table_str != NULL); + const char *table_str_etalon = + "+-----+----------+-----------------------+----------+\n" + "| | | | |\n" + "| 3 | c | 234 | 3.140000 |\n" + "| | | | |\n" + "+-----+----------+-----------------------+----------+\n" + "| | | | |\n" + "| c | 234 | string|with separator | 3 |\n" + "| | | | |\n" + "+-----+----------+-----------------------+----------+\n" + "| | | | |\n" + "| 234 | 3.140000 | 3 | c |\n" + "| | | | |\n" + "+-----+----------+-----------------------+----------+\n"; + assert_str_equal(table_str, table_str_etalon); + ft_destroy_table(table); + } + } diff --git a/tests/wb_tests/test_vector.c b/tests/wb_tests/test_vector.c index 36f1aba..d758216 100644 --- a/tests/wb_tests/test_vector.c +++ b/tests/wb_tests/test_vector.c @@ -83,6 +83,39 @@ void test_vector_basic(void) } } + WHEN("Moving from another vector") { + vector_clear(vector); + for (i = 0; i < 10; ++i) { + item_t item = (item_t)i; + vector_push(vector, &item); + } + + vector_t *mv_vector = create_vector(sizeof(item_t), 5); + assert_true(mv_vector != NULL); + for (i = 0; i < 5; ++i) { + item_t item = (item_t)i * 2; + assert_true(vector_push(mv_vector, &item) == FT_SUCCESS); + } + assert_true(vector_swap(vector, mv_vector, 2) == FT_SUCCESS); + destroy_vector(mv_vector); + assert_true(vector_size(vector) == 10); + + assert_true(*(item_t *)vector_at(vector, 1) == 1); /* original value */ + assert_true(*(item_t *)vector_at(vector, 2) == 0); /* inserted value */ + assert_true(*(item_t *)vector_at(vector, 4) == 4); /* inserted value */ + assert_true(*(item_t *)vector_at(vector, 9) == 9); /* original value */ + + mv_vector = create_vector(sizeof(item_t), 5); + assert_true(mv_vector != NULL); + for (i = 0; i < 5; ++i) { + item_t item = (item_t)i * 2; + assert_true(vector_push(mv_vector, &item) == FT_SUCCESS); + } + assert_true(vector_swap(vector, mv_vector, 10) == FT_SUCCESS); + destroy_vector(mv_vector); + assert_true(vector_size(vector) == 15); + } + destroy_vector(vector); }