From: Corey Farrell Date: Mon, 20 Nov 2017 02:10:09 +0000 (-0500) Subject: vector: Additional string vector definitions. X-Git-Tag: 16.0.0-rc1~420 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=35ae99c712d2b0de2f780269fbabf8ceaf8c11ec;p=thirdparty%2Fasterisk.git vector: Additional string vector definitions. ast_vector_string_split: This function will add items to an ast_vector_string by splitting values of a string buffer. Items are appended to the vector in the order they are found. ast_vector_const_string: A vector of 'const char *'. Change-Id: I1bf02a1efeb2baeea11c59c557d39dd1197494d7 --- diff --git a/include/asterisk/vector.h b/include/asterisk/vector.h index 8bd1cefef7..d1b2973bfd 100644 --- a/include/asterisk/vector.h +++ b/include/asterisk/vector.h @@ -51,8 +51,38 @@ /*! \brief Integer vector definition */ AST_VECTOR(ast_vector_int, int); -/*! \brief String vector definition */ +/*! \brief String vector definitions */ AST_VECTOR(ast_vector_string, char *); +AST_VECTOR(ast_vector_const_string, const char *); + +/*! Options to override default processing of ast_vector_string_split. */ +enum ast_vector_string_split_flags { + /*! Do not trim whitespace from values. */ + AST_VECTOR_STRING_SPLIT_NO_TRIM = 0x01, + /*! Append empty strings to the vector. */ + AST_VECTOR_STRING_SPLIT_ALLOW_EMPTY = 0x02, +}; + +/*! + * \brief Append a string vector by splitting a string. + * + * \param dest Pointer to an initialized vector. + * \param input String buffer to split. + * \param delim String delimeter passed to strsep. + * \param flags Processing options defined by \ref enum ast_vector_string_split_flags. + * \param excludes_cmp NULL or a function like strcmp to exclude duplicate strings. + * + * \retval 0 Success + * \retval -1 Failure + * + * \note All elements added to the vector are allocated. The caller is always + * responsible for calling ast_free on each element in the vector even + * after failure. It's possible for this function to successfully add + * some elements before failing. + */ +int ast_vector_string_split(struct ast_vector_string *dest, + const char *input, const char *delim, int flags, + int (*excludes_cmp)(const char *s1, const char *s2)); /*! * \brief Define a vector structure with a read/write lock diff --git a/main/strings.c b/main/strings.c index 82e315aeac..ad96df2498 100644 --- a/main/strings.c +++ b/main/strings.c @@ -40,6 +40,7 @@ #include #include "asterisk/strings.h" #include "asterisk/pbx.h" +#include "asterisk/vector.h" /*! * core handler for dynamic strings. @@ -389,3 +390,44 @@ char *ast_read_line_from_buffer(char **buffer) return start; } + +int ast_vector_string_split(struct ast_vector_string *dest, + const char *input, const char *delim, int flags, + int (*excludes_cmp)(const char *s1, const char *s2)) +{ + char *buf; + char *cur; + int no_trim = flags & AST_VECTOR_STRING_SPLIT_NO_TRIM; + int allow_empty = flags & AST_VECTOR_STRING_SPLIT_ALLOW_EMPTY; + + ast_assert(dest != NULL); + ast_assert(!ast_strlen_zero(delim)); + + if (ast_strlen_zero(input)) { + return 0; + } + + buf = ast_strdupa(input); + while ((cur = strsep(&buf, delim))) { + if (!no_trim) { + cur = ast_strip(cur); + } + + if (!allow_empty && ast_strlen_zero(cur)) { + continue; + } + + if (excludes_cmp && AST_VECTOR_GET_CMP(dest, cur, !excludes_cmp)) { + continue; + } + + cur = ast_strdup(cur); + if (!cur || AST_VECTOR_APPEND(dest, cur)) { + ast_free(cur); + + return -1; + } + } + + return 0; +}