diff --git a/docs/Doxyfile b/docs/Doxyfile index 01cbfb6..7e9bdbc 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -2100,7 +2100,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = FT_GCC_COMPILER # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/docs/index.md b/docs/index.md index 6af72fc..3a5d675 100644 --- a/docs/index.md +++ b/docs/index.md @@ -38,6 +38,7 @@ These pages contain the API documentation of **libfort** - simple library to cre - Others - @link ft_set_memory_funcs ft_set_memory_funcs @endlink -- set memory allocation functions for the library + - @link ft_set_default_printf_field_separator ft_set_default_printf_field_separator @endlink -- Set field separator for ft_printf, ft_printf_ln - Data structures and types - @link ft_table_t ft_table_t @endlink -- table handler diff --git a/lib/fort.c b/lib/fort.c index e470ce3..aaf96f7 100644 --- a/lib/fort.c +++ b/lib/fort.c @@ -59,7 +59,8 @@ SOFTWARE. #endif /* FT_AMALGAMED_SORCE */ -#define FORT_COL_SEPARATOR '|' +#define FORT_DEFAULT_COL_SEPARATOR '|' +extern char g_col_separator; #define FORT_COL_SEPARATOR_LENGTH 1 @@ -1484,6 +1485,11 @@ int ft_wprintf_ln(ft_table_t *table, const wchar_t *fmt, ...) #endif +void ft_set_default_printf_field_separator(char separator) +{ + g_col_separator = separator; +} + static int ft_write_impl(ft_table_t *table, const char *cell_content) { @@ -2180,6 +2186,7 @@ int ft_set_cell_span(ft_table_t *table, size_t row, size_t col, size_t hor_span) #endif +char g_col_separator = FORT_DEFAULT_COL_SEPARATOR; /***************************************************************************** * LIBFORT helpers @@ -2315,7 +2322,7 @@ size_t number_of_columns_in_format_string(const char *fmt) size_t separator_counter = 0; const char *pos = fmt; while (1) { - pos = strchr(pos, FORT_COL_SEPARATOR); + pos = strchr(pos, g_col_separator); if (pos == NULL) break; @@ -2333,7 +2340,7 @@ size_t number_of_columns_in_format_wstring(const wchar_t *fmt) size_t separator_counter = 0; const wchar_t *pos = fmt; while (1) { - pos = wcschr(pos, FORT_COL_SEPARATOR); + pos = wcschr(pos, g_col_separator); if (pos == NULL) break; @@ -4145,7 +4152,7 @@ fort_row_t *create_row_from_string(const char *str) base_pos = str_copy; number_of_separators = 0; while (*pos) { - pos = STRCHR(pos, FORT_COL_SEPARATOR); + pos = STRCHR(pos, g_col_separator); if (pos != NULL) { *(pos) = zero_char; ++pos; @@ -4234,7 +4241,7 @@ fort_row_t *create_row_from_wstring(const wchar_t *str) base_pos = str_copy; number_of_separators = 0; while (*pos) { - pos = STRCHR(pos, FORT_COL_SEPARATOR); + pos = STRCHR(pos, g_col_separator); if (pos != NULL) { *(pos) = zero_char; ++pos; diff --git a/lib/fort.h b/lib/fort.h index fd970a6..897c838 100644 --- a/lib/fort.h +++ b/lib/fort.h @@ -313,8 +313,9 @@ void ft_set_cur_cell(ft_table_t *table, size_t row, size_t col); * the data. The format string consists of ordinary characters (except % and |), * which are copied unchanged into the output stream, and conversion * specifications. Conversion specifications are the same as for standard - * printf function. Character '|' in the format string is treated as a cell - * separator. + * printf function. Character '|' (wich can be changed with + * {@link ft_set_default_printf_field_separator}) in the format string is treated as + * a cell separator. * @param ... * Arguments specifying data to print. Similarly to standard printf-like * functions if any argument after default conversions is not the type @@ -339,8 +340,9 @@ int ft_printf(ft_table_t *table, const char *fmt, ...) FT_PRINTF_ATTRIBUTE_FORMA * the data. The format string consists of ordinary characters (except % and |), * which are copied unchanged into the output stream, and conversion * specifications. Conversion specifications are the same as for standard - * printf function. Character '|' in the format string is treated as a cell - * separator. + * printf function. Character '|' (wich can be changed with + * {@link ft_set_default_printf_field_separator}) in the format string is treated as + * a cell separator. * @param ... * Arguments specifying data to print. Similarly to standard printf-like * functions if any argument after default conversions is not the type @@ -373,6 +375,15 @@ int ft_printf_ln_impl(ft_table_t *table, const char *fmt, ...) FT_PRINTF_ATTRIBU */ #endif +/** + * Set field separator for {@link ft_printf}, {@link ft_printf_ln} + * (default separator is '|'). + * + * @param separator + * New separator. + */ +void ft_set_default_printf_field_separator(char separator); + /** * Write strings to the table. diff --git a/src/fort_impl.c b/src/fort_impl.c index 6360dae..5a457ac 100644 --- a/src/fort_impl.c +++ b/src/fort_impl.c @@ -324,6 +324,11 @@ int ft_wprintf_ln(ft_table_t *table, const wchar_t *fmt, ...) #endif +void ft_set_default_printf_field_separator(char separator) +{ + g_col_separator = separator; +} + static int ft_write_impl(ft_table_t *table, const char *cell_content) { diff --git a/src/fort_utils.c b/src/fort_utils.c index a59b342..f1f69ef 100644 --- a/src/fort_utils.c +++ b/src/fort_utils.c @@ -4,6 +4,7 @@ #endif +char g_col_separator = FORT_DEFAULT_COL_SEPARATOR; /***************************************************************************** * LIBFORT helpers @@ -139,7 +140,7 @@ size_t number_of_columns_in_format_string(const char *fmt) size_t separator_counter = 0; const char *pos = fmt; while (1) { - pos = strchr(pos, FORT_COL_SEPARATOR); + pos = strchr(pos, g_col_separator); if (pos == NULL) break; @@ -157,7 +158,7 @@ size_t number_of_columns_in_format_wstring(const wchar_t *fmt) size_t separator_counter = 0; const wchar_t *pos = fmt; while (1) { - pos = wcschr(pos, FORT_COL_SEPARATOR); + pos = wcschr(pos, g_col_separator); if (pos == NULL) break; diff --git a/src/fort_utils.h b/src/fort_utils.h index f1a2692..d3afb62 100644 --- a/src/fort_utils.h +++ b/src/fort_utils.h @@ -22,7 +22,8 @@ #endif /* FT_AMALGAMED_SORCE */ -#define FORT_COL_SEPARATOR '|' +#define FORT_DEFAULT_COL_SEPARATOR '|' +extern char g_col_separator; #define FORT_COL_SEPARATOR_LENGTH 1 diff --git a/src/row.c b/src/row.c index 0537651..649b341 100644 --- a/src/row.c +++ b/src/row.c @@ -629,7 +629,7 @@ fort_row_t *create_row_from_string(const char *str) base_pos = str_copy; number_of_separators = 0; while (*pos) { - pos = STRCHR(pos, FORT_COL_SEPARATOR); + pos = STRCHR(pos, g_col_separator); if (pos != NULL) { *(pos) = zero_char; ++pos; @@ -718,7 +718,7 @@ fort_row_t *create_row_from_wstring(const wchar_t *str) base_pos = str_copy; number_of_separators = 0; while (*pos) { - pos = STRCHR(pos, FORT_COL_SEPARATOR); + pos = STRCHR(pos, g_col_separator); if (pos != NULL) { *(pos) = zero_char; ++pos; diff --git a/tests/bb_tests/test_table_basic.c b/tests/bb_tests/test_table_basic.c index ace5053..7dde6be 100644 --- a/tests/bb_tests/test_table_basic.c +++ b/tests/bb_tests/test_table_basic.c @@ -865,6 +865,90 @@ void test_table_write(void) } #endif + SCENARIO("Test printf functions with custom separator") { + ft_set_default_printf_field_separator('$'); + table = ft_create_table(); + assert_true(table != NULL); + assert_true(set_test_props_for_table(table) == FT_SUCCESS); + + ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER); + int n = ft_printf_ln(table, "%d$%c$%s$%f", 3, 'c', "234", 3.14); + assert_true(n == 4); + n = ft_printf(table, "%c$%s$%f$%d", 'c', "235", 3.15, 5); + assert_true(n == 4); + ft_ln(table); + n = ft_printf_ln(table, "%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_printf(table, "%s$%f$%d", "234", 3.14, 3); + assert_true(n == 3); + + const char *table_str = ft_to_string(table); + assert_true(table_str != NULL); + const char *table_str_etalon = + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| 3 | c | 234 | 3.140000 |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| c | 234 | 3.140000 | 3 |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n" + "| | | | |\n" + "| 234 | 3.140000 | 3 | c |\n" + "| | | | |\n" + "+-----+----------+----------+----------+\n"; + assert_str_equal(table_str, table_str_etalon); + ft_destroy_table(table); + ft_set_default_printf_field_separator('|'); + } + +#ifdef FT_HAVE_WCHAR + SCENARIO("Test printf functions(wide strings) with custom separator") { + ft_set_default_printf_field_separator('$'); + table = ft_create_table(); + assert_true(table != NULL); + assert_true(set_test_props_for_table(table) == FT_SUCCESS); + + ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER); + int n = ft_wprintf_ln(table, L"%d$%c$%ls$%f", 3, 'c', L"234", 3.14); + assert_true(n == 4); + n = ft_wprintf(table, L"%c$%ls$%f$%d", 'c', L"235", 3.15, 5); + assert_true(n == 4); + ft_ln(table); + n = ft_wprintf_ln(table, L"%ls$%f$%d$%c", L"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"%ls$%f$%d", L"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); + ft_set_default_printf_field_separator('|'); + } +#endif + }