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:
parent
06a8decd72
commit
3bb882be44
|
@ -16,6 +16,8 @@ libsmartcols_la_SOURCES= \
|
||||||
libsmartcols/src/line.c \
|
libsmartcols/src/line.c \
|
||||||
libsmartcols/src/table.c \
|
libsmartcols/src/table.c \
|
||||||
libsmartcols/src/print.c \
|
libsmartcols/src/print.c \
|
||||||
|
libsmartcols/src/fput.c \
|
||||||
|
libsmartcols/src/print-api.c \
|
||||||
libsmartcols/src/version.c \
|
libsmartcols/src/version.c \
|
||||||
libsmartcols/src/buffer.c \
|
libsmartcols/src/buffer.c \
|
||||||
libsmartcols/src/calculate.c \
|
libsmartcols/src/calculate.c \
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -476,101 +476,6 @@ int __cell_to_buffer(struct libscols_table *tb,
|
||||||
return rc;
|
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
|
* 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.
|
* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int print_title(struct libscols_table *tb)
|
int __scols_print_title(struct libscols_table *tb)
|
||||||
{
|
{
|
||||||
int rc, color = 0;
|
int rc, color = 0;
|
||||||
mbs_align_t align;
|
mbs_align_t align;
|
||||||
|
@ -724,7 +629,7 @@ done:
|
||||||
return rc;
|
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;
|
int rc = 0;
|
||||||
struct libscols_column *cl;
|
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_buffer *buf,
|
||||||
struct libscols_iter *itr,
|
struct libscols_iter *itr,
|
||||||
struct libscols_line *end)
|
struct libscols_line *end)
|
||||||
|
@ -788,19 +693,19 @@ static int print_range( struct libscols_table *tb,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!last && want_repeat_header(tb))
|
if (!last && want_repeat_header(tb))
|
||||||
print_header(tb, buf);
|
__scols_print_header(tb, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
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;
|
struct libscols_iter itr;
|
||||||
|
|
||||||
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
|
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;
|
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;
|
int rc = 0;
|
||||||
struct libscols_line *ln, *last = NULL;
|
struct libscols_line *ln, *last = NULL;
|
||||||
|
@ -886,7 +791,7 @@ static size_t strlen_line(struct libscols_line *ln)
|
||||||
return sz;
|
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)
|
if (!tb)
|
||||||
return;
|
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;
|
size_t bufsz, extra_bufsz = 0;
|
||||||
struct libscols_line *ln;
|
struct libscols_line *ln;
|
||||||
|
@ -996,214 +901,7 @@ static int initialize_printing(struct libscols_table *tb, struct libscols_buffer
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err:
|
err:
|
||||||
cleanup_printing(tb, *buf);
|
__scols_cleanup_printing(tb, *buf);
|
||||||
return rc;
|
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
|
|
||||||
|
|
||||||
|
|
|
@ -250,6 +250,28 @@ extern int __cell_to_buffer(struct libscols_table *tb,
|
||||||
struct libscols_column *cl,
|
struct libscols_column *cl,
|
||||||
struct libscols_buffer *buf);
|
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)
|
static inline int is_last_child(struct libscols_line *ln)
|
||||||
{
|
{
|
||||||
if (!ln || !ln->parent)
|
if (!ln || !ln->parent)
|
||||||
|
|
Loading…
Reference in New Issue