mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-29 17:13:46 +00:00
lib/command.c: rewrite command matching/parsing
Add support for keyword commands. Includes new documentation for DEFUN() in lib/command.h, for preexisting features as well as new keyword specification. Signed-off-by: Christian Franke <chris@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
e712d0e366
commit
cd40b329a2
@ -277,9 +277,6 @@ babel_init(int argc, char **argv)
|
|||||||
/* this replace kernel_setup && kernel_setup_socket */
|
/* this replace kernel_setup && kernel_setup_socket */
|
||||||
babelz_zebra_init ();
|
babelz_zebra_init ();
|
||||||
|
|
||||||
/* Sort all installed commands. */
|
|
||||||
sort_node ();
|
|
||||||
|
|
||||||
/* Get zebra configuration file. */
|
/* Get zebra configuration file. */
|
||||||
zlog_set_level (NULL, ZLOG_DEST_STDOUT, ZLOG_DISABLED);
|
zlog_set_level (NULL, ZLOG_DEST_STDOUT, ZLOG_DISABLED);
|
||||||
vty_read_config (babel_config_file, babel_config_default);
|
vty_read_config (babel_config_file, babel_config_default);
|
||||||
|
@ -431,9 +431,6 @@ main (int argc, char **argv)
|
|||||||
/* BGP related initialization. */
|
/* BGP related initialization. */
|
||||||
bgp_init ();
|
bgp_init ();
|
||||||
|
|
||||||
/* Sort CLI commands. */
|
|
||||||
sort_node ();
|
|
||||||
|
|
||||||
/* Parse config file. */
|
/* Parse config file. */
|
||||||
vty_read_config (config_file, config_default);
|
vty_read_config (config_file, config_default);
|
||||||
|
|
||||||
|
@ -339,8 +339,6 @@ main (int argc, char **argv, char **envp)
|
|||||||
|
|
||||||
isis_zebra_init ();
|
isis_zebra_init ();
|
||||||
|
|
||||||
sort_node ();
|
|
||||||
|
|
||||||
/* parse config file */
|
/* parse config file */
|
||||||
/* this is needed three times! because we have interfaces before the areas */
|
/* this is needed three times! because we have interfaces before the areas */
|
||||||
vty_read_config (config_file, config_default);
|
vty_read_config (config_file, config_default);
|
||||||
|
1983
lib/command.c
1983
lib/command.c
File diff suppressed because it is too large
Load Diff
195
lib/command.h
195
lib/command.h
@ -138,18 +138,32 @@ struct cmd_element
|
|||||||
int (*func) (struct cmd_element *, struct vty *, int, const char *[]);
|
int (*func) (struct cmd_element *, struct vty *, int, const char *[]);
|
||||||
const char *doc; /* Documentation of this command. */
|
const char *doc; /* Documentation of this command. */
|
||||||
int daemon; /* Daemon to which this command belong. */
|
int daemon; /* Daemon to which this command belong. */
|
||||||
vector strvec; /* Pointing out each description vector. */
|
vector tokens; /* Vector of cmd_tokens */
|
||||||
unsigned int cmdsize; /* Command index count. */
|
|
||||||
char *config; /* Configuration string */
|
|
||||||
vector subconfig; /* Sub configuration string */
|
|
||||||
u_char attr; /* Command attributes */
|
u_char attr; /* Command attributes */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Command description structure. */
|
|
||||||
struct desc
|
enum cmd_token_type
|
||||||
{
|
{
|
||||||
|
TOKEN_TERMINAL = 0,
|
||||||
|
TOKEN_MULTIPLE,
|
||||||
|
TOKEN_KEYWORD,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Command description structure. */
|
||||||
|
struct cmd_token
|
||||||
|
{
|
||||||
|
enum cmd_token_type type;
|
||||||
|
|
||||||
|
/* Used for type == MULTIPLE */
|
||||||
|
vector multiple; /* vector of cmd_token, type == FINAL */
|
||||||
|
|
||||||
|
/* Used for type == KEYWORD */
|
||||||
|
vector keyword; /* vector of vector of cmd_tokens */
|
||||||
|
|
||||||
|
/* Used for type == TERMINAL */
|
||||||
char *cmd; /* Command string. */
|
char *cmd; /* Command string. */
|
||||||
char *str; /* Command's description. */
|
char *desc; /* Command's description. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Return value of the commands. */
|
/* Return value of the commands. */
|
||||||
@ -192,7 +206,170 @@ struct desc
|
|||||||
int argc __attribute__ ((unused)), \
|
int argc __attribute__ ((unused)), \
|
||||||
const char *argv[] __attribute__ ((unused)) )
|
const char *argv[] __attribute__ ((unused)) )
|
||||||
|
|
||||||
/* DEFUN for vty command interafce. Little bit hacky ;-). */
|
/* DEFUN for vty command interafce. Little bit hacky ;-).
|
||||||
|
*
|
||||||
|
* DEFUN(funcname, cmdname, cmdstr, helpstr)
|
||||||
|
*
|
||||||
|
* funcname
|
||||||
|
* ========
|
||||||
|
*
|
||||||
|
* Name of the function that will be defined.
|
||||||
|
*
|
||||||
|
* cmdname
|
||||||
|
* =======
|
||||||
|
*
|
||||||
|
* Name of the struct that will be defined for the command.
|
||||||
|
*
|
||||||
|
* cmdstr
|
||||||
|
* ======
|
||||||
|
*
|
||||||
|
* The cmdstr defines the command syntax. It is used by the vty subsystem
|
||||||
|
* and vtysh to perform matching and completion in the cli. So you have to take
|
||||||
|
* care to construct it adhering to the following grammar. The names used
|
||||||
|
* for the production rules losely represent the names used in lib/command.c
|
||||||
|
*
|
||||||
|
* cmdstr = cmd_token , { " " , cmd_token } ;
|
||||||
|
*
|
||||||
|
* cmd_token = cmd_terminal
|
||||||
|
* | cmd_multiple
|
||||||
|
* | cmd_keyword ;
|
||||||
|
*
|
||||||
|
* cmd_terminal_fixed = fixed_string
|
||||||
|
* | variable
|
||||||
|
* | range
|
||||||
|
* | ipv4
|
||||||
|
* | ipv4_prefix
|
||||||
|
* | ipv6
|
||||||
|
* | ipv6_prefix ;
|
||||||
|
*
|
||||||
|
* cmd_terminal = cmd_terminal_fixed
|
||||||
|
* | option
|
||||||
|
* | vararg ;
|
||||||
|
*
|
||||||
|
* multiple_part = cmd_terminal_fixed ;
|
||||||
|
* cmd_multiple = "(" , multiple_part , ( "|" | { "|" , multiple_part } ) , ")" ;
|
||||||
|
*
|
||||||
|
* keyword_part = fixed_string , { " " , ( cmd_terminal_fixed | cmd_multiple ) } ;
|
||||||
|
* cmd_keyword = "{" , keyword_part , { "|" , keyword_part } , "}" ;
|
||||||
|
*
|
||||||
|
* lowercase = "a" | ... | "z" ;
|
||||||
|
* uppercase = "A" | ... | "Z" ;
|
||||||
|
* digit = "0" | ... | "9" ;
|
||||||
|
* number = digit , { digit } ;
|
||||||
|
*
|
||||||
|
* fixed_string = (lowercase | digit) , { lowercase | digit | uppercase | "-" | "_" } ;
|
||||||
|
* variable = uppercase , { uppercase | "_" } ;
|
||||||
|
* range = "<" , number , "-" , number , ">" ;
|
||||||
|
* ipv4 = "A.B.C.D" ;
|
||||||
|
* ipv4_prefix = "A.B.C.D/M" ;
|
||||||
|
* ipv6 = "X:X::X:X" ;
|
||||||
|
* ipv6_prefix = "X:X::X:X/M" ;
|
||||||
|
* option = "[" , variable , "]" ;
|
||||||
|
* vararg = "." , variable ;
|
||||||
|
*
|
||||||
|
* To put that all in a textual description: A cmdstr is a sequence of tokens,
|
||||||
|
* separated by spaces.
|
||||||
|
*
|
||||||
|
* Terminal Tokens:
|
||||||
|
*
|
||||||
|
* A very simple cmdstring would be something like: "show ip bgp". It consists
|
||||||
|
* of three Terminal Tokens, each containing a fixed string. When this command
|
||||||
|
* is called, no arguments will be passed down to the function implementing it,
|
||||||
|
* as it only consists of fixed strings.
|
||||||
|
*
|
||||||
|
* Apart from fixed strings, Terminal Tokens can also contain variables:
|
||||||
|
* An example would be "show ip bgp A.B.C.D". This command expects an IPv4
|
||||||
|
* as argument. As this is a variable, the IP address entered by the user will
|
||||||
|
* be passed down as an argument. Apart from two exceptions, the other options
|
||||||
|
* for Terminal Tokens behave exactly as we just discussed and only make a
|
||||||
|
* difference for the CLI. The two exceptions will be discussed in the next
|
||||||
|
* paragraphs.
|
||||||
|
*
|
||||||
|
* A Terminal Token can contain a so called option match. This is a simple
|
||||||
|
* string variable that the user may omit. An example would be:
|
||||||
|
* "show interface [IFNAME]". If the user calls this without an interface as
|
||||||
|
* argument, no arguments will be passed down to the function implementing
|
||||||
|
* this command. Otherwise, the interface name will be provided to the function
|
||||||
|
* as a regular argument.
|
||||||
|
|
||||||
|
* Also, a Terminal Token can contain a so called vararg. This is used e.g. in
|
||||||
|
* "show ip bgp regexp .LINE". The last token is a vararg match and will
|
||||||
|
* consume all the arguments the user inputs on the command line and append
|
||||||
|
* those to the list of arguments passed down to the function implementing this
|
||||||
|
* command. (Therefore, it doesn't make much sense to have any tokens after a
|
||||||
|
* vararg because the vararg will already consume all the words the user entered
|
||||||
|
* in the CLI)
|
||||||
|
*
|
||||||
|
* Multiple Tokens:
|
||||||
|
*
|
||||||
|
* The Multiple Token type can be used if there are multiple possibilities what
|
||||||
|
* arguments may be used for a command, but it should map to the same function
|
||||||
|
* nonetheless. An example would be "ip route A.B.C.D/M (reject|blackhole)"
|
||||||
|
* In that case both "reject" and "blackhole" would be acceptable as last
|
||||||
|
* arguments. The words matched by Multiple Tokens are always added to the
|
||||||
|
* argument list, even if they are matched by fixed strings. Such a Multiple
|
||||||
|
* Token can contain almost any type of token that would also be acceptable
|
||||||
|
* for a Terminal Token, the exception are optional variables and varag.
|
||||||
|
*
|
||||||
|
* There is one special case that is used in some places of Quagga that should be
|
||||||
|
* pointed out here shortly. An example would be "password (8|) WORD". This
|
||||||
|
* construct is used to have fixed strings communicated as arguments. (The "8"
|
||||||
|
* will be passed down as an argument in this case) It does not mean that
|
||||||
|
* the "8" is optional. Another historic and possibly surprising property of
|
||||||
|
* this construct is that it consumes two parts of helpstr. (Help
|
||||||
|
* strings will be explained later)
|
||||||
|
*
|
||||||
|
* Keyword Tokens:
|
||||||
|
*
|
||||||
|
* There are commands that take a lot of different and possibly optional arguments.
|
||||||
|
* An example from ospf would be the "default-information originate" command. This
|
||||||
|
* command takes a lot of optional arguments that may be provided in any order.
|
||||||
|
* To accomodate such commands, the Keyword Token has been implemented.
|
||||||
|
* Using the keyword token, the "default-information originate" command and all
|
||||||
|
* its possible options can be represented using this single cmdstr:
|
||||||
|
* "default-information originate \
|
||||||
|
* {always|metric <0-16777214>|metric-type (1|2)|route-map WORD}"
|
||||||
|
*
|
||||||
|
* Keywords always start with a fixed string and may be followed by arguments.
|
||||||
|
* Except optional variables and vararg, everything is permitted here.
|
||||||
|
*
|
||||||
|
* For the special case of a keyword without arguments, either NULL or the
|
||||||
|
* keyword itself will be pushed as an argument, depending on whether the
|
||||||
|
* keyword is present.
|
||||||
|
* For the other keywords, arguments will be only pushed for
|
||||||
|
* variables/Multiple Tokens. If the keyword is not present, the arguments that
|
||||||
|
* would have been pushed will be substituted by NULL.
|
||||||
|
*
|
||||||
|
* A few examples:
|
||||||
|
* "default information originate metric-type 1 metric 1000"
|
||||||
|
* would yield the following arguments:
|
||||||
|
* { NULL, "1000", "1", NULL }
|
||||||
|
*
|
||||||
|
* "default information originate always route-map RMAP-DEFAULT"
|
||||||
|
* would yield the following arguments:
|
||||||
|
* { "always", NULL, NULL, "RMAP-DEFAULT" }
|
||||||
|
*
|
||||||
|
* helpstr
|
||||||
|
* =======
|
||||||
|
*
|
||||||
|
* The helpstr is used to show a short explantion for the commands that
|
||||||
|
* are available when the user presses '?' on the CLI. It is the concatenation
|
||||||
|
* of the helpstrings for all the tokens that make up the command.
|
||||||
|
*
|
||||||
|
* There should be one helpstring for each token in the cmdstr except those
|
||||||
|
* containing other tokens, like Multiple or Keyword Tokens. For those, there
|
||||||
|
* will only be the helpstrings of the contained tokens.
|
||||||
|
*
|
||||||
|
* The individual helpstrings are expected to be in the same order as their
|
||||||
|
* respective Tokens appear in the cmdstr. They should each be terminated with
|
||||||
|
* a linefeed. The last helpstring should be terminated with a linefeed as well.
|
||||||
|
*
|
||||||
|
* Care should also be taken to avoid having similar tokens with different
|
||||||
|
* helpstrings. Imagine e.g. the commands "show ip ospf" and "show ip bgp".
|
||||||
|
* they both contain a helpstring for "show", but only one will be displayed
|
||||||
|
* when the user enters "sh?". If those two helpstrings differ, it is not
|
||||||
|
* defined which one will be shown and the behavior is therefore unpredictable.
|
||||||
|
*/
|
||||||
#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
|
#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
|
||||||
DEFUN_CMD_FUNC_DECL(funcname) \
|
DEFUN_CMD_FUNC_DECL(funcname) \
|
||||||
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
|
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
|
||||||
@ -330,7 +507,6 @@ struct desc
|
|||||||
extern void install_node (struct cmd_node *, int (*) (struct vty *));
|
extern void install_node (struct cmd_node *, int (*) (struct vty *));
|
||||||
extern void install_default (enum node_type);
|
extern void install_default (enum node_type);
|
||||||
extern void install_element (enum node_type, struct cmd_element *);
|
extern void install_element (enum node_type, struct cmd_element *);
|
||||||
extern void sort_node (void);
|
|
||||||
|
|
||||||
/* Concatenates argv[shift] through argv[argc-1] into a single NUL-terminated
|
/* Concatenates argv[shift] through argv[argc-1] into a single NUL-terminated
|
||||||
string with a space between each element (allocated using
|
string with a space between each element (allocated using
|
||||||
@ -346,7 +522,6 @@ extern int config_from_file (struct vty *, FILE *);
|
|||||||
extern enum node_type node_parent (enum node_type);
|
extern enum node_type node_parent (enum node_type);
|
||||||
extern int cmd_execute_command (vector, struct vty *, struct cmd_element **, int);
|
extern int cmd_execute_command (vector, struct vty *, struct cmd_element **, int);
|
||||||
extern int cmd_execute_command_strict (vector, struct vty *, struct cmd_element **);
|
extern int cmd_execute_command_strict (vector, struct vty *, struct cmd_element **);
|
||||||
extern void config_replace_string (struct cmd_element *, char *, ...);
|
|
||||||
extern void cmd_init (int);
|
extern void cmd_init (int);
|
||||||
extern void cmd_terminate (void);
|
extern void cmd_terminate (void);
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ struct memory_list memory_list_lib[] =
|
|||||||
{ MTYPE_ROUTE_MAP_RULE, "Route map rule" },
|
{ MTYPE_ROUTE_MAP_RULE, "Route map rule" },
|
||||||
{ MTYPE_ROUTE_MAP_RULE_STR, "Route map rule str" },
|
{ MTYPE_ROUTE_MAP_RULE_STR, "Route map rule str" },
|
||||||
{ MTYPE_ROUTE_MAP_COMPILED, "Route map compiled" },
|
{ MTYPE_ROUTE_MAP_COMPILED, "Route map compiled" },
|
||||||
{ MTYPE_DESC, "Command desc" },
|
{ MTYPE_CMD_TOKENS, "Command desc" },
|
||||||
{ MTYPE_KEY, "Key" },
|
{ MTYPE_KEY, "Key" },
|
||||||
{ MTYPE_KEYCHAIN, "Key chain" },
|
{ MTYPE_KEYCHAIN, "Key chain" },
|
||||||
{ MTYPE_IF_RMAP, "Interface route map" },
|
{ MTYPE_IF_RMAP, "Interface route map" },
|
||||||
|
54
lib/vty.c
54
lib/vty.c
@ -931,23 +931,23 @@ vty_complete_command (struct vty *vty)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
vty_describe_fold (struct vty *vty, int cmd_width,
|
vty_describe_fold (struct vty *vty, int cmd_width,
|
||||||
unsigned int desc_width, struct desc *desc)
|
unsigned int desc_width, struct cmd_token *token)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
const char *cmd, *p;
|
const char *cmd, *p;
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
cmd = desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd;
|
cmd = token->cmd[0] == '.' ? token->cmd + 1 : token->cmd;
|
||||||
|
|
||||||
if (desc_width <= 0)
|
if (desc_width <= 0)
|
||||||
{
|
{
|
||||||
vty_out (vty, " %-*s %s%s", cmd_width, cmd, desc->str, VTY_NEWLINE);
|
vty_out (vty, " %-*s %s%s", cmd_width, cmd, token->desc, VTY_NEWLINE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = XCALLOC (MTYPE_TMP, strlen (desc->str) + 1);
|
buf = XCALLOC (MTYPE_TMP, strlen (token->desc) + 1);
|
||||||
|
|
||||||
for (p = desc->str; strlen (p) > desc_width; p += pos + 1)
|
for (p = token->desc; strlen (p) > desc_width; p += pos + 1)
|
||||||
{
|
{
|
||||||
for (pos = desc_width; pos > 0; pos--)
|
for (pos = desc_width; pos > 0; pos--)
|
||||||
if (*(p + pos) == ' ')
|
if (*(p + pos) == ' ')
|
||||||
@ -976,7 +976,7 @@ vty_describe_command (struct vty *vty)
|
|||||||
vector vline;
|
vector vline;
|
||||||
vector describe;
|
vector describe;
|
||||||
unsigned int i, width, desc_width;
|
unsigned int i, width, desc_width;
|
||||||
struct desc *desc, *desc_cr = NULL;
|
struct cmd_token *token, *token_cr = NULL;
|
||||||
|
|
||||||
vline = cmd_make_strvec (vty->buf);
|
vline = cmd_make_strvec (vty->buf);
|
||||||
|
|
||||||
@ -1010,15 +1010,15 @@ vty_describe_command (struct vty *vty)
|
|||||||
/* Get width of command string. */
|
/* Get width of command string. */
|
||||||
width = 0;
|
width = 0;
|
||||||
for (i = 0; i < vector_active (describe); i++)
|
for (i = 0; i < vector_active (describe); i++)
|
||||||
if ((desc = vector_slot (describe, i)) != NULL)
|
if ((token = vector_slot (describe, i)) != NULL)
|
||||||
{
|
{
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
if (desc->cmd[0] == '\0')
|
if (token->cmd[0] == '\0')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
len = strlen (desc->cmd);
|
len = strlen (token->cmd);
|
||||||
if (desc->cmd[0] == '.')
|
if (token->cmd[0] == '.')
|
||||||
len--;
|
len--;
|
||||||
|
|
||||||
if (width < len)
|
if (width < len)
|
||||||
@ -1030,27 +1030,27 @@ vty_describe_command (struct vty *vty)
|
|||||||
|
|
||||||
/* Print out description. */
|
/* Print out description. */
|
||||||
for (i = 0; i < vector_active (describe); i++)
|
for (i = 0; i < vector_active (describe); i++)
|
||||||
if ((desc = vector_slot (describe, i)) != NULL)
|
if ((token = vector_slot (describe, i)) != NULL)
|
||||||
{
|
{
|
||||||
if (desc->cmd[0] == '\0')
|
if (token->cmd[0] == '\0')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strcmp (desc->cmd, command_cr) == 0)
|
if (strcmp (token->cmd, command_cr) == 0)
|
||||||
{
|
{
|
||||||
desc_cr = desc;
|
token_cr = token;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!desc->str)
|
if (!token->desc)
|
||||||
vty_out (vty, " %-s%s",
|
vty_out (vty, " %-s%s",
|
||||||
desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
|
token->cmd[0] == '.' ? token->cmd + 1 : token->cmd,
|
||||||
VTY_NEWLINE);
|
VTY_NEWLINE);
|
||||||
else if (desc_width >= strlen (desc->str))
|
else if (desc_width >= strlen (token->desc))
|
||||||
vty_out (vty, " %-*s %s%s", width,
|
vty_out (vty, " %-*s %s%s", width,
|
||||||
desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
|
token->cmd[0] == '.' ? token->cmd + 1 : token->cmd,
|
||||||
desc->str, VTY_NEWLINE);
|
token->desc, VTY_NEWLINE);
|
||||||
else
|
else
|
||||||
vty_describe_fold (vty, width, desc_width, desc);
|
vty_describe_fold (vty, width, desc_width, token);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
vty_out (vty, " %-*s %s%s", width
|
vty_out (vty, " %-*s %s%s", width
|
||||||
@ -1059,18 +1059,18 @@ vty_describe_command (struct vty *vty)
|
|||||||
#endif /* 0 */
|
#endif /* 0 */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((desc = desc_cr))
|
if ((token = token_cr))
|
||||||
{
|
{
|
||||||
if (!desc->str)
|
if (!token->desc)
|
||||||
vty_out (vty, " %-s%s",
|
vty_out (vty, " %-s%s",
|
||||||
desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
|
token->cmd[0] == '.' ? token->cmd + 1 : token->cmd,
|
||||||
VTY_NEWLINE);
|
VTY_NEWLINE);
|
||||||
else if (desc_width >= strlen (desc->str))
|
else if (desc_width >= strlen (token->desc))
|
||||||
vty_out (vty, " %-*s %s%s", width,
|
vty_out (vty, " %-*s %s%s", width,
|
||||||
desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
|
token->cmd[0] == '.' ? token->cmd + 1 : token->cmd,
|
||||||
desc->str, VTY_NEWLINE);
|
token->desc, VTY_NEWLINE);
|
||||||
else
|
else
|
||||||
vty_describe_fold (vty, width, desc_width, desc);
|
vty_describe_fold (vty, width, desc_width, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -325,9 +325,6 @@ main (int argc, char *argv[], char *envp[])
|
|||||||
/* initialize ospf6 */
|
/* initialize ospf6 */
|
||||||
ospf6_init ();
|
ospf6_init ();
|
||||||
|
|
||||||
/* sort command vector */
|
|
||||||
sort_node ();
|
|
||||||
|
|
||||||
/* parse config file */
|
/* parse config file */
|
||||||
vty_read_config (config_file, config_default);
|
vty_read_config (config_file, config_default);
|
||||||
|
|
||||||
|
@ -310,8 +310,6 @@ main (int argc, char **argv)
|
|||||||
ospf_opaque_init ();
|
ospf_opaque_init ();
|
||||||
#endif /* HAVE_OPAQUE_LSA */
|
#endif /* HAVE_OPAQUE_LSA */
|
||||||
|
|
||||||
sort_node ();
|
|
||||||
|
|
||||||
/* Get configuration file. */
|
/* Get configuration file. */
|
||||||
vty_read_config (config_file, config_default);
|
vty_read_config (config_file, config_default);
|
||||||
|
|
||||||
|
@ -287,9 +287,6 @@ main (int argc, char **argv)
|
|||||||
rip_zclient_init ();
|
rip_zclient_init ();
|
||||||
rip_peer_init ();
|
rip_peer_init ();
|
||||||
|
|
||||||
/* Sort all installed commands. */
|
|
||||||
sort_node ();
|
|
||||||
|
|
||||||
/* Get configuration file. */
|
/* Get configuration file. */
|
||||||
vty_read_config (config_file, config_default);
|
vty_read_config (config_file, config_default);
|
||||||
|
|
||||||
|
@ -282,9 +282,6 @@ main (int argc, char **argv)
|
|||||||
zebra_init ();
|
zebra_init ();
|
||||||
ripng_peer_init ();
|
ripng_peer_init ();
|
||||||
|
|
||||||
/* Sort all installed commands. */
|
|
||||||
sort_node ();
|
|
||||||
|
|
||||||
/* Get configuration file. */
|
/* Get configuration file. */
|
||||||
vty_read_config (config_file, config_default);
|
vty_read_config (config_file, config_default);
|
||||||
|
|
||||||
|
@ -171,8 +171,6 @@ main (int argc, char **argv)
|
|||||||
/* OSPF vty inits. */
|
/* OSPF vty inits. */
|
||||||
test_vty_init ();
|
test_vty_init ();
|
||||||
|
|
||||||
sort_node ();
|
|
||||||
|
|
||||||
/* Change to the daemon program. */
|
/* Change to the daemon program. */
|
||||||
if (daemon_mode && daemon (0, 0) < 0)
|
if (daemon_mode && daemon (0, 0) < 0)
|
||||||
{
|
{
|
||||||
|
@ -233,8 +233,6 @@ test_init(void)
|
|||||||
cmd->daemon = 0;
|
cmd->daemon = 0;
|
||||||
cmd->func = test_callback;
|
cmd->func = test_callback;
|
||||||
}
|
}
|
||||||
sort_node();
|
|
||||||
|
|
||||||
test_load();
|
test_load();
|
||||||
vty_init_vtysh();
|
vty_init_vtysh();
|
||||||
}
|
}
|
||||||
@ -340,8 +338,8 @@ test_run(struct prng *prng, struct vty *vty, const char *cmd, unsigned int edit_
|
|||||||
{
|
{
|
||||||
for (j = 0; j < vector_active(descriptions); j++)
|
for (j = 0; j < vector_active(descriptions); j++)
|
||||||
{
|
{
|
||||||
struct desc *cmd = vector_slot(descriptions, j);
|
struct cmd_token *cmd = vector_slot(descriptions, j);
|
||||||
printf(" '%s' '%s'\n", cmd->cmd, cmd->str);
|
printf(" '%s' '%s'\n", cmd->cmd, cmd->desc);
|
||||||
}
|
}
|
||||||
vector_free(descriptions);
|
vector_free(descriptions);
|
||||||
}
|
}
|
||||||
|
@ -554,7 +554,7 @@ vtysh_rl_describe (void)
|
|||||||
vector vline;
|
vector vline;
|
||||||
vector describe;
|
vector describe;
|
||||||
int width;
|
int width;
|
||||||
struct desc *desc;
|
struct cmd_token *token;
|
||||||
|
|
||||||
vline = cmd_make_strvec (rl_line_buffer);
|
vline = cmd_make_strvec (rl_line_buffer);
|
||||||
|
|
||||||
@ -592,15 +592,15 @@ vtysh_rl_describe (void)
|
|||||||
/* Get width of command string. */
|
/* Get width of command string. */
|
||||||
width = 0;
|
width = 0;
|
||||||
for (i = 0; i < vector_active (describe); i++)
|
for (i = 0; i < vector_active (describe); i++)
|
||||||
if ((desc = vector_slot (describe, i)) != NULL)
|
if ((token = vector_slot (describe, i)) != NULL)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (desc->cmd[0] == '\0')
|
if (token->cmd[0] == '\0')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
len = strlen (desc->cmd);
|
len = strlen (token->cmd);
|
||||||
if (desc->cmd[0] == '.')
|
if (token->cmd[0] == '.')
|
||||||
len--;
|
len--;
|
||||||
|
|
||||||
if (width < len)
|
if (width < len)
|
||||||
@ -608,19 +608,19 @@ vtysh_rl_describe (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < vector_active (describe); i++)
|
for (i = 0; i < vector_active (describe); i++)
|
||||||
if ((desc = vector_slot (describe, i)) != NULL)
|
if ((token = vector_slot (describe, i)) != NULL)
|
||||||
{
|
{
|
||||||
if (desc->cmd[0] == '\0')
|
if (token->cmd[0] == '\0')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (! desc->str)
|
if (! token->desc)
|
||||||
fprintf (stdout," %-s\n",
|
fprintf (stdout," %-s\n",
|
||||||
desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd);
|
token->cmd[0] == '.' ? token->cmd + 1 : token->cmd);
|
||||||
else
|
else
|
||||||
fprintf (stdout," %-*s %s\n",
|
fprintf (stdout," %-*s %s\n",
|
||||||
width,
|
width,
|
||||||
desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
|
token->cmd[0] == '.' ? token->cmd + 1 : token->cmd,
|
||||||
desc->str);
|
token->desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_free_strvec (vline);
|
cmd_free_strvec (vline);
|
||||||
|
@ -299,8 +299,6 @@ main (int argc, char **argv, char **env)
|
|||||||
|
|
||||||
vty_init_vtysh ();
|
vty_init_vtysh ();
|
||||||
|
|
||||||
sort_node ();
|
|
||||||
|
|
||||||
/* Read vtysh configuration file before connecting to daemons. */
|
/* Read vtysh configuration file before connecting to daemons. */
|
||||||
vtysh_read_config (config_default);
|
vtysh_read_config (config_default);
|
||||||
|
|
||||||
|
@ -343,9 +343,6 @@ main (int argc, char **argv)
|
|||||||
interface_list ();
|
interface_list ();
|
||||||
route_read ();
|
route_read ();
|
||||||
|
|
||||||
/* Sort VTY commands. */
|
|
||||||
sort_node ();
|
|
||||||
|
|
||||||
#ifdef HAVE_SNMP
|
#ifdef HAVE_SNMP
|
||||||
zebra_snmp_init ();
|
zebra_snmp_init ();
|
||||||
#endif /* HAVE_SNMP */
|
#endif /* HAVE_SNMP */
|
||||||
|
@ -298,9 +298,6 @@ main (int argc, char **argv)
|
|||||||
route_read ();
|
route_read ();
|
||||||
zebra_vty_init();
|
zebra_vty_init();
|
||||||
|
|
||||||
/* Sort VTY commands. */
|
|
||||||
sort_node ();
|
|
||||||
|
|
||||||
/* Configuration file read*/
|
/* Configuration file read*/
|
||||||
vty_read_config (config_file, config_default);
|
vty_read_config (config_file, config_default);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user