summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libsmartcols/src/table.c6
-rw-r--r--libsmartcols/src/table_print.c53
2 files changed, 52 insertions, 7 deletions
diff --git a/libsmartcols/src/table.c b/libsmartcols/src/table.c
index a9beab122..cb4cfae0d 100644
--- a/libsmartcols/src/table.c
+++ b/libsmartcols/src/table.c
@@ -362,7 +362,11 @@ FILE *scols_table_get_stream(struct libscols_table *tb)
* @tb: table
* @reduce: width
*
- * Reduce the output width to @reduce.
+ * If necessary then libsmartcols use all terminal width, the @reduce setting
+ * provides extra space (for example for borders in ncurses applications).
+ *
+ * The @reduce must be smaller than terminal width, otherwise it's sillently
+ * ignored. The reduction is not applied when STDOUT_FILENO is not terminal.
*
* Returns: 0, a negative value in case of an error.
*/
diff --git a/libsmartcols/src/table_print.c b/libsmartcols/src/table_print.c
index daab10a82..8c08e5026 100644
--- a/libsmartcols/src/table_print.c
+++ b/libsmartcols/src/table_print.c
@@ -990,7 +990,7 @@ static size_t strlen_line(struct libscols_line *ln)
int scols_print_table(struct libscols_table *tb)
{
int rc = 0;
- size_t bufsz;
+ size_t bufsz, extra_bufsz = 0;
struct libscols_line *ln;
struct libscols_iter itr;
struct libscols_buffer *buf;
@@ -1008,15 +1008,56 @@ int scols_print_table(struct libscols_table *tb)
if (!tb->symbols)
scols_table_set_symbols(tb, NULL); /* use default */
- tb->is_term = isatty(STDOUT_FILENO) ? 1 : 0;
- tb->termwidth = tb->is_term ? get_terminal_width(80) : 0;
- tb->termwidth -= tb->termreduce;
+ if (tb->format == SCOLS_FMT_HUMAN)
+ tb->is_term = isatty(STDOUT_FILENO) ? 1 : 0;
- bufsz = tb->termwidth;
+ if (tb->is_term) {
+ tb->termwidth = get_terminal_width(80);
+ if (tb->termreduce < tb->termwidth)
+ tb->termwidth -= tb->termreduce;
+ bufsz = tb->termwidth;
+ } else
+ bufsz = BUFSIZ;
+ /*
+ * Estimate extra space necessary for tree, JSON or another output
+ * decoration.
+ */
+ if (scols_table_is_tree(tb))
+ extra_bufsz += tb->nlines * strlen(tb->symbols->vert);
+
+ switch (tb->format) {
+ case SCOLS_FMT_RAW:
+ extra_bufsz += tb->ncols; /* separator between columns */
+ break;
+ case SCOLS_FMT_JSON:
+ if (tb->format == SCOLS_FMT_JSON)
+ extra_bufsz += tb->nlines * 3; /* indention */
+ /* fallthrough */
+ case SCOLS_FMT_EXPORT:
+ {
+ struct libscols_column *cl;
+ scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
+ while (rc == 0 && scols_table_next_column(tb, &itr, &cl) == 0) {
+ if (scols_column_is_hidden(cl))
+ continue;
+ extra_bufsz += strlen(scols_cell_get_data(&cl->header)); /* data */
+ extra_bufsz += 2; /* separators */
+ }
+ break;
+ }
+ case SCOLS_FMT_HUMAN:
+ break;
+ }
+
+
+ /*
+ * Enlarge buffer if necessary, the buffer should be large enough to
+ * store line data and tree ascii art (or another decoration).
+ */
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_line(tb, &itr, &ln) == 0) {
- size_t sz = strlen_line(ln) + tb->termwidth;
+ size_t sz = strlen_line(ln) + extra_bufsz;
if (sz > bufsz)
bufsz = sz;
}