[A] Added multibyte borders

This commit is contained in:
seleznevae 2018-05-02 21:16:41 +03:00
parent cbb05f3db2
commit 19217a805d
13 changed files with 523 additions and 255 deletions

View File

@ -123,9 +123,18 @@ int main(void)
printf("Table:\n%s\n", ft_to_string(table));
ft_destroy_table(table);
ft_set_default_border_style(FT_SOLID_STYLE);
table = create_basic_table();
printf("Table:\n%s\n", ft_to_string(table));
ft_destroy_table(table);
ft_set_default_border_style(FT_DOUBLE_STYLE);
table = create_basic_table();
printf("Table:\n%s\n", ft_to_string(table));
ft_destroy_table(table);
/* Debug */
ft_set_default_border_style(FT_DOT_STYLE);
ft_set_default_border_style(FT_SOLID_STYLE);
table = create_basic_table();
ft_set_cell_option(table, FT_CUR_ROW, FT_ANY_COLUMN, FT_COPT_ROW_TYPE, FT_ROW_HEADER);
ft_write_ln(table, "Summary", "", "", "8.7");
@ -133,12 +142,14 @@ int main(void)
ft_some_api(table, 0, 0, 3);
printf("Table:\n%s\n", ft_to_string(table));
ft_destroy_table(table);
return 0;
fflush(stdout);
/*-------------------------------------------------------------*/
#if defined(FT_HAVE_WCHAR) && !defined(FT_MICROSOFT_COMPILER)
setlocale(LC_CTYPE, "");
ft_set_default_border_style(FT_BASIC_STYLE);
table = ft_create_table();
ft_set_cell_option(table, FT_ANY_ROW, 0, FT_COPT_TEXT_ALIGN, FT_ALIGNED_CENTER);
ft_set_cell_option(table, FT_ANY_ROW, 1, FT_COPT_TEXT_ALIGN, FT_ALIGNED_LEFT);

View File

@ -418,12 +418,12 @@ FT_EXTERN const char *ft_to_string(const FTABLE *table);
* Structure describing border appearance.
*/
struct ft_border_chars {
char top_border_ch;
char separator_ch;
char bottom_border_ch;
char side_border_ch;
char out_intersect_ch;
char in_intersect_ch;
const char *top_border_ch;
const char *separator_ch;
const char *bottom_border_ch;
const char *side_border_ch;
const char *out_intersect_ch;
const char *in_intersect_ch;
};
/**
@ -432,7 +432,7 @@ struct ft_border_chars {
struct ft_border_style {
struct ft_border_chars border_chs;
struct ft_border_chars header_border_chs;
char hor_separator_char;
const char *hor_separator_char;
};
/**
@ -443,6 +443,8 @@ extern struct ft_border_style *FT_SIMPLE_STYLE;
extern struct ft_border_style *FT_PLAIN_STYLE;
extern struct ft_border_style *FT_DOT_STYLE;
extern struct ft_border_style *FT_EMPTY_STYLE;
extern struct ft_border_style *FT_SOLID_STYLE;
extern struct ft_border_style *FT_DOUBLE_STYLE;
/**
* Set default border style for all new formatted tables.

View File

@ -106,9 +106,11 @@ static int lines_number_cell(fort_cell_t *cell)
int cell_printf(fort_cell_t *cell, size_t row, char *buf, size_t buf_len, const context_t *context)
{
char space_char = ' ';
const char *space_char = " ";
int (*buffer_printf_)(string_buffer_t *, size_t, char *, size_t, const context_t *) = buffer_printf;
int (*snprint_n_chars_)(char *, size_t, size_t, char) = snprint_n_chars;
// int (*snprint_n_chars_)(char *, size_t, size_t, char) = snprint_n_chars;
int (*snprint_n_strings_)(char *, size_t, size_t, const char *) = snprint_n_strings;
if (cell == NULL || buf_len == 0
@ -123,7 +125,7 @@ int cell_printf(fort_cell_t *cell, size_t row, char *buf, size_t buf_len, const
if (row >= hint_height_cell(cell, context)
|| row < cell_padding_top
|| row >= (cell_padding_top + buffer_text_height(cell->str_buffer))) {
return snprint_n_chars_(buf, buf_len, buf_len - 1, space_char);
return snprint_n_strings_(buf, buf_len, buf_len - 1, space_char);
}
@ -132,13 +134,13 @@ int cell_printf(fort_cell_t *cell, size_t row, char *buf, size_t buf_len, const
int left = cell_padding_left;
int right = cell_padding_right;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buf + written, buf_len - written, left, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, left, space_char));
if (cell->str_buffer)
CHCK_RSLT_ADD_TO_WRITTEN(buffer_printf_(cell->str_buffer, row - cell_padding_top, buf + written, buf_len - written - right, context));
else
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buf + written, buf_len - written, buf_len - written - right, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buf + written, buf_len - written, right, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, buf_len - written - right, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, right, space_char));
return written;
@ -149,9 +151,11 @@ clear:
#ifdef FT_HAVE_WCHAR
int cell_wprintf(fort_cell_t *cell, size_t row, wchar_t *buf, size_t buf_len, const context_t *context)
{
wchar_t space_char = L' ';
const char *space_char = " ";
int (*buffer_printf_)(string_buffer_t *, size_t, wchar_t *, size_t, const context_t *) = buffer_wprintf;
int (*snprint_n_chars_)(wchar_t *, size_t, size_t, wchar_t) = wsnprint_n_chars;
// int (*snprint_n_chars_)(wchar_t *, size_t, size_t, wchar_t) = wsnprint_n_chars;
int (*snprint_n_strings_)(wchar_t *, size_t, size_t, const char *) = wsnprint_n_string;
if (cell == NULL || buf_len == 0
@ -166,7 +170,7 @@ int cell_wprintf(fort_cell_t *cell, size_t row, wchar_t *buf, size_t buf_len, co
if (row >= hint_height_cell(cell, context)
|| row < cell_padding_top
|| row >= (cell_padding_top + buffer_text_height(cell->str_buffer))) {
return snprint_n_chars_(buf, buf_len, buf_len - 1, space_char);
return snprint_n_strings_(buf, buf_len, buf_len - 1, space_char);
}
int written = 0;
@ -174,13 +178,13 @@ int cell_wprintf(fort_cell_t *cell, size_t row, wchar_t *buf, size_t buf_len, co
int left = cell_padding_left;
int right = cell_padding_right;
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buf + written, buf_len - written, left, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, left, space_char));
if (cell->str_buffer)
CHCK_RSLT_ADD_TO_WRITTEN(buffer_printf_(cell->str_buffer, row - cell_padding_top, buf + written, buf_len - written - right, context));
else
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buf + written, buf_len - written, buf_len - written - right, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buf + written, buf_len - written, right, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, buf_len - written - right, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buf + written, buf_len - written, right, space_char));
return written;

View File

@ -537,8 +537,8 @@ const char *ft_to_string(const FTABLE *table)
typedef char char_type;
const char_type *empty_string = "";
const enum str_buf_type buf_type = CharBuf;
char space_char = ' ';
char new_line_char = '\n';
const char *space_char = " ";
const char *new_line_char = "\n";
#define cur_F_STRDUP F_STRDUP
int (*snprintf_row_)(const fort_row_t *, char *, size_t, size_t *, size_t, size_t, const context_t *) = snprintf_row;
int (*print_row_separator_)(char *, size_t,
@ -546,7 +546,8 @@ const char *ft_to_string(const FTABLE *table)
const fort_row_t *, const fort_row_t *,
enum HorSeparatorPos, const separator_t *,
const context_t *) = print_row_separator;
int (*snprint_n_chars_)(char *, size_t, size_t, char) = snprint_n_chars;
// int (*snprint_n_chars_)(char *, size_t, size_t, char) = snprint_n_chars;
int (*snprint_n_strings_)(char *, size_t, size_t, const char *) = snprint_n_strings;
assert(table);
/* Determing size of table string representation */
@ -595,8 +596,8 @@ const char *ft_to_string(const FTABLE *table)
/* Print top margin */
for (i = 0; i < context.table_options->entire_table_options.top_margin; ++i) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, sz - written, width - 1/* minus new_line*/, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, sz - written, 1, new_line_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, sz - written, width - 1/* minus new_line*/, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, sz - written, 1, new_line_char));
}
for (i = 0; i < rows; ++i) {
@ -614,8 +615,8 @@ const char *ft_to_string(const FTABLE *table)
/* Print bottom margin */
for (i = 0; i < context.table_options->entire_table_options.bottom_margin; ++i) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, sz - written, width - 1/* minus new_line*/, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, sz - written, 1, new_line_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, sz - written, width - 1/* minus new_line*/, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, sz - written, 1, new_line_char));
}
@ -637,8 +638,8 @@ const wchar_t *ft_to_wstring(const FTABLE *table)
typedef wchar_t char_type;
const char_type *empty_string = L"";
const enum str_buf_type buf_type = WCharBuf;
wchar_t space_char = L' ';
wchar_t new_line_char = L'\n';
const char *space_char = " ";
const char *new_line_char = "\n";
#define cur_F_STRDUP F_WCSDUP
int (*snprintf_row_)(const fort_row_t *, wchar_t *, size_t, size_t *, size_t, size_t, const context_t *) = wsnprintf_row;
int (*print_row_separator_)(wchar_t *, size_t,
@ -646,7 +647,9 @@ const wchar_t *ft_to_wstring(const FTABLE *table)
const fort_row_t *, const fort_row_t *,
enum HorSeparatorPos, const separator_t *,
const context_t *) = wprint_row_separator;
int (*snprint_n_chars_)(wchar_t *, size_t, size_t, wchar_t) = wsnprint_n_chars;
// int (*snprint_n_chars_)(wchar_t *, size_t, size_t, wchar_t) = wsnprint_n_chars;
int (*snprint_n_strings_)(wchar_t *, size_t, size_t, const char *) = wsnprint_n_string;
assert(table);
@ -697,8 +700,8 @@ const wchar_t *ft_to_wstring(const FTABLE *table)
/* Print top margin */
for (i = 0; i < context.table_options->entire_table_options.top_margin; ++i) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, sz - written, width - 1/* minus new_line*/, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, sz - written, 1, new_line_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, sz - written, width - 1/* minus new_line*/, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, sz - written, 1, new_line_char));
}
for (i = 0; i < rows; ++i) {
@ -716,8 +719,8 @@ const wchar_t *ft_to_wstring(const FTABLE *table)
/* Print bottom margin */
for (i = 0; i < context.table_options->entire_table_options.bottom_margin; ++i) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, sz - written, width - 1/* minus new_line*/, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, sz - written, 1, new_line_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, sz - written, width - 1/* minus new_line*/, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, sz - written, 1, new_line_char));
}
F_FREE(col_width_arr);
@ -794,6 +797,8 @@ struct ft_border_style *FT_SIMPLE_STYLE = (struct ft_border_style *) &FORT_SIMPL
struct ft_border_style *FT_PLAIN_STYLE = (struct ft_border_style *) &FORT_PLAIN_STYLE;
struct ft_border_style *FT_DOT_STYLE = (struct ft_border_style *) &FORT_DOT_STYLE;
struct ft_border_style *FT_EMPTY_STYLE = (struct ft_border_style *) &FORT_EMPTY_STYLE;
struct ft_border_style *FT_SOLID_STYLE = (struct ft_border_style *) &FORT_SOLID_STYLE;
struct ft_border_style *FT_DOUBLE_STYLE = (struct ft_border_style *) &FORT_DOUBLE_STYLE;
@ -803,7 +808,9 @@ static void set_border_options_for_options(fort_table_options_t *options, struct
|| (struct fort_border_style *)style == &FORT_SIMPLE_STYLE
|| (struct fort_border_style *)style == &FORT_DOT_STYLE
|| (struct fort_border_style *)style == &FORT_PLAIN_STYLE
|| (struct fort_border_style *)style == &FORT_EMPTY_STYLE) {
|| (struct fort_border_style *)style == &FORT_EMPTY_STYLE
|| (struct fort_border_style *)style == &FORT_SOLID_STYLE
|| (struct fort_border_style *)style == &FORT_DOUBLE_STYLE) {
memcpy(&(options->border_style), (struct fort_border_style *)style, sizeof(struct fort_border_style));
return;
}
@ -837,8 +844,11 @@ static void set_border_options_for_options(fort_table_options_t *options, struct
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';
// if (border_chs->separator_ch == '\0' && border_chs->in_intersect_ch == '\0') {
// BOR_CHARS[LH_bip] = BOR_CHARS[RH_bip] = '\0';
// }
if (strlen(border_chs->separator_ch) == 0 && strlen(border_chs->in_intersect_ch) == 0) {
BOR_CHARS[LH_bip] = BOR_CHARS[RH_bip] = "\0";
}
@ -852,8 +862,11 @@ static void set_border_options_for_options(fort_table_options_t *options, struct
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';
// 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';
// }
if (strlen(header_border_chs->separator_ch) == 0 && strlen(header_border_chs->in_intersect_ch) == 0) {
BOR_CHARS[LH_bip] = BOR_CHARS[RH_bip] = "\0";
}
SEP_CHARS[LH_sip] = SEP_CHARS[RH_sip] = SEP_CHARS[II_sip] = header_border_chs->out_intersect_ch;

View File

@ -156,51 +156,113 @@ size_t number_of_columns_in_format_wstring(const wchar_t *fmt)
}
int snprint_n_chars(char *buf, size_t length, size_t n, char ch)
//int snprint_n_chars(char *buf, size_t length, size_t n, char ch)
//{
// if (length <= n)
// return -1;
// if (n == 0)
// return 0;
// /* To ensure valid return value it is safely not print such big strings */
// if (n > INT_MAX)
// return -1;
// int status = snprintf(buf, length, "%0*d", (int)n, 0);
// if (status < 0)
// return status;
// size_t i = 0;
// for (i = 0; i < n; ++i) {
// *buf = ch;
// buf++;
// }
// return (int)n;
//}
int snprint_n_strings(char *buf, size_t length, size_t n, const char *str)
{
if (length <= n)
size_t str_len = strlen(str);
if (length <= n * str_len)
return -1;
if (n == 0)
return 0;
/* To ensure valid return value it is safely not print such big strings */
if (n > INT_MAX)
if (n * str_len > INT_MAX)
return -1;
int status = snprintf(buf, length, "%0*d", (int)n, 0);
int status = snprintf(buf, length, "%0*d", (int)(n * str_len), 0);
if (status < 0)
return status;
size_t i = 0;
for (i = 0; i < n; ++i) {
*buf = ch;
buf++;
const char *str_p = str;
while (*str_p)
*(buf++) = *(str_p++);
}
return (int)n;
return (int)(n * str_len);
}
int wsnprint_n_chars(wchar_t *buf, size_t length, size_t n, wchar_t ch)
//int wsnprint_n_chars(wchar_t *buf, size_t length, size_t n, wchar_t ch)
//{
// if (length <= n)
// return -1;
// if (n == 0)
// return 0;
// /* To ensure valid return value it is safely not print such big strings */
// if (n > INT_MAX)
// return -1;
// int status = swprintf(buf, length, L"%0*d", (int)n, 0);
// if (status < 0)
// return status;
// size_t i = 0;
// for (i = 0; i < n; ++i) {
// *buf = ch;
// buf++;
// }
// return (int)n;
//}
int wsnprint_n_string(wchar_t *buf, size_t length, size_t n, const char *str)
{
if (length <= n)
size_t str_len = strlen(str);
/* This function doesn't work properly with multibyte characters
* so it is better return an error in this case
*/
if (str_len > 1)
return -1;
if (length <= n * str_len)
return -1;
if (n == 0)
return 0;
/* To ensure valid return value it is safely not print such big strings */
if (n > INT_MAX)
if (n * str_len > INT_MAX)
return -1;
int status = swprintf(buf, length, L"%0*d", (int)n, 0);
int status = swprintf(buf, length, L"%0*d", (int)(n * str_len), 0);
if (status < 0)
return status;
size_t i = 0;
for (i = 0; i < n; ++i) {
*buf = ch;
buf++;
const char *str_p = str;
while (*str_p)
*(buf++) = (wchar_t) * (str_p++);
}
return (int)n;
return (int)(n * str_len);
}

View File

@ -127,8 +127,10 @@ char *fort_strdup(const char* str);
wchar_t *fort_wcsdup(const wchar_t* str);
size_t number_of_columns_in_format_string(const char *fmt);
size_t number_of_columns_in_format_wstring(const wchar_t *fmt);
int snprint_n_chars(char *buf, size_t length, size_t n, char ch);
int wsnprint_n_chars(wchar_t *buf, size_t length, size_t n, wchar_t ch);
//int snprint_n_chars(char *buf, size_t length, size_t n, char ch);
//int wsnprint_n_chars(wchar_t *buf, size_t length, size_t n, wchar_t ch);
int snprint_n_strings(char *buf, size_t length, size_t n, const char *str);
int wsnprint_n_string(wchar_t *buf, size_t length, size_t n, const char *str);
#define CHCK_RSLT_ADD_TO_WRITTEN(statement) \

View File

@ -218,113 +218,159 @@ fort_status_t set_default_cell_option(uint32_t option, int value)
#define BASIC_STYLE { \
/* border_chars */ \
{ \
'+', '-', '+', '+', \
'|', '|', '|', \
'\0', '\0', '\0', '\0', \
'+', '-', '+', '+' \
"+", "-", "+", "+", \
"|", "|", "|", \
"\0", "\0", "\0", "\0", \
"+", "-", "+", "+" \
}, \
/* header_border_chars */ \
{ \
'+', '-', '+', '+', \
'|', '|', '|', \
'+', '-', '+', '+', \
'+', '-', '+', '+' \
"+", "-", "+", "+", \
"|", "|", "|", \
"+", "-", "+", "+", \
"+", "-", "+", "+" \
}, \
/* separator_chars */ \
{ \
'+', '-', '+', '+', \
"+", "-", "+", "+", \
}, \
}
#define SIMPLE_STYLE { \
/* border_chars */ \
{ \
' ', ' ', ' ', ' ', \
' ', ' ', ' ', \
'\0', '\0', '\0', '\0', \
' ', ' ', ' ', ' ' \
" ", " ", " ", " ", \
" ", " ", " ", \
"\0", "\0", "\0", "\0", \
" ", " ", " ", " " \
}, \
/* header_border_chars */ \
{ \
' ', ' ', ' ', ' ', \
' ', ' ', ' ', \
' ', '-', ' ', ' ', \
' ', ' ', ' ', ' ' \
" ", " ", " ", " ", \
" ", " ", " ", \
" ", "-", " ", " ", \
" ", " ", " ", " " \
}, \
/* separator_chars */ \
{ \
' ', '-', ' ', ' ', \
" ", "-", " ", " ", \
}, \
}
#define PLAIN_STYLE { \
/* border_chars */ \
{ \
' ', ' ', ' ', ' ', \
' ', ' ', ' ', \
'\0', '\0', '\0', '\0', \
' ', ' ', ' ', ' ' \
" ", " ", " ", " ", \
" ", " ", " ", \
"\0", "\0", "\0", "\0", \
" ", " ", " ", " " \
}, \
/* header_border_chars */ \
{ \
' ', '-', '-', ' ', \
' ', ' ', ' ', \
' ', '-', '-', ' ', \
' ', '-', '-', ' ' \
" ", "-", "-", " ", \
" ", " ", " ", \
" ", "-", "-", " ", \
" ", "-", "-", " " \
}, \
/* separator_chars */ \
{ \
' ', '-', '-', ' ', \
" ", "-", "-", " ", \
}, \
}
#define DOT_STYLE { \
/* border_chars */ \
{ \
'.', '.', '.', '.', \
':', ':', ':', \
'\0', '\0', '\0', '\0', \
':', '.', ':', ':' \
".", ".", ".", ".", \
":", ":", ":", \
"\0", "\0", "\0", "\0", \
":", ".", ":", ":" \
}, \
/* header_border_chars */ \
{ \
'.', '.', '.', '.', \
':', ':', ':', \
':', '.', ':', ':', \
':', '.', ':', ':' \
".", ".", ".", ".", \
":", ":", ":", \
":", ".", ":", ":", \
":", ".", ":", ":" \
}, \
/* separator_chars */ \
{ \
':', '.', ':', ':', \
":", ".", ":", ":", \
}, \
}
#define EMPTY_STYLE { \
/* border_chars */ \
{ \
' ', ' ', ' ', ' ', \
' ', ' ', ' ', \
'\0', '\0', '\0', '\0', \
' ', ' ', ' ', ' ' \
" ", " ", " ", " ", \
" ", " ", " ", \
"\0", "\0", "\0", "\0", \
" ", " ", " ", " " \
}, \
/* header_border_chars */ \
{ \
' ', ' ', ' ', ' ', \
' ', ' ', ' ', \
'\0', '\0', '\0', '\0', \
' ', ' ', ' ', ' ' \
" ", " ", " ", " ", \
" ", " ", " ", \
"\0", "\0", "\0", "\0", \
" ", " ", " ", " " \
}, \
/* separator_chars */ \
{ \
' ', ' ', ' ', ' ', \
" ", " ", " ", " ", \
}, \
}
#define SOLID_STYLE { \
/* border_chars */ \
{ \
"", "", "", "", \
"", "", "", \
"", "", "", "", \
"", "", "", "" \
}, \
/* header_border_chars */ \
{ \
"", "", "", "", \
"", "", "", \
"", "", "", "", \
"", "", "", "" \
}, \
/* separator_chars */ \
{ \
"", "", "", "", \
}, \
}
#define DOUBLE_STYLE { \
/* border_chars */ \
{ \
"", "", "", "", \
"", "", "", \
"", "", "", "", \
"", "", "", "" \
}, \
/* header_border_chars */ \
{ \
"", "", "", "", \
"", "", "", \
"", "", "", "", \
"", "", "", "" \
}, \
/* separator_chars */ \
{ \
"", "", "", "", \
}, \
}
struct fort_border_style FORT_BASIC_STYLE = BASIC_STYLE;
struct fort_border_style FORT_SIMPLE_STYLE = SIMPLE_STYLE;
struct fort_border_style FORT_PLAIN_STYLE = PLAIN_STYLE;
struct fort_border_style FORT_DOT_STYLE = DOT_STYLE;
struct fort_border_style FORT_EMPTY_STYLE = EMPTY_STYLE;
struct fort_border_style FORT_SOLID_STYLE = SOLID_STYLE;
struct fort_border_style FORT_DOUBLE_STYLE = DOUBLE_STYLE;
@ -367,7 +413,26 @@ fort_status_t set_default_entire_table_option(uint32_t option, int value)
return set_entire_table_option_internal(&g_entire_table_options, option, value);
}
size_t max_border_elem_strlen(struct fort_table_options *options)
{
assert(options);
size_t result = 1;
int i = 0;
for (i = 0; i < BorderItemPosSize; ++i) {
result = MAX(result, strlen(options->border_style.border_chars[i]));
}
i = 0;
for (i = 0; i < BorderItemPosSize; ++i) {
result = MAX(result, strlen(options->border_style.header_border_chars[i]));
}
i = 0;
for (i = 0; i < SepratorItemPosSize; ++i) {
result = MAX(result, strlen(options->border_style.separator_chars[i]));
}
return result;
}
fort_table_options_t g_table_options = {

View File

@ -112,15 +112,17 @@ enum SeparatorItemPos
struct fort_border_style
{
char border_chars[BorderItemPosSize];
char header_border_chars[BorderItemPosSize];
char separator_chars[SepratorItemPosSize];
const char *border_chars[BorderItemPosSize];
const char *header_border_chars[BorderItemPosSize];
const char *separator_chars[SepratorItemPosSize];
};
extern struct fort_border_style FORT_BASIC_STYLE;
extern struct fort_border_style FORT_SIMPLE_STYLE;
extern struct fort_border_style FORT_PLAIN_STYLE;
extern struct fort_border_style FORT_DOT_STYLE;
extern struct fort_border_style FORT_EMPTY_STYLE;
extern struct fort_border_style FORT_SOLID_STYLE;
extern struct fort_border_style FORT_DOUBLE_STYLE;
struct fort_entire_table_options
@ -144,6 +146,7 @@ struct fort_table_options
typedef struct fort_table_options fort_table_options_t;
extern fort_table_options_t g_table_options;
size_t max_border_elem_strlen(struct fort_table_options*);
fort_table_options_t* create_table_options(void);

271
src/row.c
View File

@ -167,14 +167,13 @@ int print_row_separator(char *buffer, size_t buffer_sz,
enum HorSeparatorPos separatorPos,
const separator_t *sep, const context_t *context)
{
typedef char char_type;
char new_line_char = '\n';
int (*snprint_n_chars_)(char *, size_t, size_t, char) = snprint_n_chars;
char space_char = ' ';
// int (*snprint_n_chars_)(char *, size_t, size_t, char) = snprint_n_chars;
int (*snprint_n_strings_)(char *, size_t, size_t, const char *) = snprint_n_strings;
assert(buffer);
assert(context);
const char *space_char = " ";
int status = -1;
/* Get cell types
@ -221,17 +220,17 @@ int print_row_separator(char *buffer, size_t buffer_sz,
* L I I I IV I I IT I I I IB I I II I I R
* | C21 | C22 | C23 C24 C25 |
*/
const char *L = NULL;
const char *I = NULL;
const char *IV = NULL;
const char *R = NULL;
const char *IT = NULL;
const char *IB = NULL;
const char *II = NULL;
const char **L = NULL;
const char **I = NULL;
const char **IV = NULL;
const char **R = NULL;
const char **IT = NULL;
const char **IB = NULL;
const char **II = NULL;
typedef const char (*border_chars_point_t)[BorderItemPosSize];
const char (*border_chars)[BorderItemPosSize] = NULL;
typedef const char *(*border_chars_point_t)[BorderItemPosSize];
const char *(*border_chars)[BorderItemPosSize] = NULL;
border_chars = (border_chars_point_t)&context->table_options->border_style.border_chars;
if (upper_row_type == FT_ROW_HEADER || lower_row_type == FT_ROW_HEADER) {
border_chars = (border_chars_point_t)&context->table_options->border_style.header_border_chars;
@ -284,7 +283,14 @@ int print_row_separator(char *buffer, size_t buffer_sz,
}
/* If all chars are not printable, skip line separator */ /* todo: add processing for wchar_t */
if (!isprint(*L) && !isprint(*I) && !isprint(*IV) && !isprint(*R)) {
// if (!isprint(*L) && !isprint(*I) && !isprint(*IV) && !isprint(*R)) {
// status = 0;
// goto clear;
// }
if ((strlen(*L) == 0 || (strlen(*L) == 1 && !isprint(**L)))
&& (strlen(*I) == 0 || (strlen(*I) == 1 && !isprint(**I)))
&& (strlen(*IV) == 0 || (strlen(*IV) == 1 && !isprint(**IV)))
&& (strlen(*R) == 0 || (strlen(*R) == 1 && !isprint(**R)))) {
status = 0;
goto clear;
}
@ -292,31 +298,31 @@ int print_row_separator(char *buffer, size_t buffer_sz,
size_t i = 0;
/* Print left margin */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, context->table_options->entire_table_options.left_margin, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, context->table_options->entire_table_options.left_margin, space_char));
for (i = 0; i < cols; ++i) {
if (i == 0) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, 1, (char_type)*L));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, *L));
} else {
if ((top_row_types[i] == CommonCell || top_row_types[i] == GroupMasterCell)
&& (bottom_row_types[i] == CommonCell || bottom_row_types[i] == GroupMasterCell)) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, 1, (char_type)*IV));
&& (bottom_row_types[i] == CommonCell || bottom_row_types[i] == GroupMasterCell)) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, *IV));
} else if (top_row_types[i] == GroupSlaveCell && bottom_row_types[i] == GroupSlaveCell) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, 1, (char_type)*II));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, *II));
} else if (top_row_types[i] == GroupSlaveCell) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, 1, (char_type)*IT));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, *IT));
} else {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, 1, (char_type)*IB));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, *IB));
}
}
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, col_width_arr[i], (char_type)*I));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, col_width_arr[i], *I));
}
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, 1, (char_type)*R));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, *R));
/* Print right margin */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, context->table_options->entire_table_options.right_margin, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, context->table_options->entire_table_options.right_margin, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, 1, new_line_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, "\n"));
status = written;
@ -333,14 +339,41 @@ int wprint_row_separator(wchar_t *buffer, size_t buffer_sz,
enum HorSeparatorPos separatorPos, const separator_t *sep,
const context_t *context)
{
typedef wchar_t char_type;
char new_line_char = L'\n';
int (*snprint_n_chars_)(wchar_t *, size_t, size_t, wchar_t) = wsnprint_n_chars;
wchar_t space_char = L' ';
// int (*snprint_n_chars_)(wchar_t *, size_t, size_t, wchar_t) = wsnprint_n_chars;
int (*snprint_n_strings_)(wchar_t *, size_t, size_t, const char *) = wsnprint_n_string;
assert(buffer);
assert(context);
const char *space_char = " ";
int status = -1;
/* Get cell types
*
* Regions above top row and below bottom row areconsidered full of virtual
* GroupSlaveCell cells
*/
enum CellType *top_row_types = F_MALLOC(sizeof(enum CellType) * cols * 2);
if (top_row_types == NULL) {
return FT_MEMORY_ERROR;
}
enum CellType *bottom_row_types = top_row_types + cols;
if (upper_row) {
get_row_cell_types(upper_row, top_row_types, cols);
} else {
size_t i = 0;
for (i = 0; i < cols; ++i)
top_row_types[i] = GroupSlaveCell;
}
if (lower_row) {
get_row_cell_types(lower_row, bottom_row_types, cols);
} else {
size_t i = 0;
for (i = 0; i < cols; ++i)
bottom_row_types[i] = GroupSlaveCell;
}
int written = 0;
int tmp = 0;
@ -353,28 +386,37 @@ int wprint_row_separator(wchar_t *buffer, size_t buffer_sz,
upper_row_type = (enum ft_row_type)get_cell_opt_value_hierarcial(context->table_options, context->row - 1, FT_ANY_COLUMN, FT_COPT_ROW_TYPE);
}
/* Row separator anatomy
/* Row separator anatomy
*
* L I I I IV I I I R
*/
const char *L = NULL;
const char *I = NULL;
const char *IV = NULL;
const char *R = NULL;
* | C11 | C12 C13 | C14 C15 |
* L I I I IV I I IT I I I IB I I II I I R
* | C21 | C22 | C23 C24 C25 |
*/
const char **L = NULL;
const char **I = NULL;
const char **IV = NULL;
const char **R = NULL;
const char **IT = NULL;
const char **IB = NULL;
const char **II = NULL;
typedef const char (*border_chars_point_t)[BorderItemPosSize];
const char (*border_chars)[BorderItemPosSize] = NULL;
typedef const char *(*border_chars_point_t)[BorderItemPosSize];
const char *(*border_chars)[BorderItemPosSize] = NULL;
border_chars = (border_chars_point_t)&context->table_options->border_style.border_chars;
if (upper_row_type == FT_ROW_HEADER || lower_row_type == FT_ROW_HEADER) {
border_chars = (border_chars_point_t)&context->table_options->border_style.header_border_chars;
}
if (sep && sep->enabled) {
L = &(context->table_options->border_style.separator_chars[LH_sip]);
I = &(context->table_options->border_style.separator_chars[IH_sip]);
IV = &(context->table_options->border_style.separator_chars[II_sip]);
R = &(context->table_options->border_style.separator_chars[RH_sip]);
IT = &(context->table_options->border_style.separator_chars[II_sip]);
IB = &(context->table_options->border_style.separator_chars[II_sip]);
II = &(context->table_options->border_style.separator_chars[IH_sip]);
} else {
switch (separatorPos) {
case TopSeparator:
@ -382,18 +424,30 @@ int wprint_row_separator(wchar_t *buffer, size_t buffer_sz,
I = &(*border_chars)[TT_bip];
IV = &(*border_chars)[TV_bip];
R = &(*border_chars)[TR_bip];
IT = &(*border_chars)[TV_bip];
IB = &(*border_chars)[TV_bip];
II = &(*border_chars)[TT_bip];
break;
case InsideSeparator:
L = &(*border_chars)[LH_bip];
I = &(*border_chars)[IH_bip];
IV = &(*border_chars)[II_bip];
R = &(*border_chars)[RH_bip];
IT = &(*border_chars)[TV_bip];
IB = &(*border_chars)[BV_bip];
II = &(*border_chars)[IH_bip];
break;
case BottomSeparator:
L = &(*border_chars)[BL_bip];
I = &(*border_chars)[BB_bip];
IV = &(*border_chars)[BV_bip];
R = &(*border_chars)[BR_bip];
IT = &(*border_chars)[BV_bip];
IB = &(*border_chars)[BV_bip];
II = &(*border_chars)[BB_bip];
break;
default:
break;
@ -401,33 +455,52 @@ int wprint_row_separator(wchar_t *buffer, size_t buffer_sz,
}
/* If all chars are not printable, skip line separator */ /* todo: add processing for wchar_t */
if (!isprint(*L) && !isprint(*I) && !isprint(*IV) && !isprint(*R))
return 0;
// if (!isprint(*L) && !isprint(*I) && !isprint(*IV) && !isprint(*R)) {
// status = 0;
// goto clear;
// }
if ((strlen(*L) == 0 || (strlen(*L) == 1 && !isprint(**L)))
&& (strlen(*I) == 0 || (strlen(*I) == 1 && !isprint(**I)))
&& (strlen(*IV) == 0 || (strlen(*IV) == 1 && !isprint(**IV)))
&& (strlen(*R) == 0 || (strlen(*R) == 1 && !isprint(**R)))) {
status = 0;
goto clear;
}
size_t i = 0;
/* Print left margin */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, context->table_options->entire_table_options.left_margin, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, context->table_options->entire_table_options.left_margin, space_char));
for (i = 0; i < cols; ++i) {
if (i == 0) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, 1, (char_type)*L));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, *L));
} else {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, 1, (char_type)*IV));
if ((top_row_types[i] == CommonCell || top_row_types[i] == GroupMasterCell)
&& (bottom_row_types[i] == CommonCell || bottom_row_types[i] == GroupMasterCell)) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, *IV));
} else if (top_row_types[i] == GroupSlaveCell && bottom_row_types[i] == GroupSlaveCell) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, *II));
} else if (top_row_types[i] == GroupSlaveCell) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, *IT));
} else {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, *IB));
}
}
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, col_width_arr[i], (char_type)*I));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, col_width_arr[i], *I));
}
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, 1, (char_type)*R));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, *R));
/* Print right margin */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, context->table_options->entire_table_options.right_margin, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, context->table_options->entire_table_options.right_margin, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buffer_sz - written, 1, new_line_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buffer_sz - written, 1, "\n"));
return written;
status = written;
clear:
return -1;
F_FREE(top_row_types);
return status;
}
@ -724,14 +797,15 @@ clear:
int snprintf_row(const fort_row_t *row, char *buffer, size_t buf_sz, size_t *col_width_arr, size_t col_width_arr_sz,
size_t row_height, const context_t *context)
{
typedef char char_type;
char space_char = ' ';
char new_line_char = '\n';
int (*snprint_n_chars_)(char *, size_t, size_t, char) = snprint_n_chars;
// int (*snprint_n_chars_)(char *, size_t, size_t, char) = snprint_n_chars;
int (*snprint_n_strings_)(char *, size_t, size_t, const char *) = snprint_n_strings;
int (*cell_printf_)(fort_cell_t *, size_t, char *, size_t, const context_t *) = cell_printf;
assert(context);
const char *space_char = " ";
const char *new_line_char = "\n";
if (row == NULL)
return -1;
@ -744,14 +818,14 @@ int snprintf_row(const fort_row_t *row, char *buffer, size_t buf_sz, size_t *col
* L data IV data IV data R
*/
typedef const char (*border_chars_point_t)[BorderItemPosSize];
typedef const char *(*border_chars_point_t)[BorderItemPosSize];
enum ft_row_type row_type = (enum ft_row_type)get_cell_opt_value_hierarcial(context->table_options, context->row, FT_ANY_COLUMN, FT_COPT_ROW_TYPE);
const char (*bord_chars)[BorderItemPosSize] = (row_type == FT_ROW_HEADER)
const char *(*bord_chars)[BorderItemPosSize] = (row_type == FT_ROW_HEADER)
? (border_chars_point_t)(&context->table_options->border_style.header_border_chars)
: (border_chars_point_t)(&context->table_options->border_style.border_chars);
const char *L = &(*bord_chars)[LL_bip];
const char *IV = &(*bord_chars)[IV_bip];
const char *R = &(*bord_chars)[RR_bip];
const char **L = &(*bord_chars)[LL_bip];
const char **IV = &(*bord_chars)[IV_bip];
const char **R = &(*bord_chars)[RR_bip];
int written = 0;
@ -759,10 +833,10 @@ int snprintf_row(const fort_row_t *row, char *buffer, size_t buf_sz, size_t *col
size_t i = 0;
for (i = 0; i < row_height; ++i) {
/* Print left margin */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, context->table_options->entire_table_options.left_margin, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, context->table_options->entire_table_options.left_margin, space_char));
/* Print left table boundary */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, 1, (char_type)*L));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, 1, *L));
size_t j = 0;
while (j < col_width_arr_sz) {
if (j < cols_in_row) {
@ -782,24 +856,24 @@ int snprintf_row(const fort_row_t *row, char *buffer, size_t buf_sz, size_t *col
CHCK_RSLT_ADD_TO_WRITTEN(cell_printf_(cell, i, buffer + written, cell_width + 1, context));
} else {
/* Print empty cell */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, col_width_arr[j], space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, col_width_arr[j], space_char));
}
/* Print boundary between cells */
if (j < col_width_arr_sz - 1)
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, 1, (char_type)*IV));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, 1, *IV));
++j;
}
/* Print right table boundary */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, 1, (char_type)*R));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, 1, *R));
/* Print right margin */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, context->table_options->entire_table_options.right_margin, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, context->table_options->entire_table_options.right_margin, space_char));
/* Print new line character */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, 1, new_line_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, 1, new_line_char));
}
return written;
@ -812,14 +886,15 @@ clear:
int wsnprintf_row(const fort_row_t *row, wchar_t *buffer, size_t buf_sz, size_t *col_width_arr, size_t col_width_arr_sz,
size_t row_height, const context_t *context)
{
typedef wchar_t char_type;
char space_char = L' ';
char new_line_char = L'\n';
int (*snprint_n_chars_)(wchar_t *, size_t, size_t, wchar_t) = wsnprint_n_chars;
// int (*snprint_n_chars_)(wchar_t *, size_t, size_t, wchar_t) = wsnprint_n_chars;
int (*snprint_n_strings_)(wchar_t *, size_t, size_t, const char *) = wsnprint_n_string;
int (*cell_printf_)(fort_cell_t *, size_t, wchar_t *, size_t, const context_t *) = cell_wprintf;
assert(context);
const char *space_char = " ";
const char *new_line_char = "\n";
if (row == NULL)
return -1;
@ -832,14 +907,14 @@ int wsnprintf_row(const fort_row_t *row, wchar_t *buffer, size_t buf_sz, size_t
* L data IV data IV data R
*/
typedef const char (*border_chars_point_t)[BorderItemPosSize];
typedef const char *(*border_chars_point_t)[BorderItemPosSize];
enum ft_row_type row_type = (enum ft_row_type)get_cell_opt_value_hierarcial(context->table_options, context->row, FT_ANY_COLUMN, FT_COPT_ROW_TYPE);
const char (*bord_chars)[BorderItemPosSize] = (row_type)
const char *(*bord_chars)[BorderItemPosSize] = (row_type == FT_ROW_HEADER)
? (border_chars_point_t)(&context->table_options->border_style.header_border_chars)
: (border_chars_point_t)(&context->table_options->border_style.border_chars);
const char *L = &(*bord_chars)[LL_bip];
const char *IV = &(*bord_chars)[IV_bip];
const char *R = &(*bord_chars)[RR_bip];
const char **L = &(*bord_chars)[LL_bip];
const char **IV = &(*bord_chars)[IV_bip];
const char **R = &(*bord_chars)[RR_bip];
int written = 0;
@ -847,29 +922,47 @@ int wsnprintf_row(const fort_row_t *row, wchar_t *buffer, size_t buf_sz, size_t
size_t i = 0;
for (i = 0; i < row_height; ++i) {
/* Print left margin */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, context->table_options->entire_table_options.left_margin, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, context->table_options->entire_table_options.left_margin, space_char));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, 1, (char_type)*L));
/* Print left table boundary */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, 1, *L));
size_t j = 0;
for (j = 0; j < col_width_arr_sz; ++j) {
((context_t *)context)->column = j;
while (j < col_width_arr_sz) {
if (j < cols_in_row) {
((context_t *)context)->column = j;
fort_cell_t *cell = *(fort_cell_t **)vector_at(row->cells, j);
CHCK_RSLT_ADD_TO_WRITTEN(cell_printf_(cell, i, buffer + written, col_width_arr[j] + 1, context));
size_t cell_width = 0;
size_t group_slave_sz = group_cell_number(row, j);
cell_width = col_width_arr[j];
size_t slave_j = 0;
size_t master_j = j;
for (slave_j = master_j + 1; slave_j < (master_j + group_slave_sz); ++slave_j) {
cell_width += col_width_arr[slave_j] + FORT_COL_SEPARATOR_LENGTH;
++j;
}
CHCK_RSLT_ADD_TO_WRITTEN(cell_printf_(cell, i, buffer + written, cell_width + 1, context));
} else {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, col_width_arr[j], space_char));
}
if (j == col_width_arr_sz - 1) {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, 1, (char_type)*R));
} else {
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, 1, (char_type)*IV));
/* Print empty cell */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, col_width_arr[j], space_char));
}
/* Print boundary between cells */
if (j < col_width_arr_sz - 1)
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, 1, *IV));
++j;
}
/* Print right margin */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, context->table_options->entire_table_options.right_margin, space_char));
/* Print right table boundary */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, 1, *R));
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_chars_(buffer + written, buf_sz - written, 1, new_line_char));
/* Print right margin */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, context->table_options->entire_table_options.right_margin, space_char));
/* Print new line character */
CHCK_RSLT_ADD_TO_WRITTEN(snprint_n_strings_(buffer + written, buf_sz - written, 1, new_line_char));
}
return written;

View File

@ -279,11 +279,12 @@ int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t
#define CHAR_TYPE char
#define NULL_CHAR '\0'
#define NEWLINE_CHAR '\n'
#define SPACE_CHAR ' '
#define SPACE_CHAR " "
#define SNPRINTF_FMT_STR "%*s"
#define SNPRINTF snprintf
#define BUFFER_STR str.cstr
#define SNPRINT_N_CHARS snprint_n_chars
//#define SNPRINT_N_CHARS snprint_n_chars
#define SNPRINT_N_STRINGS snprint_n_strings
#define STR_N_SUBSTRING str_n_substring
#define STR_ITER_WIDTH str_iter_width
@ -323,7 +324,7 @@ int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t
const CHAR_TYPE *end = NULL;
CHAR_TYPE old_value;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_CHARS(buf + written, buf_len - written, left, SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, left, SPACE_CHAR));
STR_N_SUBSTRING(buffer->BUFFER_STR, NEWLINE_CHAR, buffer_row, &beg, &end);
if (beg == NULL || end == NULL)
@ -337,8 +338,8 @@ int buffer_printf(string_buffer_t *buffer, size_t buffer_row, char *buf, size_t
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINTF(buf + written, buf_len - written, SNPRINTF_FMT_STR, (int)(end - beg), beg));
*(CHAR_TYPE *)end = old_value;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_CHARS(buf + written, buf_len - written, (content_width - (size_t)str_it_width), SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_CHARS(buf + written, buf_len - written, right, SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, (content_width - (size_t)str_it_width), SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, right, SPACE_CHAR));
return written;
clear:
@ -351,7 +352,8 @@ clear:
#undef SNPRINTF_FMT_STR
#undef SNPRINTF
#undef BUFFER_STR
#undef SNPRINT_N_CHARS
//#undef SNPRINT_N_CHARS
#undef SNPRINT_N_STRINGS
#undef STR_N_SUBSTRING
#undef STR_ITER_WIDTH
}
@ -362,11 +364,12 @@ int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, siz
#define CHAR_TYPE wchar_t
#define NULL_CHAR L'\0'
#define NEWLINE_CHAR L'\n'
#define SPACE_CHAR L' '
#define SPACE_CHAR " "
#define SNPRINTF_FMT_STR L"%*ls"
#define SNPRINTF swprintf
#define BUFFER_STR str.wstr
#define SNPRINT_N_CHARS wsnprint_n_chars
//#define SNPRINT_N_CHARS wsnprint_n_chars
#define SNPRINT_N_STRINGS wsnprint_n_string
#define STR_N_SUBSTRING wstr_n_substring
#define STR_ITER_WIDTH wcs_iter_width
@ -406,7 +409,7 @@ int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, siz
const CHAR_TYPE *end = NULL;
CHAR_TYPE old_value;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_CHARS(buf + written, buf_len - written, left, SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, left, SPACE_CHAR));
STR_N_SUBSTRING(buffer->BUFFER_STR, NEWLINE_CHAR, buffer_row, &beg, &end);
if (beg == NULL || end == NULL)
@ -420,8 +423,8 @@ int buffer_wprintf(string_buffer_t *buffer, size_t buffer_row, wchar_t *buf, siz
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINTF(buf + written, buf_len - written, SNPRINTF_FMT_STR, (int)(end - beg), beg));
*(CHAR_TYPE *)end = old_value;
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_CHARS(buf + written, buf_len - written, (content_width - (size_t)str_it_width), SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_CHARS(buf + written, buf_len - written, right, SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, (content_width - (size_t)str_it_width), SPACE_CHAR));
CHCK_RSLT_ADD_TO_WRITTEN(SNPRINT_N_STRINGS(buf + written, buf_len - written, right, SPACE_CHAR));
return written;
clear:
@ -434,7 +437,8 @@ clear:
#undef SNPRINTF_FMT_STR
#undef SNPRINTF
#undef BUFFER_STR
#undef SNPRINT_N_CHARS
//#undef SNPRINT_N_CHARS
#undef SNPRINT_N_STRINGS
#undef STR_N_SUBSTRING
#undef STR_ITER_WIDTH
}

View File

@ -234,6 +234,11 @@ fort_status_t table_geometry(const FTABLE *table, size_t *height, size_t *width)
*width += table->options->entire_table_options.right_margin;
}
/* Take into account that border elements can be more than one byte long */
fort_table_options_t *table_options = table->options ? table->options : &g_table_options;
size_t max_border_elem_len = max_border_elem_strlen(table_options);
*width *= max_border_elem_len;
return FT_SUCCESS;
}

View File

@ -15,19 +15,21 @@ void test_table_border_style(void)
WHEN("Changing cell separators") {
struct ft_border_style brdr_style;
brdr_style.border_chs.top_border_ch = '|';
brdr_style.border_chs.separator_ch = '|';
brdr_style.border_chs.bottom_border_ch = '|';
brdr_style.border_chs.side_border_ch = '=';
brdr_style.border_chs.out_intersect_ch = '+';
brdr_style.border_chs.in_intersect_ch = '#';
brdr_style.border_chs.top_border_ch = "|";
brdr_style.border_chs.separator_ch = "|";
brdr_style.border_chs.bottom_border_ch = "|";
brdr_style.border_chs.side_border_ch = "=";
brdr_style.border_chs.out_intersect_ch = "+";
brdr_style.border_chs.in_intersect_ch = "#";
brdr_style.header_border_chs.top_border_ch = '*';
brdr_style.header_border_chs.separator_ch = '*';
brdr_style.header_border_chs.bottom_border_ch = '*';
brdr_style.header_border_chs.side_border_ch = 'v';
brdr_style.header_border_chs.out_intersect_ch = '+';
brdr_style.header_border_chs.in_intersect_ch = '#';
brdr_style.header_border_chs.top_border_ch = "*";
brdr_style.header_border_chs.separator_ch = "*";
brdr_style.header_border_chs.bottom_border_ch = "*";
brdr_style.header_border_chs.side_border_ch = "v";
brdr_style.header_border_chs.out_intersect_ch = "+";
brdr_style.header_border_chs.in_intersect_ch = "#";
brdr_style.hor_separator_char = "|";
ft_set_default_border_style(&brdr_style);
@ -54,19 +56,21 @@ void test_table_border_style(void)
brdr_style.border_chs.top_border_ch = '|';
brdr_style.border_chs.separator_ch = '\0';
brdr_style.border_chs.bottom_border_ch = '|';
brdr_style.border_chs.side_border_ch = '=';
brdr_style.border_chs.out_intersect_ch = '+';
brdr_style.border_chs.in_intersect_ch = '\0';
brdr_style.border_chs.top_border_ch = "|";
brdr_style.border_chs.separator_ch = "\0";
brdr_style.border_chs.bottom_border_ch = "|";
brdr_style.border_chs.side_border_ch = "=";
brdr_style.border_chs.out_intersect_ch = "+";
brdr_style.border_chs.in_intersect_ch = "\0";
brdr_style.header_border_chs.top_border_ch = '*';
brdr_style.header_border_chs.separator_ch = '*';
brdr_style.header_border_chs.bottom_border_ch = '*';
brdr_style.header_border_chs.side_border_ch = 'v';
brdr_style.header_border_chs.out_intersect_ch = '+';
brdr_style.header_border_chs.in_intersect_ch = '#';
brdr_style.header_border_chs.top_border_ch = "*";
brdr_style.header_border_chs.separator_ch = "*";
brdr_style.header_border_chs.bottom_border_ch = "*";
brdr_style.header_border_chs.side_border_ch = "v";
brdr_style.header_border_chs.out_intersect_ch = "+";
brdr_style.header_border_chs.in_intersect_ch = "#";
brdr_style.hor_separator_char = "";
ft_set_default_border_style(&brdr_style);

View File

@ -15,21 +15,21 @@ int set_test_options_for_table(FTABLE *table)
struct ft_border_style brdr_style;
brdr_style.border_chs.top_border_ch = '-';
brdr_style.border_chs.separator_ch = '-';
brdr_style.border_chs.bottom_border_ch = '-';
brdr_style.border_chs.side_border_ch = '|';
brdr_style.border_chs.out_intersect_ch = '+';
brdr_style.border_chs.in_intersect_ch = '+';
brdr_style.border_chs.top_border_ch = "-";
brdr_style.border_chs.separator_ch = "-";
brdr_style.border_chs.bottom_border_ch = "-";
brdr_style.border_chs.side_border_ch = "|";
brdr_style.border_chs.out_intersect_ch = "+";
brdr_style.border_chs.in_intersect_ch = "+";
brdr_style.header_border_chs.top_border_ch = '-';
brdr_style.header_border_chs.separator_ch = '-';
brdr_style.header_border_chs.bottom_border_ch = '-';
brdr_style.header_border_chs.side_border_ch = '|';
brdr_style.header_border_chs.out_intersect_ch = '+';
brdr_style.header_border_chs.in_intersect_ch = '+';
brdr_style.header_border_chs.top_border_ch = "-";
brdr_style.header_border_chs.separator_ch = "-";
brdr_style.header_border_chs.bottom_border_ch = "-";
brdr_style.header_border_chs.side_border_ch = "|";
brdr_style.header_border_chs.out_intersect_ch = "+";
brdr_style.header_border_chs.in_intersect_ch = "+";
brdr_style.hor_separator_char = '=';
brdr_style.hor_separator_char = "=";
return ft_set_border_style(table, &brdr_style);
}
@ -50,21 +50,21 @@ int set_test_options_as_default(void)
struct ft_border_style brdr_style;
brdr_style.border_chs.top_border_ch = '-';
brdr_style.border_chs.separator_ch = '-';
brdr_style.border_chs.bottom_border_ch = '-';
brdr_style.border_chs.side_border_ch = '|';
brdr_style.border_chs.out_intersect_ch = '+';
brdr_style.border_chs.in_intersect_ch = '+';
brdr_style.border_chs.top_border_ch = "-";
brdr_style.border_chs.separator_ch = "-";
brdr_style.border_chs.bottom_border_ch = "-";
brdr_style.border_chs.side_border_ch = "|";
brdr_style.border_chs.out_intersect_ch = "+";
brdr_style.border_chs.in_intersect_ch = "+";
brdr_style.header_border_chs.top_border_ch = '-';
brdr_style.header_border_chs.separator_ch = '-';
brdr_style.header_border_chs.bottom_border_ch = '-';
brdr_style.header_border_chs.side_border_ch = '|';
brdr_style.header_border_chs.out_intersect_ch = '+';
brdr_style.header_border_chs.in_intersect_ch = '+';
brdr_style.header_border_chs.top_border_ch = "-";
brdr_style.header_border_chs.separator_ch = "-";
brdr_style.header_border_chs.bottom_border_ch = "-";
brdr_style.header_border_chs.side_border_ch = "|";
brdr_style.header_border_chs.out_intersect_ch = "+";
brdr_style.header_border_chs.in_intersect_ch = "+";
brdr_style.hor_separator_char = '=';
brdr_style.hor_separator_char = "=";
return ft_set_default_border_style(&brdr_style);
}