]> git.proxmox.com Git - mirror_frr.git/blame - tools/permutations.c
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / tools / permutations.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
73baf6a3
QY
2/*
3 * Generates all possible matching inputs for a command string.
4 * --
5 * Copyright (C) 2016 Cumulus Networks, Inc.
73baf6a3
QY
6 */
7
b45ac5f5
DL
8#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif
11
96dcc565
QY
12#include "command.h"
13#include "graph.h"
96dcc565
QY
14#include "vector.h"
15
73baf6a3
QY
16#define USAGE "usage: permutations <cmdstr>"
17
d62a17ae 18void permute(struct graph_node *);
19void pretty_print_graph(struct graph_node *start, int level);
96dcc565 20
d62a17ae 21int main(int argc, char *argv[])
96dcc565 22{
d62a17ae 23 if (argc < 2) {
24 fprintf(stdout, USAGE "\n");
25 exit(EXIT_SUCCESS);
26 }
3b23c6c3
A
27 struct cmd_element *cmd = XCALLOC(MTYPE_TMP,
28 sizeof(struct cmd_element));
d62a17ae 29 cmd->string = strdup(argv[1]);
96dcc565 30
d62a17ae 31 struct graph *graph = graph_new();
32 struct cmd_token *token =
33 cmd_token_new(START_TKN, cmd->attr, NULL, NULL);
34 graph_new_node(graph, token, NULL);
35 cmd_graph_parse(graph, cmd);
96dcc565 36
d62a17ae 37 permute(vector_slot(graph->nodes, 0));
96dcc565
QY
38}
39
d62a17ae 40void permute(struct graph_node *start)
96dcc565 41{
d62a17ae 42 static struct list *position = NULL;
43 if (!position)
44 position = list_new();
96dcc565 45
d62a17ae 46 struct cmd_token *stok = start->data;
47 struct graph_node *gnn;
48 struct listnode *ln;
90c8406c 49 bool is_neg = false;
e4e63cb6 50
d62a17ae 51 // recursive dfs
52 listnode_add(position, start);
90c8406c
DL
53
54 for (ALL_LIST_ELEMENTS_RO(position, ln, gnn)) {
55 struct cmd_token *tok = gnn->data;
56
57 if (tok->type == WORD_TKN && !strcmp(tok->text, "no")) {
58 is_neg = true;
59 break;
60 }
61 if (tok->type < SPECIAL_TKN)
62 break;
63 }
64
d62a17ae 65 for (unsigned int i = 0; i < vector_active(start->to); i++) {
66 struct graph_node *gn = vector_slot(start->to, i);
67 struct cmd_token *tok = gn->data;
9eebf97e 68 if (tok->attr & CMD_ATTR_HIDDEN)
d62a17ae 69 continue;
70 else if (tok->type == END_TKN || gn == start) {
71 fprintf(stdout, " ");
72 for (ALL_LIST_ELEMENTS_RO(position, ln, gnn)) {
73 struct cmd_token *tt = gnn->data;
74 if (tt->type < SPECIAL_TKN)
75 fprintf(stdout, " %s", tt->text);
76 }
77 if (gn == start)
78 fprintf(stdout, "...");
79 fprintf(stdout, "\n");
80 } else {
81 bool skip = false;
90c8406c
DL
82
83 if (tok->type == NEG_ONLY_TKN && !is_neg)
84 continue;
d62a17ae 85 if (stok->type == FORK_TKN && tok->type != FORK_TKN)
86 for (ALL_LIST_ELEMENTS_RO(position, ln, gnn))
87 if (gnn == gn) {
88 skip = true;
89 break;
90 }
91 if (!skip)
92 permute(gn);
93 }
94 }
95 list_delete_node(position, listtail(position));
943624d7 96}