libsmartcols: (groups) print group childrent after regualr tree
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
46634fc90d
commit
b94932c063
|
@ -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
|
||||
|
|
|
@ -839,49 +839,33 @@ static int print_tree_line(struct libscols_table *tb,
|
|||
goto done;
|
||||
|
||||
children = has_children(ln);
|
||||
|
||||
/* 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++;
|
||||
}
|
||||
|
||||
if (children || gr_children)
|
||||
fput_children_open(tb);
|
||||
|
||||
/* 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue