[R] Table printing refactoring
This commit is contained in:
parent
a2c793cda2
commit
6dc77bd5a1
@ -110,6 +110,7 @@ struct fort_table_options
|
|||||||
int cell_empty_string_height;
|
int cell_empty_string_height;
|
||||||
char hor_separator;
|
char hor_separator;
|
||||||
char ver_separator;
|
char ver_separator;
|
||||||
|
char header_hor_separator;
|
||||||
};
|
};
|
||||||
typedef struct fort_table_options fort_table_options_t;
|
typedef struct fort_table_options fort_table_options_t;
|
||||||
|
|
||||||
|
88
src/fort.c
88
src/fort.c
@ -48,6 +48,12 @@ SOFTWARE.
|
|||||||
#define MIN(a,b) ((a) < (b) ? (a) : b)
|
#define MIN(a,b) ((a) < (b) ? (a) : b)
|
||||||
|
|
||||||
|
|
||||||
|
enum F_BOOL
|
||||||
|
{
|
||||||
|
F_FALSE = 0,
|
||||||
|
F_TRUE = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#define STR_2_CAT_(arg1, arg2) \
|
#define STR_2_CAT_(arg1, arg2) \
|
||||||
arg1##arg2
|
arg1##arg2
|
||||||
@ -180,7 +186,16 @@ static void* vector_at(vector_t*, size_t index);
|
|||||||
//};
|
//};
|
||||||
//typedef struct cell_options cell_options_t;
|
//typedef struct cell_options cell_options_t;
|
||||||
typedef fort_table_options_t context_t;
|
typedef fort_table_options_t context_t;
|
||||||
static fort_table_options_t g_table_options = {1, 1, 1, 1, 1, '=', '|'};
|
static fort_table_options_t g_table_options = {
|
||||||
|
1, /* cell_padding_top */
|
||||||
|
1, /* cell_padding_bottom */
|
||||||
|
1, /* cell_padding_left */
|
||||||
|
1, /* cell_padding_right */
|
||||||
|
1, /* cell_empty_string_height */
|
||||||
|
'=', /* hor_separator */
|
||||||
|
'|', /* ver_separator */
|
||||||
|
'=' /* header_hor_separator */
|
||||||
|
};
|
||||||
|
|
||||||
//static void set_cell_options(fort_table_options_t *dst_options, const fort_table_options_t *src_options)
|
//static void set_cell_options(fort_table_options_t *dst_options, const fort_table_options_t *src_options)
|
||||||
//{
|
//{
|
||||||
@ -306,6 +321,7 @@ typedef struct fort_row fort_row_t;
|
|||||||
struct fort_row
|
struct fort_row
|
||||||
{
|
{
|
||||||
vector_t *cells;
|
vector_t *cells;
|
||||||
|
enum F_BOOL is_header;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -319,6 +335,7 @@ static fort_row_t * create_row()
|
|||||||
F_FREE(row);
|
F_FREE(row);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
row->is_header = F_FALSE;
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,6 +384,50 @@ static const fort_cell_t *get_cell_c(const fort_row_t *row, size_t col)
|
|||||||
return get_cell((fort_row_t *)row, col);
|
return get_cell((fort_row_t *)row, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int print_row_separator(char *buffer, size_t buffer_sz, size_t table_width,
|
||||||
|
const fort_row_t *upper_row, const fort_row_t *lower_row,
|
||||||
|
const context_t *context)
|
||||||
|
{
|
||||||
|
#define CHECK_RESULT_AND_MOVE_DEV(statement) \
|
||||||
|
k = statement; \
|
||||||
|
if (k < 0) {\
|
||||||
|
goto clear; \
|
||||||
|
} \
|
||||||
|
dev += k;
|
||||||
|
|
||||||
|
assert(buffer);
|
||||||
|
assert(context);
|
||||||
|
|
||||||
|
int dev = 0;
|
||||||
|
int k = 0;
|
||||||
|
const char *hor_separator = NULL;
|
||||||
|
|
||||||
|
const fort_row_t *main_row = NULL;
|
||||||
|
if (upper_row != NULL && lower_row != NULL) {
|
||||||
|
main_row = lower_row->is_header == F_TRUE ? lower_row : upper_row;
|
||||||
|
} else if (upper_row != NULL && lower_row == NULL) {
|
||||||
|
main_row = upper_row;
|
||||||
|
} else if (upper_row == NULL && lower_row != NULL) {
|
||||||
|
main_row = lower_row;
|
||||||
|
} else if (upper_row == NULL && lower_row == NULL) {
|
||||||
|
main_row = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
hor_separator = (main_row && main_row->is_header == F_TRUE)
|
||||||
|
? &(context->header_hor_separator)
|
||||||
|
: &(context->hor_separator);
|
||||||
|
|
||||||
|
CHECK_RESULT_AND_MOVE_DEV(snprint_n_chars(buffer + dev, buffer_sz - dev, table_width - 1, *hor_separator));
|
||||||
|
CHECK_RESULT_AND_MOVE_DEV(snprint_n_chars(buffer + dev, buffer_sz - dev, 1, '\n'));
|
||||||
|
|
||||||
|
return dev;
|
||||||
|
|
||||||
|
clear:
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
#undef CHECK_RESULT_AND_MOVE_DEV
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* TABLE
|
* TABLE
|
||||||
@ -516,6 +577,12 @@ int ft_hdr_printf(FTABLE *FORT_RESTRICT table, const char* FORT_RESTRICT fmt, ..
|
|||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
int result = ft_row_printf_impl(table, 0, fmt, &va);
|
int result = ft_row_printf_impl(table, 0, fmt, &va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
if (result >= 0 && table->rows) {
|
||||||
|
int sz = vector_size(table->rows);
|
||||||
|
if (sz != 0) {
|
||||||
|
(*(fort_row_t**)vector_at(table->rows, sz - 1))->is_header = F_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1051,21 +1118,26 @@ char* ft_to_string(const FTABLE *FORT_RESTRICT table)
|
|||||||
size_t *row_height_arr = NULL;
|
size_t *row_height_arr = NULL;
|
||||||
status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows);
|
status = table_rows_and_cols_geometry(table, &col_width_arr, &cols, &row_height_arr, &rows);
|
||||||
|
|
||||||
|
if (rows == 0)
|
||||||
|
return F_STRDUP("");
|
||||||
|
|
||||||
if (IS_ERROR(status))
|
if (IS_ERROR(status))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
int dev = 0;
|
int dev = 0;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
context_t *context = (table->options ? table->options : &g_table_options);
|
context_t *context = (table->options ? table->options : &g_table_options);
|
||||||
CHECK_RESULT_AND_MOVE_DEV(snprint_n_chars(buffer + dev, sz - dev, width - 1, context->hor_separator));
|
fort_row_t *prev_row = NULL;
|
||||||
CHECK_RESULT_AND_MOVE_DEV(snprint_n_chars(buffer + dev, sz - dev, 1, '\n'));
|
fort_row_t *cur_row = NULL;
|
||||||
|
|
||||||
for (size_t i = 0; i < rows; ++i) {
|
for (size_t i = 0; i < rows; ++i) {
|
||||||
fort_row_t *row = *(fort_row_t**)vector_at(table->rows, i);
|
cur_row = *(fort_row_t**)vector_at(table->rows, i);
|
||||||
CHECK_RESULT_AND_MOVE_DEV(snprintf_row(row, buffer + dev, sz - dev, col_width_arr, cols, row_height_arr[i], context));
|
CHECK_RESULT_AND_MOVE_DEV(print_row_separator(buffer + dev, sz - dev, width, prev_row, cur_row, context));
|
||||||
CHECK_RESULT_AND_MOVE_DEV(snprint_n_chars(buffer + dev, sz - dev, width - 1, context->hor_separator));
|
CHECK_RESULT_AND_MOVE_DEV(snprintf_row(cur_row, buffer + dev, sz - dev, col_width_arr, cols, row_height_arr[i], context));
|
||||||
CHECK_RESULT_AND_MOVE_DEV(snprint_n_chars(buffer + dev, sz - dev, 1, '\n'));
|
prev_row = cur_row;
|
||||||
}
|
}
|
||||||
|
cur_row = NULL;
|
||||||
|
CHECK_RESULT_AND_MOVE_DEV(print_row_separator(buffer + dev, sz - dev, width, prev_row, cur_row, context));
|
||||||
|
|
||||||
|
|
||||||
F_FREE(col_width_arr);
|
F_FREE(col_width_arr);
|
||||||
F_FREE(row_height_arr);
|
F_FREE(row_height_arr);
|
||||||
|
@ -390,7 +390,6 @@ void test_table_options(void **state)
|
|||||||
ft_destroy_table(table);
|
ft_destroy_table(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WHEN("Empty string has 0 heigt") {
|
WHEN("Empty string has 0 heigt") {
|
||||||
fort_table_options_t table_options;
|
fort_table_options_t table_options;
|
||||||
memcpy(&table_options, &def_options, sizeof(fort_table_options_t));
|
memcpy(&table_options, &def_options, sizeof(fort_table_options_t));
|
||||||
@ -432,12 +431,12 @@ void test_table_options(void **state)
|
|||||||
ft_destroy_table(table);
|
ft_destroy_table(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WHEN("Changing cell separators") {
|
WHEN("Changing cell separators") {
|
||||||
fort_table_options_t table_options;
|
fort_table_options_t table_options;
|
||||||
memcpy(&table_options, &def_options, sizeof(fort_table_options_t));
|
memcpy(&table_options, &def_options, sizeof(fort_table_options_t));
|
||||||
table_options.hor_separator = '|';
|
table_options.hor_separator = '|';
|
||||||
table_options.ver_separator = '=';
|
table_options.ver_separator = '=';
|
||||||
|
table_options.header_hor_separator = '*';
|
||||||
|
|
||||||
ft_set_default_options(&table_options);
|
ft_set_default_options(&table_options);
|
||||||
|
|
||||||
@ -447,11 +446,11 @@ void test_table_options(void **state)
|
|||||||
char *table_str = ft_to_string(table);
|
char *table_str = ft_to_string(table);
|
||||||
assert_true( table_str != NULL );
|
assert_true( table_str != NULL );
|
||||||
const char *table_str_etalon =
|
const char *table_str_etalon =
|
||||||
"|||||||||||||||||||\n"
|
"*******************\n"
|
||||||
"= = = = =\n"
|
"= = = = =\n"
|
||||||
"= 3 = 4 = 55 = 67 =\n"
|
"= 3 = 4 = 55 = 67 =\n"
|
||||||
"= = = = =\n"
|
"= = = = =\n"
|
||||||
"|||||||||||||||||||\n"
|
"*******************\n"
|
||||||
"= = = = =\n"
|
"= = = = =\n"
|
||||||
"= 3 = 4 = 55 = 67 =\n"
|
"= 3 = 4 = 55 = 67 =\n"
|
||||||
"= = = = =\n"
|
"= = = = =\n"
|
||||||
|
Loading…
Reference in New Issue
Block a user