summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@cumulusnetworks.com>2016-10-02 06:47:31 +0200
committerQuentin Young <qlyoung@cumulusnetworks.com>2016-10-02 06:47:31 +0200
commita78596c42d43a01de85c7ada95d15b165743f6ff (patch)
treeef4c84ce04a8219f2416d974a6cd5dd55be8ce36
parentlib: Null-terminate tab completions char*[] (diff)
downloadfrr-a78596c42d43a01de85c7ada95d15b165743f6ff.tar.xz
frr-a78596c42d43a01de85c7ada95d15b165743f6ff.zip
lib: explicitly support the case of empty input for completions
When the user tab- or ?-completes when the character prior to the position of the cursor is a space, completion logic is passed null. Explicitly handle this case instead of using partly_match, which has special logic associated with it to allow abbreviating certain tokens. Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
-rw-r--r--lib/command_match.c24
-rw-r--r--lib/command_match.h7
2 files changed, 11 insertions, 20 deletions
diff --git a/lib/command_match.c b/lib/command_match.c
index aa961d351..85d627e1b 100644
--- a/lib/command_match.c
+++ b/lib/command_match.c
@@ -303,6 +303,7 @@ command_complete (struct graph *graph,
struct cmd_token *token = gn->data;
switch (match_token (token, input_token))
{
+ case trivial_match:
case partly_match:
if (idx == vector_active (vline) - 1)
{
@@ -526,6 +527,10 @@ del_arglist (struct list *list)
static enum match_type
match_token (struct cmd_token *token, char *input_token)
{
+ // nothing trivially matches everything
+ if (!input_token)
+ return trivial_match;
+
switch (token->type) {
case WORD_TKN:
return match_word (token, input_token);
@@ -557,9 +562,6 @@ match_ipv4 (const char *str)
int dots = 0, nums = 0;
char buf[4];
- if (str == NULL)
- return partly_match;
-
for (;;)
{
memset (buf, 0, sizeof (buf));
@@ -614,9 +616,6 @@ match_ipv4_prefix (const char *str)
int dots = 0;
char buf[4];
- if (str == NULL)
- return partly_match;
-
for (;;)
{
memset (buf, 0, sizeof (buf));
@@ -696,9 +695,6 @@ match_ipv6 (const char *str)
struct sockaddr_in6 sin6_dummy;
int ret;
- if (str == NULL)
- return partly_match;
-
if (strspn (str, IPV6_ADDR_STR) != strlen (str))
return no_match;
@@ -718,9 +714,6 @@ match_ipv6_prefix (const char *str)
char *tofree, *dupe, *prefix, *mask, *endptr;
int nmask = -1;
- if (str == NULL)
- return partly_match;
-
if (strspn (str, IPV6_PREFIX_STR) != strlen (str))
return no_match;
@@ -763,9 +756,6 @@ match_range (struct cmd_token *token, const char *str)
char *endptr = NULL;
long long val;
- if (str == NULL)
- return 1;
-
val = strtoll (str, &endptr, 10);
if (*endptr != '\0')
return 0;
@@ -781,8 +771,8 @@ match_word (struct cmd_token *token, const char *word)
{
assert (token->type == WORD_TKN);
- // if the passed token is null or 0 length, partly match
- if (!word || !strlen(word))
+ // if the passed token is 0 length, partly match
+ if (!strlen(word))
return partly_match;
// if the passed token is strictly a prefix of the full word, partly match
diff --git a/lib/command_match.h b/lib/command_match.h
index 728d9c1d9..ac4e70c31 100644
--- a/lib/command_match.h
+++ b/lib/command_match.h
@@ -50,9 +50,10 @@ enum matcher_rv
/* completion match types */
enum match_type
{
- no_match,
- partly_match,
- exact_match
+ trivial_match, // the input is null
+ no_match, // the input does not match
+ partly_match, // the input matches but is incomplete
+ exact_match // the input matches and is complete
};
/* Defines which matcher_rv values constitute an error. Should be used with