]>
git.proxmox.com Git - mirror_frr.git/blob - lib/command_graph.c
3 * Provides a DFA data structure and associated functions for manipulating it.
4 * Used to match user command line input.
6 * @author Quentin Young <qlyoung@cumulusnetworks.com>
9 #include "command_graph.h"
14 add_node(struct graph_node
*parent
, struct graph_node
*child
)
16 struct graph_node
*p_child
;
18 for (unsigned int i
= 0; i
< vector_active(parent
->children
); i
++)
20 p_child
= vector_slot(parent
->children
, i
);
21 if (cmp_node(child
, p_child
))
24 vector_set(parent
->children
, child
);
29 cmp_node(struct graph_node
*first
, struct graph_node
*second
)
32 if (first
->type
!= second
->type
) return 0;
34 switch (first
->type
) {
37 if (first
->text
&& second
->text
) {
38 if (strcmp(first
->text
, second
->text
)) return 0;
40 else if (first
->text
!= second
->text
) return 0;
43 if (first
->min
!= second
->min
|| first
->max
!= second
->max
)
47 if (first
->value
!= second
->value
) return 0;
49 /* selectors and options should be equal if all paths are equal,
50 * but the graph isomorphism problem is not solvable in polynomial
51 * time so we consider selectors and options inequal in all cases
56 /* end nodes are always considered equal, since each node may only
69 new_node(enum graph_node_type type
)
71 struct graph_node
*node
=
72 XMALLOC(MTYPE_CMD_TOKENS
, sizeof(struct graph_node
));
75 node
->children
= vector_init(VECTOR_MIN_SIZE
);
88 free_node (struct graph_node
*node
)
91 free_node (node
->end
);
92 vector_free (node
->children
);
100 describe_node(struct graph_node
*node
, char* buffer
, unsigned int bufsize
)
103 snprintf(buffer
, bufsize
, "(null node)");
108 switch (node
->type
) {
116 snprintf(buffer
, bufsize
, node
->text
);
119 snprintf(buffer
, bufsize
, "%ld", node
->value
);
122 snprintf(buffer
, bufsize
, "<>");
125 snprintf(buffer
, bufsize
, "[]");
128 snprintf(buffer
, bufsize
, "NUL");
131 snprintf(buffer
, bufsize
, "END");
134 snprintf(buffer
, bufsize
, "START");
137 snprintf(buffer
, bufsize
, "ERROR");
145 walk_graph(struct graph_node
*start
, int level
)
147 char* desc
= malloc(50);
149 fprintf(stderr
, "%s[%d] ", describe_node(start
, desc
, 50), vector_active(start
->children
));
152 if (vector_active(start
->children
)) {
153 if (vector_active(start
->children
) == 1)
154 walk_graph(vector_slot(start
->children
, 0), level
);
156 fprintf(stderr
, "\n");
157 for (unsigned int i
= 0; i
< vector_active(start
->children
); i
++) {
158 struct graph_node
*r
= vector_slot(start
->children
, i
);
159 for (int j
= 0; j
< level
+1; j
++)
160 fprintf(stderr
, " ");
161 walk_graph(r
, level
+1);
166 fprintf(stderr
, "\n");