]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libsmartcols: add header-repeat feature
authorKarel Zak <kzak@redhat.com>
Tue, 13 Jun 2017 09:11:17 +0000 (11:11 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 13 Jun 2017 09:11:17 +0000 (11:11 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
libsmartcols/src/libsmartcols.h.in
libsmartcols/src/libsmartcols.sym
libsmartcols/src/smartcolsP.h
libsmartcols/src/table.c
libsmartcols/src/table_print.c

index cfe2439efbd8e303245e08b5cc50c6d2e92ca245..bce2cc725e1485c14b6f283f1f913e447ba466e2 100644 (file)
@@ -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);
index 7b9a3d97b0071fe8ba2f2a6a7789879abb898046..fec33cbfdd78600d77a17cc9274352d056c4a912 100644 (file)
@@ -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;
index 1a749b247afc1f3dbfd362e35a51c69e83ec7a09..65009779aea2f573ae0f7a7867f4248d569200b5 100644 (file)
@@ -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 */
index dd412b2209830a5f0467395e1a35470f4107270a..3306ff57c70eee6a0fac2e67520d4687f2d81037 100644 (file)
@@ -1032,6 +1032,28 @@ int scols_table_enable_noheadings(struct libscols_table *tb, int enable)
        return 0;
 }
 
+/**
+ * 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
@@ -1128,6 +1150,19 @@ int scols_table_is_noheadings(const struct libscols_table *tb)
        return tb->no_headings;
 }
 
+/**
+ * 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
index 8cd737c8babb194ce7fab184190c67e3dae02d20..8e37c80cbb34f3bc642b81f4774ab214d10d1f5f 100644 (file)
@@ -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.