mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-09-07 22:15:19 +00:00
Client: Add support for completion of command options
We can easily extend command completion to handle also keywords for command options. Help for command options is not yet supported.
This commit is contained in:
parent
114be2af28
commit
1b064355f7
@ -20,6 +20,7 @@ struct cmd_info {
|
|||||||
char *args;
|
char *args;
|
||||||
char *help;
|
char *help;
|
||||||
int is_real_cmd;
|
int is_real_cmd;
|
||||||
|
int is_option;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct cmd_info command_table[] = {
|
static struct cmd_info command_table[] = {
|
||||||
@ -30,7 +31,8 @@ struct cmd_node {
|
|||||||
struct cmd_node *sibling, *son, **plastson;
|
struct cmd_node *sibling, *son, **plastson;
|
||||||
struct cmd_info *cmd, *help;
|
struct cmd_info *cmd, *help;
|
||||||
int len;
|
int len;
|
||||||
signed char prio;
|
u8 final;
|
||||||
|
s8 prio;
|
||||||
char token[1];
|
char token[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -51,12 +53,13 @@ cmd_build_tree(void)
|
|||||||
struct cmd_node *old, *new;
|
struct cmd_node *old, *new;
|
||||||
char *c = cmd->command;
|
char *c = cmd->command;
|
||||||
|
|
||||||
old = &cmd_root;
|
new = &cmd_root;
|
||||||
while (*c)
|
while (*c)
|
||||||
{
|
{
|
||||||
char *d = c;
|
char *d = c;
|
||||||
while (*c && !isspace_(*c))
|
while (*c && !isspace_(*c))
|
||||||
c++;
|
c++;
|
||||||
|
old = new;
|
||||||
for(new=old->son; new; new=new->sibling)
|
for(new=old->son; new; new=new->sibling)
|
||||||
if (new->len == c-d && !memcmp(new->token, d, c-d))
|
if (new->len == c-d && !memcmp(new->token, d, c-d))
|
||||||
break;
|
break;
|
||||||
@ -72,14 +75,17 @@ cmd_build_tree(void)
|
|||||||
memcpy(new->token, d, c-d);
|
memcpy(new->token, d, c-d);
|
||||||
new->prio = (new->len == 3 && (!memcmp(new->token, "roa", 3) || !memcmp(new->token, "rip", 3))) ? 0 : 1; /* Hack */
|
new->prio = (new->len == 3 && (!memcmp(new->token, "roa", 3) || !memcmp(new->token, "rip", 3))) ? 0 : 1; /* Hack */
|
||||||
}
|
}
|
||||||
old = new;
|
|
||||||
while (isspace_(*c))
|
while (isspace_(*c))
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd->is_real_cmd)
|
if (cmd->is_real_cmd)
|
||||||
old->cmd = cmd;
|
new->cmd = cmd;
|
||||||
else
|
else
|
||||||
old->help = cmd;
|
new->help = cmd;
|
||||||
|
|
||||||
|
if (cmd->is_option)
|
||||||
|
old->final = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +153,7 @@ cmd_help(char *cmd, int len)
|
|||||||
int ambig;
|
int ambig;
|
||||||
|
|
||||||
n = &cmd_root;
|
n = &cmd_root;
|
||||||
while (cmd < end)
|
while (cmd < end && !n->final)
|
||||||
{
|
{
|
||||||
if (isspace_(*cmd))
|
if (isspace_(*cmd))
|
||||||
{
|
{
|
||||||
@ -168,6 +174,11 @@ cmd_help(char *cmd, int len)
|
|||||||
n = m;
|
n = m;
|
||||||
}
|
}
|
||||||
cmd_display_help(n->cmd, NULL);
|
cmd_display_help(n->cmd, NULL);
|
||||||
|
|
||||||
|
/* Currently no help for options */
|
||||||
|
if (n->final)
|
||||||
|
return;
|
||||||
|
|
||||||
for (m=n->son; m; m=m->sibling)
|
for (m=n->son; m; m=m->sibling)
|
||||||
cmd_display_help(m->help, m->cmd);
|
cmd_display_help(m->help, m->cmd);
|
||||||
}
|
}
|
||||||
@ -229,7 +240,7 @@ cmd_complete(char *cmd, int len, char *buf, int again)
|
|||||||
|
|
||||||
/* Find the context */
|
/* Find the context */
|
||||||
n = &cmd_root;
|
n = &cmd_root;
|
||||||
while (cmd < fin && n->son)
|
while (cmd < fin && n->son && !n->final)
|
||||||
{
|
{
|
||||||
if (isspace_(*cmd))
|
if (isspace_(*cmd))
|
||||||
{
|
{
|
||||||
@ -290,7 +301,7 @@ cmd_expand(char *cmd)
|
|||||||
|
|
||||||
args = c = cmd;
|
args = c = cmd;
|
||||||
n = &cmd_root;
|
n = &cmd_root;
|
||||||
while (*c)
|
while (*c && !n->final)
|
||||||
{
|
{
|
||||||
if (isspace_(*c))
|
if (isspace_(*c))
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,9 @@ m4_divert(-1)')
|
|||||||
m4_define(CF_CLI_CMD, `m4_divert(0){ "m4_translit($1,A-Z,a-z)", "$2", "$3", 1 },
|
m4_define(CF_CLI_CMD, `m4_divert(0){ "m4_translit($1,A-Z,a-z)", "$2", "$3", 1 },
|
||||||
m4_divert(-1)')
|
m4_divert(-1)')
|
||||||
|
|
||||||
|
m4_define(CF_CLI_OPT, `m4_divert(0){ "m4_translit($1,A-Z,a-z)", "$2", "$3", 1, .is_option = 1 },
|
||||||
|
m4_divert(-1)')
|
||||||
|
|
||||||
m4_define(CF_CLI_HELP, `m4_divert(0){ "m4_translit($1,A-Z,a-z)", "$2", "$3", 0 },
|
m4_define(CF_CLI_HELP, `m4_divert(0){ "m4_translit($1,A-Z,a-z)", "$2", "$3", 0 },
|
||||||
m4_divert(-1)')
|
m4_divert(-1)')
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ m4_divert(2)CF_KEYWORDS(m4_translit($1, [[ ]], [[,]]))
|
|||||||
m4_divert(3)cli_cmd: CF_cmd
|
m4_divert(3)cli_cmd: CF_cmd
|
||||||
CF_cmd: $1 $2 END')
|
CF_cmd: $1 $2 END')
|
||||||
m4_define(CF_CLI_CMD, `')
|
m4_define(CF_CLI_CMD, `')
|
||||||
|
m4_define(CF_CLI_OPT, `')
|
||||||
m4_define(CF_CLI_HELP, `')
|
m4_define(CF_CLI_HELP, `')
|
||||||
|
|
||||||
# ENUM declarations are ignored
|
# ENUM declarations are ignored
|
||||||
|
@ -650,6 +650,23 @@ CF_CLI_HELP(SHOW ROUTE, ..., [[Show routing table]])
|
|||||||
CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>|in <prefix>] [table <t>] [(import|export) table <p>.<c>] [filter <f>|where <cond>] [all] [primary] [filtered] [(export|preexport|noexport) <p>] [protocol <p>] [stats|count]]], [[Show routing table]])
|
CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>|in <prefix>] [table <t>] [(import|export) table <p>.<c>] [filter <f>|where <cond>] [all] [primary] [filtered] [(export|preexport|noexport) <p>] [protocol <p>] [stats|count]]], [[Show routing table]])
|
||||||
{ rt_show($3); } ;
|
{ rt_show($3); } ;
|
||||||
|
|
||||||
|
CF_CLI_OPT(SHOW ROUTE FOR, <ip>|<prefix>)
|
||||||
|
CF_CLI_OPT(SHOW ROUTE IN, <prefix>)
|
||||||
|
CF_CLI_OPT(SHOW ROUTE TABLE, <t>)
|
||||||
|
CF_CLI_OPT(SHOW ROUTE FILTER, <f>)
|
||||||
|
CF_CLI_OPT(SHOW ROUTE WHERE, <cond>)
|
||||||
|
CF_CLI_OPT(SHOW ROUTE ALL)
|
||||||
|
CF_CLI_OPT(SHOW ROUTE PRIMARY)
|
||||||
|
CF_CLI_OPT(SHOW ROUTE FILTERED)
|
||||||
|
CF_CLI_OPT(SHOW ROUTE IMPORT, <p>[.<c>])
|
||||||
|
CF_CLI_OPT(SHOW ROUTE EXPORT, <p>[.<c>])
|
||||||
|
CF_CLI_OPT(SHOW ROUTE EXPORTED, <p>[.<c>])
|
||||||
|
CF_CLI_OPT(SHOW ROUTE PREEXPORT, <p>[.<c>])
|
||||||
|
CF_CLI_OPT(SHOW ROUTE NOEXPORT, <p>[.<c>])
|
||||||
|
CF_CLI_OPT(SHOW ROUTE PROTOCOL, <p>)
|
||||||
|
CF_CLI_OPT(SHOW ROUTE STATS)
|
||||||
|
CF_CLI_OPT(SHOW ROUTE COUNT)
|
||||||
|
|
||||||
r_args:
|
r_args:
|
||||||
/* empty */ {
|
/* empty */ {
|
||||||
$$ = cfg_allocz(sizeof(struct rt_show_data));
|
$$ = cfg_allocz(sizeof(struct rt_show_data));
|
||||||
@ -841,13 +858,19 @@ CF_CLI_HELP(SHOW SYMBOLS, ..., [[Show all known symbolic names]])
|
|||||||
CF_CLI(SHOW SYMBOLS, sym_args, [table|filter|function|protocol|template|<symbol>], [[Show all known symbolic names]])
|
CF_CLI(SHOW SYMBOLS, sym_args, [table|filter|function|protocol|template|<symbol>], [[Show all known symbolic names]])
|
||||||
{ cmd_show_symbols($3); } ;
|
{ cmd_show_symbols($3); } ;
|
||||||
|
|
||||||
|
CF_CLI_OPT(SHOW SYMBOLS TABLE)
|
||||||
|
CF_CLI_OPT(SHOW SYMBOLS FILTER)
|
||||||
|
CF_CLI_OPT(SHOW SYMBOLS FUNCTION)
|
||||||
|
CF_CLI_OPT(SHOW SYMBOLS PROTOCOL)
|
||||||
|
CF_CLI_OPT(SHOW SYMBOLS TEMPLATE)
|
||||||
|
|
||||||
sym_args:
|
sym_args:
|
||||||
/* empty */ {
|
/* empty */ {
|
||||||
$$ = cfg_allocz(sizeof(struct sym_show_data));
|
$$ = cfg_allocz(sizeof(struct sym_show_data));
|
||||||
}
|
}
|
||||||
| sym_args TABLE { $$ = $1; $$->type = SYM_TABLE; }
|
| sym_args TABLE { $$ = $1; $$->type = SYM_TABLE; }
|
||||||
| sym_args FUNCTION { $$ = $1; $$->type = SYM_FUNCTION; }
|
|
||||||
| sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; }
|
| sym_args FILTER { $$ = $1; $$->type = SYM_FILTER; }
|
||||||
|
| sym_args FUNCTION { $$ = $1; $$->type = SYM_FUNCTION; }
|
||||||
| sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; }
|
| sym_args PROTOCOL { $$ = $1; $$->type = SYM_PROTO; }
|
||||||
| sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; }
|
| sym_args TEMPLATE { $$ = $1; $$->type = SYM_TEMPLATE; }
|
||||||
| sym_args CF_SYM_KNOWN { $$ = $1; $$->sym = $2; }
|
| sym_args CF_SYM_KNOWN { $$ = $1; $$->sym = $2; }
|
||||||
@ -914,6 +937,15 @@ CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging via BIRD logs]])
|
|||||||
CF_CLI(DEBUG, debug_args, (<protocol> | <channel> | \"<pattern>\" | all) (all | off | { states|routes|filters|interfaces|events|packets [, ...] }), [[Control protocol debugging via BIRD logs]])
|
CF_CLI(DEBUG, debug_args, (<protocol> | <channel> | \"<pattern>\" | all) (all | off | { states|routes|filters|interfaces|events|packets [, ...] }), [[Control protocol debugging via BIRD logs]])
|
||||||
{ /* Done in debug_args */ };
|
{ /* Done in debug_args */ };
|
||||||
|
|
||||||
|
CF_CLI_OPT(DEBUG ALL)
|
||||||
|
CF_CLI_OPT(DEBUG OFF)
|
||||||
|
CF_CLI_OPT(DEBUG STATES)
|
||||||
|
CF_CLI_OPT(DEBUG ROUTES)
|
||||||
|
CF_CLI_OPT(DEBUG FILTERS)
|
||||||
|
CF_CLI_OPT(DEBUG INTERFACES)
|
||||||
|
CF_CLI_OPT(DEBUG EVENTS)
|
||||||
|
CF_CLI_OPT(DEBUG PACKETS)
|
||||||
|
|
||||||
debug_args:
|
debug_args:
|
||||||
proto_patt debug_mask { proto_apply_cmd($1, proto_cmd_debug, 1, $2); }
|
proto_patt debug_mask { proto_apply_cmd($1, proto_cmd_debug, 1, $2); }
|
||||||
| channel_arg debug_mask { channel_cmd_debug($1, $2); }
|
| channel_arg debug_mask { channel_cmd_debug($1, $2); }
|
||||||
|
@ -189,6 +189,15 @@ CF_CLI_HELP(SHOW BFD SESSIONS, ..., [[Show information about BFD sessions]]);
|
|||||||
CF_CLI(SHOW BFD SESSIONS, bfd_show_sessions_args, [<name>] [address <ip|prefix>] [(interface|dev) \"<name>\"] [ipv4|ipv6] [direct|multihop] [all], [[Show information about BFD sessions]])
|
CF_CLI(SHOW BFD SESSIONS, bfd_show_sessions_args, [<name>] [address <ip|prefix>] [(interface|dev) \"<name>\"] [ipv4|ipv6] [direct|multihop] [all], [[Show information about BFD sessions]])
|
||||||
{ PROTO_WALK_CMD($4->name, &proto_bfd, p) bfd_show_sessions(p, $4); };
|
{ PROTO_WALK_CMD($4->name, &proto_bfd, p) bfd_show_sessions(p, $4); };
|
||||||
|
|
||||||
|
CF_CLI_OPT(SHOW BFD SESSIONS ADDRESS, <ip>|<prefix>)
|
||||||
|
CF_CLI_OPT(SHOW BFD SESSIONS INTERFACE, \"<name>\")
|
||||||
|
CF_CLI_OPT(SHOW BFD SESSIONS DEV, \"<name>\")
|
||||||
|
CF_CLI_OPT(SHOW BFD SESSIONS ALL)
|
||||||
|
CF_CLI_OPT(SHOW BFD SESSIONS IPV4)
|
||||||
|
CF_CLI_OPT(SHOW BFD SESSIONS IPV6)
|
||||||
|
CF_CLI_OPT(SHOW BFD SESSIONS DIRECT)
|
||||||
|
CF_CLI_OPT(SHOW BFD SESSIONS MULTIHOP)
|
||||||
|
|
||||||
bfd_show_sessions_args:
|
bfd_show_sessions_args:
|
||||||
/* empty */ { $$ = cfg_allocz(sizeof(struct bfd_show_sessions_cmd)); }
|
/* empty */ { $$ = cfg_allocz(sizeof(struct bfd_show_sessions_cmd)); }
|
||||||
| bfd_show_sessions_args CF_SYM_KNOWN { cf_assert_symbol($2, SYM_PROTO); $$->name = $2; }
|
| bfd_show_sessions_args CF_SYM_KNOWN { cf_assert_symbol($2, SYM_PROTO); $$->name = $2; }
|
||||||
|
@ -53,6 +53,11 @@ CF_CLI_HELP(MRT DUMP, [table <name>|\"<pattern>\"] [to \"<file>\"] [filter <filt
|
|||||||
CF_CLI(MRT DUMP, mrt_dump_args, [table <name>|\"<pattern>\"] [to \"<file>\"] [filter <filter>|where <where filter>], [[Save mrt table dump v2 of table name <t> right now]])
|
CF_CLI(MRT DUMP, mrt_dump_args, [table <name>|\"<pattern>\"] [to \"<file>\"] [filter <filter>|where <where filter>], [[Save mrt table dump v2 of table name <t> right now]])
|
||||||
{ mrt_dump_cmd($3); } ;
|
{ mrt_dump_cmd($3); } ;
|
||||||
|
|
||||||
|
CF_CLI_OPT(MRT DUMP TABLE, <name>|\"<pattern>\")
|
||||||
|
CF_CLI_OPT(MRT DUMP TO, \"<file>\")
|
||||||
|
CF_CLI_OPT(MRT DUMP FILTER, <filter>)
|
||||||
|
CF_CLI_OPT(MRT DUMP WHERE, <where filter>)
|
||||||
|
|
||||||
mrt_dump_args:
|
mrt_dump_args:
|
||||||
/* empty */ { $$ = cfg_allocz(sizeof(struct mrt_dump_data)); }
|
/* empty */ { $$ = cfg_allocz(sizeof(struct mrt_dump_data)); }
|
||||||
| mrt_dump_args TABLE rtable { $$ = $1; $$->table_ptr = $3->table; }
|
| mrt_dump_args TABLE rtable { $$ = $1; $$->table_ptr = $3->table; }
|
||||||
|
@ -546,6 +546,14 @@ CF_CLI(SHOW OSPF LSADB, lsadb_args, [global | area <id> | link] [type <num>] [ls
|
|||||||
ospf_sh_lsadb($4);
|
ospf_sh_lsadb($4);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CF_CLI_OPT(SHOW OSPF LSADB GLOBAL)
|
||||||
|
CF_CLI_OPT(SHOW OSPF LSADB AREA, <id>)
|
||||||
|
CF_CLI_OPT(SHOW OSPF LSADB LINK)
|
||||||
|
CF_CLI_OPT(SHOW OSPF LSADB TYPE, <num>)
|
||||||
|
CF_CLI_OPT(SHOW OSPF LSADB LSID, <id>)
|
||||||
|
CF_CLI_OPT(SHOW OSPF LSADB SELF)
|
||||||
|
CF_CLI_OPT(SHOW OSPF LSADB ROUTER, <id>)
|
||||||
|
|
||||||
lsadb_args:
|
lsadb_args:
|
||||||
/* empty */ {
|
/* empty */ {
|
||||||
$$ = cfg_allocz(sizeof(struct lsadb_show_data));
|
$$ = cfg_allocz(sizeof(struct lsadb_show_data));
|
||||||
|
Loading…
Reference in New Issue
Block a user