diff --git a/include/asterisk/cli.h b/include/asterisk/cli.h index 3ed88eb61d..51f077fa16 100644 --- a/include/asterisk/cli.h +++ b/include/asterisk/cli.h @@ -287,6 +287,9 @@ int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len); * Useful for readline, that's about it * \retval 0 on success * \retval -1 on failure + * + * Only call this function to proxy the CLI generator to + * another. */ char *ast_cli_generator(const char *, const char *, int); diff --git a/main/cli.c b/main/cli.c index eae14adc4e..1653838ead 100644 --- a/main/cli.c +++ b/main/cli.c @@ -2475,18 +2475,17 @@ static char *parse_args(const char *s, int *argc, const char *argv[], int max, i /*! \brief Return the number of unique matches for the generator */ int ast_cli_generatornummatches(const char *text, const char *word) { - int matches = 0, i = 0; - char *buf = NULL, *oldbuf = NULL; - - while ((buf = ast_cli_generator(text, word, i++))) { - if (!oldbuf || strcmp(buf,oldbuf)) - matches++; - if (oldbuf) - ast_free(oldbuf); - oldbuf = buf; - } - if (oldbuf) - ast_free(oldbuf); + int matches; + struct ast_vector_string *vec = ast_cli_completion_vector(text, word); + + if (!vec) { + return 0; + } + + matches = AST_VECTOR_SIZE(vec) - 1; + AST_VECTOR_CALLBACK_VOID(vec, ast_free); + AST_VECTOR_PTR_FREE(vec); + return matches; } diff --git a/tests/test_substitution.c b/tests/test_substitution.c index 3a1dc1fbac..8b9a164aa8 100644 --- a/tests/test_substitution.c +++ b/tests/test_substitution.c @@ -43,6 +43,7 @@ #include "asterisk/stringfields.h" #include "asterisk/threadstorage.h" #include "asterisk/test.h" +#include "asterisk/vector.h" static enum ast_test_result_state test_chan_integer(struct ast_test *test, struct ast_channel *c, int *ifield, const char *expression) @@ -225,6 +226,7 @@ AST_TEST_DEFINE(test_substitution) struct ast_channel *c; int i; enum ast_test_result_state res = AST_TEST_PASS; + struct ast_vector_string *funcs; switch (cmd) { case TEST_INIT: @@ -302,11 +304,12 @@ AST_TEST_DEFINE(test_substitution) #undef TEST /* For testing dialplan functions */ - for (i = 0; ; i++) { - char *cmd = ast_cli_generator("core show function", "", i); - if (cmd == NULL) { - break; - } + funcs = ast_cli_completion_vector("core show function", ""); + + /* Skip "best match" element 0 */ + for (i = 1; funcs && i < AST_VECTOR_SIZE(funcs); i++) { + char *cmd = AST_VECTOR_GET(funcs, i); + if (strcmp(cmd, "CHANNEL") && strcmp(cmd, "CALLERID") && strncmp(cmd, "CURL", 4) && strncmp(cmd, "AES", 3) && strncmp(cmd, "BASE64", 6) && strcmp(cmd, "CDR") && strcmp(cmd, "ENV") && strcmp(cmd, "GLOBAL") && @@ -321,10 +324,14 @@ AST_TEST_DEFINE(test_substitution) } } } - ast_free(cmd); } + if (funcs) { + AST_VECTOR_CALLBACK_VOID(funcs, ast_free); + AST_VECTOR_PTR_FREE(funcs); + } ast_hangup(c); + return res; }