[A] Added hor separator
This commit is contained in:
parent
4d4635162b
commit
1741a8a169
@ -227,6 +227,7 @@ FORT_EXTERN int ft_table_write_ln(FTABLE *FORT_RESTRICT table, size_t rows, size
|
||||
|
||||
|
||||
|
||||
FORT_EXTERN int ft_add_separator(FTABLE *FORT_RESTRICT table);
|
||||
|
||||
|
||||
|
||||
|
49
src/fort.c
49
src/fort.c
@ -58,6 +58,12 @@ FTABLE * ft_create_table(void)
|
||||
F_FREE(result);
|
||||
return NULL;
|
||||
}
|
||||
result->separators = create_vector(sizeof(separator_t*), DEFAULT_VECTOR_CAPACITY);
|
||||
if (result->separators == NULL) {
|
||||
destroy_vector(result->rows);
|
||||
F_FREE(result);
|
||||
return NULL;
|
||||
}
|
||||
result->options = NULL;
|
||||
result->conv_buffer = NULL;
|
||||
result->cur_row = 0;
|
||||
@ -78,6 +84,13 @@ void ft_destroy_table(FTABLE *FORT_RESTRICT table)
|
||||
}
|
||||
destroy_vector(table->rows);
|
||||
}
|
||||
if (table->separators) {
|
||||
size_t row_n = vector_size(table->separators);
|
||||
for (size_t i = 0; i < row_n; ++i) {
|
||||
destroy_separator(*(separator_t **)vector_at(table->separators, i));
|
||||
}
|
||||
destroy_vector(table->separators);
|
||||
}
|
||||
destroy_table_options(table->options);
|
||||
destroy_string_buffer(table->conv_buffer);
|
||||
F_FREE(table);
|
||||
@ -509,15 +522,20 @@ const char* ft_to_string(const FTABLE *FORT_RESTRICT table)
|
||||
context_t *context = (table->options ? table->options : &g_table_options);
|
||||
fort_row_t *prev_row = NULL;
|
||||
fort_row_t *cur_row = NULL;
|
||||
for (size_t i = 0; i < rows; ++i) {
|
||||
separator_t *cur_sep = NULL;
|
||||
size_t sep_size = vector_size(table->separators);
|
||||
size_t i = 0;
|
||||
for (i = 0; i < rows; ++i) {
|
||||
cur_sep = (i < sep_size) ? (*(separator_t **)vector_at(table->separators, i)) : NULL;
|
||||
cur_row = *(fort_row_t**)vector_at(table->rows, i);
|
||||
enum HorSeparatorPos separatorPos = (i == 0) ? TopSeparator : InsideSeparator;
|
||||
CHECK_RESULT_AND_MOVE_DEV(print_row_separator(buffer + dev, sz - dev, col_width_arr, cols, prev_row, cur_row, separatorPos, context));
|
||||
CHECK_RESULT_AND_MOVE_DEV(print_row_separator(buffer + dev, sz - dev, col_width_arr, cols, prev_row, cur_row, separatorPos, cur_sep, context));
|
||||
CHECK_RESULT_AND_MOVE_DEV(snprintf_row(cur_row, buffer + dev, sz - dev, col_width_arr, cols, row_height_arr[i], context));
|
||||
prev_row = cur_row;
|
||||
}
|
||||
cur_row = NULL;
|
||||
CHECK_RESULT_AND_MOVE_DEV(print_row_separator(buffer + dev, sz - dev, col_width_arr, cols, prev_row, cur_row, BottomSeparator, context));
|
||||
cur_sep = (i < sep_size) ? (*(separator_t **)vector_at(table->separators, i)) : NULL;
|
||||
CHECK_RESULT_AND_MOVE_DEV(print_row_separator(buffer + dev, sz - dev, col_width_arr, cols, prev_row, cur_row, BottomSeparator, cur_sep, context));
|
||||
|
||||
|
||||
F_FREE(col_width_arr);
|
||||
@ -555,3 +573,28 @@ static int dummy_function()
|
||||
|
||||
|
||||
|
||||
|
||||
int ft_add_separator(FTABLE *table)
|
||||
{
|
||||
assert(table);
|
||||
assert(table->separators);
|
||||
|
||||
while(vector_size(table->separators) <= table->cur_row) {
|
||||
separator_t *sep_p = create_separator(F_FALSE);
|
||||
if (sep_p == NULL)
|
||||
return F_MEMORY_ERROR;
|
||||
int status = vector_push(table->separators, &sep_p);
|
||||
if (IS_ERROR(status))
|
||||
return status;
|
||||
}
|
||||
|
||||
separator_t **sep_p = (separator_t **)vector_at(table->separators, table->cur_row);
|
||||
if (*sep_p == NULL)
|
||||
*sep_p = create_separator(F_TRUE);
|
||||
else
|
||||
(*sep_p)->enabled = F_TRUE;
|
||||
|
||||
if (*sep_p == NULL)
|
||||
return F_ERROR;
|
||||
return F_SUCCESS;
|
||||
}
|
||||
|
@ -79,7 +79,10 @@ struct fort_row;
|
||||
struct vector;
|
||||
struct fort_cell;
|
||||
struct string_buffer;
|
||||
|
||||
struct separator
|
||||
{
|
||||
int enabled;
|
||||
};
|
||||
|
||||
typedef struct fort_table_options fort_table_options_t;
|
||||
typedef fort_table_options_t context_t;
|
||||
@ -89,7 +92,7 @@ typedef struct fort_cell fort_cell_t;
|
||||
typedef struct string_buffer string_buffer_t;
|
||||
typedef struct fort_row fort_row_t;
|
||||
typedef struct fort_table FTABLE;
|
||||
|
||||
typedef struct separator separator_t;
|
||||
|
||||
|
||||
|
||||
|
@ -77,6 +77,11 @@ fort_table_options_t g_table_options = {
|
||||
'+', '-', '+', '+'
|
||||
},
|
||||
|
||||
/* separator_chars */
|
||||
{
|
||||
'+', '=', '+', '+',
|
||||
},
|
||||
|
||||
NULL, /* col_options */
|
||||
};
|
||||
|
||||
|
@ -75,6 +75,16 @@ enum BorderItemPos
|
||||
};
|
||||
|
||||
|
||||
enum SeparatorItemPos
|
||||
{
|
||||
LH_sip = 0,
|
||||
IH_sip = 1,
|
||||
II_sip = 2,
|
||||
RH_sip = 3,
|
||||
|
||||
SepratorItemPosSize
|
||||
};
|
||||
|
||||
|
||||
struct fort_table_options
|
||||
{
|
||||
@ -86,6 +96,7 @@ struct fort_table_options
|
||||
|
||||
char border_chars[BorderItemPosSize];
|
||||
char header_border_chars[BorderItemPosSize];
|
||||
char separator_chars[SepratorItemPosSize];
|
||||
vector_t *col_options;
|
||||
|
||||
};
|
||||
|
52
src/row.c
52
src/row.c
@ -110,7 +110,8 @@ fort_cell_t *get_cell_and_create_if_not_exists(fort_row_t *row, size_t col)
|
||||
int print_row_separator(char *buffer, size_t buffer_sz,
|
||||
const size_t *col_width_arr, size_t cols,
|
||||
const fort_row_t *upper_row, const fort_row_t *lower_row,
|
||||
enum HorSeparatorPos separatorPos, const context_t *context)
|
||||
enum HorSeparatorPos separatorPos,
|
||||
const separator_t *sep, const context_t *context)
|
||||
{
|
||||
#define CHECK_RESULT_AND_MOVE_DEV(statement) \
|
||||
k = statement; \
|
||||
@ -152,27 +153,34 @@ int print_row_separator(char *buffer, size_t buffer_sz,
|
||||
border_chars = &context->border_chars;
|
||||
}
|
||||
|
||||
switch (separatorPos) {
|
||||
case TopSeparator:
|
||||
L = &(*border_chars)[TL_bip];
|
||||
I = &(*border_chars)[TT_bip];
|
||||
IV = &(*border_chars)[TV_bip];
|
||||
R = &(*border_chars)[TR_bip];
|
||||
break;
|
||||
case InsideSeparator:
|
||||
L = &(*border_chars)[LH_bip];
|
||||
I = &(*border_chars)[IH_bip];
|
||||
IV = &(*border_chars)[II_bip];
|
||||
R = &(*border_chars)[RH_bip];
|
||||
break;
|
||||
case BottomSeparator:
|
||||
L = &(*border_chars)[BL_bip];
|
||||
I = &(*border_chars)[BB_bip];
|
||||
IV = &(*border_chars)[BV_bip];
|
||||
R = &(*border_chars)[BR_bip];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (sep && sep->enabled) {
|
||||
L = &(context->separator_chars[LH_sip]);
|
||||
I = &(context->separator_chars[IH_sip]);
|
||||
IV = &(context->separator_chars[II_sip]);
|
||||
R = &(context->separator_chars[RH_sip]);
|
||||
} else {
|
||||
switch (separatorPos) {
|
||||
case TopSeparator:
|
||||
L = &(*border_chars)[TL_bip];
|
||||
I = &(*border_chars)[TT_bip];
|
||||
IV = &(*border_chars)[TV_bip];
|
||||
R = &(*border_chars)[TR_bip];
|
||||
break;
|
||||
case InsideSeparator:
|
||||
L = &(*border_chars)[LH_bip];
|
||||
I = &(*border_chars)[IH_bip];
|
||||
IV = &(*border_chars)[II_bip];
|
||||
R = &(*border_chars)[RH_bip];
|
||||
break;
|
||||
case BottomSeparator:
|
||||
L = &(*border_chars)[BL_bip];
|
||||
I = &(*border_chars)[BB_bip];
|
||||
IV = &(*border_chars)[BV_bip];
|
||||
R = &(*border_chars)[BR_bip];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If all chars are not printable, skip line separator */
|
||||
|
@ -33,7 +33,8 @@ fort_cell_t *get_cell_and_create_if_not_exists(fort_row_t *row, size_t col);
|
||||
int print_row_separator(char *buffer, size_t buffer_sz,
|
||||
const size_t *col_width_arr, size_t cols,
|
||||
const fort_row_t *upper_row, const fort_row_t *lower_row,
|
||||
enum HorSeparatorPos separatorPos, const context_t *context);
|
||||
enum HorSeparatorPos separatorPos, const separator_t *sep,
|
||||
const context_t *context);
|
||||
|
||||
|
||||
|
||||
|
19
src/table.h
19
src/table.h
@ -3,6 +3,7 @@
|
||||
|
||||
#include "fort_impl.h"
|
||||
#include "fort.h"
|
||||
|
||||
struct fort_table;
|
||||
typedef struct fort_table fort_table_t;
|
||||
struct fort_table
|
||||
@ -12,8 +13,26 @@ struct fort_table
|
||||
string_buffer_t *conv_buffer;
|
||||
size_t cur_row;
|
||||
size_t cur_col;
|
||||
vector_t *separators;
|
||||
};
|
||||
|
||||
static inline
|
||||
separator_t *create_separator(int enabled)
|
||||
{
|
||||
separator_t *res = F_CALLOC(1, sizeof(separator_t));
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
res->enabled = enabled;
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline
|
||||
void destroy_separator(separator_t *sep)
|
||||
{
|
||||
F_FREE(sep);
|
||||
}
|
||||
|
||||
|
||||
|
||||
fort_status_t get_table_sizes(const FTABLE *table, size_t *rows, size_t *cols);
|
||||
fort_row_t *get_row_implementation(fort_table_t *table, size_t row, enum PolicyOnNull policy);
|
||||
|
@ -33,6 +33,11 @@ fort_table_options_t test_table_opts = {
|
||||
'+', '-', '+', '+'
|
||||
},
|
||||
|
||||
/* separator_chars */
|
||||
{
|
||||
'+', '=', '+', '+',
|
||||
},
|
||||
|
||||
NULL, /* col_options */
|
||||
};
|
||||
|
||||
@ -347,6 +352,40 @@ void test_table_options(void **state)
|
||||
ft_destroy_table(table);
|
||||
}
|
||||
|
||||
WHEN("Separator testing") {
|
||||
table = create_test_int_table(0);
|
||||
ft_add_separator(table);
|
||||
|
||||
int n = ft_hdr_printf_ln(table, "%d|%d|%d|%d", 3, 4, 55, 67);
|
||||
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 | 4 | 55 | 67 |\n"
|
||||
"| | | | |\n"
|
||||
"+---+---+----+----+\n"
|
||||
"| | | | |\n"
|
||||
"| 3 | 4 | 55 | 67 |\n"
|
||||
"| | | | |\n"
|
||||
"+---+---+----+----+\n"
|
||||
"| | | | |\n"
|
||||
"| 3 | 4 | 55 | 67 |\n"
|
||||
"| | | | |\n"
|
||||
"+===+===+====+====+\n"
|
||||
"| | | | |\n"
|
||||
"| 3 | 4 | 55 | 67 |\n"
|
||||
"| | | | |\n"
|
||||
"+---+---+----+----+\n";
|
||||
// fprintf(stderr, "content:\n%s", table_str);
|
||||
|
||||
assert_true( strcmp(table_str, table_str_etalon) == 0);
|
||||
|
||||
ft_destroy_table(table);
|
||||
}
|
||||
|
||||
WHEN("Top and bottom padding = 0") {
|
||||
fort_table_options_t table_options;
|
||||
memcpy(&table_options, &test_table_opts, sizeof(fort_table_options_t));
|
||||
|
Loading…
Reference in New Issue
Block a user