|
|
be81ba |
From 543e87865c5b9b7cb08ce8d55da1ef414154d213 Mon Sep 17 00:00:00 2001
|
|
|
be81ba |
From: Karel Zak <kzak@redhat.com>
|
|
|
be81ba |
Date: Wed, 24 Mar 2021 12:43:17 +0100
|
|
|
be81ba |
Subject: [PATCH 61/63] libsmartcols: introduce default sort column
|
|
|
be81ba |
|
|
|
be81ba |
* add default sort column, set by scols_sort_table()
|
|
|
be81ba |
|
|
|
be81ba |
* sort tree according to default sort column also in scols_sort_table_by_tree()
|
|
|
be81ba |
|
|
|
be81ba |
The function scols_sort_table() does not sort tree branches if tree
|
|
|
be81ba |
is not enabled. The function scols_sort_table_by_tree() does not care
|
|
|
be81ba |
if tree is enabled and it always follows parent->child relations. For
|
|
|
be81ba |
scols_sort_table_by_tree() we need to follow order in branches if
|
|
|
be81ba |
previously scols_sort_table() has been called.
|
|
|
be81ba |
|
|
|
be81ba |
For example lsblk calls
|
|
|
be81ba |
|
|
|
be81ba |
scols_sort_table(tb, cl);
|
|
|
be81ba |
scols_sort_table_by_tree(tb);
|
|
|
be81ba |
|
|
|
be81ba |
for list-like output (for example lsblk -P) and users assume the
|
|
|
be81ba |
same order as for tree (lsblk --tree).
|
|
|
be81ba |
|
|
|
be81ba |
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1940607
|
|
|
be81ba |
Upstream: http://github.com/karelzak/util-linux/commit/529b51706ef06611a8165023f14e6593e06901de
|
|
|
be81ba |
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
|
be81ba |
---
|
|
|
be81ba |
libsmartcols/src/smartcolsP.h | 3 ++
|
|
|
be81ba |
libsmartcols/src/table.c | 60 ++++++++++++++++++++++++----------
|
|
|
be81ba |
libsmartcols/src/table_print.c | 6 ++--
|
|
|
be81ba |
misc-utils/lsblk.c | 6 ++--
|
|
|
be81ba |
4 files changed, 52 insertions(+), 23 deletions(-)
|
|
|
be81ba |
|
|
|
be81ba |
diff --git a/libsmartcols/src/smartcolsP.h b/libsmartcols/src/smartcolsP.h
|
|
|
be81ba |
index 510e7a980..8037fb9f5 100644
|
|
|
be81ba |
--- a/libsmartcols/src/smartcolsP.h
|
|
|
be81ba |
+++ b/libsmartcols/src/smartcolsP.h
|
|
|
be81ba |
@@ -160,6 +160,9 @@ struct libscols_table {
|
|
|
be81ba |
|
|
|
be81ba |
struct list_head tb_columns;
|
|
|
be81ba |
struct list_head tb_lines;
|
|
|
be81ba |
+
|
|
|
be81ba |
+ struct libscols_column *dflt_sort_column; /* default sort column, set by scols_sort_table() */
|
|
|
be81ba |
+
|
|
|
be81ba |
struct libscols_symbols *symbols;
|
|
|
be81ba |
struct libscols_cell title; /* optional table title (for humans) */
|
|
|
be81ba |
|
|
|
be81ba |
diff --git a/libsmartcols/src/table.c b/libsmartcols/src/table.c
|
|
|
be81ba |
index 979a09a39..bbabc0817 100644
|
|
|
be81ba |
--- a/libsmartcols/src/table.c
|
|
|
be81ba |
+++ b/libsmartcols/src/table.c
|
|
|
be81ba |
@@ -224,6 +224,8 @@ int scols_table_remove_column(struct libscols_table *tb,
|
|
|
be81ba |
|
|
|
be81ba |
if (cl->flags & SCOLS_FL_TREE)
|
|
|
be81ba |
tb->ntreecols--;
|
|
|
be81ba |
+ if (tb->dflt_sort_column == cl)
|
|
|
be81ba |
+ tb->dflt_sort_column = NULL;
|
|
|
be81ba |
|
|
|
be81ba |
DBG(TAB, ul_debugobj(tb, "remove column"));
|
|
|
be81ba |
list_del_init(&cl->cl_columns);
|
|
|
be81ba |
@@ -1362,41 +1364,63 @@ static int sort_line_children(struct libscols_line *ln, struct libscols_column *
|
|
|
be81ba |
return 0;
|
|
|
be81ba |
}
|
|
|
be81ba |
|
|
|
be81ba |
+static int __scols_sort_tree(struct libscols_table *tb, struct libscols_column *cl)
|
|
|
be81ba |
+{
|
|
|
be81ba |
+ struct libscols_line *ln;
|
|
|
be81ba |
+ struct libscols_iter itr;
|
|
|
be81ba |
+
|
|
|
be81ba |
+ if (!tb || !cl || !cl->cmpfunc)
|
|
|
be81ba |
+ return -EINVAL;
|
|
|
be81ba |
+
|
|
|
be81ba |
+ scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
|
|
|
be81ba |
+ while (scols_table_next_line(tb, &itr, &ln) == 0)
|
|
|
be81ba |
+ sort_line_children(ln, cl);
|
|
|
be81ba |
+ return 0;
|
|
|
be81ba |
+}
|
|
|
be81ba |
+
|
|
|
be81ba |
/**
|
|
|
be81ba |
* scols_sort_table:
|
|
|
be81ba |
* @tb: table
|
|
|
be81ba |
- * @cl: order by this column
|
|
|
be81ba |
+ * @cl: order by this column or NULL
|
|
|
be81ba |
*
|
|
|
be81ba |
* Orders the table by the column. See also scols_column_set_cmpfunc(). If the
|
|
|
be81ba |
* tree output is enabled then children in the tree are recursively sorted too.
|
|
|
be81ba |
*
|
|
|
be81ba |
+ * The column @cl is saved as the default sort column to the @tb and the next time
|
|
|
be81ba |
+ * is possible to call scols_sort_table(tb, NULL). The saved column is also used by
|
|
|
be81ba |
+ * scols_sort_table_by_tree().
|
|
|
be81ba |
+ *
|
|
|
be81ba |
* Returns: 0, a negative value in case of an error.
|
|
|
be81ba |
*/
|
|
|
be81ba |
int scols_sort_table(struct libscols_table *tb, struct libscols_column *cl)
|
|
|
be81ba |
{
|
|
|
be81ba |
- if (!tb || !cl || !cl->cmpfunc)
|
|
|
be81ba |
+ if (!tb)
|
|
|
be81ba |
+ return -EINVAL;
|
|
|
be81ba |
+ if (!cl)
|
|
|
be81ba |
+ cl = tb->dflt_sort_column;
|
|
|
be81ba |
+ if (!cl || !cl->cmpfunc)
|
|
|
be81ba |
return -EINVAL;
|
|
|
be81ba |
|
|
|
be81ba |
- DBG(TAB, ul_debugobj(tb, "sorting table"));
|
|
|
be81ba |
+ DBG(TAB, ul_debugobj(tb, "sorting table by %zu column", cl->seqnum));
|
|
|
be81ba |
list_sort(&tb->tb_lines, cells_cmp_wrapper_lines, cl);
|
|
|
be81ba |
|
|
|
be81ba |
- if (scols_table_is_tree(tb)) {
|
|
|
be81ba |
- struct libscols_line *ln;
|
|
|
be81ba |
- struct libscols_iter itr;
|
|
|
be81ba |
+ if (scols_table_is_tree(tb))
|
|
|
be81ba |
+ __scols_sort_tree(tb, cl);
|
|
|
be81ba |
|
|
|
be81ba |
- scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
|
|
|
be81ba |
- while (scols_table_next_line(tb, &itr, &ln) == 0)
|
|
|
be81ba |
- sort_line_children(ln, cl);
|
|
|
be81ba |
- }
|
|
|
be81ba |
+ if (cl && cl != tb->dflt_sort_column)
|
|
|
be81ba |
+ tb->dflt_sort_column = cl;
|
|
|
be81ba |
|
|
|
be81ba |
return 0;
|
|
|
be81ba |
}
|
|
|
be81ba |
|
|
|
be81ba |
+/*
|
|
|
be81ba |
+ * Move all @ln's children after @ln in the table.
|
|
|
be81ba |
+ */
|
|
|
be81ba |
static struct libscols_line *move_line_and_children(struct libscols_line *ln, struct libscols_line *pre)
|
|
|
be81ba |
{
|
|
|
be81ba |
if (pre) {
|
|
|
be81ba |
list_del_init(&ln->ln_lines); /* remove from old position */
|
|
|
be81ba |
- list_add(&ln->ln_lines, &pre->ln_lines); /* add to the new place (behind @pre) */
|
|
|
be81ba |
+ list_add(&ln->ln_lines, &pre->ln_lines); /* add to the new place (after @pre) */
|
|
|
be81ba |
}
|
|
|
be81ba |
pre = ln;
|
|
|
be81ba |
|
|
|
be81ba |
@@ -1418,7 +1442,10 @@ static struct libscols_line *move_line_and_children(struct libscols_line *ln, st
|
|
|
be81ba |
* @tb: table
|
|
|
be81ba |
*
|
|
|
be81ba |
* Reorders lines in the table by parent->child relation. Note that order of
|
|
|
be81ba |
- * the lines in the table is independent on the tree hierarchy.
|
|
|
be81ba |
+ * the lines in the table is independent on the tree hierarchy by default.
|
|
|
be81ba |
+ *
|
|
|
be81ba |
+ * The children of the lines are sorted according to the default sort column
|
|
|
be81ba |
+ * if scols_sort_table() has been previously called.
|
|
|
be81ba |
*
|
|
|
be81ba |
* Since: 2.30
|
|
|
be81ba |
*
|
|
|
be81ba |
@@ -1434,13 +1461,12 @@ int scols_sort_table_by_tree(struct libscols_table *tb)
|
|
|
be81ba |
|
|
|
be81ba |
DBG(TAB, ul_debugobj(tb, "sorting table by tree"));
|
|
|
be81ba |
|
|
|
be81ba |
- scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
|
|
|
be81ba |
- while (scols_table_next_line(tb, &itr, &ln) == 0) {
|
|
|
be81ba |
- if (ln->parent)
|
|
|
be81ba |
- continue;
|
|
|
be81ba |
+ if (tb->dflt_sort_column)
|
|
|
be81ba |
+ __scols_sort_tree(tb, tb->dflt_sort_column);
|
|
|
be81ba |
|
|
|
be81ba |
+ scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
|
|
|
be81ba |
+ while (scols_table_next_line(tb, &itr, &ln) == 0)
|
|
|
be81ba |
move_line_and_children(ln, NULL);
|
|
|
be81ba |
- }
|
|
|
be81ba |
|
|
|
be81ba |
return 0;
|
|
|
be81ba |
}
|
|
|
be81ba |
diff --git a/libsmartcols/src/table_print.c b/libsmartcols/src/table_print.c
|
|
|
be81ba |
index 8ecfc30e2..337dbbd84 100644
|
|
|
be81ba |
--- a/libsmartcols/src/table_print.c
|
|
|
be81ba |
+++ b/libsmartcols/src/table_print.c
|
|
|
be81ba |
@@ -585,11 +585,9 @@ static int cell_to_buffer(struct libscols_table *tb,
|
|
|
be81ba |
|
|
|
be81ba |
ce = scols_line_get_cell(ln, cl->seqnum);
|
|
|
be81ba |
data = ce ? scols_cell_get_data(ce) : NULL;
|
|
|
be81ba |
- if (!data)
|
|
|
be81ba |
- return 0;
|
|
|
be81ba |
|
|
|
be81ba |
if (!scols_column_is_tree(cl))
|
|
|
be81ba |
- return buffer_set_data(buf, data);
|
|
|
be81ba |
+ return data ? buffer_set_data(buf, data) : 0;
|
|
|
be81ba |
|
|
|
be81ba |
/*
|
|
|
be81ba |
* Tree stuff
|
|
|
be81ba |
@@ -605,7 +603,7 @@ static int cell_to_buffer(struct libscols_table *tb,
|
|
|
be81ba |
buffer_set_art_index(buf);
|
|
|
be81ba |
}
|
|
|
be81ba |
|
|
|
be81ba |
- if (!rc)
|
|
|
be81ba |
+ if (!rc && data)
|
|
|
be81ba |
rc = buffer_append_data(buf, data);
|
|
|
be81ba |
return rc;
|
|
|
be81ba |
}
|
|
|
be81ba |
diff --git a/misc-utils/lsblk.c b/misc-utils/lsblk.c
|
|
|
be81ba |
index d0369d3e7..cc7894ecf 100644
|
|
|
be81ba |
--- a/misc-utils/lsblk.c
|
|
|
be81ba |
+++ b/misc-utils/lsblk.c
|
|
|
be81ba |
@@ -1894,10 +1894,12 @@ int main(int argc, char *argv[])
|
|
|
be81ba |
* /sys is no more sorted */
|
|
|
be81ba |
lsblk->sort_id = COL_MAJMIN;
|
|
|
be81ba |
|
|
|
be81ba |
- /* For --inverse --list we still follow parent->child relation */
|
|
|
be81ba |
- if (lsblk->inverse && !(lsblk->flags & LSBLK_TREE))
|
|
|
be81ba |
+ /* For --{inverse,raw,pairs} --list we still follow parent->child relation */
|
|
|
be81ba |
+ if (!(lsblk->flags & LSBLK_TREE)
|
|
|
be81ba |
+ && (lsblk->inverse || lsblk->flags & LSBLK_EXPORT || lsblk->flags & LSBLK_RAW))
|
|
|
be81ba |
lsblk->force_tree_order = 1;
|
|
|
be81ba |
|
|
|
be81ba |
+
|
|
|
be81ba |
if (lsblk->sort_id >= 0 && column_id_to_number(lsblk->sort_id) < 0) {
|
|
|
be81ba |
/* the sort column is not between output columns -- add as hidden */
|
|
|
be81ba |
add_column(lsblk->sort_id);
|
|
|
be81ba |
--
|
|
|
be81ba |
2.31.1
|
|
|
be81ba |
|