summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2024-07-20 18:28:35 -0700
committerDonald Sharp <sharpd@nvidia.com>2024-07-31 08:08:53 -0400
commitece3132471a1f361b82dde47bbf8cbf9675a12a8 (patch)
tree2ba5c877ded4d23c303712f079e0c596b8f43aa8
parentcb9d20b712c6b09ee6516f134e44e2a4a7181694 (diff)
lib/clippy: add `CMD_ELEMENT_TKN`
The command graph has its tail end nodes pointing at the `struct cmd_element` rather than a `struct cmd_token`. This is a bit weird to begin with, but becomes very annoying for the python bindings where there is just no `struct cmd_element`. Create a `CMD_ELEMENT_TKN` type for `cmd_token` instead, and replace the tail end token in the python bindings with an instance of that. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
-rw-r--r--lib/command_graph.c3
-rw-r--r--lib/command_graph.h3
-rw-r--r--lib/command_py.c21
3 files changed, 21 insertions, 6 deletions
diff --git a/lib/command_graph.c b/lib/command_graph.c
index ff3c11db69..20ab6b321b 100644
--- a/lib/command_graph.c
+++ b/lib/command_graph.c
@@ -267,6 +267,9 @@ static bool cmd_nodes_equal(struct graph_node *ga, struct graph_node *gb)
case NEG_ONLY_TKN:
case WORD_TKN:
case ASNUM_TKN:
+#ifdef BUILDING_CLIPPY
+ case CMD_ELEMENT_TKN:
+#endif
return true;
}
diff --git a/lib/command_graph.h b/lib/command_graph.h
index 25aa47db7b..313c97fe87 100644
--- a/lib/command_graph.h
+++ b/lib/command_graph.h
@@ -54,6 +54,9 @@ enum cmd_token_type {
END_TKN, // last token in line
NEG_ONLY_TKN, // filter token, match if "no ..." command
+#ifdef BUILDING_CLIPPY
+ CMD_ELEMENT_TKN, // python bindings only
+#endif
SPECIAL_TKN = FORK_TKN,
};
/* clang-format on */
diff --git a/lib/command_py.c b/lib/command_py.c
index e459071426..a77adcd7dc 100644
--- a/lib/command_py.c
+++ b/lib/command_py.c
@@ -160,8 +160,8 @@ static PyObject *graph_node_next(PyObject *self, PyObject *args)
struct wrap_graph_node *wrap = (struct wrap_graph_node *)self;
PyObject *pylist;
- if (wrap->node->data
- && ((struct cmd_token *)wrap->node->data)->type == END_TKN)
+ if (wrap->node->data &&
+ ((struct cmd_token *)wrap->node->data)->type == CMD_ELEMENT_TKN)
return PyList_New(0);
pylist = PyList_New(vector_active(wrap->node->to));
for (size_t i = 0; i < vector_active(wrap->node->to); i++) {
@@ -335,6 +335,7 @@ static PyObject *graph_to_pyobj_idx(struct wrap_graph *wgraph, size_t i)
item(START_TKN);
item(END_TKN);
item(NEG_ONLY_TKN);
+ item(CMD_ELEMENT_TKN);
#undef item
default:
wrap->type = "???";
@@ -436,16 +437,16 @@ static PyObject *graph_merge(PyObject *self, PyObject *args)
/* top call / entrypoint for python code */
static PyObject *graph_parse(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
- const char *def, *doc = NULL;
+ const char *def, *doc = NULL, *name = NULL;
struct wrap_graph *gwrap;
- static const char *kwnames[] = {"cmddef", "doc", NULL};
+ static const char *const kwnames[] = { "cmddef", "doc", "name", NULL };
gwrap = (struct wrap_graph *)typeobj_graph.tp_alloc(&typeobj_graph, 0);
if (!gwrap)
return NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "z|s", (char **)kwnames,
- &def, &doc))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "z|ss", (char **)kwnames,
+ &def, &doc, &name))
return NULL;
struct graph *graph = graph_new();
@@ -454,10 +455,18 @@ static PyObject *graph_parse(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (def) {
struct cmd_element cmd = { .string = def, .doc = doc };
+ struct graph_node *last;
cmd_graph_parse(graph, &cmd);
cmd_graph_names(graph);
+ last = vector_slot(graph->nodes,
+ vector_active(graph->nodes) - 1);
+ assert(last->data == &cmd);
+
+ last->data = cmd_token_new(CMD_ELEMENT_TKN, 0, name, def);
+ last->del = (void (*)(void *))cmd_token_del;
+
gwrap->definition = strdup(def);
} else {
gwrap->definition = strdup("NULL");