-struct item_path
- {
- const struct spv_item **nodes;
- size_t n;
-
-#define N_STUB 10
- const struct spv_item *stub[N_STUB];
- };
-
-static void
-swap_nodes (const struct spv_item **a, const struct spv_item **b)
-{
- const struct spv_item *tmp = *a;
- *a = *b;
- *b = tmp;
-}
-
-static void
-get_path (const struct spv_item *item, struct item_path *path)
-{
- size_t allocated = 10;
- path->nodes = path->stub;
- path->n = 0;
-
- while (item)
- {
- if (path->n >= allocated)
- {
- if (path->nodes == path->stub)
- path->nodes = xmemdup (path->stub, sizeof path->stub);
- path->nodes = x2nrealloc (path->nodes, &allocated,
- sizeof *path->nodes);
- }
- path->nodes[path->n++] = item;
- item = item->parent;
- }
-
- for (size_t i = 0; i < path->n / 2; i++)
- swap_nodes (&path->nodes[i], &path->nodes[path->n - i - 1]);
-}
-
-static void
-free_path (struct item_path *path)
-{
- if (path && path->nodes != path->stub)
- free (path->nodes);
-}
-
-static void
-dump_heading_transition (const struct spv_item *old,
- const struct spv_item *new)
-{
- if (old == new)
- return;
-
- struct item_path old_path, new_path;
- get_path (old, &old_path);
- get_path (new, &new_path);
-
- size_t common = 0;
- for (; common < old_path.n && common < new_path.n; common++)
- if (old_path.nodes[common] != new_path.nodes[common])
- break;
-
- for (size_t i = common; i < old_path.n; i++)
- group_close_item_submit (group_close_item_create ());
- for (size_t i = common; i < new_path.n; i++)
- group_open_item_submit (group_open_item_create (
- new_path.nodes[i]->command_id));
-
- free_path (&old_path);
- free_path (&new_path);
-}
-