diff options
author | George Joseph <gjoseph@digium.com> | 2017-11-27 12:29:10 -0600 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2017-11-27 12:29:10 -0600 |
commit | d5eb530bdf73ce94a14c3fb7be48375e70e49368 (patch) | |
tree | 7dba7ba2ce8721104f16ea13f563bf7919b4c8f1 /main | |
parent | c34223c958fbdd049917596826c64f4e5cc82e9e (diff) | |
parent | 6748f690f5d0e40044fbe440303154b133dd6619 (diff) |
Merge "CLI: Create ast_cli_completion_add function." into 15
Diffstat (limited to 'main')
-rw-r--r-- | main/cli.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/main/cli.c b/main/cli.c index 1653838ea..0f023b29f 100644 --- a/main/cli.c +++ b/main/cli.c @@ -2512,6 +2512,44 @@ char **ast_cli_completion_matches(const char *text, const char *word) return match_list; } +AST_THREADSTORAGE_RAW(completion_storage); + +/*! + * \internal + * \brief Add a value to the vector. + * + * \param vec Vector to add \a value to. Must be from threadstorage. + * \param value The value to add. + * + * \retval 0 Success + * \retval -1 Failure + */ +static int cli_completion_vector_add(struct ast_vector_string *vec, char *value) +{ + if (!value) { + return 0; + } + + if (!vec || AST_VECTOR_ADD_SORTED(vec, value, strcasecmp)) { + if (vec) { + ast_threadstorage_set_ptr(&completion_storage, NULL); + + AST_VECTOR_CALLBACK_VOID(vec, ast_free); + AST_VECTOR_FREE(vec); + } + ast_free(value); + + return -1; + } + + return 0; +} + +int ast_cli_completion_add(char *value) +{ + return cli_completion_vector_add(ast_threadstorage_get_ptr(&completion_storage), value); +} + struct ast_vector_string *ast_cli_completion_vector(const char *text, const char *word) { char *retstr, *prevstr; @@ -2519,13 +2557,23 @@ struct ast_vector_string *ast_cli_completion_vector(const char *text, const char size_t which = 0; struct ast_vector_string *vec = ast_calloc(1, sizeof(*vec)); + /* Recursion into this function is a coding error. */ + ast_assert(!ast_threadstorage_get_ptr(&completion_storage)); + if (!vec) { return NULL; } + if (ast_threadstorage_set_ptr(&completion_storage, vec)) { + ast_log(LOG_ERROR, "Failed to initialize threadstorage for completion.\n"); + ast_free(vec); + + return NULL; + } + while ((retstr = ast_cli_generator(text, word, which)) != NULL) { - if (AST_VECTOR_ADD_SORTED(vec, retstr, strcasecmp)) { - ast_free(retstr); + if (cli_completion_vector_add(vec, retstr)) { + ast_threadstorage_set_ptr(&completion_storage, NULL); goto vector_cleanup; } @@ -2533,6 +2581,8 @@ struct ast_vector_string *ast_cli_completion_vector(const char *text, const char ++which; } + ast_threadstorage_set_ptr(&completion_storage, NULL); + if (!AST_VECTOR_SIZE(vec)) { AST_VECTOR_PTR_FREE(vec); @@ -2571,6 +2621,7 @@ struct ast_vector_string *ast_cli_completion_vector(const char *text, const char retstr = ast_strndup(AST_VECTOR_GET(vec, 0), max_equal); if (!retstr || AST_VECTOR_INSERT_AT(vec, 0, retstr)) { ast_free(retstr); + goto vector_cleanup; } |