]> git.proxmox.com Git - mirror_frr.git/blob - tools/permutations.c
bgpd: attr evpn attributes should be modified before interning attr
[mirror_frr.git] / tools / permutations.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Generates all possible matching inputs for a command string.
4 * --
5 * Copyright (C) 2016 Cumulus Networks, Inc.
6 */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include "command.h"
13 #include "graph.h"
14 #include "vector.h"
15
16 #define USAGE "usage: permutations <cmdstr>"
17
18 void permute(struct graph_node *);
19 void pretty_print_graph(struct graph_node *start, int level);
20
21 int main(int argc, char *argv[])
22 {
23 if (argc < 2) {
24 fprintf(stdout, USAGE "\n");
25 exit(EXIT_SUCCESS);
26 }
27 struct cmd_element *cmd = XCALLOC(MTYPE_TMP,
28 sizeof(struct cmd_element));
29 cmd->string = strdup(argv[1]);
30
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);
36
37 permute(vector_slot(graph->nodes, 0));
38 }
39
40 void permute(struct graph_node *start)
41 {
42 static struct list *position = NULL;
43 if (!position)
44 position = list_new();
45
46 struct cmd_token *stok = start->data;
47 struct graph_node *gnn;
48 struct listnode *ln;
49 bool is_neg = false;
50
51 // recursive dfs
52 listnode_add(position, start);
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
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;
68 if (tok->attr & CMD_ATTR_HIDDEN)
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;
82
83 if (tok->type == NEG_ONLY_TKN && !is_neg)
84 continue;
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));
96 }