[C] Began options refactoring

This commit is contained in:
seleznevae
2018-02-25 11:39:41 +03:00
parent 1741a8a169
commit 570113aa29
7 changed files with 574 additions and 142 deletions

View File

@@ -394,17 +394,17 @@ int ft_table_write_ln(FTABLE *FORT_RESTRICT table, size_t rows, size_t cols, con
int ft_set_default_options(const fort_table_options_t *options)
{
memcpy(&g_table_options, options, sizeof(fort_table_options_t));
return 0;
}
//int ft_set_default_options(const fort_table_options_t *options)
//{
// memcpy(&g_table_options, options, sizeof(fort_table_options_t));
// return 0;
//}
int ft_get_default_options(fort_table_options_t *options)
{
memcpy(options, &g_table_options, sizeof(fort_table_options_t));
return 0;
}
//int ft_get_default_options(fort_table_options_t *options)
//{
// memcpy(options, &g_table_options, sizeof(fort_table_options_t));
// return 0;
//}
int ft_set_table_options(FTABLE * FORT_RESTRICT table, const fort_table_options_t * FORT_RESTRICT options)
{
@@ -598,3 +598,129 @@ int ft_add_separator(FTABLE *table)
return F_ERROR;
return F_SUCCESS;
}
int ft_set_default_option(uint32_t option, int value)
{
switch (option) {
case FT_OPT_TOP_PADDING:
g_table_options.cell_padding_top = value;
break;
case FT_OPT_BOTTOM_PADDING:
g_table_options.cell_padding_bottom = value;
break;
case FT_OPT_LEFT_PADDING:
g_table_options.cell_padding_left = value;
break;
case FT_OPT_RIGHT_PADDING:
g_table_options.cell_padding_right = value;
break;
case FT_OPT_EMPTY_STR_HEIGHT:
g_table_options.cell_empty_string_height = value;
break;
default:
// todo
exit(22);
}
return F_SUCCESS;
}
static void set_border_options_for_options(fort_table_options_t *options, struct border_chars *border_chs, struct border_chars *header_border_chs)
{
#define BOR_CHARS options->border_chars
#define H_BOR_CHARS options->header_border_chars
// BOR_CHARS[TL_bip] = BOR_CHARS[TT_bip] = BOR_CHARS[TV_bip] = BOR_CHARS[TR_bip] = border_chs->top_border_ch;
// BOR_CHARS[LH_bip] = BOR_CHARS[IH_bip] = BOR_CHARS[II_bip] = BOR_CHARS[RH_bip] = border_chs->separator_ch;
// BOR_CHARS[BL_bip] = BOR_CHARS[BB_bip] = BOR_CHARS[BV_bip] = BOR_CHARS[BR_bip] = border_chs->bottom_border_ch;
// BOR_CHARS[LL_bip] = BOR_CHARS[IV_bip] = BOR_CHARS[RR_bip] = border_chs->side_border_ch;
// H_BOR_CHARS[TL_bip] = H_BOR_CHARS[TT_bip] = H_BOR_CHARS[TV_bip] = H_BOR_CHARS[TR_bip] = header_border_chs->top_border_ch;
// H_BOR_CHARS[LH_bip] = H_BOR_CHARS[IH_bip] = H_BOR_CHARS[II_bip] = H_BOR_CHARS[RH_bip] = header_border_chs->separator_ch;
// H_BOR_CHARS[BL_bip] = H_BOR_CHARS[BB_bip] = H_BOR_CHARS[BV_bip] = H_BOR_CHARS[BR_bip] = header_border_chs->bottom_border_ch;
// H_BOR_CHARS[LL_bip] = H_BOR_CHARS[IV_bip] = H_BOR_CHARS[RR_bip] = header_border_chs->side_border_ch;
BOR_CHARS[TT_bip] = border_chs->top_border_ch;
BOR_CHARS[IH_bip] = border_chs->separator_ch;
BOR_CHARS[BB_bip] = border_chs->bottom_border_ch;
BOR_CHARS[LL_bip] = BOR_CHARS[IV_bip] = BOR_CHARS[RR_bip] = border_chs->side_border_ch;
BOR_CHARS[TL_bip] = BOR_CHARS[TV_bip] = BOR_CHARS[TR_bip] = border_chs->out_intersect_ch;
BOR_CHARS[LH_bip] = BOR_CHARS[RH_bip] = border_chs->out_intersect_ch;
BOR_CHARS[BL_bip] = BOR_CHARS[BV_bip] = BOR_CHARS[BR_bip] = border_chs->out_intersect_ch;
BOR_CHARS[II_bip] = border_chs->in_intersect_ch;
if (border_chs->separator_ch == '\0' && border_chs->in_intersect_ch == '\0') {
BOR_CHARS[LH_bip] = BOR_CHARS[RH_bip] = '\0';
}
H_BOR_CHARS[TT_bip] = header_border_chs->top_border_ch;
H_BOR_CHARS[IH_bip] = header_border_chs->separator_ch;
H_BOR_CHARS[BB_bip] = header_border_chs->bottom_border_ch;
H_BOR_CHARS[LL_bip] = H_BOR_CHARS[IV_bip] = H_BOR_CHARS[RR_bip] = header_border_chs->side_border_ch;
H_BOR_CHARS[TL_bip] = H_BOR_CHARS[TV_bip] = H_BOR_CHARS[TR_bip] = header_border_chs->out_intersect_ch;
H_BOR_CHARS[LH_bip] = H_BOR_CHARS[RH_bip] = header_border_chs->out_intersect_ch;
H_BOR_CHARS[BL_bip] = H_BOR_CHARS[BV_bip] = H_BOR_CHARS[BR_bip] = header_border_chs->out_intersect_ch;
H_BOR_CHARS[II_bip] = header_border_chs->in_intersect_ch;
if (header_border_chs->separator_ch == '\0' && header_border_chs->in_intersect_ch == '\0') {
H_BOR_CHARS[LH_bip] = H_BOR_CHARS[RH_bip] = '\0';
}
#undef BOR_CHARS
#undef H_BOR_CHARS
}
int ft_set_default_borders(struct border_chars *border_chs, struct border_chars *header_border_chs)
{
set_border_options_for_options(&g_table_options, border_chs, header_border_chs);
return F_SUCCESS;
}
int ft_set_table_borders(FTABLE *table, struct border_chars *border_chs, struct border_chars *header_border_chs)
{
assert(table);
if (table->options == NULL) {
table->options = create_table_options();
if (table->options == NULL)
return F_MEMORY_ERROR;
}
set_border_options_for_options(table->options, border_chs, header_border_chs);
return F_SUCCESS;
}
int ft_set_table_option(FTABLE *table, uint32_t option, int value)
{
assert(table);
if (table->options == NULL) {
table->options = create_table_options();
if (table->options == NULL)
return F_MEMORY_ERROR;
}
switch (option) {
case FT_OPT_TOP_PADDING:
table->options->cell_padding_top = value;
break;
case FT_OPT_BOTTOM_PADDING:
table->options->cell_padding_bottom = value;
break;
case FT_OPT_LEFT_PADDING:
table->options->cell_padding_left = value;
break;
case FT_OPT_RIGHT_PADDING:
table->options->cell_padding_right = value;
break;
case FT_OPT_EMPTY_STR_HEIGHT:
table->options->cell_empty_string_height = value;
break;
default:
// todo
exit(22);
}
return F_SUCCESS;
}

View File

@@ -21,6 +21,68 @@ fort_column_options_t create_column_options()
return result;
}
#define DEFAULT_CELL_OPTION {FT_ROW_UNSPEC, FT_COLUMN_UNSPEC, 0, 0, 0}
fort_cell_opt_container_t *create_cell_opt_container()
{
fort_cell_opt_container_t *ret = create_vector(sizeof(fort_cell_options_t), DEFAULT_VECTOR_CAPACITY);
return ret;
}
void destroy_cell_opt_container(fort_cell_opt_container_t *cont)
{
if (cont)
destroy_vector(cont);
}
const fort_cell_options_t* cget_cell_opt(const fort_cell_opt_container_t *cont, unsigned row, unsigned col)
{
assert(cont);
size_t sz = vector_size(cont);
for (size_t i = 0; i < sz; ++i) {
const fort_cell_options_t* opt = (const fort_cell_options_t*)vector_at_c(cont, i);
if (opt->cell_row == row && opt->cell_col == col)
return opt;
}
return NULL;
}
fort_cell_options_t* get_cell_opt_and_create_if_not_exists(fort_cell_opt_container_t *cont, unsigned row, unsigned col)
{
assert(cont);
size_t sz = vector_size(cont);
for (size_t i = 0; i < sz; ++i) {
fort_cell_options_t* opt = (fort_cell_options_t*)vector_at(cont, i);
if (opt->cell_row == row && opt->cell_col == col)
return opt;
}
const fort_cell_options_t opt = DEFAULT_CELL_OPTION;
if (IS_SUCCESS(vector_push(cont, &opt))) {
vector_at(cont, sz);
}
return NULL;
}
fort_status_t set_cell_option(fort_cell_opt_container_t *cont, unsigned row, unsigned col, uint32_t option, int value)
{
fort_cell_options_t* opt = get_cell_opt_and_create_if_not_exists(cont, row, col);
if (opt == NULL)
return F_ERROR;
OPTION_SET(*opt, option);
if (OPTION_IS_SET(*opt, FT_OPT_MIN_WIDTH)) {
opt->col_min_width = value;
} else if (OPTION_IS_SET(*opt, FT_OPT_TEXT_ALIGN)) {
opt->align = value;
}
return F_SUCCESS;
}
/*****************************************************************************
* OPTIONS
* ***************************************************************************/
@@ -83,6 +145,7 @@ fort_table_options_t g_table_options = {
},
NULL, /* col_options */
NULL, /* cell_options */
};
@@ -93,6 +156,12 @@ fort_table_options_t* create_table_options()
return NULL;
}
memcpy(options, &g_table_options, sizeof(fort_table_options_t));
options->cell_options = create_cell_opt_container();
if (options->cell_options == NULL) {
destroy_table_options(options);
options = NULL;
}
return options;
}
@@ -105,6 +174,15 @@ fort_table_options_t* copy_table_options(const fort_table_options_t *option)
return NULL;
memcpy(new_opt, option, sizeof(fort_table_options_t));
if (option->cell_options) {
destroy_cell_opt_container(new_opt->cell_options);
new_opt->cell_options = copy_vector(option->cell_options);
if (new_opt->cell_options == NULL) {
destroy_table_options(new_opt);
new_opt = NULL;
}
}
return new_opt;
}
@@ -117,6 +195,9 @@ void destroy_table_options(fort_table_options_t* options)
if (options->col_options != NULL) {
destroy_vector(options->col_options);
}
if (options->cell_options != NULL) {
destroy_cell_opt_container(options->cell_options);
}
F_FREE(options);
}

View File

@@ -2,6 +2,8 @@
#define OPTIONS_H
#include "fort_impl.h"
#include <stdint.h>
#include <limits.h>
enum TextAlignment
{
@@ -26,10 +28,44 @@ fort_column_options_t create_column_options();
struct vector;
typedef struct vector vector_t;
#define FT_ANY_COLUMN (UINT_MAX)
#define FT_ANY_ROW (UINT_MAX)
#define FT_ROW_UNSPEC (UINT_MAX-1)
#define FT_COLUMN_UNSPEC (UINT_MAX-1)
#define FT_OPT_MIN_WIDTH ((uint32_t)(0x01U << (0)))
#define FT_OPT_TEXT_ALIGN ((uint32_t)(0x01U << (1)))
#define FT_OPT_TOP_PADDING ((uint32_t)(0x01U << (2)))
#define FT_OPT_BOTTOM_PADDING ((uint32_t)(0x01U << (3)))
#define FT_OPT_LEFT_PADDING ((uint32_t)(0x01U << (4)))
#define FT_OPT_RIGHT_PADDING ((uint32_t)(0x01U << (5)))
#define FT_OPT_EMPTY_STR_HEIGHT ((uint32_t)(0x01U << (6)))
#define OPTION_IS_SET(ft_opts, option) ((ft_opts).options & (option))
#define OPTION_SET(ft_opts, option) ((ft_opts).options |=(option))
#define OPTION_UNSET(ft_opts, option) ((ft_opts).options &= ~((uint32_t)option))
struct fort_cell_options
{
unsigned cell_row;
unsigned cell_col;
uint32_t options;
int col_min_width;
enum TextAlignment align;
};
typedef struct fort_cell_options fort_cell_options_t;
typedef vector_t fort_cell_opt_container_t;
fort_cell_opt_container_t *create_cell_opt_container();
void destroy_cell_opt_container(fort_cell_opt_container_t *cont);
const fort_cell_options_t* cget_cell_opt(const fort_cell_opt_container_t *cont, unsigned row, unsigned col);
fort_cell_options_t* get_cell_opt_and_create_if_not_exists(fort_cell_opt_container_t *cont, unsigned row, unsigned col);
fort_status_t set_cell_option(fort_cell_opt_container_t *cont, unsigned row, unsigned col, uint32_t option, int value);
fort_status_t unset_cell_option(fort_cell_opt_container_t *cont, unsigned row, unsigned col, uint32_t option);
/*****************************************************************************
* TABLE BORDER
@@ -99,6 +135,7 @@ struct fort_table_options
char separator_chars[SepratorItemPosSize];
vector_t *col_options;
fort_cell_opt_container_t * cell_options;
};
typedef struct fort_table_options fort_table_options_t;
typedef fort_table_options_t context_t;

View File

@@ -58,6 +58,22 @@ void destroy_vector(vector_t* vector)
free(vector);
}
vector_t* copy_vector(vector_t *v)
{
if (v == NULL)
return NULL;
vector_t* new_vector = create_vector(v->m_item_size, v->m_capacity);
if (new_vector == NULL)
return NULL;
memcpy(new_vector->m_data, v->m_data, v->m_item_size * v->m_size);
new_vector->m_size = v->m_size ;
new_vector->m_item_size = v->m_item_size ;
return new_vector;
}
/* ----------- Nonmodifying functions --------------------------------- */
@@ -131,6 +147,13 @@ void vector_clear(vector_t *vector)
vector->m_size = 0;
}
const void *vector_at_c(const vector_t *vector, size_t index)
{
if (index >= vector->m_size)
return NULL;
return vector->m_data + index * vector->m_item_size;
}
void *vector_at(vector_t *vector, size_t index)

View File

@@ -15,6 +15,7 @@ typedef struct vector vector_t;
extern vector_t* create_vector(size_t item_size, size_t capacity);
extern void destroy_vector(vector_t*);
extern vector_t* copy_vector(vector_t*);
extern size_t vector_size(const vector_t*);
extern size_t vector_capacity(const vector_t*);
@@ -23,6 +24,7 @@ extern size_t vector_index_of(const vector_t*, const void *item);
extern int vector_push(vector_t*, const void *item);
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);