seleznevae / libfort Goto Github PK
View Code? Open in Web Editor NEWC/C++ library to create formatted ASCII tables for console applications
License: MIT License
C/C++ library to create formatted ASCII tables for console applications
License: MIT License
Any Fix?
[atta@atta-pc APP]$ g++ app.cpp -std=c++11
/usr/bin/ld: /tmp/ccgEbx1a.o: in function fort::table<(fort::table_type)0>::table()': app.cpp:(.text._ZN4fort5tableILNS_10table_typeE0EEC2Ev[_ZN4fort5tableILNS_10table_typeE0EEC5Ev]+0x33): undefined reference to
ft_create_table'
/usr/bin/ld: /tmp/ccgEbx1a.o: in function fort::table<(fort::table_type)0>::~table()': app.cpp:(.text._ZN4fort5tableILNS_10table_typeE0EED2Ev[_ZN4fort5tableILNS_10table_typeE0EED5Ev]+0x18): undefined reference to
ft_destroy_table'
/usr/bin/ld: /tmp/ccgEbx1a.o: in function fort::table<(fort::table_type)0>::operator<<(fort::table_manipulator const&)': app.cpp:(.text._ZN4fort5tableILNS_10table_typeE0EElsERKNS_17table_manipulatorE[_ZN4fort5tableILNS_10table_typeE0EElsERKNS_17table_manipulatorE]+0x41): undefined reference to
ft_set_cell_prop'
/usr/bin/ld: app.cpp:(.text._ZN4fort5tableILNS_10table_typeE0EElsERKNS_17table_manipulatorE[_ZN4fort5tableILNS_10table_typeE0EElsERKNS_17table_manipulatorE]+0x63): undefined reference to ft_ln' /usr/bin/ld: app.cpp:(.text._ZN4fort5tableILNS_10table_typeE0EElsERKNS_17table_manipulatorE[_ZN4fort5tableILNS_10table_typeE0EElsERKNS_17table_manipulatorE]+0x85): undefined reference to
ft_add_separator'
/usr/bin/ld: /tmp/ccgEbx1a.o: in function fort::table<(fort::table_type)0>& fort::table<(fort::table_type)0>::operator<< <char [2]>(char const (&) [2])': app.cpp:(.text._ZN4fort5tableILNS_10table_typeE0EElsIA2_cEERS2_RKT_[_ZN4fort5tableILNS_10table_typeE0EElsIA2_cEERS2_RKT_]+0xa2): undefined reference to
ft_nwrite'
/usr/bin/ld: /tmp/ccgEbx1a.o: in function fort::table<(fort::table_type)0>& fort::table<(fort::table_type)0>::operator<< <char [7]>(char const (&) [7])': app.cpp:(.text._ZN4fort5tableILNS_10table_typeE0EElsIA7_cEERS2_RKT_[_ZN4fort5tableILNS_10table_typeE0EElsIA7_cEERS2_RKT_]+0xa2): undefined reference to
ft_nwrite'
/usr/bin/ld: /tmp/ccgEbx1a.o: in function fort::table<(fort::table_type)0>& fort::table<(fort::table_type)0>::operator<< <char [5]>(char const (&) [5])': app.cpp:(.text._ZN4fort5tableILNS_10table_typeE0EElsIA5_cEERS2_RKT_[_ZN4fort5tableILNS_10table_typeE0EElsIA5_cEERS2_RKT_]+0xa2): undefined reference to
ft_nwrite'
/usr/bin/ld: /tmp/ccgEbx1a.o: in function fort::table<(fort::table_type)0>& fort::table<(fort::table_type)0>::operator<< <char [10]>(char const (&) [10])': app.cpp:(.text._ZN4fort5tableILNS_10table_typeE0EElsIA10_cEERS2_RKT_[_ZN4fort5tableILNS_10table_typeE0EElsIA10_cEERS2_RKT_]+0xa2): undefined reference to
ft_nwrite'
/usr/bin/ld: /tmp/ccgEbx1a.o: in function fort::table<(fort::table_type)0>& fort::table<(fort::table_type)0>::operator<< <char [9]>(char const (&) [9])': app.cpp:(.text._ZN4fort5tableILNS_10table_typeE0EElsIA9_cEERS2_RKT_[_ZN4fort5tableILNS_10table_typeE0EElsIA9_cEERS2_RKT_]+0xa2): undefined reference to
ft_nwrite'
/usr/bin/ld: /tmp/ccgEbx1a.o:app.cpp:(.text.ZN4fort5tableILNS_10table_typeE0EElsIA6_cEERS2_RKT[ZN4fort5tableILNS_10table_typeE0EElsIA6_cEERS2_RKT]+0xa2): more undefined references to ft_nwrite' follow /usr/bin/ld: /tmp/ccgEbx1a.o: in function
fort::table<(fort::table_type)0>::c_str() const':
app.cpp:(.text._ZNK4fort5tableILNS_10table_typeE0EE5c_strEv[_ZNK4fort5tableILNS_10table_typeE0EE5c_strEv]+0x18): undefined reference to `ft_to_string'
collect2: error: ld returned 1 exit status
Because of following externs:
Lines 716 to 730 in 51910b1
it's not possible to use library as a .dll
please add corresponding macros for windows with __declspec(dllimport)/__declspec(dllexport).
IMHO it would be better to use enum and resolve it internally into a pointer to a built in style.
I get the following warnings when I try to compile libfort as a component for the esp32 platform with esp-idf:
[2/7] Building C object esp-idf/libfort/CMakeFiles/idf_component_libfort.dir/fort.c.obj
FAILED: esp-idf/libfort/CMakeFiles/idf_component_libfort.dir/fort.c.obj
ccache /home/bruno/dev/esp/xtensa-esp32-elf/bin/xtensa-esp32-elf-gcc -DESP_PLATFORM -DGCC_NOT_5_2_0=0 -DHAVE_CONFIG_H -DIDF_VER=\"v3.3-71-g46b12a560\" -I../components/libfort -Iconfig -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/esp32/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/driver/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/esp_ringbuf/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/tcpip_adapter/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/lwip/include/apps -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/lwip/lwip/src/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/lwip/port/esp32/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/lwip/port/esp32/include/arch -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/lwip/include_compat -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/vfs/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/esp_event/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/log/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/efuse/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/efuse/esp32/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/newlib/platform_include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/newlib/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/freertos/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/app_trace/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/heap/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/soc/esp32/include -I/home/bruno/dev/esp/esp-mdf/esp-idf/components/soc/include -mlongcalls -mlongcalls -Og -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -nostdlib -Wall -Werror=all -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wextra -Wno-unused-parameter -Wno-sign-compare -ggdb -std=gnu99 -Wno-old-style-declaration -MD -MT esp-idf/libfort/CMakeFiles/idf_component_libfort.dir/fort.c.obj -MF esp-idf/libfort/CMakeFiles/idf_component_libfort.dir/fort.c.obj.d -o esp-idf/libfort/CMakeFiles/idf_component_libfort.dir/fort.c.obj -c ../components/libfort/fort.c
In file included from ../components/libfort/fort.c:2585:0:
../components/libfort/fort.c: In function 'print_row_separator_impl':
/home/bruno/dev/esp/esp-mdf/esp-idf/components/newlib/include/ctype.h:57:54: error: array subscript has type 'char' [-Werror=char-subscripts]
#define __ctype_lookup(__c) ((__ctype_ptr__+sizeof(""[__c]))[(int)(__c)])
^
/home/bruno/dev/esp/esp-mdf/esp-idf/components/newlib/include/ctype.h:67:23: note: in expansion of macro '__ctype_lookup'
#define isprint(__c) (__ctype_lookup(__c)&(_P|_U|_L|_N|_B))
^
../components/libfort/fort.c:5419:50: note: in expansion of macro 'isprint'
if ((strlen(*L) == 0 || (strlen(*L) == 1 && !isprint(**L)))
^
/home/bruno/dev/esp/esp-mdf/esp-idf/components/newlib/include/ctype.h:57:54: error: array subscript has type 'char' [-Werror=char-subscripts]
#define __ctype_lookup(__c) ((__ctype_ptr__+sizeof(""[__c]))[(int)(__c)])
^
/home/bruno/dev/esp/esp-mdf/esp-idf/components/newlib/include/ctype.h:67:23: note: in expansion of macro '__ctype_lookup'
#define isprint(__c) (__ctype_lookup(__c)&(_P|_U|_L|_N|_B))
^
../components/libfort/fort.c:5420:53: note: in expansion of macro 'isprint'
&& (strlen(*I) == 0 || (strlen(*I) == 1 && !isprint(**I)))
^
/home/bruno/dev/esp/esp-mdf/esp-idf/components/newlib/include/ctype.h:57:54: error: array subscript has type 'char' [-Werror=char-subscripts]
#define __ctype_lookup(__c) ((__ctype_ptr__+sizeof(""[__c]))[(int)(__c)])
^
/home/bruno/dev/esp/esp-mdf/esp-idf/components/newlib/include/ctype.h:67:23: note: in expansion of macro '__ctype_lookup'
#define isprint(__c) (__ctype_lookup(__c)&(_P|_U|_L|_N|_B))
^
../components/libfort/fort.c:5421:55: note: in expansion of macro 'isprint'
&& (strlen(*IV) == 0 || (strlen(*IV) == 1 && !isprint(**IV)))
^
/home/bruno/dev/esp/esp-mdf/esp-idf/components/newlib/include/ctype.h:57:54: error: array subscript has type 'char' [-Werror=char-subscripts]
#define __ctype_lookup(__c) ((__ctype_ptr__+sizeof(""[__c]))[(int)(__c)])
^
/home/bruno/dev/esp/esp-mdf/esp-idf/components/newlib/include/ctype.h:67:23: note: in expansion of macro '__ctype_lookup'
#define isprint(__c) (__ctype_lookup(__c)&(_P|_U|_L|_N|_B))
^
../components/libfort/fort.c:5422:53: note: in expansion of macro 'isprint'
&& (strlen(*R) == 0 || (strlen(*R) == 1 && !isprint(**R)))) {
^
../components/libfort/fort.c: In function 'mk_wcwidth':
../components/libfort/fort.c:7282:11: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
^
../components/libfort/fort.c:7282:20: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
^
../components/libfort/fort.c:7282:33: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
^
../components/libfort/fort.c:7282:42: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
^
../components/libfort/fort.c:7282:55: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
^
../components/libfort/fort.c:7282:64: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
^
../components/libfort/fort.c:7283:11: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
^
../components/libfort/fort.c:7283:20: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
^
../components/libfort/fort.c:7283:33: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
^
../components/libfort/fort.c:7283:42: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
^
../components/libfort/fort.c:7283:55: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
^
../components/libfort/fort.c:7283:64: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
^
../components/libfort/fort.c:7284:11: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
^
../components/libfort/fort.c:7284:20: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
^
../components/libfort/fort.c:7284:33: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
^
../components/libfort/fort.c:7284:42: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
^
../components/libfort/fort.c:7284:55: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
^
../components/libfort/fort.c:7284:64: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
^
../components/libfort/fort.c:7285:11: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
^
../components/libfort/fort.c:7285:20: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
^
../components/libfort/fort.c:7285:33: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
^
../components/libfort/fort.c:7285:42: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
^
../components/libfort/fort.c:7285:55: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
^
../components/libfort/fort.c:7285:64: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
^
../components/libfort/fort.c:7286:11: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0xE0100, 0xE01EF }
^
../components/libfort/fort.c:7286:20: warning: large integer implicitly truncated to unsigned type [-Woverflow]
{ 0xE0100, 0xE01EF }
^
../components/libfort/fort.c:7314:19: warning: comparison is always false due to limited range of data type [-Wtype-limits]
(ucs >= 0x20000 && ucs <= 0x2fffd) ||
^
../components/libfort/fort.c:7314:37: warning: comparison is always true due to limited range of data type [-Wtype-limits]
(ucs >= 0x20000 && ucs <= 0x2fffd) ||
^
../components/libfort/fort.c:7315:19: warning: comparison is always false due to limited range of data type [-Wtype-limits]
(ucs >= 0x30000 && ucs <= 0x3fffd)));
^
../components/libfort/fort.c:7315:37: warning: comparison is always true due to limited range of data type [-Wtype-limits]
(ucs >= 0x30000 && ucs <= 0x3fffd)));
^
cc1: some warnings being treated as errors
ninja: build stopped: subcommand failed.
ninja failed with exit code 1
I saw set_cell_min_width
API to set minimum width but there is nothing to set maximum width
diff --git a/src/fort.h b/src/fort.h
index 11c35a2..39f7b8d 100644
--- a/src/fort.h
+++ b/src/fort.h
@@ -820,9 +820,9 @@ enum ft_color {
FT_COLOR_LIGHT_GREEN = 11, /**< Light green color */
FT_COLOR_LIGHT_YELLOW = 12, /**< Light yellow color */
FT_COLOR_LIGHT_BLUE = 13, /**< Light blue color */
- FT_COLOR_LIGHT_MAGENTA = 15, /**< Light magenta color */
- FT_COLOR_LIGHT_CYAN = 16, /**< Light cyan color */
- FT_COLOR_LIGHT_WHYTE = 17 /**< Light whyte color */
+ FT_COLOR_LIGHT_MAGENTA = 14, /**< Light magenta color */
+ FT_COLOR_LIGHT_CYAN = 15, /**< Light cyan color */
+ FT_COLOR_LIGHT_WHITE = 16 /**< Light white color */
};
/**
I'm still working on getting a backtrace and simplified code that reproduces, but encountered a segfault/crash if one tries to set the current cell position to an empty/non-existent cell. For example, code filling in what will ultimately be a 2-row, 6-col table out of order like this:
ft_printf(t, "%s|%.2lf|%d|%c", "testing", 21.0/7.0, 12, 'X');
ft_ln(t);
ft_printf(t, "123|321|abc|def|hij|klm");
ft_set_cur_cell(t, 0, 4); // causes badness, but not yet observed
ft_printf(t, "1|2");
ft_to_string(t); // crash
I am not able to add more than 15 columns as it throws compiler warning and segmentation fault on running it.
warning: passing argument 2 of ‘ft_u8nwrite_ln’ makes integer from pointer without a cast [-Wint-conversion]
Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг", "Ранг", "Название", "s","x");
^
util/libfort/fort.h:187:23: note: in definition of macro ‘FT_EXPAND_’
#define FT_EXPAND_(x) x
^
util/libfort/fort.h:189:16: note: in expansion of macro ‘FT_NARGS_IMPL_’
FT_EXPAND_(FT_NARGS_IMPL_(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
^~~~~~~~~~~~~~
util/libfort/fort.h:1011:28: note: in expansion of macro ‘FT_PP_NARG_’
(ft_u8nwrite_ln(table, FT_PP_NARG_(__VA_ARGS__), __VA_ARGS__))
^~~~~~~~~~~
testprogram.c:72:5: note: in expansion of macro ‘ft_u8write_ln’
ft_u8write_ln(table, "Ранг", "Название", "Год", "Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг", "Ранг", "Название", "s","x");
^~~~~~~~~~~~~
In file included from testprogram.c:12:0:
util/libfort/fort.c:3680:5: note: expected ‘size_t {aka long unsigned int}’ but argument is of type ‘char *’
int ft_u8nwrite_ln(ft_table_t *table, size_t n, const void *cell_content, ...)warning: passing argument 2 of ‘ft_u8nwrite_ln’ makes integer from pointer without a cast [-Wint-conversion]
Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг", "Ранг", "Название", "s","x");
^
util/libfort/fort.h:187:23: note: in definition of macro ‘FT_EXPAND_’
#define FT_EXPAND_(x) x
^
util/libfort/fort.h:189:16: note: in expansion of macro ‘FT_NARGS_IMPL_’
FT_EXPAND_(FT_NARGS_IMPL_(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
^~~~~~~~~~~~~~
util/libfort/fort.h:1011:28: note: in expansion of macro ‘FT_PP_NARG_’
(ft_u8nwrite_ln(table, FT_PP_NARG_(__VA_ARGS__), __VA_ARGS__))
^~~~~~~~~~~
testprogram.c:72:5: note: in expansion of macro ‘ft_u8write_ln’
ft_u8write_ln(table, "Ранг", "Название", "Год", "Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг","Рейтинг", "Ранг", "Название", "s","x");
^~~~~~~~~~~~~
In file included from testprogram.c:12:0:
util/libfort/fort.c:3680:5: note: expected ‘size_t {aka long unsigned int}’ but argument is of type ‘char *’
int ft_u8nwrite_ln(ft_table_t *table, size_t n, const void *cell_content, ...)
I need a table with only the header (row[0]
) in bold:
fort::table table;
table << fort::header << "A" << "B" << fort::endr;
table << 3.14 << 12345 << fort::endr;
table << 3.14 << 12345 << fort::endr;
table << 3.14 << 12345 << fort::endr;
table.row(0).set_cell_content_text_style(fort::text_style::bold);
table.row(0).set_cell_content_fg_color(fort::color::red);
std::cout << table.to_string() << std::endl;
This is making the whole table bold, in fact everything I type in the terminal is bold after running this code. Guess the closing tag for bold text encoding is missing.
However text color for the header row is red as expected.
So that is_empty()
returns true
? I did not find one.
The following code crashes on commit bb6002ec0b0cf04a528d434944b617f5816dd633 (tag: v0.1.5)
- this is the version we are using.
int main()
{
// the pipe character appears occasionally in our strings
// we use \n to wrap long strings
std::string s =
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||||||||||||||||||||||||||\n"
"||||||";
fort::table table;
table.set_border_style(FT_PLAIN_STYLE);
table << fort::header << "hdr1"
<< "hdr2"
<< "xxx" << fort::endr;
table << "3"
<< "" << s << fort::endr;
// some of the rows in our table are rendered in red colour,
// while rest are in default colour.
table.row(1).set_cell_content_fg_color(fort::color::red);
std::cout << table.to_string() << std::endl;
}
$ ./a.out
terminate called after throwing an instance of 'std::runtime_error'
what(): Libfort runtime error
Aborted (core dumped)
I am not seeing this problem on tip of develop
. Would you happen to know if this was ever found and fixed and which commit fixes this? We want to be sure that this has been fixed before updating libfort
.
#include <iostream>
#include "../src/fort.hpp"
int main(int argc, char** argv) {
fort::table table;
table.set_border_style(FT_PLAIN_STYLE);
table << fort::header << "A"
<< "B" << fort::endr;
int n_rows = argc > 1 ? std::stoi(argv[1]) : 5;
for (int i = 0; i < n_rows; i++) {
table << 3.14 << 12345 << fort::endr;
}
std::cout << table.to_string() << std::endl;
return 0;
}
Can you build and run this code (accepts number of rows to be rendered as an argument):
~/libfort$ ./a.out 3
--------------
A B
--------------
3.14 12345
3.14 12345
3.14 12345
~/libfort$ ./a.out 2
--------------
A B
--------------
3.14 12345
3.14 12345
~/libfort$ ./a.out 1
--------------
A B
--------------
3.14 12345
--------------
Note the dashed line at the bottom of the table when there is only one row (other than the header). This line vanishes if I have more than one row in the table (other than the header). Isn't this a bug?
Hello,
With cm² and cm³ text in tables are not properly aligned.
This happens both on headers and cells values
https://pastebin.com/Q4frZq45
Is there a possibility to ignore escape sequences when calculating table layout? I've found that escape sequences are processed as regular text which lead to improper table layout calculations. Can I propose to add such support?
I think the simple solution would be to implement a function like ft_set_u8strwid_func for char buffers. Separate concept of string length from string width. Implement two different functions: one for calculating string length and another for calculating string visible width.
I don't see any APIs like this. I can know if the table is empty by checking if to_string
returns empty, but an API will help!
I have a C++ project using the CMake build system. I tried to link to libfort with
add_subdirectory(…)
+ target_link_libraries(mylib libfort)
but cmake complains as it does not export targets. Indeed, there is no install(export )
for targets with CMake configuration files.
It would be possible to support also exported targets for use in an external project?
Thanks in advance for any help!
If you look at the output of a table using this style:
------------
Key Value
-------------
Key1 true
Key2 2000
-------------
Every line of string that is generated has the same length, some of them have been appended with whitespaces for achieving same length. This is required for styles that use table borders, but not for styles like FT_PLAIN_STYLE
which do not have table borders.
Can such trailing whitespaces be removed? It would be good enhancement, the resulting test when copied from a terminal and pasted at other places, won't have these unnecessary trailing whitespace
Everything works file is the library is static. But when SHARED
is added to add_library
then it gives linker error.
project(fortapp)
add_subdirectory(libfort)
add_library(fortapplib SHARED lib.cpp)
target_link_libraries(fortapplib fort)
add_executable(fortapp main.cpp)
target_link_libraries(fortapp fortapplib)
With the above CMake configuration I get
[1/3] Building CXX object CMakeFiles/fortapplib.dir/lib.cpp.o
[2/3] Linking CXX shared library libfortapplib.so
FAILED: libfortapplib.so
: && /usr/bin/c++ -fPIC -shared -Wl,-soname,libfortapplib.so -o libfortapplib.so CMakeFiles/fortapplib.dir/lib.cpp.o libfort/lib/libfort.a && :
/usr/bin/ld: libfort/lib/libfort.a(fort.c.o): relocation R_X86_64_PC32 against symbol `fort_calloc' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
*** Failure: Exit code 1 ***
Adding a flag to automatically number the rows (except header) will be a great addition
Test project /disk-samsung/freebsd-ports/devel/libfort/work/.build
Start 1: libfort_test_dev
1/18 Test #1: libfort_test_dev .................Subprocess aborted***Exception: 0.01 sec
Start 2: libfort_test_cpp
2/18 Test #2: libfort_test_cpp ................. Passed 0.01 sec
Start 3: libfort_test
3/18 Test #3: libfort_test .....................Subprocess aborted***Exception: 0.01 sec
Start 4: libfort_simple_table
4/18 Test #4: libfort_simple_table ............. Passed 0.00 sec
Start 5: libfort_custom_table
5/18 Test #5: libfort_custom_table ............. Passed 0.00 sec
Start 6: libfort_fill_table
6/18 Test #6: libfort_fill_table ............... Passed 0.00 sec
Start 7: libfort_custom_border_style
7/18 Test #7: libfort_custom_border_style ...... Passed 0.00 sec
Start 8: libfort_print_styles
8/18 Test #8: libfort_print_styles ............. Passed 0.01 sec
Start 9: libfort_math_table
9/18 Test #9: libfort_math_table ............... Passed 0.00 sec
Start 10: libfort_beautiful_table
10/18 Test #10: libfort_beautiful_table .......... Passed 0.00 sec
Start 11: libfort_complex_layout
11/18 Test #11: libfort_complex_layout ........... Passed 0.00 sec
Start 12: libfort_non_ascii_table
12/18 Test #12: libfort_non_ascii_table .......... Passed 0.00 sec
Start 13: libfort_simple_table_cpp
13/18 Test #13: libfort_simple_table_cpp ......... Passed 0.00 sec
Start 14: libfort_custom_table_cpp
14/18 Test #14: libfort_custom_table_cpp ......... Passed 0.00 sec
Start 15: libfort_complex_layout_cpp
15/18 Test #15: libfort_complex_layout_cpp ....... Passed 0.00 sec
Start 16: libfort_fill_table_cpp
16/18 Test #16: libfort_fill_table_cpp ........... Passed 0.00 sec
Start 17: libfort_beautiful_table_cpp
17/18 Test #17: libfort_beautiful_table_cpp ...... Passed 0.00 sec
Start 18: libfort_non_ascii_table_cpp
18/18 Test #18: libfort_non_ascii_table_cpp ...... Passed 0.00 sec
89% tests passed, 2 tests failed out of 18
Total Test time (real) = 0.07 sec
The following tests FAILED:
1 - libfort_test_dev (Subprocess aborted)
3 - libfort_test (Subprocess aborted)
Errors while running CTest
Output from these tests are in: /disk-samsung/freebsd-ports/devel/libfort/work/.build/Testing/Temporary/LastTest.log
Use "--rerun-failed --output-on-failure" to re-run the failed cases verbosely.
FAILED: CMakeFiles/test.util
cd /disk-samsung/freebsd-ports/devel/libfort/work/.build && /usr/local/bin/ctest --force-new-ctest-process
ninja: build stopped: subcommand failed.
*** Error code 1
libfort_test
, when run alone, succeeds:
$ ./work/.build/tests/libfort_test
== RUNNING BLACK BOX TEST SUITE ==
[==========] Running 15 test(s).
[ RUN ] test_bug_fixes
[ OK ] test_bug_fixes
[ RUN ] test_table_basic
[ OK ] test_table_basic
[ RUN ] test_wcs_table_boundaries
[ OK ] test_wcs_table_boundaries
[ RUN ] test_utf8_table
[ OK ] test_utf8_table
[ RUN ] test_table_write
[ OK ] test_table_write
[ RUN ] test_table_insert_strategy
[ OK ] test_table_insert_strategy
[ RUN ] test_table_changing_cell
[ OK ] test_table_changing_cell
[ RUN ] test_table_erase
[ OK ] test_table_erase
[ RUN ] test_table_border_style
[ OK ] test_table_border_style
[ RUN ] test_table_builtin_border_styles
[ OK ] test_table_builtin_border_styles
[ RUN ] test_table_cell_properties
[ OK ] test_table_cell_properties
[ RUN ] test_table_tbl_properties
[ OK ] test_table_tbl_properties
[ RUN ] test_table_text_styles
[ OK ] test_table_text_styles
[ RUN ] test_memory_errors
[ OK ] test_memory_errors
[ RUN ] test_error_codes
[ OK ] test_error_codes
[==========] 15 test(s) run.
[ PASSED ] 15 test(s).
Is there a way to print a table and then update a value from a column and then reprint only that column not the whole table, because nothing else changed?
Hey there. I love the library! And so I would like to know if you would be okay with me packaging it as a dev package for Alpine Linux.
To do this, I probably need to package fort.h, fort.hpp, and fort.a into a dev package.
If you are interested in adding support for generating a .so file, then I could potentially also make a regular library package just containing that.
Finally, it would be helpful if you could make a release so that I can make a URL directly to your repo to grab the source tarball for packaging and pointing others to your great library.
Thought on this?
+------------------------+------------+----------+----------+
| Header row, column 1 | Header 2 | Header 3 | Header 4 |
| (header rows optional) | | | |
+========================+============+==========+==========+
| body row 1, column 1 | column 2 | column 3 | column 4 |
+------------------------+------------+----------+----------+
| body row 2 | ... | ... | |
+------------------------+------------+----------+----------+
an RST table looks like this, see https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#grid-tables
Do we have a build-in table style in libfort that gives result like above? If not can we add one (please name it RST_STYLE)
Hello,
I followed the instruction in README.md
But I get something wrong using FT_DOUBLE2_STYLE
.
In windows like bash (cmd and powershell), I got something like this.
But when I use Unix like bash (git bash) it went right.
I use clang v8.0.0 and msvc 2017 for compiling.
Thanks for the lib, it helped me a lot.
Error when compile with compiler other than clang, gcc, msvc (e.g. with tcc).
This would be the equivalent of existing horizontal span for cells, but vertically.
Hi,
I am trying to integrate libfort as part of a project built using CMake. I would like to link to it either statically by using a .lib
file, or dynamically but with exports linked through a .lib
file also.
I can't figure out how to build libfort one way or the other using CMake. All I've managed is to generate a .dll
file alone.
Any pointers ?
Thanks !
I tried the following code on latest libfort code
int main() {
fort::char_table table;
table << fort::header << "N"
<< "Driver"
<< "Time"
<< "Avg Speed" << fort::endr;
table << "α" // unicode!
<< "Hamilton"
<< "1:26.373"
<< "35.02" << fort::endr;
std::cout << table.to_string() << std::endl;
}
Here is the output, note how the formatting has gone bad!
+----+----------+----------+-----------+
| N | Driver | Time | Avg Speed |
+----+----------+----------+-----------+
| α | Hamilton | 1:26.373 | 35.02 |
+----+----------+----------+-----------+
Looks like string length calculations go haywire if we try to put unicode characters in a table.
In my application, I pretty-print the data, but save them in a CSV as well. This would relieve me from having to manually write to the CSV stream myself (though the C++ syntax is similar).
I am dynamically populating a table in a function which returns ta string by calling to_string()
in the end. My logic is such that I may end up in not adding any data at all to the table. In such cases I don't want to add any header to the table, so that to_string()
returns an empty string.
Hence a feature to add the header at the end after knowing the number of rows (or whenever we wish) will be helpful. Currently I use workarounds to return an empty string from my function, as adding the header afterwards adds it after all the data added till then.
The library has a relatively high RAM footprint, making it difficult to use on low-spec embedded systems. Printing a table with 4 or 5 rows easly allocates several kB of RAM.
Jumping in the code, I noticed that in the background buffers are allocated for each cell of the table, before printing starts.
Would it be possible to selectively draw the table in lines? For example, something like this:
for (size_t i = 0; i != ft_get_number_of_rows_to_print(table); ++i)
{
memset(buffer, 0, 128);
if (0 == ft_print_single_row(table, i, buffer, 256))
{
printf(buffer);
}
}
So that in the background, only the necessary allocations are done for a single row, and the buffers are freed after printing out.
Judging from the code, this would mean major code changes regarding the cell buffer handling.
We have a command line utility that uses this library to show the output in a tabular form, which is fetched from a running application. The header row of this output does not change between 2 invocations of the tool, but the data might change (as it has time stamps etc). Currently we create a table from scratch every time the tool is run. But the tool is run quite frequently (in fact with watch
command), so I was wondering if we can create the header added just once and the data can be repopulated every time.. Is it possible?
An API to sort the table on one of the columns before calling to_string()
will be a great addition!
table << 123
does not seem to work, have to do: table << "123"
all your examples are showing numbers within quotes!
Check for different ci services that support platforms different from x86 (e.g. https://blog.drone.io/drone-announces-official-support-for-arm/).
Please add CMake option to disable unit tests and examples for this sub project only.
First, thanks for this great lib. I'm filling a table with data from a double
array. However, I can't manage to print the table with exactly two digits after decimal point without generating extra columns.
Here's the code to generate the table:
double data[3][3] = {
{3.4403, 5.1802, 0.0071},
{18.931, 22.004, 0.0000},
{ 74.5, 100.01, 9.1110}
};
fort::char_table t1;
t1 << fort::header << "#" << "arrival time" << "departure time" << "waiting time" << fort::endr;
t1.column(0).set_cell_text_align(fort::text_align::center);
t1.column(1).set_cell_text_align(fort::text_align::right);
t1.column(2).set_cell_text_align(fort::text_align::right);
t1.column(3).set_cell_text_align(fort::text_align::right);
// Fill with data
for (int i = 0; i < 3; i++) {
t1 << i;
for (int j = 0; j < 3; j++)
t1 << data[i][j];
t1 << fort::endr;
}
std::cout << t1.to_string() << std::endl;
Output:
+---+--------------+----------------+--------------+
| # | arrival time | departure time | waiting time |
+---+--------------+----------------+--------------+
| 0 | 3.4403 | 5.1802 | 0.0071 |
| 1 | 18.931 | 22.004 | 0 |
| 2 | 74.5 | 100.01 | 9.111 |
+---+--------------+----------------+--------------+
I tried using std::setprecision
and std::fixed
from <iomanip>
to print every cell with two digits after decimal point, but it did not work.
My attempts:
Adding std::cout << std::fixed << std::setprecision(2);
before the line std::cout << t1.to_string() << std::endl;
. Output is the same as before.
Replacing t1 << data[i][j];
by t1 << std::fixed << std::setprecision(2) << data[i][j];
. Output:
+---+--------------+----------------+--------------+--+--+--------+--+--+------+
| # | arrival time | departure time | waiting time | | | | | | |
+---+--------------+----------------+--------------+--+--+--------+--+--+------+
| 0 | | | 3.44 | | | 5.18 | | | 0.01 |
| 1 | | | 18.93 | | | 22.00 | | | 0.00 |
| 2 | | | 74.50 | | | 100.01 | | | 9.11 |
+---+--------------+----------------+--------------+--+--+--------+--+--+------+
As you can see, it actually prints the values as expected, but it generates empty columns and disarranges the table.
t1 << std::fixed << std::setprecision(2);
before the first for
loop. Output has issues similar to 2nd attempt:+---+--------------+----------------+--------------+------+------+
| # | arrival time | departure time | waiting time | | |
+---+--------------+----------------+--------------+------+------+
| | | 0 | 3.44 | 5.18 | 0.01 |
| 1 | 18.93 | 22.00 | 0.00 | | |
| 2 | 74.50 | 100.01 | 9.11 | | |
+---+--------------+----------------+--------------+------+------+
Other attempts also did not produce the expected output. I'm sorry, but I did not find in the tutorials something related to this issue. What am I missing here? Thanks in advance.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.