static gboolean prune_maybe (MuContainer *c) { MuContainer *cur; for (cur = c->child; cur; cur = cur->next) { if (cur->flags & MU_CONTAINER_FLAG_DELETE) c = mu_container_remove_child (c, cur); else if (cur->flags & MU_CONTAINER_FLAG_SPLICE) c = mu_container_splice_children (c, cur); } g_return_val_if_fail (c, FALSE); /* don't touch containers with messages */ if (c->msg) return TRUE; /* A. If it is an msg-less container with no children, mark it * for deletion. */ if (!c->child) { c->flags |= MU_CONTAINER_FLAG_DELETE; return TRUE; } /* B. If the MuContainer has no Message, but does have * children, remove this container but promote its * children to this level (that is, splice them in to * the current child list.) * * Do not promote the children if doing so would * promote them to the root set -- unless there is * only one child, in which case, do. */ if (c->child->next) /* ie., > 1 child */ return TRUE; c->flags |= MU_CONTAINER_FLAG_SPLICE; return TRUE; }
static MuContainer* prune_empty_containers (MuContainer *root_set) { MuContainer *cur; mu_container_foreach (root_set, (MuContainerForeachFunc)prune_maybe, NULL); /* and prune the root_set itself... */ for (cur = root_set; cur; cur = cur->next) { if (cur->flags & MU_CONTAINER_FLAG_DELETE) { root_set = mu_container_remove_sibling (root_set, cur); } else if (cur->flags & MU_CONTAINER_FLAG_SPLICE) { root_set = mu_container_splice_children (root_set, cur); root_set = mu_container_remove_sibling (root_set, cur); } } return root_set; }