summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/command.c20
-rw-r--r--lib/command.h6
-rw-r--r--lib/command_graph.c5
-rw-r--r--lib/command_graph.h8
-rw-r--r--lib/command_match.c3
-rw-r--r--lib/command_py.c9
-rw-r--r--lib/grammar_sandbox.c3
-rw-r--r--python/clippy/__init__.py22
-rw-r--r--python/xrelfo.py14
-rw-r--r--tools/permutations.c3
10 files changed, 59 insertions, 34 deletions
diff --git a/lib/command.c b/lib/command.c
index a23afb1e4..e555404c1 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -264,8 +264,7 @@ void install_node(struct cmd_node *node)
node->cmdgraph = graph_new();
node->cmd_vector = vector_init(VECTOR_MIN_SIZE);
// add start node
- struct cmd_token *token =
- cmd_token_new(START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
+ struct cmd_token *token = cmd_token_new(START_TKN, 0, NULL, NULL);
graph_new_node(node->cmdgraph, token,
(void (*)(void *)) & cmd_token_del);
@@ -325,7 +324,7 @@ void _install_element(enum node_type ntype, const struct cmd_element *cmd)
if (cnode->graph_built || !defer_cli_tree) {
struct graph *graph = graph_new();
struct cmd_token *token =
- cmd_token_new(START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
+ cmd_token_new(START_TKN, 0, NULL, NULL);
graph_new_node(graph, token,
(void (*)(void *)) & cmd_token_del);
@@ -348,8 +347,7 @@ static void cmd_finalize_iter(struct hash_bucket *hb, void *arg)
struct cmd_node *cnode = arg;
const struct cmd_element *cmd = hb->data;
struct graph *graph = graph_new();
- struct cmd_token *token =
- cmd_token_new(START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
+ struct cmd_token *token = cmd_token_new(START_TKN, 0, NULL, NULL);
graph_new_node(graph, token, (void (*)(void *)) & cmd_token_del);
@@ -404,7 +402,7 @@ void uninstall_element(enum node_type ntype, const struct cmd_element *cmd)
if (cnode->graph_built) {
struct graph *graph = graph_new();
struct cmd_token *token =
- cmd_token_new(START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
+ cmd_token_new(START_TKN, 0, NULL, NULL);
graph_new_node(graph, token,
(void (*)(void *)) & cmd_token_del);
@@ -990,7 +988,7 @@ static int cmd_execute_command_real(vector vline, enum cmd_filter_type filter,
* Perform pending commit (if any) before executing
* non-YANG command.
*/
- if (matched_element->attr != CMD_ATTR_YANG)
+ if (!(matched_element->attr & CMD_ATTR_YANG))
(void)nb_cli_pending_commit_check(vty);
}
@@ -1471,8 +1469,7 @@ static void permute(struct graph_node *start, struct vty *vty)
for (unsigned int i = 0; i < vector_active(start->to); i++) {
struct graph_node *gn = vector_slot(start->to, i);
struct cmd_token *tok = gn->data;
- if (tok->attr == CMD_ATTR_HIDDEN
- || tok->attr == CMD_ATTR_DEPRECATED)
+ if (tok->attr & CMD_ATTR_HIDDEN)
continue;
else if (tok->type == END_TKN || gn == start) {
vty_out(vty, " ");
@@ -1561,9 +1558,8 @@ int cmd_list_cmds(struct vty *vty, int do_permute)
const struct cmd_element *element = NULL;
for (unsigned int i = 0; i < vector_active(node->cmd_vector);
i++)
- if ((element = vector_slot(node->cmd_vector, i))
- && element->attr != CMD_ATTR_DEPRECATED
- && element->attr != CMD_ATTR_HIDDEN) {
+ if ((element = vector_slot(node->cmd_vector, i)) &&
+ !(element->attr & CMD_ATTR_HIDDEN)) {
vty_out(vty, " ");
print_cmd(vty, element->string);
}
diff --git a/lib/command.h b/lib/command.h
index fd686af94..46763ed0d 100644
--- a/lib/command.h
+++ b/lib/command.h
@@ -358,9 +358,13 @@ struct cmd_node {
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN, \
0)
+/* note: DEPRECATED implies HIDDEN, and other than that there is currently no
+ * difference. It's purely for expressing intent in the source code - a
+ * DEPRECATED command is supposed to go away, a HIDDEN one is likely to stay.
+ */
#define ALIAS_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, \
- CMD_ATTR_DEPRECATED, 0)
+ CMD_ATTR_DEPRECATED | CMD_ATTR_HIDDEN, 0)
#define ALIAS_YANG(funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_YANG, 0)
diff --git a/lib/command_graph.c b/lib/command_graph.c
index 09d802e79..e94068525 100644
--- a/lib/command_graph.c
+++ b/lib/command_graph.c
@@ -494,9 +494,10 @@ void cmd_graph_node_print_cb(struct graph_node *gn, struct buffer *buf)
snprintf(nbuf, sizeof(nbuf), "<b>%s</b>",
lookup_msg(tokennames, tok->type, NULL));
buffer_putstr(buf, nbuf);
- if (tok->attr == CMD_ATTR_DEPRECATED)
+ if (tok->attr & CMD_ATTR_DEPRECATED)
buffer_putstr(buf, " (d)");
- else if (tok->attr == CMD_ATTR_HIDDEN)
+ /* DEPRECATED implies HIDDEN, don't print both */
+ else if (tok->attr & CMD_ATTR_HIDDEN)
buffer_putstr(buf, " (h)");
if (tok->text) {
if (tok->type == WORD_TKN)
diff --git a/lib/command_graph.h b/lib/command_graph.h
index ed4da6aa4..57a70a818 100644
--- a/lib/command_graph.h
+++ b/lib/command_graph.h
@@ -73,10 +73,10 @@ enum cmd_token_type {
#define IS_VARYING_TOKEN(x) ((x) >= VARIABLE_TKN && (x) < FORK_TKN)
/* Command attributes */
-enum { CMD_ATTR_NORMAL,
- CMD_ATTR_DEPRECATED,
- CMD_ATTR_HIDDEN,
- CMD_ATTR_YANG,
+enum {
+ CMD_ATTR_YANG = (1 << 0),
+ CMD_ATTR_HIDDEN = (1 << 1),
+ CMD_ATTR_DEPRECATED = (1 << 2),
};
enum varname_src {
diff --git a/lib/command_match.c b/lib/command_match.c
index f221e0a02..ce2dbc952 100644
--- a/lib/command_match.c
+++ b/lib/command_match.c
@@ -395,8 +395,7 @@ enum matcher_rv command_complete(struct graph *graph, vector vline,
for (ALL_LIST_ELEMENTS_RO(current, node, gstack)) {
struct cmd_token *token = gstack[0]->data;
- if (token->attr == CMD_ATTR_HIDDEN
- || token->attr == CMD_ATTR_DEPRECATED)
+ if (token->attr & CMD_ATTR_HIDDEN)
continue;
enum match_type minmatch = min_match_level(token->type);
diff --git a/lib/command_py.c b/lib/command_py.c
index 6301eec5e..ff7b2d18a 100644
--- a/lib/command_py.c
+++ b/lib/command_py.c
@@ -226,8 +226,8 @@ static PyObject *graph_to_pyobj(struct wrap_graph *wgraph,
wrap->type = "???";
}
- wrap->deprecated = (tok->attr == CMD_ATTR_DEPRECATED);
- wrap->hidden = (tok->attr == CMD_ATTR_HIDDEN);
+ wrap->deprecated = !!(tok->attr & CMD_ATTR_DEPRECATED);
+ wrap->hidden = !!(tok->attr & CMD_ATTR_HIDDEN);
wrap->text = tok->text;
wrap->desc = tok->desc;
wrap->varname = tok->varname;
@@ -353,6 +353,11 @@ PyMODINIT_FUNC command_py_init(void)
if (!pymod)
initret(NULL);
+ if (PyModule_AddIntMacro(pymod, CMD_ATTR_YANG)
+ || PyModule_AddIntMacro(pymod, CMD_ATTR_HIDDEN)
+ || PyModule_AddIntMacro(pymod, CMD_ATTR_DEPRECATED))
+ initret(NULL);
+
Py_INCREF(&typeobj_graph_node);
PyModule_AddObject(pymod, "GraphNode", (PyObject *)&typeobj_graph_node);
Py_INCREF(&typeobj_graph);
diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c
index f9778c5d4..8fa47c053 100644
--- a/lib/grammar_sandbox.c
+++ b/lib/grammar_sandbox.c
@@ -76,8 +76,7 @@ DEFUN (grammar_test,
// parse the command and install it into the command graph
struct graph *graph = graph_new();
- struct cmd_token *token =
- cmd_token_new(START_TKN, CMD_ATTR_NORMAL, NULL, NULL);
+ struct cmd_token *token = cmd_token_new(START_TKN, 0, NULL, NULL);
graph_new_node(graph, token, (void (*)(void *)) & cmd_token_del);
cmd_graph_parse(graph, cmd);
diff --git a/python/clippy/__init__.py b/python/clippy/__init__.py
index 344a1c91e..c356a29d3 100644
--- a/python/clippy/__init__.py
+++ b/python/clippy/__init__.py
@@ -17,8 +17,22 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import os, stat
+
+try:
+ from enum import IntFlag as _IntFlag
+except ImportError:
+ # python <3.6
+ from enum import IntEnum as _IntFlag # type: ignore
+
import _clippy
-from _clippy import parse, Graph, GraphNode
+from _clippy import (
+ parse,
+ Graph,
+ GraphNode,
+ CMD_ATTR_YANG,
+ CMD_ATTR_HIDDEN,
+ CMD_ATTR_DEPRECATED,
+)
frr_top_src = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
@@ -78,3 +92,9 @@ def wrdiff(filename, buf, reffiles=[]):
with open(newname, "w") as out:
out.write(buf)
os.rename(newname, filename)
+
+
+class CmdAttr(_IntFlag):
+ YANG = CMD_ATTR_YANG
+ HIDDEN = CMD_ATTR_HIDDEN
+ DEPRECATED = CMD_ATTR_DEPRECATED
diff --git a/python/xrelfo.py b/python/xrelfo.py
index 17262da8d..3bfe9950d 100644
--- a/python/xrelfo.py
+++ b/python/xrelfo.py
@@ -26,7 +26,7 @@ import argparse
from clippy.uidhash import uidhash
from clippy.elf import *
-from clippy import frr_top_src
+from clippy import frr_top_src, CmdAttr
from tiabwarfo import FieldApplicator
try:
@@ -196,8 +196,6 @@ Xref.containers[XREFT_LOGMSG] = XrefLogmsg
class CmdElement(ELFDissectStruct, XrelfoJson):
struct = 'cmd_element'
- cmd_attrs = { 0: None, 1: 'deprecated', 2: 'hidden'}
-
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -207,10 +205,14 @@ class CmdElement(ELFDissectStruct, XrelfoJson):
jsobj.update({
'string': self.string,
'doc': self.doc,
- 'attr': self.cmd_attrs.get(self.attr, self.attr),
})
- if jsobj['attr'] is None:
- del jsobj['attr']
+ if self.attr:
+ jsobj['attr'] = attr = self.attr
+ for attrname in CmdAttr.__members__:
+ val = CmdAttr[attrname]
+ if attr & val:
+ jsobj.setdefault('attrs', []).append(attrname.lower())
+ attr &= ~val
jsobj['defun'] = dict([(i, getattr(self.xref, i)) for i in ['file', 'line', 'func']])
diff --git a/tools/permutations.c b/tools/permutations.c
index b280cc15b..a0b041f2f 100644
--- a/tools/permutations.c
+++ b/tools/permutations.c
@@ -80,8 +80,7 @@ void permute(struct graph_node *start)
for (unsigned int i = 0; i < vector_active(start->to); i++) {
struct graph_node *gn = vector_slot(start->to, i);
struct cmd_token *tok = gn->data;
- if (tok->attr == CMD_ATTR_HIDDEN
- || tok->attr == CMD_ATTR_DEPRECATED)
+ if (tok->attr & CMD_ATTR_HIDDEN)
continue;
else if (tok->type == END_TKN || gn == start) {
fprintf(stdout, " ");