[A] Multiline cells
This commit is contained in:
parent
ac6533cd63
commit
859ff31b8a
@ -42,7 +42,8 @@ add_executable(TEST
|
||||
${FORT_SOURCES}
|
||||
tests/test.c
|
||||
tests/test_vector.c
|
||||
tests/test_table.c)
|
||||
tests/test_table.c
|
||||
tests/test_string_buffer.c)
|
||||
|
||||
target_link_libraries(TEST
|
||||
cmocka)
|
||||
|
@ -6,6 +6,8 @@ int main()
|
||||
{
|
||||
FTABLE *table = ft_create_table();
|
||||
|
||||
ft_set_column_alignment(table, 2, LeftAligned);
|
||||
|
||||
ft_hdr_printf_ln(table, "%d , %c|| %s|%f", 3, 'c', "234", 3.14);
|
||||
|
||||
const char *row[] = {"AAA", " ADf qwer", "qwerwqer", "11111 23333", "qwe"};
|
||||
@ -34,16 +36,10 @@ int main()
|
||||
ft_nwrite(table, 3, "123", "2345", "4567");
|
||||
ft_ln(table);
|
||||
|
||||
FT_NWRITE(table, "123", "345", "Anton", "Petr", "Pavel");
|
||||
FT_NWRITE_LN(table, "123", "132445\n123\n123", "Anton", "Petr", "Pavel");
|
||||
|
||||
fprintf(stderr, "Table:\n");
|
||||
fprintf(stderr, "%s\n", ft_to_string(table));
|
||||
|
||||
// printf("Hello, world!\n");
|
||||
// char buffer[3] = {'a', 'b', 'c'};
|
||||
// int ret = snprintf(buffer, 3, "so");
|
||||
// printf("result is %s = lent = %d\n", buffer, ret);
|
||||
// fprintf(stderr, "asd %d|", 3);
|
||||
// fprintf(stderr, "%d\n", 3.14);
|
||||
ft_destroy_table(table);
|
||||
}
|
||||
|
@ -183,6 +183,9 @@ static inline void fort_check_if_string_helper(const char*str)
|
||||
#define FT_NWRITE(table, ...)\
|
||||
(CHECK_IF_ARGS_ARE_STRINGS(__VA_ARGS__),ft_nwrite(table, PP_NARG(__VA_ARGS__), __VA_ARGS__))
|
||||
|
||||
#define FT_NWRITE_LN(table, ...)\
|
||||
(CHECK_IF_ARGS_ARE_STRINGS(__VA_ARGS__),ft_nwrite_ln(table, PP_NARG(__VA_ARGS__), __VA_ARGS__))
|
||||
|
||||
FORT_EXTERN int ft_nwrite(FTABLE *FORT_RESTRICT table, size_t n, const char* FORT_RESTRICT cell_content, ...);
|
||||
FORT_EXTERN int ft_nwrite_ln(FTABLE *FORT_RESTRICT table, size_t n, const char* FORT_RESTRICT cell_content, ...);
|
||||
|
||||
|
@ -83,12 +83,13 @@ int hint_height_cell(const fort_cell_t *cell, const context_t *context)
|
||||
|
||||
int cell_printf(fort_cell_t *cell, size_t row, size_t column, char *buf, size_t buf_len, const context_t *context)
|
||||
{
|
||||
if (cell == NULL || buf_len == 0 || row >= hint_height_cell(cell, context)
|
||||
if (cell == NULL || buf_len == 0
|
||||
|| (buf_len <= hint_width_cell(cell, context))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (row < context->cell_padding_top
|
||||
if (row >= hint_height_cell(cell, context)
|
||||
|| row < context->cell_padding_top
|
||||
|| row >= (context->cell_padding_top + buffer_text_height(cell->str_buffer))) {
|
||||
int k = snprint_n_chars(buf, buf_len, buf_len - 1, ' ');
|
||||
return k;
|
||||
|
@ -117,7 +117,8 @@ static int ft_row_printf_impl(FTABLE *FORT_RESTRICT table, size_t row, const cha
|
||||
}
|
||||
}
|
||||
}
|
||||
/* todo clearing pushed items in case of error */
|
||||
/* todo: clearing pushed items in case of error */
|
||||
/* todo: this function always create new row, this is not correct, it should be more complicated */
|
||||
|
||||
cur_row_p = (fort_row_t**)vector_at(table->rows, row);
|
||||
|
||||
|
@ -6,6 +6,61 @@
|
||||
* STRING BUFFER
|
||||
* ***************************************************************************/
|
||||
|
||||
size_t strchr_count(const char* str, char ch)
|
||||
{
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
|
||||
size_t count = 0;
|
||||
str = strchr(str, ch);
|
||||
while (str) {
|
||||
count++;
|
||||
str++;
|
||||
str = strchr(str, ch);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
const char* str_n_substring_beg(const char* str, char ch_separator, size_t n)
|
||||
{
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
|
||||
if (n == 0)
|
||||
return str;
|
||||
|
||||
str = strchr(str, ch_separator);
|
||||
--n;
|
||||
while (n > 0) {
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
--n;
|
||||
str++;
|
||||
str = strchr(str, ch_separator);
|
||||
}
|
||||
return str ? (str + 1) : NULL;
|
||||
}
|
||||
|
||||
void str_n_substring(const char* str, char ch_separator, size_t n, const char **begin, const char **end)
|
||||
{
|
||||
const char *beg = str_n_substring_beg(str, ch_separator, n);
|
||||
if (beg == NULL) {
|
||||
*begin = NULL;
|
||||
*end = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
const char *en = strchr(beg, ch_separator);
|
||||
if (en == NULL) {
|
||||
en = str + strlen(str);
|
||||
}
|
||||
|
||||
*begin = beg;
|
||||
*end = en;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
string_buffer_t* create_string_buffer(size_t sz)
|
||||
{
|
||||
string_buffer_t *result = (string_buffer_t *)F_MALLOC(sizeof(string_buffer_t));
|
||||
@ -72,15 +127,23 @@ size_t buffer_text_height(string_buffer_t *buffer)
|
||||
if (buffer == NULL || buffer->str == NULL || strlen(buffer->str) == 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
return 1 + strchr_count(buffer->str, '\n');
|
||||
}
|
||||
|
||||
size_t buffer_text_width(string_buffer_t *buffer)
|
||||
{
|
||||
if (buffer == NULL || buffer->str == NULL) {
|
||||
return 0;
|
||||
size_t max_length = 0;
|
||||
int n = 0;
|
||||
while (1) {
|
||||
const char *beg = NULL;
|
||||
const char *end = NULL;
|
||||
str_n_substring(buffer->str, '\n', n, &beg, &end);
|
||||
if (beg == NULL || end == NULL)
|
||||
return max_length;
|
||||
|
||||
max_length = MAX(max_length, (end - beg));
|
||||
++n;
|
||||
}
|
||||
return strlen(buffer->str);
|
||||
}
|
||||
|
||||
|
||||
@ -124,9 +187,47 @@ int buffer_printf(string_buffer_t *buffer, size_t buffer_row, size_t table_colum
|
||||
if (written < 0)
|
||||
return written;
|
||||
|
||||
written += snprintf(buf + written, buf_len - written, "%*s", (int)content_width, buffer->str);
|
||||
|
||||
|
||||
// const char *substr = str_n_substring(buffer->str, '\n', buffer_row);
|
||||
// if (substr == NULL)
|
||||
// return -1;
|
||||
// const char *next_substr = str_n_substring(buffer->str, '\n', buffer_row + 1);
|
||||
// size_t buf_row_len = 0;
|
||||
// if (next_substr) {
|
||||
// buf_row_len = next_substr - substr - 1;
|
||||
// } else {
|
||||
// buf_row_len = strlen(buffer->str) - (next_substr - buffer->str);
|
||||
// } todo
|
||||
// if (buf_row_len > content_width)
|
||||
// return -1;
|
||||
|
||||
// written += snprintf(buf + written, buf_len - written, "%*s", (int)buf_row_len, substr);
|
||||
// if (written < 0)
|
||||
// return written;
|
||||
// written += snprint_n_chars(buf + written, buf_len - written, content_width - buf_row_len, ' ');
|
||||
// if (written < 0)
|
||||
// return written;
|
||||
|
||||
const char *beg = NULL;
|
||||
const char *end = NULL;
|
||||
str_n_substring(buffer->str, '\n', buffer_row, &beg, &end);
|
||||
if (beg == NULL || end == NULL)
|
||||
return -1;
|
||||
char old_value = *end;
|
||||
*(char *)end = '\0';
|
||||
|
||||
written += snprintf(buf + written, buf_len - written, "%*s", (int)(end - beg), beg);
|
||||
*(char *)end = old_value;
|
||||
if (written < 0)
|
||||
return written;
|
||||
written += snprint_n_chars(buf + written, buf_len - written, (int)(content_width - (end - beg)), ' ');
|
||||
if (written < 0)
|
||||
return written;
|
||||
|
||||
// written += snprintf(buf + written, buf_len - written, "%*s", (int)content_width, buffer->str);
|
||||
// if (written < 0)
|
||||
// return written;
|
||||
|
||||
written += snprint_n_chars(buf + written, buf_len - written, right, ' ');
|
||||
return written;
|
||||
|
@ -7,7 +7,9 @@ int main(void) {
|
||||
cmocka_unit_test(test_table_sizes),
|
||||
cmocka_unit_test(test_table_geometry),
|
||||
cmocka_unit_test(test_table_basic),
|
||||
cmocka_unit_test(test_table_options)
|
||||
cmocka_unit_test(test_table_options),
|
||||
cmocka_unit_test(test_string_buffer),
|
||||
|
||||
};
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
||||
|
169
tests/test_string_buffer.c
Normal file
169
tests/test_string_buffer.c
Normal file
@ -0,0 +1,169 @@
|
||||
#include "tests.h"
|
||||
|
||||
#include "string_buffer.h"
|
||||
//#include "../src/fort.c"
|
||||
|
||||
size_t strchr_count(const char* str, int ch);
|
||||
const char* str_n_substring_beg(const char* str, int ch, int n);
|
||||
fort_status_t str_n_substring(const char* str, char ch_separator, size_t n, const char **begin, const char **end);
|
||||
size_t buffer_text_width(string_buffer_t *buffer);
|
||||
|
||||
|
||||
void test_strchr_count(void);
|
||||
void test_str_n_substring(void);
|
||||
void test_buffer_text_width(void);
|
||||
void test_buffer_text_height(void);
|
||||
|
||||
|
||||
void test_string_buffer(void **state)
|
||||
{
|
||||
(void)state;
|
||||
|
||||
test_strchr_count();
|
||||
test_str_n_substring();
|
||||
test_buffer_text_width();
|
||||
test_buffer_text_height();
|
||||
}
|
||||
|
||||
|
||||
void test_strchr_count(void)
|
||||
{
|
||||
assert_true(strchr_count(NULL, '\n') == 0);
|
||||
assert_true(strchr_count("", '\n') == 0);
|
||||
assert_true(strchr_count("asbd", '\n') == 0);
|
||||
|
||||
assert_true(strchr_count("asbd\n", '\n') == 1);
|
||||
assert_true(strchr_count("\nasbd", '\n') == 1);
|
||||
assert_true(strchr_count("a\nsbd", '\n') == 1);
|
||||
|
||||
assert_true(strchr_count("\n12\n123", '\n') == 2);
|
||||
assert_true(strchr_count("\n12\n123\n", '\n') == 3);
|
||||
assert_true(strchr_count("\n\n\n", '\n') == 3);
|
||||
assert_true(strchr_count("\n123123\n123123\n\n\n123", '\n') == 5);
|
||||
|
||||
assert_true(strchr_count("1a23123a123123aaa123", 'a') == 5);
|
||||
}
|
||||
|
||||
|
||||
void test_str_n_substring(void)
|
||||
{
|
||||
const char *empty_str = "";
|
||||
assert_true(str_n_substring_beg(empty_str, '\n', 0) == empty_str);
|
||||
assert_true(str_n_substring_beg(empty_str, '\n', 1) == NULL);
|
||||
assert_true(str_n_substring_beg(empty_str, '\n', 2) == NULL);
|
||||
|
||||
const char *str = "123\n5678\n9";
|
||||
assert_true(str_n_substring_beg(NULL, '\n', 0) == NULL);
|
||||
assert_true(str_n_substring_beg(str, '\n', 0) == str);
|
||||
assert_true(str_n_substring_beg(str, '1', 0) == str);
|
||||
|
||||
assert_true(str_n_substring_beg(str, '\n', 1) == str + 4);
|
||||
assert_true(str_n_substring_beg(str, '\n', 2) == str + 9);
|
||||
assert_true(str_n_substring_beg(str, '\n', 3) == NULL);
|
||||
|
||||
const char *str2 = "\n123\n56\n\n9\n";
|
||||
assert_true(str_n_substring_beg(str2, '\n', 0) == str2);
|
||||
assert_true(str_n_substring_beg(str2, '\n', 1) == str2 + 1);
|
||||
assert_true(str_n_substring_beg(str2, '\n', 2) == str2 + 5);
|
||||
assert_true(str_n_substring_beg(str2, '\n', 3) == str2 + 8);
|
||||
assert_true(str_n_substring_beg(str2, '\n', 4) == str2 + 9);
|
||||
assert_true(str_n_substring_beg(str2, '\n', 5) == str2 + 11);
|
||||
assert_true(str_n_substring_beg(str2, '\n', 6) == NULL);
|
||||
|
||||
const char *beg = NULL;
|
||||
const char *end = NULL;
|
||||
str_n_substring(empty_str, '\n', 0, &beg, &end);
|
||||
assert_true(beg == empty_str && end == empty_str + strlen(empty_str));
|
||||
str_n_substring(empty_str, '\n', 1, &beg, &end);
|
||||
assert_true(beg == NULL && end == NULL);
|
||||
str_n_substring(empty_str, '\n', 2, &beg, &end);
|
||||
assert_true(beg == NULL && end == NULL);
|
||||
|
||||
str_n_substring(NULL, '\n', 0, &beg, &end);
|
||||
assert_true(beg == NULL && end == NULL);
|
||||
str_n_substring(str, '\n', 0, &beg, &end);
|
||||
assert_true(beg == str && end == str + 3);
|
||||
str_n_substring(str, '2', 0, &beg, &end);
|
||||
assert_true(beg == str && end == str + 1);
|
||||
|
||||
str_n_substring(str, '\n', 1, &beg, &end);
|
||||
assert_true(beg == str +4 && end == str + 8);
|
||||
str_n_substring(str, '\n', 2, &beg, &end);
|
||||
assert_true(beg == str + 9 && end == str + strlen(str));
|
||||
str_n_substring(str, '\n', 3, &beg, &end);
|
||||
assert_true(beg == NULL && end == NULL);
|
||||
|
||||
|
||||
str_n_substring(str2, '\n', 0, &beg, &end);
|
||||
assert_true(beg == str2 && end == str2);
|
||||
str_n_substring(str2, '\n', 1, &beg, &end);
|
||||
assert_true(beg == str2 + 1 && end == str2 + 4);
|
||||
str_n_substring(str2, '\n', 2, &beg, &end);
|
||||
assert_true(beg == str2 + 5 && end == str2 + 7);
|
||||
str_n_substring(str2, '\n', 3, &beg, &end);
|
||||
assert_true(beg == str2 + 8 && end == str2 + 8);
|
||||
str_n_substring(str2, '\n', 4, &beg, &end);
|
||||
assert_true(beg == str2 + 9 && end == str2 + 10);
|
||||
str_n_substring(str2, '\n', 5, &beg, &end);
|
||||
assert_true(beg == str2 + 11 && end == str2 + 11);
|
||||
str_n_substring(str2, '\n', 6, &beg, &end);
|
||||
assert_true(beg == NULL && end == NULL);
|
||||
}
|
||||
|
||||
void test_buffer_text_width(void)
|
||||
{
|
||||
string_buffer_t *buffer = create_string_buffer(200);
|
||||
char *old_value = buffer->str;
|
||||
|
||||
buffer->str = "";
|
||||
assert_true(buffer_text_width(buffer) == 0);
|
||||
|
||||
buffer->str = "\n\n\n\n";
|
||||
assert_true(buffer_text_width(buffer) == 0);
|
||||
|
||||
buffer->str = "12345";
|
||||
assert_true(buffer_text_width(buffer) == 5);
|
||||
|
||||
buffer->str = "12345\n1234567";
|
||||
assert_true(buffer_text_width(buffer) == 7);
|
||||
|
||||
buffer->str = "12345\n1234567\n";
|
||||
assert_true(buffer_text_width(buffer) == 7);
|
||||
|
||||
buffer->str = "12345\n1234567\n123";
|
||||
assert_true(buffer_text_width(buffer) == 7);
|
||||
|
||||
buffer->str = old_value;
|
||||
destroy_string_buffer(buffer);
|
||||
}
|
||||
|
||||
|
||||
void test_buffer_text_height(void)
|
||||
{
|
||||
string_buffer_t *buffer = create_string_buffer(200);
|
||||
char *old_value = buffer->str;
|
||||
|
||||
buffer->str = "";
|
||||
assert_true(buffer_text_height(buffer) == 0);
|
||||
|
||||
buffer->str = "\n";
|
||||
assert_true(buffer_text_height(buffer) == 2);
|
||||
|
||||
buffer->str = "\n\n";
|
||||
assert_true(buffer_text_height(buffer) == 3);
|
||||
|
||||
buffer->str = "\n\n\n\n";
|
||||
assert_true(buffer_text_height(buffer) == 5);
|
||||
|
||||
buffer->str = "12345";
|
||||
assert_true(buffer_text_height(buffer) == 1);
|
||||
|
||||
buffer->str = "\n12345";
|
||||
assert_true(buffer_text_height(buffer) == 2);
|
||||
|
||||
buffer->str = "\n12345\n\n2";
|
||||
assert_true(buffer_text_height(buffer) == 4);
|
||||
|
||||
buffer->str = old_value;
|
||||
destroy_string_buffer(buffer);
|
||||
}
|
@ -94,9 +94,12 @@ void test_table_geometry(void **state)
|
||||
void test_table_basic(void **state)
|
||||
{
|
||||
(void)state;
|
||||
FTABLE *table = ft_create_table();
|
||||
|
||||
FTABLE *table = NULL;
|
||||
|
||||
WHEN("All columns are equal and not empty") {
|
||||
table = ft_create_table();
|
||||
|
||||
int n = FT_HDR_PRINTF_LN(table, "%d|%c|%s|%f", 3, 'c', "234", 3.14);
|
||||
assert_true( n == 4 );
|
||||
n = FT_PRINTF_LN(table, 1, "%d|%c|%s|%f", 3, 'c', "234", 3.14);
|
||||
@ -611,4 +614,41 @@ void test_table_options(void **state)
|
||||
|
||||
ft_destroy_table(table);
|
||||
}
|
||||
|
||||
WHEN("All columns are equal and not empty") {
|
||||
table = ft_create_table();
|
||||
|
||||
int n = FT_HDR_PRINTF_LN(table, "%d|%c|%s|%f", 3, 'c', "234", 3.14);
|
||||
assert_true( n == 4 );
|
||||
// n = FT_PRINTF_LN(table, 1, "%d|%c|%s|%f", 3, 'c', "234\n123", 3.14);
|
||||
// assert_true( n == 4 );
|
||||
// FT_NWRITE_LN(table, "3", "c", "234", "3.140000");
|
||||
FT_NWRITE_LN(table, "3", "c", "234\n12", "3.140000");
|
||||
n = FT_PRINTF_LN(table, 2, "%d|%c|%s|%f", 3, 'c', "234", 3.14);
|
||||
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 | c | 234 | 3.140000 |\n"
|
||||
"| | | | |\n"
|
||||
"+---+---+-----+----------+\n"
|
||||
"| | | | |\n"
|
||||
"| 3 | c | 234 | 3.140000 |\n"
|
||||
"| | | 12 | |\n"
|
||||
"| | | | |\n"
|
||||
"+---+---+-----+----------+\n"
|
||||
"| | | | |\n"
|
||||
"| 3 | c | 234 | 3.140000 |\n"
|
||||
"| | | | |\n"
|
||||
"+---+---+-----+----------+\n";
|
||||
// fprintf(stderr, "content:\n%s", table_str);
|
||||
|
||||
assert_true( strcmp(table_str, table_str_etalon) == 0);
|
||||
|
||||
ft_destroy_table(table);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ void test_table_sizes(void **state);
|
||||
void test_table_geometry(void **state);
|
||||
void test_table_basic(void **state);
|
||||
void test_table_options(void **state);
|
||||
void test_string_buffer(void **state);
|
||||
|
||||
|
||||
#endif // TESTS_H
|
||||
|
Loading…
Reference in New Issue
Block a user