[Asterisk-code-review] CLI: Fix composite completion generators. (asterisk[master])
Corey Farrell
asteriskteam at digium.com
Wed Dec 13 10:25:38 CST 2017
Corey Farrell has uploaded this change for review. ( https://gerrit.asterisk.org/7558
Change subject: CLI: Fix composite completion generators.
......................................................................
CLI: Fix composite completion generators.
In cases where a parameter can be "all" or a list of channels we assume
that "all" will always match when generating the list of channels.
This issue is resolved by adding support for ast_cli_complete and
ast_complete_channels to use ast_cli_completion_add instead of returning
values. Both functions switch modes when they are given -1 instead of
a->n. Now adding "all" and adding the list of channels are two
independent operations.
ASTERISK-21038
Change-Id: Iebef61424689569338d0916ff2e37df944ac76fa
---
M channels/chan_iax2.c
M channels/chan_sip.c
M channels/chan_skinny.c
M include/asterisk/cli.h
M main/bridge.c
M main/cli.c
6 files changed, 49 insertions(+), 42 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/58/7558/1
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 69261f3..1e2ffaf 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -3636,7 +3636,6 @@
struct iax2_peer *peer = NULL;
struct iax2_user *user = NULL;
static const char * const choices[] = { "all", NULL };
- char *cmplt;
switch (cmd) {
case CLI_INIT:
@@ -3647,10 +3646,8 @@
return NULL;
case CLI_GENERATE:
if (a->pos == 3) {
- cmplt = ast_cli_complete(a->word, choices, a->n);
- if (!cmplt)
- cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
- return cmplt;
+ ast_cli_complete(a->word, choices, -1);
+ return complete_iax2_peers(a->line, a->word, a->pos, a->n, IAX_RTCACHEFRIENDS);
}
return NULL;
}
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index f5cf8ca..fa2599c 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -20610,7 +20610,6 @@
int havepattern = 0;
struct ao2_iterator i;
static const char * const choices[] = { "all", "like", NULL };
- char *cmplt;
if (cmd == CLI_INIT) {
e->command = "sip prune realtime [peer|all]";
@@ -20621,10 +20620,9 @@
return NULL;
} else if (cmd == CLI_GENERATE) {
if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) {
- cmplt = ast_cli_complete(a->word, choices, a->n);
- if (!cmplt)
- cmplt = complete_sip_peer(a->word, a->n - sizeof(choices), SIP_PAGE2_RTCACHEFRIENDS);
- return cmplt;
+ ast_cli_complete(a->word, choices, -1);
+
+ return complete_sip_peer(a->word, a->n, SIP_PAGE2_RTCACHEFRIENDS);
}
if (a->pos == 5 && !strcasecmp(a->argv[4], "like"))
return complete_sip_peer(a->word, a->n, SIP_PAGE2_RTCACHEFRIENDS);
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index 6f4231a..3b27f5e 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -3923,11 +3923,8 @@
{
if (pos == 2) {
static const char * const completions[] = { "all", NULL };
- char *ret = ast_cli_complete(word, completions, state);
- if (!ret) {
- ret = complete_skinny_devices(word, state - 1);
- }
- return ret;
+ ast_cli_complete(word, completions, -1);
+ return complete_skinny_devices(word, state);
} else if (pos == 3) {
static const char * const completions[] = { "restart", NULL };
return ast_cli_complete(word, completions, state);
diff --git a/include/asterisk/cli.h b/include/asterisk/cli.h
index 30c5dc7..eb1749a 100644
--- a/include/asterisk/cli.h
+++ b/include/asterisk/cli.h
@@ -201,6 +201,10 @@
* Helper function to generate cli entries from a NULL-terminated array.
* Returns the n-th matching entry from the array, or NULL if not found.
* Can be used to implement generate() for static entries as below
+ *
+ * If 'pos' is less than 0 this function will always return NULL after all
+ * matching channels are added with ast_cli_completion_add.
+ *
* (in this example we complete the word in position 2):
\code
char *my_generate(const char *line, const char *word, int pos, int n)
@@ -357,6 +361,9 @@
* complete from the list of active channels. 'rpos' is the required
* position in the command. This function will return NULL immediately if
* 'rpos' is not the same as the current position, 'pos'.
+ *
+ * If 'state' is less than 0 this function will always return NULL after all
+ * matching channels are added with ast_cli_completion_add.
*/
char *ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos);
diff --git a/main/bridge.c b/main/bridge.c
index 5d9c0c1..fbb6465 100644
--- a/main/bridge.c
+++ b/main/bridge.c
@@ -5243,7 +5243,6 @@
static char *handle_bridge_kick_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
static const char * const completions[] = { "all", NULL };
- char *complete;
struct ast_bridge *bridge;
switch (cmd) {
@@ -5260,11 +5259,9 @@
return complete_bridge_live(a->word, a->n);
}
if (a->pos == 3) {
- complete = ast_cli_complete(a->word, completions, a->n);
- if (!complete) {
- complete = complete_bridge_participant(a->argv[2], a->line, a->word, a->pos, a->n - 1);
- }
- return complete;
+ ast_cli_complete(a->word, completions, -1);
+
+ return complete_bridge_participant(a->argv[2], a->line, a->word, a->pos, a->n);
}
return NULL;
}
diff --git a/main/cli.c b/main/cli.c
index 75846b8..d3792a3 100644
--- a/main/cli.c
+++ b/main/cli.c
@@ -913,9 +913,12 @@
return NULL;
case CLI_GENERATE:
- if (a->pos != e->args)
+ if (a->pos != e->args) {
return NULL;
- return ast_cli_complete(a->word, completions, a->n);
+ }
+ ast_cli_complete(a->word, completions, -1);
+
+ return NULL;
}
/* regular handler */
@@ -1088,7 +1091,6 @@
{
struct ast_channel *c = NULL;
static const char * const completions[] = { "all", NULL };
- char *complete;
switch (cmd) {
case CLI_INIT:
@@ -1104,11 +1106,10 @@
if (a->pos != e->args) {
return NULL;
}
- complete = ast_cli_complete(a->word, completions, a->n);
- if (!complete) {
- complete = ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args);
- }
- return complete;
+ ast_cli_complete(a->word, completions, -1);
+ ast_complete_channels(a->line, a->word, a->pos, -1, e->args);
+
+ return NULL;
}
if (a->argc != 4) {
@@ -1383,14 +1384,13 @@
return NULL;
case CLI_GENERATE:
if (a->pos == 4) {
- char *complete = ast_cli_complete(a->word, completions_all, a->n);
- if (!complete) {
- complete = ast_complete_channels(a->line, a->word, a->pos, a->n - 1, e->args);
- }
- return complete;
+ ast_cli_complete(a->word, completions_all, -1);
+ ast_complete_channels(a->line, a->word, a->pos, -1, e->args);
} else if (a->pos == 5) {
- return ast_cli_complete(a->word, completions_off, a->n);
+ ast_cli_complete(a->word, completions_off, -1);
}
+
+ return NULL;
}
if (cmd == (CLI_HANDLER + 1000)) {
@@ -1482,7 +1482,9 @@
" Shows lots of information about the specified channel.\n";
return NULL;
case CLI_GENERATE:
- return ast_complete_channels(a->line, a->word, a->pos, a->n, 3);
+ ast_complete_channels(a->line, a->word, a->pos, a->n, -1);
+
+ return NULL;
}
if (a->argc != 4) {
@@ -1650,8 +1652,13 @@
len = ast_strlen_zero(word) ? 0 : strlen(word);
for (i = 0; choices[i]; i++) {
- if ((!len || !strncasecmp(word, choices[i], len)) && ++which > state)
- return ast_strdup(choices[i]);
+ if ((!len || !strncasecmp(word, choices[i], len))) {
+ if (state < 0) {
+ ast_cli_completion_add(ast_strdup(choices[i]));
+ } else if (++which > state) {
+ return ast_strdup(choices[i]);
+ }
+ }
}
return NULL;
}
@@ -1676,10 +1683,14 @@
for (; (msg = ao2_iterator_next(&iter)); ao2_ref(msg, -1)) {
struct ast_channel_snapshot *snapshot = stasis_message_data(msg);
- if (!strncasecmp(word, snapshot->name, wordlen) && (++which > state)) {
- ret = ast_strdup(snapshot->name);
- ao2_ref(msg, -1);
- break;
+ if (!strncasecmp(word, snapshot->name, wordlen)) {
+ if (state < 0) {
+ ast_cli_completion_add(ast_strdup(snapshot->name));
+ } else if (++which > state) {
+ ret = ast_strdup(snapshot->name);
+ ao2_ref(msg, -1);
+ break;
+ }
}
}
ao2_iterator_destroy(&iter);
--
To view, visit https://gerrit.asterisk.org/7558
To unsubscribe, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iebef61424689569338d0916ff2e37df944ac76fa
Gerrit-Change-Number: 7558
Gerrit-PatchSet: 1
Gerrit-Owner: Corey Farrell <git at cfware.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20171213/0abefbfd/attachment.html>
More information about the asterisk-code-review
mailing list