[A] Added cpp wrappers

This commit is contained in:
seleznevae 2018-04-01 11:36:52 +03:00
parent 9169cb8a71
commit 0fa22238ef
7 changed files with 210 additions and 76 deletions

View File

@ -50,7 +50,7 @@ endif(FORT_COMPILER STREQUAL "MSVC")
# Sources and executables # Sources and executables
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
FILE(GLOB_RECURSE FortHeaders "include/*.h" "tests/*.h" "src/*.h") FILE(GLOB_RECURSE FortHeaders "include/*.h" "include/*.hpp" "tests/*.h" "src/*.h")
add_custom_target(headers SOURCES ${FortHeaders}) add_custom_target(headers SOURCES ${FortHeaders})
@ -74,6 +74,11 @@ add_executable(${PROJECT_NAME}_example
${EXAMPLE_SOURCES} ${EXAMPLE_SOURCES}
${FORT_SOURCES}) ${FORT_SOURCES})
set(EXAMPLE_CPP_SOURCES
example/main.cpp)
add_executable(${PROJECT_NAME}_example_cpp
${EXAMPLE_CPP_SOURCES}
${FORT_SOURCES})
set(TEST_SOURCES set(TEST_SOURCES
tests/test.c tests/test.c
@ -107,6 +112,7 @@ if(FORT_COMPILER STREQUAL "GNU" OR FORT_COMPILER STREQUAL "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
if(FORT_COMPILER STREQUAL "GNU") if(FORT_COMPILER STREQUAL "GNU")
target_link_libraries(${PROJECT_NAME}_example asan) target_link_libraries(${PROJECT_NAME}_example asan)
target_link_libraries(${PROJECT_NAME}_example_cpp asan)
target_link_libraries(${PROJECT_NAME}_test asan) target_link_libraries(${PROJECT_NAME}_test asan)
endif(FORT_COMPILER STREQUAL "GNU") endif(FORT_COMPILER STREQUAL "GNU")
endif(FORT_BUILD_TYPE STREQUAL "asan") endif(FORT_BUILD_TYPE STREQUAL "asan")
@ -117,6 +123,7 @@ if(FORT_COMPILER STREQUAL "GNU" OR FORT_COMPILER STREQUAL "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-sanitize-recover") #to force fail set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-sanitize-recover") #to force fail
if(FORT_COMPILER STREQUAL "GNU") if(FORT_COMPILER STREQUAL "GNU")
target_link_libraries(${PROJECT_NAME}_example ubsan) target_link_libraries(${PROJECT_NAME}_example ubsan)
target_link_libraries(${PROJECT_NAME}_example_cpp ubsan)
target_link_libraries(${PROJECT_NAME}_test ubsan) target_link_libraries(${PROJECT_NAME}_test ubsan)
endif(FORT_COMPILER STREQUAL "GNU") endif(FORT_COMPILER STREQUAL "GNU")
endif(FORT_BUILD_TYPE STREQUAL "ubsan") endif(FORT_BUILD_TYPE STREQUAL "ubsan")

21
example/main.cpp Normal file
View File

@ -0,0 +1,21 @@
#include <iostream>
#include "fort.hpp"
int main()
{
fort::FTable table;
// Fill table with data
table << fort::header
<< "Rank" << "Title" << "Year" << "Rating" << fort::endl
<< "1" << "The Shawshank Redemption" << "1994" << "9.5" << fort::endl
<< "2" << "12 Angry Men" << "1957" << "8.8" << fort::endl
<< "3" << "It's a Wonderful Life" << "1946" << "8.6" << fort::endl
<< fort::separator
<< "4" << "2001: A Space Odyssey" << "1968" << "8.5" << fort::endl
<< "5" << "Blade Runner" << "1982" << "8.1" << fort::endl;
std::cout << table.to_string();
return 0;
}

View File

@ -107,9 +107,6 @@ SOFTWARE.
#endif #endif
#define STRING2(x) #x
#define STRING(x) STRING2(x)
/* /*
* Wchar support * Wchar support
@ -138,23 +135,6 @@ static FT_INLINE int ft_check_if_wstring_helper(const wchar_t *str)
return 0; return 0;
} }
/*
#define PP_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31, N, ...) N
#define PP_RSEQ_N() \
31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#define PP_NARG_(...) \
PP_ARG_N(__VA_ARGS__)
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
*/
#define FORT_NARGS_IMPL_(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,N,...) N #define FORT_NARGS_IMPL_(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,N,...) N
#define FT_EXPAND_(x) x #define FT_EXPAND_(x) x
#define PP_NARG(...) \ #define PP_NARG(...) \
@ -193,11 +173,15 @@ static FT_INLINE int ft_check_if_wstring_helper(const wchar_t *str)
#define CHECK_IF_STRING_2(checker,arg,...) (checker(arg),FT_EXPAND_(CHECK_IF_STRING_1(checker,__VA_ARGS__))) #define CHECK_IF_STRING_2(checker,arg,...) (checker(arg),FT_EXPAND_(CHECK_IF_STRING_1(checker,__VA_ARGS__)))
#define CHECK_IF_STRING_1(checker,arg) (checker(arg)) #define CHECK_IF_STRING_1(checker,arg) (checker(arg))
#define CHECK_IF_ARGS_ARE_STRINGS__(checker,func, ...) FT_EXPAND_(func(checker,__VA_ARGS__)) #define CHECK_IF_ARGS_ARE_STRINGS__(checker,func, ...) \
#define CHECK_IF_ARGS_ARE_STRINGS_(checker,basis, n, ...) CHECK_IF_ARGS_ARE_STRINGS__(checker,STR_2_CAT_(basis, n), __VA_ARGS__) FT_EXPAND_(func(checker,__VA_ARGS__))
#define CHECK_IF_ARGS_ARE_STRINGS(...) CHECK_IF_ARGS_ARE_STRINGS_(ft_check_if_string_helper,CHECK_IF_STRING_,PP_NARG(__VA_ARGS__), __VA_ARGS__) #define CHECK_IF_ARGS_ARE_STRINGS_(checker,basis, n, ...) \
CHECK_IF_ARGS_ARE_STRINGS__(checker,STR_2_CAT_(basis, n), __VA_ARGS__)
#define CHECK_IF_ARGS_ARE_STRINGS(...) \
CHECK_IF_ARGS_ARE_STRINGS_(ft_check_if_string_helper,CHECK_IF_STRING_,PP_NARG(__VA_ARGS__), __VA_ARGS__)
#ifdef FT_HAVE_WCHAR #ifdef FT_HAVE_WCHAR
#define CHECK_IF_ARGS_ARE_WSTRINGS(...) CHECK_IF_ARGS_ARE_STRINGS_(ft_check_if_wstring_helper,CHECK_IF_STRING_,PP_NARG(__VA_ARGS__), __VA_ARGS__) #define CHECK_IF_ARGS_ARE_WSTRINGS(...) \
CHECK_IF_ARGS_ARE_STRINGS_(ft_check_if_wstring_helper,CHECK_IF_STRING_,PP_NARG(__VA_ARGS__), __VA_ARGS__)
#endif #endif
/* /*
@ -209,11 +193,35 @@ FT_BEGIN_DECLS
struct fort_table; struct fort_table;
typedef struct fort_table FTABLE; typedef struct fort_table FTABLE;
/**
* Create formatted table.
*
* @return
* The pointer to the new allocated FTABLE, on success. NULL on error
* with ft_errno set appropriately.
*/
FT_EXTERN FTABLE *ft_create_table(void); FT_EXTERN FTABLE *ft_create_table(void);
/**
* Destroy formatted table.
*
* Destroy formatted table and free all resources allocated during table creation
* and work with it.
*
* @param table
* Pointer to formatted table previousley created with ft_create_table.
*/
FT_EXTERN void ft_destroy_table(FTABLE *table); FT_EXTERN void ft_destroy_table(FTABLE *table);
/**
* Move current position to the first cell of the next line(row).
*
* @param table
* Pointer to formatted table.
*/
FT_EXTERN void ft_ln(FTABLE *table); FT_EXTERN void ft_ln(FTABLE *table);
FT_EXTERN size_t ft_cur_row(FTABLE *table);
FT_EXTERN size_t ft_cur_col(FTABLE *table);
#if defined(FT_CLANG_COMPILER) || defined(FT_GCC_COMPILER) #if defined(FT_CLANG_COMPILER) || defined(FT_GCC_COMPILER)
@ -262,13 +270,35 @@ FT_EXTERN int ft_table_write_ln(FTABLE *table, size_t rows, size_t cols, const c
/**
* Add separator after the current row.
*
* @param table
* Formatted table.
* @return
* - 0: Success; separator was added.
* - (-1): !!!!!!!! todo
*/
FT_EXTERN int ft_add_separator(FTABLE *table); FT_EXTERN int ft_add_separator(FTABLE *table);
/**
* Convert table to string representation.
*
* FTABLE has ownership of the returned pointer. So there is no need to
* free it. To take ownership user should explicitly copy the returned
* string with strdup or similar functions. Returned pointer remaines valid
* until table is destroyed with ft_destroy_table or other invocations of
* ft_to_string.
*
* @param table
* Formatted table.
* @return
* The pointer to the string representation of formatted table, on success.
* NULL on error with ft_errno set appropriately.
*/
FT_EXTERN const char *ft_to_string(const FTABLE *table); FT_EXTERN const char *ft_to_string(const FTABLE *table);
@ -278,28 +308,32 @@ FT_EXTERN const char *ft_to_string(const FTABLE *table);
#define FT_ANY_COLUMN (UINT_MAX) #define FT_ANY_COLUMN (UINT_MAX)
#define FT_ANY_ROW (UINT_MAX) #define FT_ANY_ROW (UINT_MAX)
#define FT_ROW_UNSPEC (UINT_MAX-1) #define FT_CUR_COLUMN (UINT_MAX - 1)
#define FT_COLUMN_UNSPEC (UINT_MAX-1) #define FT_CUR_ROW (UINT_MAX - 1)
/* #define FT_ROW_UNSPEC (UINT_MAX - 2)
#define FT_COLUMN_UNSPEC (UINT_MAX - 2)
/**
* Cell options * Cell options
*/ */
#define FT_COPT_MIN_WIDTH ((uint32_t)(0x01U << (0))) #define FT_COPT_MIN_WIDTH (0x01U << 0) /**< Minimum width */
#define FT_COPT_TEXT_ALIGN ((uint32_t)(0x01U << (1))) #define FT_COPT_TEXT_ALIGN (0x01U << 1) /**< Text alignmemnt */
#define FT_COPT_TOP_PADDING ((uint32_t)(0x01U << (2))) #define FT_COPT_TOP_PADDING (0x01U << 2) /**< Top padding for cell content */
#define FT_COPT_BOTTOM_PADDING ((uint32_t)(0x01U << (3))) #define FT_COPT_BOTTOM_PADDING (0x01U << 3) /**< Bottom padding for cell content */
#define FT_COPT_LEFT_PADDING ((uint32_t)(0x01U << (4))) #define FT_COPT_LEFT_PADDING (0x01U << 4) /**< Left padding for cell content */
#define FT_COPT_RIGHT_PADDING ((uint32_t)(0x01U << (5))) #define FT_COPT_RIGHT_PADDING (0x01U << 5) /**< Right padding for cell content */
#define FT_COPT_EMPTY_STR_HEIGHT ((uint32_t)(0x01U << (6))) #define FT_COPT_EMPTY_STR_HEIGHT (0x01U << 6) /**< Height of empty cell */
#define FT_COPT_ROW_TYPE ((uint32_t)(0x01U << (7))) #define FT_COPT_ROW_TYPE (0x01U << 7) /**< Row type */
/* /**
* Table options * Table options
*/ */
#define FT_TOPT_LEFT_MARGIN ((uint32_t)(0x01U << (0))) #define FT_TOPT_LEFT_MARGIN (0x01U << 0)
#define FT_TOPT_TOP_MARGIN ((uint32_t)(0x01U << (1))) #define FT_TOPT_TOP_MARGIN (0x01U << 1)
#define FT_TOPT_RIGHT_MARGIN ((uint32_t)(0x01U << (2))) #define FT_TOPT_RIGHT_MARGIN (0x01U << 2)
#define FT_TOPT_BOTTOM_MARGIN ((uint32_t)(0x01U << (3))) #define FT_TOPT_BOTTOM_MARGIN (0x01U << 3)
enum TextAlignment { enum TextAlignment {
LeftAligned, LeftAligned,

85
include/fort.hpp Normal file
View File

@ -0,0 +1,85 @@
#ifndef LIBFORT_HPP
#define LIBFORT_HPP
#include "fort.h"
#include <string>
#include <exception>
#include <sstream>
namespace fort
{
class FTableManipulator {
public:
explicit FTableManipulator(int i)
:value(i)
{
}
friend class FTable;
private:
int value;
};
const FTableManipulator header(0);
const FTableManipulator endl(1);
const FTableManipulator separator(2);
class FTable {
public:
FTable()
:table(ft_create_table())
{
if (table == NULL)
throw std::runtime_error("Runtime error");
}
~FTable()
{
ft_destroy_table(table);
}
std::string to_string() const
{
const char *str = ft_to_string(table);
if (str == NULL)
throw std::runtime_error("Runtime error");
return str;
}
const char *c_str() const
{
return ft_to_string(table);
}
template <typename T>
FTable &operator<<(const T &arg)
{
std::stringstream stream;
stream << arg;
ft_nwrite(table, 1, stream.str().c_str());
return *this;
}
FTable &operator<<(const FTableManipulator &arg)
{
if (arg.value == header.value)
ft_set_cell_option(table, FT_CUR_ROW, FT_ANY_ROW, FT_COPT_ROW_TYPE, Header);
else if (arg.value == endl.value)
ft_ln(table);
else if (arg.value == separator.value)
ft_add_separator(table);
return *this;
}
private:
FTABLE *table;
};
}
#endif // LIBFORT_HPP

View File

@ -7,7 +7,6 @@
* CELL * CELL
* ***************************************************************************/ * ***************************************************************************/
struct fort_cell { struct fort_cell {
string_buffer_t *str_buffer; string_buffer_t *str_buffer;
fort_table_options_t *options; fort_table_options_t *options;

View File

@ -105,6 +105,17 @@ void ft_ln(FTABLE *table)
table->cur_row++; table->cur_row++;
} }
size_t ft_cur_row(FTABLE *table)
{
assert(table);
return table->cur_row;
}
size_t ft_cur_col(FTABLE *table)
{
assert(table);
return table->cur_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)
{ {
@ -829,6 +840,12 @@ int ft_set_cell_option(FTABLE *table, unsigned row, unsigned col, uint32_t optio
return FT_ERROR; return FT_ERROR;
} }
} }
if (row == FT_CUR_ROW)
row = table->cur_row;
if (row == FT_CUR_COLUMN)
col = table->cur_col;
return set_cell_option(table->options->cell_options, row, col, option, value); return set_cell_option(table->options->cell_options, row, col, option, value);
} }

View File

@ -5,20 +5,6 @@
#include <stdint.h> #include <stdint.h>
#include <limits.h> #include <limits.h>
//enum TextAlignment
//{
// LeftAligned,
// CenterAligned,
// RightAligned
//};
//enum RowType
//{
// Common,
// Header
//};
struct fort_column_options struct fort_column_options
{ {
int col_min_width; int col_min_width;
@ -34,21 +20,6 @@ fort_column_options_t create_column_options(void);
struct vector; struct vector;
typedef struct vector vector_t; typedef struct vector vector_t;
#define FT_ANY_COLUMN (UINT_MAX)
#define FT_ANY_ROW (UINT_MAX)
#define FT_ROW_UNSPEC (UINT_MAX-1)
#define FT_COLUMN_UNSPEC (UINT_MAX-1)
#define FT_COPT_MIN_WIDTH ((uint32_t)(0x01U << (0)))
#define FT_COPT_TEXT_ALIGN ((uint32_t)(0x01U << (1)))
#define FT_COPT_TOP_PADDING ((uint32_t)(0x01U << (2)))
#define FT_COPT_BOTTOM_PADDING ((uint32_t)(0x01U << (3)))
#define FT_COPT_LEFT_PADDING ((uint32_t)(0x01U << (4)))
#define FT_COPT_RIGHT_PADDING ((uint32_t)(0x01U << (5)))
#define FT_COPT_EMPTY_STR_HEIGHT ((uint32_t)(0x01U << (6)))
#define FT_COPT_ROW_TYPE ((uint32_t)(0x01U << (7)))
#define OPTION_IS_SET(ft_opts, option) ((ft_opts) & (option)) #define OPTION_IS_SET(ft_opts, option) ((ft_opts) & (option))
#define OPTION_SET(ft_opts, option) ((ft_opts) |=(option)) #define OPTION_SET(ft_opts, option) ((ft_opts) |=(option))
#define OPTION_UNSET(ft_opts, option) ((ft_opts) &= ~((uint32_t)option)) #define OPTION_UNSET(ft_opts, option) ((ft_opts) &= ~((uint32_t)option))