mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-16 02:30:52 +00:00
lib: Clean up completions code, fix segfault on no match
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
parent
73baf6a3a6
commit
268316d185
@ -597,46 +597,24 @@ cmd_describe_command (vector vline, struct vty *vty, int *status)
|
|||||||
char **
|
char **
|
||||||
cmd_complete_command_lib (vector vline, struct vty *vty, int *status, int islib)
|
cmd_complete_command_lib (vector vline, struct vty *vty, int *status, int islib)
|
||||||
{
|
{
|
||||||
char **ret;
|
char **ret = NULL;
|
||||||
|
int original_node = vty->node;
|
||||||
|
vector input_line = vector_init (vector_count (vline));
|
||||||
|
|
||||||
if ( cmd_try_do_shortcut(vty->node, vector_slot(vline, 0) ) )
|
// if the first token is 'do' we'll want to execute the command in the enable node
|
||||||
|
int do_shortcut = cmd_try_do_shortcut (vty->node, vector_slot (vline, 0));
|
||||||
|
vty->node = do_shortcut ? ENABLE_NODE : original_node;
|
||||||
|
|
||||||
|
// construct the input line we'll be matching on
|
||||||
|
unsigned int offset = (do_shortcut) ? 1 : 0;
|
||||||
|
for (unsigned index = 0; index + offset < vector_active (vline); index++)
|
||||||
|
vector_set_index (input_line, index + offset, vector_lookup (vline, index));
|
||||||
|
|
||||||
|
// get token completions -- this is a copying operation
|
||||||
|
vector comps = cmd_complete_command_real (input_line, vty, status);
|
||||||
|
if (!MATCHER_ERROR (*status))
|
||||||
{
|
{
|
||||||
enum node_type onode;
|
// copy completions text into an array of char*
|
||||||
vector shifted_vline;
|
|
||||||
unsigned int index;
|
|
||||||
|
|
||||||
onode = vty->node;
|
|
||||||
vty->node = ENABLE_NODE;
|
|
||||||
/* We can try it on enable node, cos' the vty is authenticated */
|
|
||||||
|
|
||||||
shifted_vline = vector_init (vector_count(vline));
|
|
||||||
/* use memcpy? */
|
|
||||||
for (index = 1; index < vector_active (vline); index++)
|
|
||||||
{
|
|
||||||
vector_set_index (shifted_vline, index-1, vector_lookup(vline, index));
|
|
||||||
}
|
|
||||||
|
|
||||||
// get token completions
|
|
||||||
vector comps = cmd_complete_command_real (shifted_vline, vty, status);
|
|
||||||
ret = XMALLOC (MTYPE_TMP, vector_active (comps) * sizeof (char *) + 1);
|
|
||||||
unsigned int i;
|
|
||||||
for (i = 0; i < vector_active (comps); i++)
|
|
||||||
{
|
|
||||||
struct cmd_token *token = vector_slot (comps, i);
|
|
||||||
ret[i] = XSTRDUP (MTYPE_TMP, token->text);
|
|
||||||
vector_unset (comps, i);
|
|
||||||
del_cmd_token (token);
|
|
||||||
}
|
|
||||||
vector_free (comps);
|
|
||||||
ret[i] = NULL;
|
|
||||||
|
|
||||||
vector_free(shifted_vline);
|
|
||||||
vty->node = onode;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get token completions
|
|
||||||
vector comps = cmd_complete_command_real (vline, vty, status);
|
|
||||||
ret = XMALLOC (MTYPE_TMP, vector_active (comps) * sizeof (char *) + 1);
|
ret = XMALLOC (MTYPE_TMP, vector_active (comps) * sizeof (char *) + 1);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 0; i < vector_active (comps); i++)
|
for (i = 0; i < vector_active (comps); i++)
|
||||||
@ -646,8 +624,20 @@ cmd_complete_command_lib (vector vline, struct vty *vty, int *status, int islib)
|
|||||||
vector_unset (comps, i);
|
vector_unset (comps, i);
|
||||||
del_cmd_token (token);
|
del_cmd_token (token);
|
||||||
}
|
}
|
||||||
|
// set the last element to NULL, which vty/vtysh uses as a sentinel value
|
||||||
ret[i] = NULL;
|
ret[i] = NULL;
|
||||||
vector_free (comps);
|
vector_free (comps);
|
||||||
|
comps = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// comps should always be null here
|
||||||
|
assert (!comps);
|
||||||
|
|
||||||
|
// free the adjusted input line
|
||||||
|
vector_free (input_line);
|
||||||
|
|
||||||
|
// reset vty->node to its original value
|
||||||
|
vty->node = original_node;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user