[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);
|
F_FREE(result);
|
||||||
return NULL;
|
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->options = NULL;
|
||||||
result->conv_buffer = NULL;
|
result->conv_buffer = NULL;
|
||||||
result->cur_row = 0;
|
result->cur_row = 0;
|
||||||
@ -78,6 +84,13 @@ void ft_destroy_table(FTABLE *FORT_RESTRICT table)
|
|||||||
}
|
}
|
||||||
destroy_vector(table->rows);
|
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_table_options(table->options);
|
||||||
destroy_string_buffer(table->conv_buffer);
|
destroy_string_buffer(table->conv_buffer);
|
||||||
F_FREE(table);
|
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);
|
context_t *context = (table->options ? table->options : &g_table_options);
|
||||||
fort_row_t *prev_row = NULL;
|
fort_row_t *prev_row = NULL;
|
||||||
fort_row_t *cur_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);
|
cur_row = *(fort_row_t**)vector_at(table->rows, i);
|
||||||
enum HorSeparatorPos separatorPos = (i == 0) ? TopSeparator : InsideSeparator;
|
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));
|
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;
|
prev_row = cur_row;
|
||||||
}
|
}
|
||||||
cur_row = NULL;
|
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);
|
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 vector;
|
||||||
struct fort_cell;
|
struct fort_cell;
|
||||||
struct string_buffer;
|
struct string_buffer;
|
||||||
|
struct separator
|
||||||
|
{
|
||||||
|
int enabled;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct fort_table_options fort_table_options_t;
|
typedef struct fort_table_options fort_table_options_t;
|
||||||
typedef fort_table_options_t context_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 string_buffer string_buffer_t;
|
||||||
typedef struct fort_row fort_row_t;
|
typedef struct fort_row fort_row_t;
|
||||||
typedef struct fort_table FTABLE;
|
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 */
|
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
|
struct fort_table_options
|
||||||
{
|
{
|
||||||
@ -86,6 +96,7 @@ struct fort_table_options
|
|||||||
|
|
||||||
char border_chars[BorderItemPosSize];
|
char border_chars[BorderItemPosSize];
|
||||||
char header_border_chars[BorderItemPosSize];
|
char header_border_chars[BorderItemPosSize];
|
||||||
|
char separator_chars[SepratorItemPosSize];
|
||||||
vector_t *col_options;
|
vector_t *col_options;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
10
src/row.c
10
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,
|
int print_row_separator(char *buffer, size_t buffer_sz,
|
||||||
const size_t *col_width_arr, size_t cols,
|
const size_t *col_width_arr, size_t cols,
|
||||||
const fort_row_t *upper_row, const fort_row_t *lower_row,
|
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) \
|
#define CHECK_RESULT_AND_MOVE_DEV(statement) \
|
||||||
k = statement; \
|
k = statement; \
|
||||||
@ -152,6 +153,12 @@ int print_row_separator(char *buffer, size_t buffer_sz,
|
|||||||
border_chars = &context->border_chars;
|
border_chars = &context->border_chars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
switch (separatorPos) {
|
||||||
case TopSeparator:
|
case TopSeparator:
|
||||||
L = &(*border_chars)[TL_bip];
|
L = &(*border_chars)[TL_bip];
|
||||||
@ -174,6 +181,7 @@ int print_row_separator(char *buffer, size_t buffer_sz,
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If all chars are not printable, skip line separator */
|
/* If all chars are not printable, skip line separator */
|
||||||
if (!isprint(*L) && !isprint(*I) && !isprint(*IV) && !isprint(*R))
|
if (!isprint(*L) && !isprint(*I) && !isprint(*IV) && !isprint(*R))
|
||||||
|
@ -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,
|
int print_row_separator(char *buffer, size_t buffer_sz,
|
||||||
const size_t *col_width_arr, size_t cols,
|
const size_t *col_width_arr, size_t cols,
|
||||||
const fort_row_t *upper_row, const fort_row_t *lower_row,
|
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_impl.h"
|
||||||
#include "fort.h"
|
#include "fort.h"
|
||||||
|
|
||||||
struct fort_table;
|
struct fort_table;
|
||||||
typedef struct fort_table fort_table_t;
|
typedef struct fort_table fort_table_t;
|
||||||
struct fort_table
|
struct fort_table
|
||||||
@ -12,8 +13,26 @@ struct fort_table
|
|||||||
string_buffer_t *conv_buffer;
|
string_buffer_t *conv_buffer;
|
||||||
size_t cur_row;
|
size_t cur_row;
|
||||||
size_t cur_col;
|
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_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);
|
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 */
|
NULL, /* col_options */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -347,6 +352,40 @@ void test_table_options(void **state)
|
|||||||
ft_destroy_table(table);
|
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") {
|
WHEN("Top and bottom padding = 0") {
|
||||||
fort_table_options_t table_options;
|
fort_table_options_t table_options;
|
||||||
memcpy(&table_options, &test_table_opts, sizeof(fort_table_options_t));
|
memcpy(&table_options, &test_table_opts, sizeof(fort_table_options_t));
|
||||||
|
Loading…
Reference in New Issue
Block a user