]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libsmartcols: add scols_table_enable_nowrap()
authorKarel Zak <kzak@redhat.com>
Mon, 7 Dec 2015 11:03:52 +0000 (12:03 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 7 Dec 2015 11:03:52 +0000 (12:03 +0100)
This allows to use libsmartcols in ncurses programs without any
additional voodoo.

Signed-off-by: Karel Zak <kzak@redhat.com>
libsmartcols/docs/libsmartcols-sections.txt
libsmartcols/src/libsmartcols.h.in
libsmartcols/src/libsmartcols.sym
libsmartcols/src/smartcolsP.h
libsmartcols/src/table.c
libsmartcols/src/table_print.c

index 01bc2a63c13dd55cc5b219b5e8eb6cab9d84319a..071df3fff2ef8b92f8c394486412f64048be3ccc 100644 (file)
@@ -96,6 +96,7 @@ scols_table_enable_export
 scols_table_enable_json
 scols_table_enable_maxout
 scols_table_enable_noheadings
+scols_table_enable_nowrap
 scols_table_enable_raw
 scols_table_get_column
 scols_table_get_column_separator
index d2a88c9cdb9128100fcc4f7bedec81893784f629..2ac166b325c0ff337891c8b1062be3b787f26222 100644 (file)
@@ -189,6 +189,7 @@ 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_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);
 
 extern int scols_table_set_column_separator(struct libscols_table *tb, const char *sep);
 extern int scols_table_set_line_separator(struct libscols_table *tb, const char *sep);
index 0ef3322b384e8c3a6adb100406205b7356825a2e..e3176ba5b3342032d664b966e9668401effe64f3 100644 (file)
@@ -120,3 +120,8 @@ global:
        scols_table_is_json;
        scols_table_set_name;
 } SMARTCOLS_2.25;
+
+SMARTCOLS_2.28 {
+global:
+       scols_table_enable_nowrap;
+} SMARTCOLS_2.27;
index c4df79b534bd933cdf183d8fe3bdb7cedd338a75..8f371a7d583dcc47bf154582ea3bb06515fa9c50 100644 (file)
@@ -89,6 +89,8 @@ struct libscols_column {
 
        struct libscols_cell    header;
        struct list_head        cl_columns;
+
+       unsigned int ignore : 1;
 };
 
 /*
@@ -147,7 +149,8 @@ struct libscols_table {
                        colors_wanted   :1,     /* enable colors */
                        is_term         :1,     /* isatty() */
                        maxout          :1,     /* maximalize output */
-                       no_headings     :1;     /* don't print header */
+                       no_headings     :1,     /* don't print header */
+                       no_wrap         :1;     /* never wrap lines */
 };
 
 #define IS_ITER_FORWARD(_i)    ((_i)->direction == SCOLS_ITER_FORWARD)
index a42ae514dae6bc8318f9890373dcc88f521874d6..a9beab122f47a1e1973be9bec6e156ec6f8b6a76 100644 (file)
@@ -838,6 +838,24 @@ int scols_table_enable_maxout(struct libscols_table *tb, int enable)
        return 0;
 }
 
+/**
+ * scols_table_enable_nowrap:
+ * @tb: table
+ * @enable: 1 or 0
+ *
+ * Never continue on next line, remove last column(s) when too large, truncate last column.
+ *
+ * Returns: 0 on success, negative number in case of an error.
+ */
+int scols_table_enable_nowrap(struct libscols_table *tb, int enable)
+{
+       if (!tb)
+               return -EINVAL;
+       DBG(TAB, ul_debugobj(tb, "nowrap: %s", enable ? "ENABLE" : "DISABLE"));
+       tb->no_wrap = enable ? 1 : 0;
+       return 0;
+}
+
 /**
  * scols_table_colors_wanted:
  * @tb: table
index 9e676e417cd4f6213a6b90c5b6c2b282d5b54b27..24f1d5a4dcab559a94033d99cbe26b37c7d76456 100644 (file)
@@ -176,8 +176,19 @@ static int line_ascii_art_to_buffer(struct libscols_table *tb,
        return buffer_append_data(buf, art);
 }
 
-#define is_last_column(_tb, _cl) \
-               list_entry_is_last(&(_cl)->cl_columns, &(_tb)->tb_columns)
+static int is_last_column(struct libscols_table *tb, struct libscols_column *cl) 
+{
+       int rc = list_entry_is_last(&cl->cl_columns, &tb->tb_columns);
+       struct libscols_column *next;
+
+       if (rc)
+               return 1;
+
+       next = list_entry(cl->cl_columns.next, struct libscols_column, cl_columns);
+       if (next && next->ignore)
+               return 1;
+       return 0;
+}
 
 #define colsep(tb) ((tb)->colsep ? (tb)->colsep : " ")
 #define linesep(tb) ((tb)->linesep ? (tb)->linesep : "\n")
@@ -518,6 +529,8 @@ static int print_line(struct libscols_table *tb,
 
        scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
        while (rc == 0 && scols_table_next_column(tb, &itr, &cl) == 0) {
+               if (cl->ignore)
+                       continue;
                rc = cell_to_buffer(tb, ln, cl, buf);
                if (!rc)
                        rc = print_data(tb, cl, ln,
@@ -547,6 +560,8 @@ static int print_header(struct libscols_table *tb, struct libscols_buffer *buf)
        /* set the width according to the size of the data */
        scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
        while (rc == 0 && scols_table_next_column(tb, &itr, &cl) == 0) {
+               if (cl->ignore)
+                       continue;
                rc = buffer_set_data(buf, scols_cell_get_data(&cl->header));
                if (!rc)
                        rc = print_data(tb, cl, NULL, &cl->header, buf);
@@ -642,9 +657,14 @@ static int print_tree(struct libscols_table *tb, struct libscols_buffer *buf)
 
 static void dbg_column(struct libscols_table *tb, struct libscols_column *cl)
 {
+       if (cl->ignore) {
+               DBG(COL, ul_debugobj(cl, "%s ignored", cl->header.data));
+               return;
+       }
+
        DBG(COL, ul_debugobj(cl, "%15s seq=%zu, width=%zd, "
                                 "hint=%d, avg=%zu, max=%zu, min=%zu, "
-                                "extreme=%s",
+                                "extreme=%s %s",
 
                cl->header.data, cl->seqnum, cl->width,
                cl->width_hint > 1 ? (int) cl->width_hint :
@@ -652,7 +672,8 @@ static void dbg_column(struct libscols_table *tb, struct libscols_column *cl)
                cl->width_avg,
                cl->width_max,
                cl->width_min,
-               cl->is_extreme ? "yes" : "not"));
+               cl->is_extreme ? "yes" : "not",
+               cl->flags & SCOLS_FL_TRUNC ? "trunc" : ""));
 }
 
 static void dbg_columns(struct libscols_table *tb)
@@ -766,7 +787,7 @@ static int recount_widths(struct libscols_table *tb, struct libscols_buffer *buf
                if (rc)
                        goto done;
 
-               width += cl->width + (is_last_column(tb, cl) ? 0 : 1);
+               width += cl->width + (is_last_column(tb, cl) ? 0 : 1);  /* separator for non-last column */
                extremes += cl->is_extreme;
        }
 
@@ -910,6 +931,26 @@ static int recount_widths(struct libscols_table *tb, struct libscols_buffer *buf
                }
        }
 
+       /* ignore last column(s) or force last column to be truncated if
+        * nowrap mode enabled */
+       if (tb->no_wrap && width > tb->termwidth) {
+               scols_reset_iter(&itr, SCOLS_ITER_BACKWARD);
+               while (scols_table_next_column(tb, &itr, &cl) == 0) {
+
+                       if (width <= tb->termwidth)
+                               break;
+                       if (width - cl->width < tb->termwidth) {
+                               size_t r =  width - tb->termwidth;
+
+                               cl->flags |= SCOLS_FL_TRUNC;
+                               cl->width -= r;
+                               width -= r;
+                       } else {
+                               cl->ignore = 1;
+                               width -= cl->width + 1;         /* +1 means separator between columns */
+                       }
+               }
+       }
 done:
        DBG(TAB, ul_debugobj(tb, "  final width: %zu (rc=%d)", width, rc));
        ON_DBG(TAB, dbg_columns(tb));