summaryrefslogtreecommitdiffstats
path: root/libsmartcols
diff options
context:
space:
mode:
authorKarel Zak2017-06-13 11:11:17 +0200
committerKarel Zak2017-06-13 11:11:17 +0200
commit36e07cebf1323098b2854b3571563abda01f0323 (patch)
treecdb3d6ec25cc443031c660c7e8ddbadbe8cbf356 /libsmartcols
parentlibsmartcols: add missing symbols (diff)
downloadkernel-qcow2-util-linux-36e07cebf1323098b2854b3571563abda01f0323.tar.gz
kernel-qcow2-util-linux-36e07cebf1323098b2854b3571563abda01f0323.tar.xz
kernel-qcow2-util-linux-36e07cebf1323098b2854b3571563abda01f0323.zip
libsmartcols: add header-repeat feature
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libsmartcols')
-rw-r--r--libsmartcols/src/libsmartcols.h.in2
-rw-r--r--libsmartcols/src/libsmartcols.sym2
-rw-r--r--libsmartcols/src/smartcolsP.h4
-rw-r--r--libsmartcols/src/table.c35
-rw-r--r--libsmartcols/src/table_print.c27
5 files changed, 67 insertions, 3 deletions
diff --git a/libsmartcols/src/libsmartcols.h.in b/libsmartcols/src/libsmartcols.h.in
index cfe2439ef..bce2cc725 100644
--- a/libsmartcols/src/libsmartcols.h.in
+++ b/libsmartcols/src/libsmartcols.h.in
@@ -219,6 +219,7 @@ extern int scols_table_is_raw(const struct libscols_table *tb);
extern int scols_table_is_ascii(const struct libscols_table *tb);
extern int scols_table_is_json(const struct libscols_table *tb);
extern int scols_table_is_noheadings(const struct libscols_table *tb);
+extern int scols_table_is_header_repeat(const struct libscols_table *tb);
extern int scols_table_is_empty(const struct libscols_table *tb);
extern int scols_table_is_export(const struct libscols_table *tb);
extern int scols_table_is_maxout(const struct libscols_table *tb);
@@ -231,6 +232,7 @@ extern int scols_table_enable_raw(struct libscols_table *tb, int enable);
extern int scols_table_enable_ascii(struct libscols_table *tb, int enable);
extern int scols_table_enable_json(struct libscols_table *tb, int enable);
extern int scols_table_enable_noheadings(struct libscols_table *tb, int enable);
+extern int scols_table_enable_header_repeat(struct libscols_table *tb, int enable);
extern int scols_table_enable_export(struct libscols_table *tb, int enable);
extern int scols_table_enable_maxout(struct libscols_table *tb, int enable);
extern int scols_table_enable_nowrap(struct libscols_table *tb, int enable);
diff --git a/libsmartcols/src/libsmartcols.sym b/libsmartcols/src/libsmartcols.sym
index 7b9a3d97b..fec33cbfd 100644
--- a/libsmartcols/src/libsmartcols.sym
+++ b/libsmartcols/src/libsmartcols.sym
@@ -171,4 +171,6 @@ global:
SMARTCOLS_2.31 {
scols_table_set_termheight;
scols_table_get_termheight;
+ scols_table_is_header_repeat;
+ scols_table_enable_header_repeat;
} SMARTCOLS_2.30;
diff --git a/libsmartcols/src/smartcolsP.h b/libsmartcols/src/smartcolsP.h
index 1a749b247..65009779a 100644
--- a/libsmartcols/src/smartcolsP.h
+++ b/libsmartcols/src/smartcolsP.h
@@ -164,12 +164,16 @@ struct libscols_table {
int indent_last_sep;/* last printed has been line separator */
int format; /* SCOLS_FMT_* */
+ size_t termlines_used; /* printed line counter */
+ size_t header_next; /* where repeat header */
+
/* flags */
unsigned int ascii :1, /* don't use unicode */
colors_wanted :1, /* enable colors */
is_term :1, /* isatty() */
padding_debug :1, /* output visible padding chars */
maxout :1, /* maximize output */
+ header_repeat :1, /* print header after libscols_table->termheight */
header_printed :1, /* header already printed */
priv_symbols :1, /* default private symbols */
no_headings :1, /* don't print header */
diff --git a/libsmartcols/src/table.c b/libsmartcols/src/table.c
index dd412b220..3306ff57c 100644
--- a/libsmartcols/src/table.c
+++ b/libsmartcols/src/table.c
@@ -1033,6 +1033,28 @@ int scols_table_enable_noheadings(struct libscols_table *tb, int enable)
}
/**
+ * scols_table_enable_header_repeat:
+ * @tb: table
+ * @enable: 1 or 0
+ *
+ * Enable/disable header line repeat. The header line is printed only once by
+ * default. Note that the flag will be silently ignored and disabled if the
+ * output is not on terminal or output format is JSON, raw, etc.
+ *
+ * Returns: 0 on success, negative number in case of an error.
+ *
+ * Since: 2.31
+ */
+int scols_table_enable_header_repeat(struct libscols_table *tb, int enable)
+{
+ if (!tb)
+ return -EINVAL;
+ DBG(TAB, ul_debugobj(tb, "header-repeat: %s", enable ? "ENABLE" : "DISABLE"));
+ tb->header_repeat = enable ? 1 : 0;
+ return 0;
+}
+
+/**
* scols_table_enable_maxout:
* @tb: table
* @enable: 1 or 0
@@ -1129,6 +1151,19 @@ int scols_table_is_noheadings(const struct libscols_table *tb)
}
/**
+ * scols_table_is_header_repeat
+ * @tb: table
+ *
+ * Returns: 1 if header repeat is enabled.
+ *
+ * Since: 2.31
+ */
+int scols_table_is_header_repeat(const struct libscols_table *tb)
+{
+ return tb->header_repeat;
+}
+
+/**
* scols_table_is_export:
* @tb: table
*
diff --git a/libsmartcols/src/table_print.c b/libsmartcols/src/table_print.c
index 8cd737c8b..8e37c80cb 100644
--- a/libsmartcols/src/table_print.c
+++ b/libsmartcols/src/table_print.c
@@ -43,6 +43,9 @@
#define cellpadding_symbol(tb) ((tb)->padding_debug ? "." : \
((tb)->symbols->cell_padding ? (tb)->symbols->cell_padding: " "))
+#define want_repeat_header(tb) (!(tb)->header_repeat || (tb)->header_next <= (tb)->termlines_used)
+
+
/* This is private struct to work with output data */
struct libscols_buffer {
char *begin; /* begin of the buffer */
@@ -307,6 +310,7 @@ static void print_newline_padding(struct libscols_table *tb,
assert(cl);
fputs(linesep(tb), tb->out); /* line break */
+ tb->termlines_used++;
/* fill cells after line break */
for (i = 0; i <= (size_t) cl->seqnum; i++)
@@ -650,6 +654,7 @@ static void fput_children_open(struct libscols_table *tb)
fputs(linesep(tb), tb->out);
tb->indent_last_sep = 1;
tb->indent++;
+ tb->termlines_used++;
}
static void fput_children_close(struct libscols_table *tb)
@@ -684,8 +689,10 @@ static void fput_line_close(struct libscols_table *tb, int last, int last_in_tab
if (!tb->no_linesep)
fputs(linesep(tb), tb->out);
- } else if (tb->no_linesep == 0 && last_in_table == 0)
+ } else if (tb->no_linesep == 0 && last_in_table == 0) {
fputs(linesep(tb), tb->out);
+ tb->termlines_used++;
+ }
tb->indent_last_sep = 1;
}
@@ -724,6 +731,7 @@ static int print_line(struct libscols_table *tb,
while (rc == 0 && pending) {
pending = 0;
fputs(linesep(tb), tb->out);
+ tb->termlines_used++;
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (rc == 0 && scols_table_next_column(tb, &itr, &cl) == 0) {
if (scols_column_is_hidden(cl))
@@ -833,7 +841,7 @@ static int print_header(struct libscols_table *tb, struct libscols_buffer *buf)
assert(tb);
- if (tb->header_printed == 1 ||
+ if ((tb->header_printed == 1 && tb->header_repeat == 0) ||
scols_table_is_noheadings(tb) ||
scols_table_is_export(tb) ||
scols_table_is_json(tb) ||
@@ -852,13 +860,20 @@ static int print_header(struct libscols_table *tb, struct libscols_buffer *buf)
rc = print_data(tb, cl, NULL, &cl->header, buf);
}
- if (rc == 0)
+ if (rc == 0) {
fputs(linesep(tb), tb->out);
+ tb->termlines_used++;
+ }
tb->header_printed = 1;
+ tb->header_next = tb->termlines_used + tb->termheight;
+ if (tb->header_repeat)
+ DBG(TAB, ul_debugobj(tb, "\tnext header: %zu [current=%zu]",
+ tb->header_next, tb->termlines_used));
return rc;
}
+
static int print_range( struct libscols_table *tb,
struct libscols_buffer *buf,
struct libscols_iter *itr,
@@ -879,6 +894,9 @@ static int print_range( struct libscols_table *tb,
if (end && ln == end)
break;
+
+ if (!last && want_repeat_header(tb))
+ print_header(tb, buf);
}
return rc;
@@ -1398,6 +1416,9 @@ static int initialize_printing(struct libscols_table *tb, struct libscols_buffer
} else
bufsz = BUFSIZ;
+ if (!tb->is_term || tb->format != SCOLS_FMT_HUMAN || scols_table_is_tree(tb))
+ tb->header_repeat = 0;
+
/*
* Estimate extra space necessary for tree, JSON or another output
* decoration.