summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libsmartcols/docs/libsmartcols-sections.txt1
-rw-r--r--libsmartcols/src/libsmartcols.h.in1
-rw-r--r--libsmartcols/src/libsmartcols.sym5
-rw-r--r--libsmartcols/src/smartcolsP.h5
-rw-r--r--libsmartcols/src/table.c18
-rw-r--r--libsmartcols/src/table_print.c51
6 files changed, 75 insertions, 6 deletions
diff --git a/libsmartcols/docs/libsmartcols-sections.txt b/libsmartcols/docs/libsmartcols-sections.txt
index 01bc2a63c..071df3fff 100644
--- a/libsmartcols/docs/libsmartcols-sections.txt
+++ b/libsmartcols/docs/libsmartcols-sections.txt
@@ -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
diff --git a/libsmartcols/src/libsmartcols.h.in b/libsmartcols/src/libsmartcols.h.in
index d2a88c9cd..2ac166b32 100644
--- a/libsmartcols/src/libsmartcols.h.in
+++ b/libsmartcols/src/libsmartcols.h.in
@@ -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);
diff --git a/libsmartcols/src/libsmartcols.sym b/libsmartcols/src/libsmartcols.sym
index 0ef3322b3..e3176ba5b 100644
--- a/libsmartcols/src/libsmartcols.sym
+++ b/libsmartcols/src/libsmartcols.sym
@@ -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;
diff --git a/libsmartcols/src/smartcolsP.h b/libsmartcols/src/smartcolsP.h
index c4df79b53..8f371a7d5 100644
--- a/libsmartcols/src/smartcolsP.h
+++ b/libsmartcols/src/smartcolsP.h
@@ -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)
diff --git a/libsmartcols/src/table.c b/libsmartcols/src/table.c
index a42ae514d..a9beab122 100644
--- a/libsmartcols/src/table.c
+++ b/libsmartcols/src/table.c
@@ -839,6 +839,24 @@ int scols_table_enable_maxout(struct libscols_table *tb, int enable)
}
/**
+ * 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
*
diff --git a/libsmartcols/src/table_print.c b/libsmartcols/src/table_print.c
index 9e676e417..24f1d5a4d 100644
--- a/libsmartcols/src/table_print.c
+++ b/libsmartcols/src/table_print.c
@@ -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));