[A] Added wprintf

This commit is contained in:
seleznevae 2018-04-24 21:36:07 +03:00
parent f8e8793565
commit efa4921b3e
9 changed files with 341 additions and 31 deletions

View File

@ -594,6 +594,10 @@ FT_EXTERN void ft_set_memory_funcs(void *(*f_malloc)(size_t size), void (*f_free
#ifdef FT_HAVE_WCHAR #ifdef FT_HAVE_WCHAR
FT_EXTERN int ft_wprintf(FTABLE *table, const wchar_t *fmt, ...);
FT_EXTERN int ft_wprintf_ln(FTABLE *table, const wchar_t *fmt, ...);
#define ft_wwrite(table, ...)\ #define ft_wwrite(table, ...)\
(0 ? CHECK_IF_ARGS_ARE_WSTRINGS(__VA_ARGS__) : ft_nwwrite(table, PP_NARG(__VA_ARGS__), __VA_ARGS__)) (0 ? CHECK_IF_ARGS_ARE_WSTRINGS(__VA_ARGS__) : ft_nwwrite(table, PP_NARG(__VA_ARGS__), __VA_ARGS__))
#define ft_wwrite_ln(table, ...)\ #define ft_wwrite_ln(table, ...)\

View File

@ -135,6 +135,7 @@ clear:
return -1; return -1;
} }
#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) 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' '; wchar_t space_char = L' ';
@ -175,6 +176,7 @@ int cell_wprintf(fort_cell_t *cell, size_t row, wchar_t *buf, size_t buf_len, co
clear: clear:
return -1; return -1;
} }
#endif
fort_status_t fill_cell_from_string(fort_cell_t *cell, const char *str) fort_status_t fill_cell_from_string(fort_cell_t *cell, const char *str)
@ -185,6 +187,17 @@ fort_status_t fill_cell_from_string(fort_cell_t *cell, const char *str)
return fill_buffer_from_string(cell->str_buffer, str); return fill_buffer_from_string(cell->str_buffer, str);
} }
#ifdef FT_HAVE_WCHAR
fort_status_t fill_cell_from_wstring(fort_cell_t *cell, const wchar_t *str)
{
assert(str);
assert(cell);
return fill_buffer_from_wstring(cell->str_buffer, str);
}
#endif
string_buffer_t *cell_get_string_buffer(fort_cell_t *cell) string_buffer_t *cell_get_string_buffer(fort_cell_t *cell)
{ {
assert(cell); assert(cell);

View File

@ -24,11 +24,13 @@ size_t hint_height_cell(const fort_cell_t *cell, const context_t *context);
/* static int lines_number_cell(fort_cell_t *cell); */ /* 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); int cell_printf(fort_cell_t *cell, size_t row, char *buf, size_t buf_len, const context_t *context);
int cell_wprintf(fort_cell_t *cell, size_t row, wchar_t *buf, size_t buf_len, const context_t *context);
fort_status_t fill_cell_from_string(fort_cell_t *cell, const char *str); fort_status_t fill_cell_from_string(fort_cell_t *cell, const char *str);
#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);
fort_status_t fill_cell_from_wstring(fort_cell_t *cell, const wchar_t *str);
#endif
string_buffer_t* cell_get_string_buffer(fort_cell_t *cell); string_buffer_t* cell_get_string_buffer(fort_cell_t *cell);
#endif /* CELL_H */ #endif /* CELL_H */

View File

@ -127,13 +127,14 @@ void ft_set_cur_cell(FTABLE *table, size_t row, size_t col)
static int ft_row_printf_impl(FTABLE *table, size_t row, const char *fmt, va_list *va) static int ft_row_printf_impl(FTABLE *table, size_t row, const char *fmt, va_list *va)
{ {
#define CREATE_ROW_FROM_FMT_STRING create_row_from_fmt_string
size_t i = 0; size_t i = 0;
size_t new_cols = 0; size_t new_cols = 0;
if (table == NULL) if (table == NULL)
return -1; return -1;
fort_row_t *new_row = create_row_from_fmt_string(fmt, va); fort_row_t *new_row = CREATE_ROW_FROM_FMT_STRING(fmt, va);
if (new_row == NULL) { if (new_row == NULL) {
return -1; return -1;
@ -167,8 +168,56 @@ static int ft_row_printf_impl(FTABLE *table, size_t row, const char *fmt, va_lis
clear: clear:
destroy_row(new_row); destroy_row(new_row);
return -1; return -1;
#undef CREATE_ROW_FROM_FMT_STRING
} }
#ifdef FT_HAVE_WCHAR
static int ft_row_wprintf_impl(FTABLE *table, size_t row, const wchar_t *fmt, va_list *va)
{
#define CREATE_ROW_FROM_FMT_STRING create_row_from_fmt_wstring
size_t i = 0;
size_t new_cols = 0;
if (table == NULL)
return -1;
fort_row_t *new_row = CREATE_ROW_FROM_FMT_STRING(fmt, va);
if (new_row == NULL) {
return -1;
}
fort_row_t **cur_row_p = NULL;
size_t sz = vector_size(table->rows);
if (row >= sz) {
size_t push_n = row - sz + 1;
for (i = 0; i < push_n; ++i) {
fort_row_t *padding_row = create_row();
if (padding_row == NULL)
goto clear;
if (IS_ERROR(vector_push(table->rows, &padding_row))) {
destroy_row(padding_row);
goto clear;
}
}
}
/* todo: clearing pushed items in case of error ?? */
new_cols = columns_in_row(new_row);
cur_row_p = (fort_row_t **)vector_at(table->rows, row);
swap_row(*cur_row_p, new_row, table->cur_col);
table->cur_col += new_cols;
destroy_row(new_row);
return new_cols;
clear:
destroy_row(new_row);
return -1;
#undef CREATE_ROW_FROM_FMT_STRING
}
#endif
#if defined(FT_CLANG_COMPILER) || defined(FT_GCC_COMPILER) #if defined(FT_CLANG_COMPILER) || defined(FT_GCC_COMPILER)
#define FT_PRINTF ft_printf #define FT_PRINTF ft_printf
@ -208,6 +257,32 @@ int FT_PRINTF_LN(FTABLE *table, const char *fmt, ...)
#undef FT_HDR_PRINTF #undef FT_HDR_PRINTF
#undef FT_HDR_PRINTF_LN #undef FT_HDR_PRINTF_LN
#ifdef FT_HAVE_WCHAR
int ft_wprintf(FTABLE *table, const wchar_t *fmt, ...)
{
assert(table);
va_list va;
va_start(va, fmt);
int result = ft_row_wprintf_impl(table, table->cur_row, fmt, &va);
va_end(va);
return result;
}
int ft_wprintf_ln(FTABLE *table, const wchar_t *fmt, ...)
{
assert(table);
va_list va;
va_start(va, fmt);
int result = ft_row_wprintf_impl(table, table->cur_row, fmt, &va);
if (result >= 0) {
ft_ln(table);
}
va_end(va);
return result;
}
#endif
static int ft_write_impl(FTABLE *table, const char *cell_content) static int ft_write_impl(FTABLE *table, const char *cell_content)
{ {

View File

@ -140,6 +140,22 @@ size_t number_of_columns_in_format_string(const char *fmt)
return separator_counter + 1; return separator_counter + 1;
} }
size_t number_of_columns_in_format_wstring(const wchar_t *fmt)
{
int separator_counter = 0;
const wchar_t *pos = fmt;
while (1) {
pos = wcschr(pos, FORT_COL_SEPARATOR);
if (pos == NULL)
break;
separator_counter++;
++pos;
}
return separator_counter + 1;
}
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) if (length <= n)

View File

@ -116,6 +116,7 @@ void set_memory_funcs(void *(*f_malloc)(size_t size), void (*f_free)(void *ptr))
char *fort_strdup(const char* str); char *fort_strdup(const char* str);
wchar_t *fort_wcsdup(const wchar_t* 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_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 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 wsnprint_n_chars(wchar_t *buf, size_t length, size_t n, wchar_t ch);

186
src/row.c
View File

@ -338,8 +338,15 @@ clear:
fort_row_t *create_row_from_string(const char *str) fort_row_t *create_row_from_string(const char *str)
{ {
char *pos = NULL; typedef char char_type;
char *base_pos = NULL; char_type *(*strdup_)(const char_type * str) = F_STRDUP;
const char_type zero_char = '\0';
fort_status_t (*fill_cell_from_string_)(fort_cell_t *cell, const char *str) = fill_cell_from_string;
const char_type *const zero_string = "";
#define STRCHR strchr
char_type *pos = NULL;
char_type *base_pos = NULL;
unsigned int number_of_separators = 0; unsigned int number_of_separators = 0;
fort_row_t *row = create_row(); fort_row_t *row = create_row();
@ -349,7 +356,7 @@ fort_row_t *create_row_from_string(const char *str)
if (str == NULL) if (str == NULL)
return row; return row;
char *str_copy = F_STRDUP(str); char_type *str_copy = strdup_(str);
if (str_copy == NULL) if (str_copy == NULL)
goto clear; goto clear;
@ -357,9 +364,9 @@ fort_row_t *create_row_from_string(const char *str)
base_pos = str_copy; base_pos = str_copy;
number_of_separators = 0; number_of_separators = 0;
while (*pos) { while (*pos) {
pos = strchr(pos, FORT_COL_SEPARATOR); pos = STRCHR(pos, FORT_COL_SEPARATOR);
if (pos != NULL) { if (pos != NULL) {
*(pos) = '\0'; *(pos) = zero_char;
++pos; ++pos;
number_of_separators++; number_of_separators++;
} }
@ -368,8 +375,7 @@ fort_row_t *create_row_from_string(const char *str)
if (cell == NULL) if (cell == NULL)
goto clear; goto clear;
/* int status = fill_buffer_from_string(cell->str_buffer, base_pos); */ int status = fill_cell_from_string_(cell, base_pos);
int status = fill_cell_from_string(cell, base_pos);
if (IS_ERROR(status)) { if (IS_ERROR(status)) {
destroy_cell(cell); destroy_cell(cell);
goto clear; goto clear;
@ -392,8 +398,7 @@ fort_row_t *create_row_from_string(const char *str)
if (cell == NULL) if (cell == NULL)
goto clear; goto clear;
/* int status = fill_buffer_from_string(cell->str_buffer, ""); */ int status = fill_cell_from_string_(cell, zero_string);
int status = fill_cell_from_string(cell, "");
if (IS_ERROR(status)) { if (IS_ERROR(status)) {
destroy_cell(cell); destroy_cell(cell);
goto clear; goto clear;
@ -413,24 +418,117 @@ clear:
destroy_row(row); destroy_row(row);
F_FREE(str_copy); F_FREE(str_copy);
return NULL; return NULL;
#undef STRCHR
} }
#ifdef FT_HAVE_WCHAR
fort_row_t *create_row_from_wstring(const wchar_t *str)
{
typedef wchar_t char_type;
char_type *(*strdup_)(const char_type * str) = F_WCSDUP;
const char_type zero_char = L'\0';
fort_status_t (*fill_cell_from_string_)(fort_cell_t *cell, const wchar_t *str) = fill_cell_from_wstring;
const char_type *const zero_string = L"";
#define STRCHR wcschr
char_type *pos = NULL;
char_type *base_pos = NULL;
unsigned int number_of_separators = 0;
fort_row_t *row = create_row();
if (row == NULL)
return NULL;
if (str == NULL)
return row;
char_type *str_copy = strdup_(str);
if (str_copy == NULL)
goto clear;
pos = str_copy;
base_pos = str_copy;
number_of_separators = 0;
while (*pos) {
pos = STRCHR(pos, FORT_COL_SEPARATOR);
if (pos != NULL) {
*(pos) = zero_char;
++pos;
number_of_separators++;
}
fort_cell_t *cell = create_cell();
if (cell == NULL)
goto clear;
int status = fill_cell_from_string_(cell, base_pos);
if (IS_ERROR(status)) {
destroy_cell(cell);
goto clear;
}
status = vector_push(row->cells, &cell);
if (IS_ERROR(status)) {
destroy_cell(cell);
goto clear;
}
if (pos == NULL)
break;
base_pos = pos;
}
/* special case if in format string last cell is empty */
while (vector_size(row->cells) < (number_of_separators + 1)) {
fort_cell_t *cell = create_cell();
if (cell == NULL)
goto clear;
int status = fill_cell_from_string_(cell, zero_string);
if (IS_ERROR(status)) {
destroy_cell(cell);
goto clear;
}
status = vector_push(row->cells, &cell);
if (IS_ERROR(status)) {
destroy_cell(cell);
goto clear;
}
}
F_FREE(str_copy);
return row;
clear:
destroy_row(row);
F_FREE(str_copy);
return NULL;
#undef STRCHR
}
#endif
fort_row_t *create_row_from_fmt_string(const char *fmt, va_list *va_args) fort_row_t *create_row_from_fmt_string(const char *fmt, va_list *va_args)
{ {
#define VSNPRINTF vsnprintf
#define STR_FILED cstr
#define CREATE_ROW_FROM_STRING create_row_from_string
#define NUMBER_OF_COLUMNS_IN_FORMAT_STRING number_of_columns_in_format_string
string_buffer_t *buffer = create_string_buffer(DEFAULT_STR_BUF_SIZE, CharBuf); string_buffer_t *buffer = create_string_buffer(DEFAULT_STR_BUF_SIZE, CharBuf);
if (buffer == NULL) if (buffer == NULL)
return NULL; return NULL;
size_t cols_origin = number_of_columns_in_format_string(fmt); size_t cols_origin = NUMBER_OF_COLUMNS_IN_FORMAT_STRING(fmt);
size_t cols = 0; size_t cols = 0;
while (1) { while (1) {
va_list va; va_list va;
va_copy(va, *va_args); va_copy(va, *va_args);
int virtual_sz = vsnprintf(buffer->str.cstr, string_buffer_capacity(buffer), fmt, va); int virtual_sz = VSNPRINTF(buffer->str.STR_FILED, string_buffer_capacity(buffer), fmt, va);
va_end(va); va_end(va);
/* If error encountered */ /* If error encountered */
if (virtual_sz < 0) if (virtual_sz < 0)
@ -445,10 +543,10 @@ fort_row_t *create_row_from_fmt_string(const char *fmt, va_list *va_args)
goto clear; goto clear;
} }
cols = number_of_columns_in_format_string(buffer->str.cstr); cols = NUMBER_OF_COLUMNS_IN_FORMAT_STRING(buffer->str.STR_FILED);
if (cols == cols_origin) { if (cols == cols_origin) {
fort_row_t *row = create_row_from_string(buffer->str.cstr); fort_row_t *row = CREATE_ROW_FROM_STRING(buffer->str.STR_FILED);
if (row == NULL) { if (row == NULL) {
goto clear; goto clear;
} }
@ -462,8 +560,70 @@ fort_row_t *create_row_from_fmt_string(const char *fmt, va_list *va_args)
clear: clear:
destroy_string_buffer(buffer); destroy_string_buffer(buffer);
return NULL; return NULL;
#undef VSNPRINTF
#undef STR_FILED
#undef CREATE_ROW_FROM_STRING
#undef NUMBER_OF_COLUMNS_IN_FORMAT_STRING
} }
#ifdef FT_HAVE_WCHAR
fort_row_t *create_row_from_fmt_wstring(const wchar_t *fmt, va_list *va_args)
{
#define VSNPRINTF vswprintf
#define STR_FILED wstr
#define CREATE_ROW_FROM_STRING create_row_from_wstring
#define NUMBER_OF_COLUMNS_IN_FORMAT_STRING number_of_columns_in_format_wstring
string_buffer_t *buffer = create_string_buffer(DEFAULT_STR_BUF_SIZE, CharBuf);
if (buffer == NULL)
return NULL;
size_t cols_origin = NUMBER_OF_COLUMNS_IN_FORMAT_STRING(fmt);
size_t cols = 0;
while (1) {
va_list va;
va_copy(va, *va_args);
int virtual_sz = VSNPRINTF(buffer->str.STR_FILED, string_buffer_capacity(buffer), fmt, va);
va_end(va);
/* If error encountered */
if (virtual_sz < 0)
goto clear;
/* Successful write */
if ((size_t)virtual_sz < string_buffer_capacity(buffer))
break;
/* Otherwise buffer was too small, so incr. buffer size ant try again. */
if (!IS_SUCCESS(realloc_string_buffer_without_copy(buffer)))
goto clear;
}
cols = NUMBER_OF_COLUMNS_IN_FORMAT_STRING(buffer->str.STR_FILED);
if (cols == cols_origin) {
fort_row_t *row = CREATE_ROW_FROM_STRING(buffer->str.STR_FILED);
if (row == NULL) {
goto clear;
}
destroy_string_buffer(buffer);
return row;
}
/* todo: add processing of cols != cols_origin */
clear:
destroy_string_buffer(buffer);
return NULL;
#undef VSNPRINTF
#undef STR_FILED
#undef CREATE_ROW_FROM_STRING
#undef NUMBER_OF_COLUMNS_IN_FORMAT_STRING
}
#endif
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, 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) size_t row_height, const context_t *context)

View File

@ -6,17 +6,12 @@
#include "stdarg.h" #include "stdarg.h"
#include "options.h" #include "options.h"
#ifdef FT_HAVE_WCHAR
#include <wchar.h>
#endif
struct fort_row; struct fort_row;
typedef struct fort_row fort_row_t; typedef struct fort_row fort_row_t;
/*
enum ft_row_type
{
FT_ROW_COMMON,
FT_ROW_HEADER
};
*/
fort_row_t * create_row(void); fort_row_t * create_row(void);
void destroy_row(fort_row_t *row); void destroy_row(fort_row_t *row);
@ -40,11 +35,7 @@ int print_row_separator(char *buffer, size_t buffer_sz,
enum HorSeparatorPos separatorPos, const separator_t *sep, enum HorSeparatorPos separatorPos, const separator_t *sep,
const context_t *context); const context_t *context);
int wprint_row_separator(wchar_t *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 separator_t *sep,
const context_t *context);
@ -52,8 +43,19 @@ int wprint_row_separator(wchar_t *buffer, size_t buffer_sz,
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, 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); size_t row_height, const context_t *context);
#ifdef FT_HAVE_WCHAR
fort_row_t *create_row_from_wstring(const wchar_t *str);
fort_row_t* create_row_from_fmt_wstring(const wchar_t* fmt, va_list *va_args);
int wprint_row_separator(wchar_t *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 separator_t *sep,
const context_t *context);
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, 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); size_t row_height, const context_t *context);
#endif
#endif /* ROW_H */ #endif /* ROW_H */

View File

@ -658,8 +658,45 @@ void test_table_write(void)
ft_destroy_table(table); ft_destroy_table(table);
} }
#ifdef FT_HAVE_WCHAR
SCENARIO("Test printf functions(wide strings)") { SCENARIO("Test printf functions(wide strings)") {
/* todo: need to implement */ table = ft_create_table();
assert_true(table != NULL);
assert_true(set_test_options_for_table(table) == FT_SUCCESS);
ft_set_cell_option(table, 0, FT_ANY_COLUMN, FT_COPT_ROW_TYPE, FT_ROW_HEADER);
int n = ft_wprintf_ln(table, L"%d|%c|%s|%f", 3, 'c', "234", 3.14);
assert_true(n == 4);
n = ft_wprintf(table, L"%c|%s|%f|%d", 'c', "235", 3.15, 5);
assert_true(n == 4);
ft_ln(table);
n = ft_wprintf_ln(table, L"%s|%f|%d|%c", "234", 3.14, 3, 'c');
assert_true(n == 4);
/* Replace old values */
ft_set_cur_cell(table, 1, 1);
n = ft_wprintf_ln(table, L"%s|%f|%d", "234", 3.14, 3);
assert_true(n == 3);
const wchar_t *table_str = ft_to_wstring(table);
assert_true(table_str != NULL);
const wchar_t *table_str_etalon =
L"+-----+----------+----------+----------+\n"
L"| | | | |\n"
L"| 3 | c | 234 | 3.140000 |\n"
L"| | | | |\n"
L"+-----+----------+----------+----------+\n"
L"| | | | |\n"
L"| c | 234 | 3.140000 | 3 |\n"
L"| | | | |\n"
L"+-----+----------+----------+----------+\n"
L"| | | | |\n"
L"| 234 | 3.140000 | 3 | c |\n"
L"| | | | |\n"
L"+-----+----------+----------+----------+\n";
assert_wcs_equal(table_str, table_str_etalon);
ft_destroy_table(table);
} }
#endif
} }