libsmartcols: split print.c into print.c, put.c and print-api.c

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2018-10-25 16:26:30 +02:00
parent 06a8decd72
commit 3bb882be44
5 changed files with 339 additions and 312 deletions

View File

@ -16,6 +16,8 @@ libsmartcols_la_SOURCES= \
libsmartcols/src/line.c \
libsmartcols/src/table.c \
libsmartcols/src/print.c \
libsmartcols/src/fput.c \
libsmartcols/src/print-api.c \
libsmartcols/src/version.c \
libsmartcols/src/buffer.c \
libsmartcols/src/calculate.c \

97
libsmartcols/src/fput.c Normal file
View File

@ -0,0 +1,97 @@
#include "carefulputc.h"
#include "smartcolsP.h"
void fput_indent(struct libscols_table *tb)
{
int i;
for (i = 0; i <= tb->indent; i++)
fputs(" ", tb->out);
}
void fput_table_open(struct libscols_table *tb)
{
tb->indent = 0;
if (scols_table_is_json(tb)) {
fputc('{', tb->out);
fputs(linesep(tb), tb->out);
fput_indent(tb);
fputs_quoted(tb->name, tb->out);
fputs(": [", tb->out);
fputs(linesep(tb), tb->out);
tb->indent++;
tb->indent_last_sep = 1;
}
}
void fput_table_close(struct libscols_table *tb)
{
tb->indent--;
if (scols_table_is_json(tb)) {
fput_indent(tb);
fputc(']', tb->out);
tb->indent--;
fputs(linesep(tb), tb->out);
fputc('}', tb->out);
tb->indent_last_sep = 1;
}
}
void fput_children_open(struct libscols_table *tb)
{
if (scols_table_is_json(tb)) {
fputc(',', tb->out);
fputs(linesep(tb), tb->out);
fput_indent(tb);
fputs("\"children\": [", tb->out);
}
/* between parent and child is separator */
fputs(linesep(tb), tb->out);
tb->indent_last_sep = 1;
tb->indent++;
tb->termlines_used++;
}
void fput_children_close(struct libscols_table *tb)
{
tb->indent--;
if (scols_table_is_json(tb)) {
fput_indent(tb);
fputc(']', tb->out);
fputs(linesep(tb), tb->out);
tb->indent_last_sep = 1;
}
}
void fput_line_open(struct libscols_table *tb)
{
if (scols_table_is_json(tb)) {
fput_indent(tb);
fputc('{', tb->out);
tb->indent_last_sep = 0;
}
tb->indent++;
}
void fput_line_close(struct libscols_table *tb, int last, int last_in_table)
{
tb->indent--;
if (scols_table_is_json(tb)) {
if (tb->indent_last_sep)
fput_indent(tb);
fputs(last ? "}" : "},", tb->out);
if (!tb->no_linesep)
fputs(linesep(tb), tb->out);
} else if (tb->no_linesep == 0 && last_in_table == 0) {
fputs(linesep(tb), tb->out);
tb->termlines_used++;
}
tb->indent_last_sep = 1;
}

View File

@ -0,0 +1,208 @@
#include "smartcolsP.h"
/**
* scola_table_print_range:
* @tb: table
* @start: first printed line or NULL to print from the begin of the table
* @end: last printed line or NULL to print all from start.
*
* If the start is the first line in the table than prints table header too.
* The header is printed only once. This does not work for trees.
*
* Returns: 0, a negative value in case of an error.
*/
int scols_table_print_range( struct libscols_table *tb,
struct libscols_line *start,
struct libscols_line *end)
{
struct libscols_buffer *buf = NULL;
struct libscols_iter itr;
int rc;
if (scols_table_is_tree(tb))
return -EINVAL;
DBG(TAB, ul_debugobj(tb, "printing range from API"));
rc = __scols_initialize_printing(tb, &buf);
if (rc)
return rc;
if (start) {
itr.direction = SCOLS_ITER_FORWARD;
itr.head = &tb->tb_lines;
itr.p = &start->ln_lines;
} else
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
if (!start || itr.p == tb->tb_lines.next) {
rc = __scols_print_header(tb, buf);
if (rc)
goto done;
}
rc = __scols_print_range(tb, buf, &itr, end);
done:
__scols_cleanup_printing(tb, buf);
return rc;
}
/**
* scols_table_print_range_to_string:
* @tb: table
* @start: first printed line or NULL to print from the beginning of the table
* @end: last printed line or NULL to print all from start.
* @data: pointer to the beginning of a memory area to print to
*
* The same as scols_table_print_range(), but prints to @data instead of
* stream.
*
* Returns: 0, a negative value in case of an error.
*/
#ifdef HAVE_OPEN_MEMSTREAM
int scols_table_print_range_to_string( struct libscols_table *tb,
struct libscols_line *start,
struct libscols_line *end,
char **data)
{
FILE *stream, *old_stream;
size_t sz;
int rc;
if (!tb)
return -EINVAL;
DBG(TAB, ul_debugobj(tb, "printing range to string"));
/* create a stream for output */
stream = open_memstream(data, &sz);
if (!stream)
return -ENOMEM;
old_stream = scols_table_get_stream(tb);
scols_table_set_stream(tb, stream);
rc = scols_table_print_range(tb, start, end);
fclose(stream);
scols_table_set_stream(tb, old_stream);
return rc;
}
#else
int scols_table_print_range_to_string(
struct libscols_table *tb __attribute__((__unused__)),
struct libscols_line *start __attribute__((__unused__)),
struct libscols_line *end __attribute__((__unused__)),
char **data __attribute__((__unused__)))
{
return -ENOSYS;
}
#endif
static int do_print_table(struct libscols_table *tb, int *is_empty)
{
int rc = 0;
struct libscols_buffer *buf = NULL;
if (!tb)
return -EINVAL;
DBG(TAB, ul_debugobj(tb, "printing"));
if (is_empty)
*is_empty = 0;
if (list_empty(&tb->tb_columns)) {
DBG(TAB, ul_debugobj(tb, "error -- no columns"));
return -EINVAL;
}
if (list_empty(&tb->tb_lines)) {
DBG(TAB, ul_debugobj(tb, "ignore -- no lines"));
if (is_empty)
*is_empty = 1;
return 0;
}
tb->header_printed = 0;
rc = __scols_initialize_printing(tb, &buf);
if (rc)
return rc;
fput_table_open(tb);
if (tb->format == SCOLS_FMT_HUMAN)
__scols_print_title(tb);
rc = __scols_print_header(tb, buf);
if (rc)
goto done;
if (scols_table_is_tree(tb))
rc = __scols_print_tree(tb, buf);
else
rc = __scols_print_table(tb, buf);
fput_table_close(tb);
done:
__scols_cleanup_printing(tb, buf);
return rc;
}
/**
* scols_print_table:
* @tb: table
*
* Prints the table to the output stream and terminate by \n.
*
* Returns: 0, a negative value in case of an error.
*/
int scols_print_table(struct libscols_table *tb)
{
int empty = 0;
int rc = do_print_table(tb, &empty);
if (rc == 0 && !empty)
fputc('\n', tb->out);
return rc;
}
/**
* scols_print_table_to_string:
* @tb: table
* @data: pointer to the beginning of a memory area to print to
*
* Prints the table to @data.
*
* Returns: 0, a negative value in case of an error.
*/
#ifdef HAVE_OPEN_MEMSTREAM
int scols_print_table_to_string(struct libscols_table *tb, char **data)
{
FILE *stream, *old_stream;
size_t sz;
int rc;
if (!tb)
return -EINVAL;
DBG(TAB, ul_debugobj(tb, "printing to string"));
/* create a stream for output */
stream = open_memstream(data, &sz);
if (!stream)
return -ENOMEM;
old_stream = scols_table_get_stream(tb);
scols_table_set_stream(tb, stream);
rc = do_print_table(tb, NULL);
fclose(stream);
scols_table_set_stream(tb, old_stream);
return rc;
}
#else
int scols_print_table_to_string(
struct libscols_table *tb __attribute__((__unused__)),
char **data __attribute__((__unused__)))
{
return -ENOSYS;
}
#endif

View File

@ -476,101 +476,6 @@ int __cell_to_buffer(struct libscols_table *tb,
return rc;
}
static void fput_indent(struct libscols_table *tb)
{
int i;
for (i = 0; i <= tb->indent; i++)
fputs(" ", tb->out);
}
static void fput_table_open(struct libscols_table *tb)
{
tb->indent = 0;
if (scols_table_is_json(tb)) {
fputc('{', tb->out);
fputs(linesep(tb), tb->out);
fput_indent(tb);
fputs_quoted(tb->name, tb->out);
fputs(": [", tb->out);
fputs(linesep(tb), tb->out);
tb->indent++;
tb->indent_last_sep = 1;
}
}
static void fput_table_close(struct libscols_table *tb)
{
tb->indent--;
if (scols_table_is_json(tb)) {
fput_indent(tb);
fputc(']', tb->out);
tb->indent--;
fputs(linesep(tb), tb->out);
fputc('}', tb->out);
tb->indent_last_sep = 1;
}
}
static void fput_children_open(struct libscols_table *tb)
{
if (scols_table_is_json(tb)) {
fputc(',', tb->out);
fputs(linesep(tb), tb->out);
fput_indent(tb);
fputs("\"children\": [", tb->out);
}
/* between parent and child is separator */
fputs(linesep(tb), tb->out);
tb->indent_last_sep = 1;
tb->indent++;
tb->termlines_used++;
}
static void fput_children_close(struct libscols_table *tb)
{
tb->indent--;
if (scols_table_is_json(tb)) {
fput_indent(tb);
fputc(']', tb->out);
fputs(linesep(tb), tb->out);
tb->indent_last_sep = 1;
}
}
static void fput_line_open(struct libscols_table *tb)
{
if (scols_table_is_json(tb)) {
fput_indent(tb);
fputc('{', tb->out);
tb->indent_last_sep = 0;
}
tb->indent++;
}
static void fput_line_close(struct libscols_table *tb, int last, int last_in_table)
{
tb->indent--;
if (scols_table_is_json(tb)) {
if (tb->indent_last_sep)
fput_indent(tb);
fputs(last ? "}" : "},", tb->out);
if (!tb->no_linesep)
fputs(linesep(tb), tb->out);
} else if (tb->no_linesep == 0 && last_in_table == 0) {
fputs(linesep(tb), tb->out);
tb->termlines_used++;
}
tb->indent_last_sep = 1;
}
/*
* Prints data. Data can be printed in more formats (raw, NAME=xxx pairs), and
* control and non-printable characters can be encoded in the \x?? encoding.
@ -622,7 +527,7 @@ static int print_line(struct libscols_table *tb,
return 0;
}
static int print_title(struct libscols_table *tb)
int __scols_print_title(struct libscols_table *tb)
{
int rc, color = 0;
mbs_align_t align;
@ -724,7 +629,7 @@ done:
return rc;
}
static int print_header(struct libscols_table *tb, struct libscols_buffer *buf)
int __scols_print_header(struct libscols_table *tb, struct libscols_buffer *buf)
{
int rc = 0;
struct libscols_column *cl;
@ -765,7 +670,7 @@ static int print_header(struct libscols_table *tb, struct libscols_buffer *buf)
}
static int print_range( struct libscols_table *tb,
int __scols_print_range(struct libscols_table *tb,
struct libscols_buffer *buf,
struct libscols_iter *itr,
struct libscols_line *end)
@ -788,19 +693,19 @@ static int print_range( struct libscols_table *tb,
break;
if (!last && want_repeat_header(tb))
print_header(tb, buf);
__scols_print_header(tb, buf);
}
return rc;
}
static int print_table(struct libscols_table *tb, struct libscols_buffer *buf)
int __scols_print_table(struct libscols_table *tb, struct libscols_buffer *buf)
{
struct libscols_iter itr;
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
return print_range(tb, buf, &itr, NULL);
return __scols_print_range(tb, buf, &itr, NULL);
}
@ -844,7 +749,7 @@ done:
return rc;
}
static int print_tree(struct libscols_table *tb, struct libscols_buffer *buf)
int __scols_print_tree(struct libscols_table *tb, struct libscols_buffer *buf)
{
int rc = 0;
struct libscols_line *ln, *last = NULL;
@ -886,7 +791,7 @@ static size_t strlen_line(struct libscols_line *ln)
return sz;
}
static void cleanup_printing(struct libscols_table *tb, struct libscols_buffer *buf)
void __scols_cleanup_printing(struct libscols_table *tb, struct libscols_buffer *buf)
{
if (!tb)
return;
@ -899,7 +804,7 @@ static void cleanup_printing(struct libscols_table *tb, struct libscols_buffer *
}
}
static int initialize_printing(struct libscols_table *tb, struct libscols_buffer **buf)
int __scols_initialize_printing(struct libscols_table *tb, struct libscols_buffer **buf)
{
size_t bufsz, extra_bufsz = 0;
struct libscols_line *ln;
@ -996,214 +901,7 @@ static int initialize_printing(struct libscols_table *tb, struct libscols_buffer
return 0;
err:
cleanup_printing(tb, *buf);
__scols_cleanup_printing(tb, *buf);
return rc;
}
/**
* scola_table_print_range:
* @tb: table
* @start: first printed line or NULL to print from the begin of the table
* @end: last printed line or NULL to print all from start.
*
* If the start is the first line in the table than prints table header too.
* The header is printed only once. This does not work for trees.
*
* Returns: 0, a negative value in case of an error.
*/
int scols_table_print_range( struct libscols_table *tb,
struct libscols_line *start,
struct libscols_line *end)
{
struct libscols_buffer *buf = NULL;
struct libscols_iter itr;
int rc;
if (scols_table_is_tree(tb))
return -EINVAL;
DBG(TAB, ul_debugobj(tb, "printing range from API"));
rc = initialize_printing(tb, &buf);
if (rc)
return rc;
if (start) {
itr.direction = SCOLS_ITER_FORWARD;
itr.head = &tb->tb_lines;
itr.p = &start->ln_lines;
} else
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
if (!start || itr.p == tb->tb_lines.next) {
rc = print_header(tb, buf);
if (rc)
goto done;
}
rc = print_range(tb, buf, &itr, end);
done:
cleanup_printing(tb, buf);
return rc;
}
/**
* scols_table_print_range_to_string:
* @tb: table
* @start: first printed line or NULL to print from the beginning of the table
* @end: last printed line or NULL to print all from start.
* @data: pointer to the beginning of a memory area to print to
*
* The same as scols_table_print_range(), but prints to @data instead of
* stream.
*
* Returns: 0, a negative value in case of an error.
*/
#ifdef HAVE_OPEN_MEMSTREAM
int scols_table_print_range_to_string( struct libscols_table *tb,
struct libscols_line *start,
struct libscols_line *end,
char **data)
{
FILE *stream, *old_stream;
size_t sz;
int rc;
if (!tb)
return -EINVAL;
DBG(TAB, ul_debugobj(tb, "printing range to string"));
/* create a stream for output */
stream = open_memstream(data, &sz);
if (!stream)
return -ENOMEM;
old_stream = scols_table_get_stream(tb);
scols_table_set_stream(tb, stream);
rc = scols_table_print_range(tb, start, end);
fclose(stream);
scols_table_set_stream(tb, old_stream);
return rc;
}
#else
int scols_table_print_range_to_string(
struct libscols_table *tb __attribute__((__unused__)),
struct libscols_line *start __attribute__((__unused__)),
struct libscols_line *end __attribute__((__unused__)),
char **data __attribute__((__unused__)))
{
return -ENOSYS;
}
#endif
static int __scols_print_table(struct libscols_table *tb, int *is_empty)
{
int rc = 0;
struct libscols_buffer *buf = NULL;
if (!tb)
return -EINVAL;
DBG(TAB, ul_debugobj(tb, "printing"));
if (is_empty)
*is_empty = 0;
if (list_empty(&tb->tb_columns)) {
DBG(TAB, ul_debugobj(tb, "error -- no columns"));
return -EINVAL;
}
if (list_empty(&tb->tb_lines)) {
DBG(TAB, ul_debugobj(tb, "ignore -- no lines"));
if (is_empty)
*is_empty = 1;
return 0;
}
tb->header_printed = 0;
rc = initialize_printing(tb, &buf);
if (rc)
return rc;
fput_table_open(tb);
if (tb->format == SCOLS_FMT_HUMAN)
print_title(tb);
rc = print_header(tb, buf);
if (rc)
goto done;
if (scols_table_is_tree(tb))
rc = print_tree(tb, buf);
else
rc = print_table(tb, buf);
fput_table_close(tb);
done:
cleanup_printing(tb, buf);
return rc;
}
/**
* scols_print_table:
* @tb: table
*
* Prints the table to the output stream and terminate by \n.
*
* Returns: 0, a negative value in case of an error.
*/
int scols_print_table(struct libscols_table *tb)
{
int empty = 0;
int rc = __scols_print_table(tb, &empty);
if (rc == 0 && !empty)
fputc('\n', tb->out);
return rc;
}
/**
* scols_print_table_to_string:
* @tb: table
* @data: pointer to the beginning of a memory area to print to
*
* Prints the table to @data.
*
* Returns: 0, a negative value in case of an error.
*/
#ifdef HAVE_OPEN_MEMSTREAM
int scols_print_table_to_string(struct libscols_table *tb, char **data)
{
FILE *stream, *old_stream;
size_t sz;
int rc;
if (!tb)
return -EINVAL;
DBG(TAB, ul_debugobj(tb, "printing to string"));
/* create a stream for output */
stream = open_memstream(data, &sz);
if (!stream)
return -ENOMEM;
old_stream = scols_table_get_stream(tb);
scols_table_set_stream(tb, stream);
rc = __scols_print_table(tb, NULL);
fclose(stream);
scols_table_set_stream(tb, old_stream);
return rc;
}
#else
int scols_print_table_to_string(
struct libscols_table *tb __attribute__((__unused__)),
char **data __attribute__((__unused__)))
{
return -ENOSYS;
}
#endif

View File

@ -250,6 +250,28 @@ extern int __cell_to_buffer(struct libscols_table *tb,
struct libscols_column *cl,
struct libscols_buffer *buf);
void __scols_cleanup_printing(struct libscols_table *tb, struct libscols_buffer *buf);
int __scols_initialize_printing(struct libscols_table *tb, struct libscols_buffer **buf);
int __scols_print_tree(struct libscols_table *tb, struct libscols_buffer *buf);
int __scols_print_table(struct libscols_table *tb, struct libscols_buffer *buf);
int __scols_print_header(struct libscols_table *tb, struct libscols_buffer *buf);
int __scols_print_title(struct libscols_table *tb);
int __scols_print_range(struct libscols_table *tb,
struct libscols_buffer *buf,
struct libscols_iter *itr,
struct libscols_line *end);
/*
* fput.c
*/
extern void fput_indent(struct libscols_table *tb);
extern void fput_table_open(struct libscols_table *tb);
extern void fput_table_close(struct libscols_table *tb);
extern void fput_children_open(struct libscols_table *tb);
extern void fput_children_close(struct libscols_table *tb);
extern void fput_line_open(struct libscols_table *tb);
extern void fput_line_close(struct libscols_table *tb, int last, int last_in_table);
static inline int is_last_child(struct libscols_line *ln)
{
if (!ln || !ln->parent)