lib: fix 'list permutations'

Cyclic graphs ftw

Also remove graph pretty printer from permutations.c 'cause it's not
really needed anymore

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
Quentin Young 2017-05-04 22:46:46 +00:00
parent d476347d5d
commit e4e63cb6eb
2 changed files with 34 additions and 39 deletions

View file

@ -1590,6 +1590,10 @@ permute (struct graph_node *start, struct vty *vty)
static struct list *position = NULL; static struct list *position = NULL;
if (!position) position = list_new (); if (!position) position = list_new ();
struct cmd_token *stok = start->data;
struct graph_node *gnn;
struct listnode *ln;
// recursive dfs // recursive dfs
listnode_add (position, start); listnode_add (position, start);
for (unsigned int i = 0; i < vector_active (start->to); i++) for (unsigned int i = 0; i < vector_active (start->to); i++)
@ -1601,8 +1605,6 @@ permute (struct graph_node *start, struct vty *vty)
continue; continue;
else if (tok->type == END_TKN || gn == start) else if (tok->type == END_TKN || gn == start)
{ {
struct graph_node *gnn;
struct listnode *ln;
vty_out (vty, " "); vty_out (vty, " ");
for (ALL_LIST_ELEMENTS_RO (position,ln,gnn)) for (ALL_LIST_ELEMENTS_RO (position,ln,gnn))
{ {
@ -1615,7 +1617,15 @@ permute (struct graph_node *start, struct vty *vty)
vty_out (vty, VTY_NEWLINE); vty_out (vty, VTY_NEWLINE);
} }
else else
permute (gn, vty); {
bool skip = false;
if (stok->type == FORK_TKN && tok->type != FORK_TKN)
for (ALL_LIST_ELEMENTS_RO (position, ln, gnn))
if (gnn == gn && (skip = true))
break;
if (!skip)
permute (gn, vty);
}
} }
list_delete_node (position, listtail(position)); list_delete_node (position, listtail(position));
} }

View file

@ -48,7 +48,6 @@ int main (int argc, char *argv[])
command_parse_format (graph, cmd); command_parse_format (graph, cmd);
permute (vector_slot (graph->nodes, 0)); permute (vector_slot (graph->nodes, 0));
pretty_print_graph (vector_slot (graph->nodes, 0), 0);
} }
void void
@ -57,56 +56,42 @@ permute (struct graph_node *start)
static struct list *position = NULL; static struct list *position = NULL;
if (!position) position = list_new (); if (!position) position = list_new ();
struct cmd_token *stok = start->data;
struct graph_node *gnn;
struct listnode *ln;
// recursive dfs // recursive dfs
listnode_add (position, start); listnode_add (position, start);
for (unsigned int i = 0; i < vector_active (start->to); i++) for (unsigned int i = 0; i < vector_active (start->to); i++)
{ {
struct graph_node *gn = vector_slot (start->to, i); struct graph_node *gn = vector_slot (start->to, i);
struct cmd_token *tok = gn->data; struct cmd_token *tok = gn->data;
if (tok->type == END_TKN) if (tok->attr == CMD_ATTR_HIDDEN ||
tok->attr == CMD_ATTR_DEPRECATED)
continue;
else if (tok->type == END_TKN || gn == start)
{ {
struct graph_node *gnn; fprintf (stdout, " ");
struct listnode *ln;
for (ALL_LIST_ELEMENTS_RO (position,ln,gnn)) for (ALL_LIST_ELEMENTS_RO (position,ln,gnn))
{ {
struct cmd_token *tt = gnn->data; struct cmd_token *tt = gnn->data;
if (tt->type < SPECIAL_TKN) if (tt->type < SPECIAL_TKN)
fprintf (stdout, "%s ", tt->text); fprintf (stdout, " %s", tt->text);
} }
if (gn == start)
fprintf (stdout, "...");
fprintf (stdout, "\n"); fprintf (stdout, "\n");
} }
else else
permute (gn); {
bool skip = false;
if (stok->type == FORK_TKN && tok->type != FORK_TKN)
for (ALL_LIST_ELEMENTS_RO (position, ln, gnn))
if (gnn == gn && (skip = true))
break;
if (!skip)
permute (gn);
}
} }
list_delete_node (position, listtail(position)); list_delete_node (position, listtail(position));
} }
void
pretty_print_graph (struct graph_node *start, int level)
{
// print this node
struct cmd_token *tok = start->data;
fprintf (stdout, "%s[%d] ", tok->text, tok->type);
int numto = vector_active (start->to);
if (numto)
{
if (numto > 1)
fprintf (stdout, "\n");
for (unsigned int i = 0; i < vector_active (start->to); i++)
{
struct graph_node *adj = vector_slot (start->to, i);
// if we're listing multiple children, indent!
if (numto > 1)
for (int j = 0; j < level+1; j++)
fprintf (stdout, " ");
// if this node is a vararg, just print *
if (adj == start)
fprintf (stdout, "*");
else
pretty_print_graph (adj, numto > 1 ? level+1 : level);
}
}
else
fprintf(stdout, "\n");
}