From 066f46e0eeea248274be1c5d6a2ddc731bcff1b3 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 13 Apr 2017 11:19:59 +0200 Subject: libsmartcols: add scols_sort_table_by_tree() Signed-off-by: Karel Zak --- libsmartcols/docs/libsmartcols-sections.txt | 1 + libsmartcols/src/libsmartcols.h.in | 2 +- libsmartcols/src/libsmartcols.sym | 1 + libsmartcols/src/table.c | 55 ++++++++++++++++++++++++++++- 4 files changed, 57 insertions(+), 2 deletions(-) diff --git a/libsmartcols/docs/libsmartcols-sections.txt b/libsmartcols/docs/libsmartcols-sections.txt index 4be9bf22b..a55716db9 100644 --- a/libsmartcols/docs/libsmartcols-sections.txt +++ b/libsmartcols/docs/libsmartcols-sections.txt @@ -105,6 +105,7 @@ scols_copy_table scols_new_table scols_ref_table scols_sort_table +scols_sort_table_by_tree scols_table_add_column scols_table_add_line scols_table_colors_wanted diff --git a/libsmartcols/src/libsmartcols.h.in b/libsmartcols/src/libsmartcols.h.in index 4b2a67284..1ff465e44 100644 --- a/libsmartcols/src/libsmartcols.h.in +++ b/libsmartcols/src/libsmartcols.h.in @@ -268,7 +268,7 @@ extern FILE *scols_table_get_stream(const struct libscols_table *tb); extern int scols_table_reduce_termwidth(struct libscols_table *tb, size_t reduce); extern int scols_sort_table(struct libscols_table *tb, struct libscols_column *cl); - +extern int scols_sort_table_by_tree(struct libscols_table *tb); /* * */ diff --git a/libsmartcols/src/libsmartcols.sym b/libsmartcols/src/libsmartcols.sym index 917cca3d6..95fcc3167 100644 --- a/libsmartcols/src/libsmartcols.sym +++ b/libsmartcols/src/libsmartcols.sym @@ -163,4 +163,5 @@ SMARTCOLS_2.30 { global: scols_cell_get_alignment; scols_table_move_column; + scols_sort_table_by_tree; } SMARTCOLS_2.29; diff --git a/libsmartcols/src/table.c b/libsmartcols/src/table.c index a67028d43..c9f043cc2 100644 --- a/libsmartcols/src/table.c +++ b/libsmartcols/src/table.c @@ -1285,7 +1285,8 @@ static int sort_line_children(struct libscols_line *ln, struct libscols_column * * @tb: table * @cl: order by this column * - * Orders the table by the column. See also scols_column_set_cmpfunc(). + * Orders the table by the column. See also scols_column_set_cmpfunc(). If the + * tree output is enabled then children in the tree are recursively sorted too. * * Returns: 0, a negative value in case of an error. */ @@ -1309,6 +1310,58 @@ int scols_sort_table(struct libscols_table *tb, struct libscols_column *cl) return 0; } +static struct libscols_line *move_line_and_children(struct libscols_line *ln, struct libscols_line *pre) +{ + if (pre) { + list_del_init(&ln->ln_lines); /* remove from old position */ + list_add(&ln->ln_lines, &pre->ln_lines); /* add to the new place (behind @pre) */ + } + pre = ln; + + if (!list_empty(&ln->ln_branch)) { + struct list_head *p; + + list_for_each(p, &ln->ln_branch) { + struct libscols_line *chld = + list_entry(p, struct libscols_line, ln_children); + pre = move_line_and_children(chld, pre); + } + } + + return pre; +} + +/** + * scols_sort_table_by_tree: + * @tb: table + * + * Reorders lines in the tree according to parent->child relation. Note that + * order of lines in the table is independent on the tree hierarchy. + * + * Returns: 0, a negative value in case of an error. + */ +int scols_sort_table_by_tree(struct libscols_table *tb) +{ + struct libscols_line *ln; + struct libscols_iter itr; + + if (!tb) + return -EINVAL; + + DBG(TAB, ul_debugobj(tb, "sorting table by tree")); + + scols_reset_iter(&itr, SCOLS_ITER_FORWARD); + while (scols_table_next_line(tb, &itr, &ln) == 0) { + if (ln->parent) + continue; + + move_line_and_children(ln, NULL); + } + + return 0; +} + + /** * scols_table_set_termforce: * @tb: table -- cgit v1.2.3-55-g7522