[F] Fixed errors in printf functions

This commit is contained in:
seleznevae 2018-04-22 21:42:22 +03:00
parent 44e734ead9
commit 68e51f90a8
10 changed files with 207 additions and 48 deletions

View File

@ -244,25 +244,41 @@ FT_EXTERN void ft_destroy_table(FTABLE *table);
FT_EXTERN void ft_ln(FTABLE *table);
/**
* Get row number of the current cell
* Get row number of the current cell.
*
* @param table
* Pointer to formatted table.
* @return
* Row number of the current cell
* Row number of the current cell.
*/
FT_EXTERN size_t ft_cur_row(FTABLE *table);
/**
* Get column number of the current cell
* Get column number of the current cell.
*
* @param table
* Pointer to formatted table.
* @return
* Column number of the current cell
* Column number of the current cell.
*/
FT_EXTERN size_t ft_cur_col(FTABLE *table);
/**
* Set current cell position.
*
* Current cell - cell that will be edited with all modifiing functions
* (ft_printf, ft_write ...).
*
* @param table
* Pointer to formatted table.
* @param row
* New row number for the current cell.
* @param col
* New row number for the current cell.
*/
FT_EXTERN void ft_set_cur_cell(FTABLE *table, size_t row, size_t col);
#if defined(FT_CLANG_COMPILER) || defined(FT_GCC_COMPILER)
@ -287,7 +303,8 @@ FT_EXTERN size_t ft_cur_col(FTABLE *table);
* more arguments than required by format, the extraneous arguments are
* evaluated and ignored.
* @return
* todo ?????
* - Number of printed cells
* - (<0): In case of error
*/
FT_EXTERN int ft_printf(FTABLE *table, const char *fmt, ...) FT_PRINTF_ATTRIBUTE_FORMAT(2, 3);
@ -312,7 +329,8 @@ FT_EXTERN int ft_printf(FTABLE *table, const char *fmt, ...) FT_PRINTF_ATTRIBUTE
* more arguments than required by format, the extraneous arguments are
* evaluated and ignored.
* @return
* todo ?????
* - Number of printed cells.
* - (<0): In case of error.
*/
FT_EXTERN int ft_printf_ln(FTABLE *table, const char *fmt, ...) FT_PRINTF_ATTRIBUTE_FORMAT(2, 3);
@ -380,8 +398,8 @@ FT_EXTERN int ft_add_separator(FTABLE *table);
* string with strdup or similar functions.
*
* Returned pointer may be later invalidated by:
* - Calling ft_destroy_table
* - Other invocations of ft_to_string
* - Calling ft_destroy_table;
* - Other invocations of ft_to_string.
*
* @param table
* Formatted table.
@ -404,7 +422,7 @@ FT_EXTERN const char *ft_to_string(const FTABLE *table);
/**
* Structure describing border appearance
* Structure describing border appearance.
*/
struct ft_border_chars {
char top_border_ch;
@ -416,7 +434,7 @@ struct ft_border_chars {
};
/**
* Structure describing border style
* Structure describing border style.
*/
struct ft_border_style {
struct ft_border_chars border_chs;
@ -425,7 +443,7 @@ struct ft_border_style {
};
/**
* Built-in table border styles
* Built-in table border styles.
*/
extern struct ft_border_style *FT_BASIC_STYLE;
extern struct ft_border_style *FT_SIMPLE_STYLE;
@ -437,7 +455,7 @@ extern struct ft_border_style *FT_EMPTY_STYLE;
* Set default border style for all new formatted tables.
*
* @param style
* Pointer to border style
* Pointer to border style.
* @return
* - 0: Success; default border style was changed.
* - (-1): !!!!!!!! todo
@ -448,9 +466,9 @@ FT_EXTERN int ft_set_default_border_style(struct ft_border_style *style);
* Set border style for the table.
*
* @param table
* A pointer to the FTABLE structure
* A pointer to the FTABLE structure.
* @param style
* Pointer to border style
* Pointer to border style.
* @return
* - 0: Success; table border style was changed.
* - (-1): !!!!!!!! todo
@ -458,7 +476,7 @@ FT_EXTERN int ft_set_default_border_style(struct ft_border_style *style);
FT_EXTERN int ft_set_border_style(FTABLE *table, struct ft_border_style *style);
/**
* Special macros to define cell position (row and column)
* Special macros to define cell position (row and column).
*/
#define FT_ANY_COLUMN (UINT_MAX)
#define FT_CUR_COLUMN (UINT_MAX - 1)
@ -466,7 +484,7 @@ FT_EXTERN int ft_set_border_style(FTABLE *table, struct ft_border_style *style);
#define FT_CUR_ROW (UINT_MAX - 1)
/**
* Cell options identifiers
* Cell options identifiers.
*/
#define FT_COPT_MIN_WIDTH (0x01U << 0) /**< Minimum width */
#define FT_COPT_TEXT_ALIGN (0x01U << 1) /**< Text alignmemnt */
@ -478,7 +496,7 @@ FT_EXTERN int ft_set_border_style(FTABLE *table, struct ft_border_style *style);
#define FT_COPT_ROW_TYPE (0x01U << 7) /**< Row type */
/**
* Alignment of cell content
* Alignment of cell content.
*/
enum ft_text_alignment {
FT_ALIGNED_LEFT,
@ -487,7 +505,7 @@ enum ft_text_alignment {
};
/**
* Type of table row
* Type of table row.
*/
enum ft_row_type {
FT_ROW_COMMON,
@ -498,9 +516,9 @@ enum ft_row_type {
* Set default cell option for all new formatted tables.
*
* @param option
* Cell option identifier
* Cell option identifier.
* @param value
* Cell option value
* Cell option value.
* @return
* - 0: Success; default cell option was changed.
* - (-1): !!!!!!!! todo
@ -511,15 +529,15 @@ FT_EXTERN int ft_set_default_cell_option(uint32_t option, int value);
* Set option for the specified cell of the table.
*
* @param table
* A pointer to the FTABLE structure
* A pointer to the FTABLE structure.
* @param row
* Cell row
* Cell row.
* @param col
* Cell column
* Cell column.
* @param option
* Cell option identifier
* Cell option identifier.
* @param value
* Cell option value
* Cell option value.
* @return
* - 0: Success; cell option was changed.
* - (-1): !!!!!!!! todo
@ -527,7 +545,7 @@ FT_EXTERN int ft_set_default_cell_option(uint32_t option, int value);
FT_EXTERN int ft_set_cell_option(FTABLE *table, size_t row, size_t col, uint32_t option, int value);
/**
* Table options identifiers
* Table options identifiers.
*/
#define FT_TOPT_LEFT_MARGIN (0x01U << 0)
#define FT_TOPT_TOP_MARGIN (0x01U << 1)
@ -538,9 +556,9 @@ FT_EXTERN int ft_set_cell_option(FTABLE *table, size_t row, size_t col, uint32_t
* Set default table option.
*
* @param option
* Table option identifier
* Table option identifier.
* @param value
* Table option value
* Table option value.
* @return
* - 0: Success; default table option was changed.
* - (-1): !!!!!!!! todo
@ -551,11 +569,11 @@ FT_EXTERN int ft_set_default_tbl_option(uint32_t option, int value);
* Set table option.
*
* @param table
* A pointer to the FTABLE structure
* A pointer to the FTABLE structure.
* @param option
* Table option identifier
* Table option identifier.
* @param value
* Table option value
* Table option value.
* @return
* - 0: Success; default table option was changed.
* - (-1): !!!!!!!! todo

View File

@ -117,6 +117,14 @@ size_t ft_cur_col(FTABLE *table)
return table->cur_col;
}
void ft_set_cur_cell(FTABLE *table, size_t row, size_t col)
{
assert(table);
table->cur_row = row;
table->cur_col = col;
}
static int ft_row_printf_impl(FTABLE *table, size_t row, const char *fmt, va_list *va)
{
size_t i = 0;
@ -146,15 +154,14 @@ static int ft_row_printf_impl(FTABLE *table, size_t row, const char *fmt, va_lis
}
}
}
/* todo: clearing pushed items in case of error */
/* todo: this function always create new row, this is not correct, it should be more complicated */
/* todo: clearing pushed items in case of error ?? */
cur_row_p = (fort_row_t **)vector_at(table->rows, row);
destroy_row(*cur_row_p);
*cur_row_p = new_row;
new_cols = columns_in_row(new_row);
cur_row_p = (fort_row_t **)vector_at(table->rows, row);
swap_row(*cur_row_p, new_row, table->cur_col);
table->cur_col += new_cols;
destroy_row(new_row);
return new_cols;
clear:

View File

@ -106,6 +106,22 @@ fort_cell_t *get_cell_and_create_if_not_exists(fort_row_t *row, size_t col)
return get_cell_implementation(row, col, Create);
}
fort_status_t swap_row(fort_row_t *cur_row, fort_row_t *ins_row, size_t pos)
{
assert(cur_row);
assert(ins_row);
size_t cur_sz = vector_size(cur_row->cells);
if (cur_sz == 0 && pos == 0) {
fort_row_t tmp;
memcpy(&tmp, cur_row, sizeof(fort_row_t));
memcpy(cur_row, ins_row, sizeof(fort_row_t));
memcpy(ins_row, &tmp, sizeof(fort_row_t));
return FT_SUCCESS;
}
return vector_swap(cur_row->cells, ins_row->cells, pos);
}

View File

@ -30,6 +30,7 @@ fort_cell_t *get_cell_implementation(fort_row_t *row, size_t col, enum PolicyOnN
fort_cell_t *get_cell(fort_row_t *row, size_t col);
const fort_cell_t *get_cell_c(const fort_row_t *row, size_t col);
fort_cell_t *get_cell_and_create_if_not_exists(fort_row_t *row, size_t col);
fort_status_t swap_row(fort_row_t *cur_row, fort_row_t *ins_row, size_t pos);

View File

@ -165,4 +165,50 @@ void *vector_at(vector_t *vector, size_t index)
return (char *)vector->m_data + index * vector->m_item_size;
}
fort_status_t vector_swap(vector_t *cur_vec, vector_t *mv_vec, size_t pos)
{
assert(cur_vec);
assert(mv_vec);
assert(cur_vec->m_item_size == mv_vec->m_item_size);
size_t cur_sz = vector_size(cur_vec);
size_t mv_sz = vector_size(mv_vec);
if (mv_sz == 0) {
return FT_SUCCESS;
}
size_t min_targ_size = pos + mv_sz;
if (cur_sz < min_targ_size) {
if (vector_reallocate_(cur_vec, min_targ_size) == -1)
return FT_ERROR;
cur_vec->m_capacity = min_targ_size;
}
ptrdiff_t deviation = pos * cur_vec->m_item_size;
void *tmp = NULL;
size_t new_mv_sz = 0;
if (cur_sz > pos) {
new_mv_sz = MIN(cur_sz - pos, mv_sz);
tmp = F_MALLOC(cur_vec->m_item_size * new_mv_sz);
if (tmp == NULL) {
return FT_MEMORY_ERROR;
}
}
memcpy(tmp,
cur_vec->m_data + deviation,
cur_vec->m_item_size * (cur_sz - pos));
memcpy(cur_vec->m_data + deviation,
mv_vec->m_data,
cur_vec->m_item_size * mv_sz);
memcpy(mv_vec->m_data,
tmp,
cur_vec->m_item_size * new_mv_sz);
mv_vec->m_size = new_mv_sz;
F_FREE(tmp);
return FT_SUCCESS;
}

View File

@ -26,6 +26,7 @@ extern int vector_erase(vector_t*, size_t index);
extern void vector_clear(vector_t*);
extern const void *vector_at_c(const vector_t *vector, size_t index);
extern void* vector_at(vector_t*, size_t index);
extern fort_status_t vector_swap(vector_t *cur_vec, vector_t *mv_vec, size_t pos);
#define FOR_EACH_(type, item, vector, index_name) \

View File

@ -3,6 +3,7 @@
struct test_case test_suit [] = {
{"test_vector_basic", test_vector_basic},
{"test_vector_stress", test_vector_stress},
{"test_string_buffer", test_string_buffer},
{"test_table_sizes", test_table_sizes},
{"test_table_geometry", test_table_geometry},

View File

@ -312,15 +312,21 @@ void test_table_write(void)
assert_true(ft_write(table, "3.140000") == FT_SUCCESS);
ft_ln(table);
assert_true(ft_write(table, "c") == FT_SUCCESS);
assert_true(ft_write(table, "234") == FT_SUCCESS);
assert_true(ft_write(table, "3.140000") == FT_SUCCESS);
assert_true(ft_write_ln(table, "3") == FT_SUCCESS);
assert_true(ft_write(table, "235") == FT_SUCCESS);
assert_true(ft_write(table, "3.150000") == FT_SUCCESS);
assert_true(ft_write_ln(table, "5") == FT_SUCCESS);
assert_true(ft_write(table, "234") == FT_SUCCESS);
assert_true(ft_write(table, "3.140000") == FT_SUCCESS);
assert_true(ft_write(table, "3") == FT_SUCCESS);
assert_true(ft_write_ln(table, "c") == FT_SUCCESS);
/* Replace old values */
ft_set_cur_cell(table, 1, 1);
assert_true(ft_write(table, "234") == FT_SUCCESS);
assert_true(ft_write(table, "3.140000") == FT_SUCCESS);
assert_true(ft_write_ln(table, "3") == FT_SUCCESS);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =
@ -354,15 +360,21 @@ void test_table_write(void)
assert_true(ft_wwrite(table, L"3.140000") == FT_SUCCESS);
ft_ln(table);
assert_true(ft_wwrite(table, L"c") == FT_SUCCESS);
assert_true(ft_wwrite(table, L"234") == FT_SUCCESS);
assert_true(ft_wwrite(table, L"3.140000") == FT_SUCCESS);
assert_true(ft_wwrite_ln(table, L"3") == FT_SUCCESS);
assert_true(ft_wwrite(table, L"235") == FT_SUCCESS);
assert_true(ft_wwrite(table, L"3.150000") == FT_SUCCESS);
assert_true(ft_wwrite_ln(table, L"5") == FT_SUCCESS);
assert_true(ft_wwrite(table, L"234") == FT_SUCCESS);
assert_true(ft_wwrite(table, L"3.140000") == FT_SUCCESS);
assert_true(ft_wwrite(table, L"3") == FT_SUCCESS);
assert_true(ft_wwrite_ln(table, L"c") == FT_SUCCESS);
/* Replace old values */
ft_set_cur_cell(table, 1, 1);
assert_true(ft_wwrite(table, L"234") == FT_SUCCESS);
assert_true(ft_wwrite(table, L"3.140000") == FT_SUCCESS);
assert_true(ft_wwrite_ln(table, L"3") == FT_SUCCESS);
const wchar_t *table_str = ft_to_wstring(table);
assert_true(table_str != NULL);
const wchar_t *table_str_etalon =
@ -392,9 +404,13 @@ void test_table_write(void)
ft_set_cell_option(table, 0, FT_ANY_COLUMN, FT_COPT_ROW_TYPE, FT_ROW_HEADER);
assert_true(ft_nwrite(table, 4, "3", "c", "234", "3.140000") == FT_SUCCESS);
ft_ln(table);
assert_true(ft_nwrite_ln(table, 4, "c", "234", "3.140000", "3") == FT_SUCCESS);
assert_true(ft_nwrite_ln(table, 4, "c", "235", "3.150000", "5") == FT_SUCCESS);
assert_true(ft_nwrite_ln(table, 4, "234", "3.140000", "3", "c") == FT_SUCCESS);
/* Replace old values */
ft_set_cur_cell(table, 1, 1);
assert_true(ft_nwrite_ln(table, 3, "234", "3.140000", "3") == FT_SUCCESS);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =
@ -424,9 +440,13 @@ void test_table_write(void)
ft_set_cell_option(table, 0, FT_ANY_COLUMN, FT_COPT_ROW_TYPE, FT_ROW_HEADER);
assert_true(ft_nwwrite(table, 4, L"3", L"c", L"234", L"3.140000") == FT_SUCCESS);
ft_ln(table);
assert_true(ft_nwwrite_ln(table, 4, L"c", L"234", L"3.140000", L"3") == FT_SUCCESS);
assert_true(ft_nwwrite_ln(table, 4, L"c", L"235", L"3.150000", L"5") == FT_SUCCESS);
assert_true(ft_nwwrite_ln(table, 4, L"234", L"3.140000", L"3", L"c") == FT_SUCCESS);
/* Replace old values */
ft_set_cur_cell(table, 1, 1);
assert_true(ft_nwwrite_ln(table, 3, L"234", L"3.140000", L"3") == FT_SUCCESS);
const wchar_t *table_str = ft_to_wstring(table);
assert_true(table_str != NULL);
const wchar_t *table_str_etalon =
@ -456,13 +476,19 @@ void test_table_write(void)
ft_set_cell_option(table, 0, FT_ANY_COLUMN, FT_COPT_ROW_TYPE, FT_ROW_HEADER);
const char *row_0[4] = {"3", "c", "234", "3.140000"};
const char *row_1[4] = {"c", "234", "3.140000", "3"};
const char *row_1[4] = {"c", "235", "3.150000", "5"};
const char *row_2[4] = {"234", "3.140000", "3", "c"};
assert_true(ft_row_write_ln(table, 4, row_0) == FT_SUCCESS);
assert_true(ft_row_write(table, 4, row_1) == FT_SUCCESS);
ft_ln(table);
assert_true(ft_row_write_ln(table, 4, row_2) == FT_SUCCESS);
/* Replace old values */
ft_set_cur_cell(table, 1, 1);
const char *row_11[3] = {"234", "3.140000", "3"};
assert_true(ft_row_write(table, 3, row_11) == FT_SUCCESS);
ft_ln(table);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =
@ -491,13 +517,19 @@ void test_table_write(void)
ft_set_cell_option(table, 0, FT_ANY_COLUMN, FT_COPT_ROW_TYPE, FT_ROW_HEADER);
const wchar_t *row_0[4] = {L"3", L"c", L"234", L"3.140000"};
const wchar_t *row_1[4] = {L"c", L"234", L"3.140000", L"3"};
const wchar_t *row_1[4] = {L"c", L"235", L"3.150000", L"5"};
const wchar_t *row_2[4] = {L"234", L"3.140000", L"3", L"c"};
assert_true(ft_row_wwrite_ln(table, 4, row_0) == FT_SUCCESS);
assert_true(ft_row_wwrite(table, 4, row_1) == FT_SUCCESS);
ft_ln(table);
assert_true(ft_row_wwrite_ln(table, 4, row_2) == FT_SUCCESS);
/* Replace old values */
ft_set_cur_cell(table, 1, 1);
const wchar_t *row_11[3] = {L"234", L"3.140000", L"3"};
assert_true(ft_row_wwrite(table, 3, row_11) == FT_SUCCESS);
ft_ln(table);
const wchar_t *table_str = ft_to_wstring(table);
assert_true(table_str != NULL);
const wchar_t *table_str_etalon =
@ -528,12 +560,17 @@ void test_table_write(void)
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|%s|%f|%d", 'c', "234", 3.14, 3);
n = ft_printf(table, "%c|%s|%f|%d", 'c', "235", 3.15, 5);
assert_true(n == 4);
ft_ln(table);
n = ft_printf_ln(table, "%s|%f|%d|%c", "234", 3.14, 3, 'c');
assert_true(n == 4);
/* Replace old values */
ft_set_cur_cell(table, 1, 1);
n = ft_printf(table, "%s|%f|%d", "234", 3.14, 3);
assert_true(n == 3);
const char *table_str = ft_to_string(table);
assert_true(table_str != NULL);
const char *table_str_etalon =

View File

@ -87,3 +87,34 @@ void test_vector_basic(void)
destroy_vector(vector);
}
void test_vector_stress(void)
{
size_t i = 0;
typedef short item_t;
const size_t init_capacity = 10;
vector_t *vector = create_vector(sizeof(item_t), init_capacity);
assert_true(vector != NULL);
assert_true(vector_size(vector) == 0);
assert_true(vector_capacity(vector) == init_capacity);
WHEN("Pushing a lot of items into vector") {
for (i = 0; i < 1000 * init_capacity; ++i) {
item_t item = (item_t)i;
vector_push(vector, &item);
}
THEN("Then capacity is not changed") {
assert_true(vector_size(vector) == 1000 * init_capacity);
assert_true(vector_capacity(vector) >= 1000 * init_capacity);
}
}
/*
* Destroy without previously called clear
*/
destroy_vector(vector);
}

View File

@ -15,6 +15,7 @@
/* Test cases */
void test_vector_basic(void);
void test_vector_stress(void);
void test_string_buffer(void);
void test_table_sizes(void);
void test_table_geometry(void);