mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 18:04:03 +00:00
doc: update CLI documentation
Fix markdown formatting & add variable names. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
b8a815e5e4
commit
4e3e06d638
105
doc/cli.md
105
doc/cli.md
@ -7,10 +7,12 @@ Definition Grammar
|
|||||||
This is a reference for the syntax used when defining new CLI commands. An
|
This is a reference for the syntax used when defining new CLI commands. An
|
||||||
example definition is:
|
example definition is:
|
||||||
|
|
||||||
|
```
|
||||||
DEFUN (command_name,
|
DEFUN (command_name,
|
||||||
command_name_cmd,
|
command_name_cmd,
|
||||||
--> "example <command|line [interface]> DEFINITION...",
|
--> "example <command|line [interface]> DEFINITION...",
|
||||||
<..doc strings..>)
|
<..doc strings..>)
|
||||||
|
```
|
||||||
|
|
||||||
The arrowed part is the definition string.
|
The arrowed part is the definition string.
|
||||||
|
|
||||||
@ -27,34 +29,36 @@ Characters allowed in each token type:
|
|||||||
|
|
||||||
Tokens
|
Tokens
|
||||||
------
|
------
|
||||||
* WORD -- A token that begins with +, -, or a lowercase letter. It is
|
* `WORD` -- A token that begins with +, -, or a lowercase letter. It is
|
||||||
an unchanging part of the command and will only match itself.
|
an unchanging part of the command and will only match itself.
|
||||||
Example: "show ip bgp", every token is a WORD.
|
Example: "show ip bgp", every token is a WORD.
|
||||||
* IPV4 -- 'A.B.C.D', matches an IPv4 address.
|
* `IPV4` -- 'A.B.C.D', matches an IPv4 address.
|
||||||
* IPV6 -- 'X:X::X:X', matches an IPv6 address.
|
* `IPV6` -- 'X:X::X:X', matches an IPv6 address.
|
||||||
* IPV4_PREFIX -- 'A.B.C.D/M', matches an IPv4 prefix in CIDR notation.
|
* `IPV4_PREFIX` -- 'A.B.C.D/M', matches an IPv4 prefix in CIDR notation.
|
||||||
* IPV6_PREFIX -- 'X:X::X:X/M', matches an IPv6 prefix in CIDR notation.
|
* `IPV6_PREFIX` -- 'X:X::X:X/M', matches an IPv6 prefix in CIDR notation.
|
||||||
* VARIABLE -- Begins with a capital letter. Matches any input.
|
* `VARIABLE` -- Begins with a capital letter. Matches any input.
|
||||||
* RANGE -- Numeric range delimited by parentheses, e.g. (-100 - 100) or
|
* `RANGE` -- Numeric range delimited by parentheses, e.g. (-100 - 100) or
|
||||||
(10-20). Will only match numbers in the range.
|
(10-20). Will only match numbers in the range.
|
||||||
|
|
||||||
Rules
|
Rules
|
||||||
-----
|
-----
|
||||||
* <angle|brackets> -- Contain sequences of tokens separated by pipes and
|
* `<angle|brackets>` -- Contain sequences of tokens separated by pipes and
|
||||||
provide mutual exclusion. Sequences may contain
|
provide mutual exclusion. Sequences may contain
|
||||||
<mutual|exclusion> but not as the first token.
|
`<mutual|exclusion>` but not as the first token.
|
||||||
Disallowed: "example <<a|b> c|d>"
|
Disallowed: `"example <<a|b> c|d>"`
|
||||||
Allowed: "example <a c|b c|d>
|
Allowed: `"example <a c|b c|d>"`
|
||||||
* [square brackets] -- Contains sequences of tokens that are optional (can be
|
* `[square brackets]` -- Contains sequences of tokens that are optional (can be
|
||||||
omitted).
|
omitted). `[<a|b>]` can be shortened to `[a|b]`.
|
||||||
* {curly|braces} -- similar to angle brackets, but instead of mutual
|
* `{curly|braces}` -- similar to angle brackets, but instead of mutual
|
||||||
exclusion, curly braces indicate that one or more of the
|
exclusion, curly braces indicate that one or more of the
|
||||||
pipe-separated sequences may be provided in any order.
|
pipe-separated sequences may be provided in any order.
|
||||||
* VARIADICS... -- Any token which accepts input (so anything except WORD)
|
* `VARIADICS...` -- Any token which accepts input (so anything except WORD)
|
||||||
and that occurs as the last token of a line may be
|
and that occurs as the last token of a line may be
|
||||||
followed by an ellipsis, which indicates that input
|
followed by an ellipsis, which indicates that input
|
||||||
matching the token may be repeated an unlimited number
|
matching the token may be repeated an unlimited number
|
||||||
of times.
|
of times.
|
||||||
|
* `$name` -- Specify a variable name for the preceding token. See
|
||||||
|
"Variable Names" below.
|
||||||
|
|
||||||
Some general notes:
|
Some general notes:
|
||||||
|
|
||||||
@ -69,6 +73,40 @@ Some general notes:
|
|||||||
configuration items should be defined in separate commands. Clarity is
|
configuration items should be defined in separate commands. Clarity is
|
||||||
preferred over LOC (within reason).
|
preferred over LOC (within reason).
|
||||||
|
|
||||||
|
Variable Names
|
||||||
|
--------------
|
||||||
|
The parser tries to fill the "varname" field on each token. This can happen
|
||||||
|
either manually or automatically. Manual specifications work by appending
|
||||||
|
`"$name"` after the input specifier:
|
||||||
|
|
||||||
|
```
|
||||||
|
foo bar$cmd WORD$name A.B.C.D$ip
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that you can also assign variable names to fixed input tokens, this can
|
||||||
|
be useful if multiple commands share code. You can also use "$name" after a
|
||||||
|
multiple-choice option:
|
||||||
|
|
||||||
|
```
|
||||||
|
foo bar <A.B.C.D|X:X::X:X>$addr [optionA|optionB]$mode
|
||||||
|
```
|
||||||
|
|
||||||
|
The variable name is in this case assigned to the last token in each of the
|
||||||
|
branches.
|
||||||
|
|
||||||
|
Automatic assignment of variable names works by applying the following rules:
|
||||||
|
|
||||||
|
- manual names always have priority
|
||||||
|
- a "[no]" at the beginning receives "no" as varname on the "no" token
|
||||||
|
- WORD tokens whose text is not "WORD" or "NAME" receive a cleaned lowercase
|
||||||
|
version of the token text as varname, e.g. "ROUTE-MAP" becomes "route_map".
|
||||||
|
- other variable tokens (i.e. everything except "fixed") receive the text of
|
||||||
|
the preceding fixed token as varname, if one can be found. E.g.:
|
||||||
|
"ip route A.B.C.D/M INTERFACE" assigns "route" to the "A.B.C.D/M" token.
|
||||||
|
|
||||||
|
These rules should make it possible to avoid manual varname assignment in 90%
|
||||||
|
of the cases.
|
||||||
|
|
||||||
Doc Strings
|
Doc Strings
|
||||||
-----------
|
-----------
|
||||||
Each token in a command definition should be documented with a brief doc
|
Each token in a command definition should be documented with a brief doc
|
||||||
@ -77,11 +115,13 @@ command tree. These strings are provided as the last parameter to DEFUN macros,
|
|||||||
concatenated together and separated by an escaped newline ('\n'). These are
|
concatenated together and separated by an escaped newline ('\n'). These are
|
||||||
best explained by example.
|
best explained by example.
|
||||||
|
|
||||||
|
```
|
||||||
DEFUN (config_terminal,
|
DEFUN (config_terminal,
|
||||||
config_terminal_cmd,
|
config_terminal_cmd,
|
||||||
"configure terminal",
|
"configure terminal",
|
||||||
"Configuration from vty interface\n"
|
"Configuration from vty interface\n"
|
||||||
"Configuration terminal\n")
|
"Configuration terminal\n")
|
||||||
|
```
|
||||||
|
|
||||||
The last parameter is split into two lines for readability. Two newline
|
The last parameter is split into two lines for readability. Two newline
|
||||||
delimited doc strings are present, one for each token in the command. The
|
delimited doc strings are present, one for each token in the command. The
|
||||||
@ -110,11 +150,13 @@ constructs.
|
|||||||
|
|
||||||
In the examples below, each arrowed token needs a doc string.
|
In the examples below, each arrowed token needs a doc string.
|
||||||
|
|
||||||
|
```
|
||||||
"show ip bgp"
|
"show ip bgp"
|
||||||
^ ^ ^
|
^ ^ ^
|
||||||
|
|
||||||
"command <foo|bar> [example]"
|
"command <foo|bar> [example]"
|
||||||
^ ^ ^ ^
|
^ ^ ^ ^
|
||||||
|
```
|
||||||
|
|
||||||
Data Structures
|
Data Structures
|
||||||
---------------
|
---------------
|
||||||
@ -216,22 +258,32 @@ it is generally _incorrect_ to assume consistent indices in this array. As a
|
|||||||
simple example:
|
simple example:
|
||||||
|
|
||||||
Command definition:
|
Command definition:
|
||||||
|
```
|
||||||
command [foo] <bar|baz>
|
command [foo] <bar|baz>
|
||||||
|
```
|
||||||
|
|
||||||
User enters:
|
User enters:
|
||||||
|
```
|
||||||
command foo bar
|
command foo bar
|
||||||
|
```
|
||||||
|
|
||||||
Array:
|
Array:
|
||||||
|
```
|
||||||
[0] -> command
|
[0] -> command
|
||||||
[1] -> foo
|
[1] -> foo
|
||||||
[2] -> bar
|
[2] -> bar
|
||||||
|
```
|
||||||
|
|
||||||
User enters:
|
User enters:
|
||||||
|
```
|
||||||
command baz
|
command baz
|
||||||
|
```
|
||||||
|
|
||||||
Array:
|
Array:
|
||||||
|
```
|
||||||
[0] -> command
|
[0] -> command
|
||||||
[1] -> baz
|
[1] -> baz
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -242,24 +294,32 @@ tokens when the CLI matcher does not need them to make an unambiguous match.
|
|||||||
This is best explained by example.
|
This is best explained by example.
|
||||||
|
|
||||||
Command definitions:
|
Command definitions:
|
||||||
|
```
|
||||||
command dog cow
|
command dog cow
|
||||||
command dog crow
|
command dog crow
|
||||||
|
```
|
||||||
|
|
||||||
User input:
|
User input:
|
||||||
|
```
|
||||||
c d c -> ambiguous command
|
c d c -> ambiguous command
|
||||||
c d co -> match "command dog cow"
|
c d co -> match "command dog cow"
|
||||||
|
```
|
||||||
|
|
||||||
In the new implementation, this functionality has improved. Where previously
|
In the new implementation, this functionality has improved. Where previously
|
||||||
the parser would stop at the first ambiguous token, it will now look ahead and
|
the parser would stop at the first ambiguous token, it will now look ahead and
|
||||||
attempt to disambiguate based on tokens later on in the input string.
|
attempt to disambiguate based on tokens later on in the input string.
|
||||||
|
|
||||||
Command definitions:
|
Command definitions:
|
||||||
|
```
|
||||||
show ip bgp A.B.C.D
|
show ip bgp A.B.C.D
|
||||||
show ipv6 bgp X:X::X:X
|
show ipv6 bgp X:X::X:X
|
||||||
|
```
|
||||||
|
|
||||||
User enters:
|
User enters:
|
||||||
|
```
|
||||||
s i b 4.3.2.1 -> match "show ip bgp A.B.C.D"
|
s i b 4.3.2.1 -> match "show ip bgp A.B.C.D"
|
||||||
s i b ::e0 -> match "show ipv6 bgp X:X::X:X"
|
s i b ::e0 -> match "show ipv6 bgp X:X::X:X"
|
||||||
|
```
|
||||||
|
|
||||||
Previously both of these commands would be ambiguous since 'i' does not
|
Previously both of these commands would be ambiguous since 'i' does not
|
||||||
explicitly select either 'ip' or 'ipv6'. However, since the user later provides
|
explicitly select either 'ip' or 'ipv6'. However, since the user later provides
|
||||||
@ -268,17 +328,23 @@ parser is able to look ahead and select the appropriate command. This has some
|
|||||||
implications for parsing the argv*[] that is passed to the command handler.
|
implications for parsing the argv*[] that is passed to the command handler.
|
||||||
|
|
||||||
Now consider a command definition such as:
|
Now consider a command definition such as:
|
||||||
|
```
|
||||||
command <foo|VAR>
|
command <foo|VAR>
|
||||||
|
```
|
||||||
|
|
||||||
'foo' only matches the string 'foo', but 'VAR' matches any input, including
|
'foo' only matches the string 'foo', but 'VAR' matches any input, including
|
||||||
'foo'. Who wins? In situations like this the matcher will always choose the
|
'foo'. Who wins? In situations like this the matcher will always choose the
|
||||||
'better' match, so 'foo' will win.
|
'better' match, so 'foo' will win.
|
||||||
|
|
||||||
Consider also:
|
Consider also:
|
||||||
|
```
|
||||||
show <ip|ipv6> foo
|
show <ip|ipv6> foo
|
||||||
|
```
|
||||||
|
|
||||||
User input:
|
User input:
|
||||||
|
```
|
||||||
show ip foo
|
show ip foo
|
||||||
|
```
|
||||||
|
|
||||||
'ip' partially matches 'ipv6' but exactly matches 'ip', so 'ip' will win.
|
'ip' partially matches 'ipv6' but exactly matches 'ip', so 'ip' will win.
|
||||||
|
|
||||||
@ -286,6 +352,7 @@ User input:
|
|||||||
struct cmd_token
|
struct cmd_token
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
```
|
||||||
/* Command token struct. */
|
/* Command token struct. */
|
||||||
struct cmd_token
|
struct cmd_token
|
||||||
{
|
{
|
||||||
@ -297,7 +364,9 @@ struct cmd_token
|
|||||||
char *desc; // token description
|
char *desc; // token description
|
||||||
long long min, max; // for ranges
|
long long min, max; // for ranges
|
||||||
char *arg; // user input that matches this token
|
char *arg; // user input that matches this token
|
||||||
|
char *varname; // variable name
|
||||||
};
|
};
|
||||||
|
```
|
||||||
|
|
||||||
This struct is used in the CLI graph to match input against. It is also used to
|
This struct is used in the CLI graph to match input against. It is also used to
|
||||||
pass user input to command handler functions, as it is frequently useful for
|
pass user input to command handler functions, as it is frequently useful for
|
||||||
@ -316,7 +385,9 @@ has the full text of the corresponding token in the definition string and using
|
|||||||
it makes for much more readable code. An example is helpful.
|
it makes for much more readable code. An example is helpful.
|
||||||
|
|
||||||
Command definition:
|
Command definition:
|
||||||
|
```
|
||||||
command <(1-10)|foo|BAR>
|
command <(1-10)|foo|BAR>
|
||||||
|
```
|
||||||
|
|
||||||
In this example, the user may enter any one of:
|
In this example, the user may enter any one of:
|
||||||
* an integer between 1 and 10
|
* an integer between 1 and 10
|
||||||
@ -325,9 +396,11 @@ In this example, the user may enter any one of:
|
|||||||
|
|
||||||
If the user enters "command f", then:
|
If the user enters "command f", then:
|
||||||
|
|
||||||
|
```
|
||||||
argv[1]->type == WORD_TKN
|
argv[1]->type == WORD_TKN
|
||||||
argv[1]->arg == "f"
|
argv[1]->arg == "f"
|
||||||
argv[1]->text == "foo"
|
argv[1]->text == "foo"
|
||||||
|
```
|
||||||
|
|
||||||
Range tokens have some special treatment; a token with ->type == RANGE_TKN will
|
Range tokens have some special treatment; a token with ->type == RANGE_TKN will
|
||||||
have the ->min and ->max fields set to the bounding values of the range.
|
have the ->min and ->max fields set to the bounding values of the range.
|
||||||
@ -342,6 +415,7 @@ all matching input permutations. It also dumps a text representation of the
|
|||||||
graph, which is more useful for debugging than anything else. It looks like
|
graph, which is more useful for debugging than anything else. It looks like
|
||||||
this:
|
this:
|
||||||
|
|
||||||
|
```
|
||||||
$ ./permutations "show [ip] bgp [<view|vrf> WORD]"
|
$ ./permutations "show [ip] bgp [<view|vrf> WORD]"
|
||||||
|
|
||||||
show ip bgp view WORD
|
show ip bgp view WORD
|
||||||
@ -350,6 +424,7 @@ show ip bgp
|
|||||||
show bgp view WORD
|
show bgp view WORD
|
||||||
show bgp vrf WORD
|
show bgp vrf WORD
|
||||||
show bgp
|
show bgp
|
||||||
|
```
|
||||||
|
|
||||||
This functionality is also built into VTY/VTYSH; the 'list permutations'
|
This functionality is also built into VTY/VTYSH; the 'list permutations'
|
||||||
command will list all possible matching input permutations in the current CLI
|
command will list all possible matching input permutations in the current CLI
|
||||||
|
Loading…
Reference in New Issue
Block a user