mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 23:33:08 +00:00
lib: make cmd_element->attr a bitmask & clarify
It already "looks" like a bitmask, but we currently can't flag a command both YANG and HIDDEN at the same time. It really should be a bitmask. Also clarify DEPRECATED behaviour (or the absence thereof.) Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
53d8bf6d7a
commit
9eebf97e3d
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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']])
|
||||
|
||||
|
@ -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, " ");
|
||||
|
Loading…
Reference in New Issue
Block a user