blob: 48b954baf33313fe54817494d829179b3f33e5b1 [file] [log] [blame]
#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