summaryrefslogtreecommitdiffstats
path: root/libsmartcols
diff options
context:
space:
mode:
authorKarel Zak2019-05-03 14:53:23 +0200
committerKarel Zak2019-05-03 14:53:23 +0200
commitb94932c063f642abe06e8f3fb72e3abe4416371f (patch)
tree4d0c2db96fe96c7ab6042a68fcb3119649d8ddc5 /libsmartcols
parentlibsmartcols: (groups) improve debug messages (diff)
downloadkernel-qcow2-util-linux-b94932c063f642abe06e8f3fb72e3abe4416371f.tar.gz
kernel-qcow2-util-linux-b94932c063f642abe06e8f3fb72e3abe4416371f.tar.xz
kernel-qcow2-util-linux-b94932c063f642abe06e8f3fb72e3abe4416371f.zip
libsmartcols: (groups) print group childrent after regualr tree
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libsmartcols')
-rw-r--r--libsmartcols/src/grouping.c28
-rw-r--r--libsmartcols/src/print.c70
-rw-r--r--libsmartcols/src/smartcolsP.h2
3 files changed, 72 insertions, 28 deletions
diff --git a/libsmartcols/src/grouping.c b/libsmartcols/src/grouping.c
index b767405aa..c8515cc92 100644
--- a/libsmartcols/src/grouping.c
+++ b/libsmartcols/src/grouping.c
@@ -468,7 +468,8 @@ int scols_groups_calculate_grpset(struct libscols_table *tb)
}
scols_groups_reset_state(tb);
- DBG(TAB, ul_debugobj(tb, "<- done grpset calculate [top-level]"));
+ DBG(TAB, ul_debugobj(tb, "<- done grpset calculate [top-level, rc=%d, size=%zu]",
+ rc, tb->grpset_size));
return rc;
}
@@ -489,6 +490,7 @@ void scols_groups_reset_state(struct libscols_table *tb)
DBG(TAB, ul_debugobj(tb, " zeroize grpset"));
memset(tb->grpset, 0, tb->grpset_size * sizeof(struct libscols_group *));
}
+ tb->ngrpchlds_pending = 0;
}
static void add_member(struct libscols_group *gr, struct libscols_line *ln)
@@ -504,6 +506,30 @@ static void add_member(struct libscols_group *gr, struct libscols_line *ln)
scols_ref_line(ln);
}
+/*
+ * Returns first group which is ready to print group children.
+ *
+ * This function scans grpset[] in backward order and returns first group
+ * with SCOLS_GSTATE_CONT_CHILDREN or SCOLS_GSTATE_LAST_MEMBER state.
+ */
+struct libscols_group *scols_grpset_get_printable_children(struct libscols_table *tb)
+{
+ size_t i;
+
+ for (i = tb->grpset_size; i > 0; i -= SCOLS_GRPSET_CHUNKSIZ) {
+ struct libscols_group *gr = tb->grpset[i-1];
+
+ if (gr == NULL)
+ continue;
+ if (gr->state == SCOLS_GSTATE_CONT_CHILDREN ||
+ gr->state == SCOLS_GSTATE_LAST_MEMBER)
+ return gr;
+ }
+
+ return NULL;
+}
+
+
/**
* scols_table_group_lines:
* @tb: a pointer to a struct libscols_table instance
diff --git a/libsmartcols/src/print.c b/libsmartcols/src/print.c
index 2a43e2243..526b0b763 100644
--- a/libsmartcols/src/print.c
+++ b/libsmartcols/src/print.c
@@ -839,49 +839,33 @@ static int print_tree_line(struct libscols_table *tb,
goto done;
children = has_children(ln);
- gr_children = is_last_group_member(ln) && has_group_children(ln);
- if (children || gr_children)
- fput_children_open(tb);
+ /* we print group children in __scols_print_tree() after tree is printed */
+ gr_children = is_last_group_member(ln) && has_group_children(ln);
+ if (gr_children) {
+ last_in_table = 0;
+ tb->ngrpchlds_pending++;
+ }
- /* print children */
if (children) {
struct list_head *p;
DBG(LINE, ul_debugobj(ln, " printing children"));
+ fput_children_open(tb);
list_for_each(p, &ln->ln_branch) {
struct libscols_line *chld =
list_entry(p, struct libscols_line, ln_children);
- int last_child = !gr_children && p->next == &ln->ln_branch;
-
- rc = print_tree_line(tb, chld, buf, last_child, last_in_table && last_child);
- if (rc)
- goto done;
- }
- }
-
- /* print group's children */
- if (gr_children) {
- struct list_head *p;
-
- DBG(LINE, ul_debugobj(ln, " printing group children"));
-
- list_for_each(p, &ln->group->gr_children) {
- struct libscols_line *chld =
- list_entry(p, struct libscols_line, ln_children);
- int last_child = p->next == &ln->group->gr_children;
+ int last_child = p->next == &ln->ln_branch;
rc = print_tree_line(tb, chld, buf, last_child, last_in_table && last_child);
if (rc)
goto done;
}
- }
-
- if (children || gr_children)
fput_children_close(tb);
+ }
- if ((!children && !gr_children) || scols_table_is_json(tb))
+ if (!children || scols_table_is_json(tb))
fput_line_close(tb, last, last_in_table);
done:
DBG(LINE, ul_debugobj(ln, "<- print tree line [rc=%d]", rc));
@@ -912,8 +896,40 @@ int __scols_print_tree(struct libscols_table *tb, struct libscols_buffer *buf)
if (ln->parent || ln->parent_group)
continue;
rc = print_tree_line(tb, ln, buf, ln == last, ln == last);
- }
+ if (rc)
+ break;
+
+ DBG(LINE, ul_debugobj(ln, " pending groups: %zu", tb->ngrpchlds_pending));
+
+ /* print group's children */
+ while (tb->ngrpchlds_pending) {
+ struct libscols_group *gr = scols_grpset_get_printable_children(tb);
+ struct list_head *p;
+
+ DBG(LINE, ul_debugobj(ln, " printing group children [pending=%zu]", tb->ngrpchlds_pending));
+ if (!gr) {
+ DBG(LINE, ul_debugobj(ln, " *** ngrpchlds_pending counter invalid"));
+ tb->ngrpchlds_pending = 0;
+ break;
+ }
+ DBG(LINE, ul_debugobj(ln, " printing group children"));
+ tb->ngrpchlds_pending--;
+ list_for_each(p, &gr->gr_children) {
+ struct libscols_line *chld =
+ list_entry(p, struct libscols_line, ln_children);
+ int last_child = p->next == &gr->gr_children;
+
+ rc = print_tree_line(tb, chld, buf, last_child,
+ last_child
+ && ln == last
+ && tb->ngrpchlds_pending == 0);
+ if (rc)
+ goto done;
+ }
+ }
+ }
+done:
return rc;
}
diff --git a/libsmartcols/src/smartcolsP.h b/libsmartcols/src/smartcolsP.h
index bbc8a98a1..c063db212 100644
--- a/libsmartcols/src/smartcolsP.h
+++ b/libsmartcols/src/smartcolsP.h
@@ -214,6 +214,7 @@ struct libscols_table {
struct list_head tb_groups; /* all defined groups */
struct libscols_group **grpset;
size_t grpset_size;
+ size_t ngrpchlds_pending; /* groups with not yet printed children */
struct libscols_symbols *symbols;
struct libscols_cell title; /* optional table title (for humans) */
@@ -311,6 +312,7 @@ void scols_groups_fix_members_order(struct libscols_table *tb);
int scols_groups_calculate_grpset(struct libscols_table *tb);
int scols_groups_update_grpset(struct libscols_table *tb, struct libscols_line *ln);
void scols_groups_reset_state(struct libscols_table *tb);
+struct libscols_group *scols_grpset_get_printable_children(struct libscols_table *tb);
/*
* calculate.c