Geolocation: Base Asterisk Prereqs
* Added ast_variable_list_from_quoted_string() Parse a quoted string into an ast_variable list. * Added ast_str_substitute_variables_full2() Perform variable/function/expression substitution on an ast_str. * Added ast_strsep_quoted() Like ast_strsep except you can specify a specific quote character. Also added unit test. * Added ast_xml_find_child_element() Find a direct child element by name. * Added ast_xml_doc_dump_memory() Dump the specified document to a buffer * ast_datastore_free() now checks for a NULL datastore before attempting to destroy it. Change-Id: I5dcefed2f5f93a109e8b489e18d80d42e45244ec
This commit is contained in:
parent
740c773781
commit
5fe9887701
|
@ -1023,6 +1023,26 @@ struct ast_str *ast_variable_list_join(const struct ast_variable *head, const ch
|
|||
struct ast_variable *ast_variable_list_from_string(const char *input, const char *item_separator,
|
||||
const char *name_value_separator);
|
||||
|
||||
/*!
|
||||
* \brief Parse a string into an ast_variable list. The reverse of ast_variable_list_join
|
||||
*
|
||||
* \param input The name-value pair string to parse.
|
||||
* \param item_separator The string used to separate the list items.
|
||||
* Only the first character in the string will be used.
|
||||
* If NULL, "," will be used.
|
||||
* \param name_value_separator The string used to separate each item's name and value.
|
||||
* Only the first character in the string will be used.
|
||||
* If NULL, "=" will be used.
|
||||
* \param quote_str The string used to quote values.
|
||||
* Only the first character in the string will be used.
|
||||
* If NULL, '"' will be used.
|
||||
*
|
||||
* \retval A pointer to a list of ast_variables.
|
||||
* \retval NULL if there was an error or no variables could be parsed.
|
||||
*/
|
||||
struct ast_variable *ast_variable_list_from_quoted_string(const char *input, const char *item_separator,
|
||||
const char *name_value_separator, const char *quote_str);
|
||||
|
||||
/*!
|
||||
* \brief Update variable value within a config
|
||||
*
|
||||
|
|
|
@ -1472,6 +1472,28 @@ void ast_str_substitute_variables_varshead(struct ast_str **buf, ssize_t maxlen,
|
|||
* \param used Number of bytes read from the template. (May be NULL)
|
||||
*/
|
||||
void ast_str_substitute_variables_full(struct ast_str **buf, ssize_t maxlen, struct ast_channel *c, struct varshead *headp, const char *templ, size_t *used);
|
||||
|
||||
/*!
|
||||
* \brief Perform variable/function/expression substitution on an ast_str
|
||||
*
|
||||
* \param buf Result will be placed in this buffer.
|
||||
* \param maxlen -1 if the buffer should not grow, 0 if the buffer
|
||||
* may grow to any size, and >0 if the buffer should
|
||||
* grow only to that number of bytes.
|
||||
* \param c A channel from which to extract values, and to pass
|
||||
* to any dialplan functions.
|
||||
* \param headp A channel variables list to also search for variables.
|
||||
* \param templ Variable template to expand.
|
||||
* \param used Number of bytes read from the template. (May be NULL)
|
||||
* \param use_both Normally, if a channel is specified, headp is ignored.
|
||||
* If this parameter is set to 1 and both a channel and headp
|
||||
* are specified, the channel will be searched for variables
|
||||
* first and any not found will be searched for in headp.
|
||||
*/
|
||||
void ast_str_substitute_variables_full2(struct ast_str **buf, ssize_t maxlen,
|
||||
struct ast_channel *c, struct varshead *headp, const char *templ,
|
||||
size_t *used, int use_both);
|
||||
|
||||
/*! @} */
|
||||
|
||||
int ast_extension_patmatch(const char *pattern, const char *data);
|
||||
|
|
|
@ -308,6 +308,24 @@ enum ast_strsep_flags {
|
|||
*/
|
||||
char *ast_strsep(char **s, const char sep, uint32_t flags);
|
||||
|
||||
/*!
|
||||
* \brief Like ast_strsep() except you can specify a specific quote character
|
||||
*
|
||||
\param s Pointer to address of the string to be processed.
|
||||
Will be modified and can't be constant.
|
||||
\param sep A single character delimiter.
|
||||
\param quote The quote character
|
||||
\param flags Controls post-processing of the result.
|
||||
AST_STRSEP_TRIM trims all leading and trailing whitespace from the result.
|
||||
AST_STRSEP_STRIP does a trim then strips the outermost quotes. You may want
|
||||
to trim again after the strip. Just OR both the TRIM and STRIP flags.
|
||||
AST_STRSEP_UNESCAPE unescapes '\' sequences.
|
||||
AST_STRSEP_ALL does all of the above processing.
|
||||
\return The next token or NULL if done or if there are more than 8 levels of
|
||||
nested quotes.
|
||||
*/
|
||||
char *ast_strsep_quoted(char **s, const char sep, const char quote, uint32_t flags);
|
||||
|
||||
/*!
|
||||
\brief Strip backslash for "escaped" semicolons,
|
||||
the string to be stripped (will be modified).
|
||||
|
|
|
@ -188,6 +188,18 @@ int ast_xml_set_attribute(struct ast_xml_node *node, const char *name, const cha
|
|||
struct ast_xml_node *ast_xml_find_element(struct ast_xml_node *root_node, const char *name, const char *attrname, const char *attrvalue);
|
||||
struct ast_xml_ns *ast_xml_find_namespace(struct ast_xml_doc *doc, struct ast_xml_node *node, const char *ns_name);
|
||||
|
||||
/*!
|
||||
* \brief Find a direct child element by name.
|
||||
* \param parent_node This is the parent node to search.
|
||||
* \param name Node name to find.
|
||||
* \param attrname attribute name to match (if NULL it won't be matched).
|
||||
* \param attrvalue attribute value to match (if NULL it won't be matched).
|
||||
* \retval NULL if not found.
|
||||
* \return The node on success.
|
||||
*/
|
||||
#define ast_xml_find_child_element(_parent_node, _name, _attrname, _attrvalue) \
|
||||
ast_xml_find_element(ast_xml_node_get_children(_parent_node), _name, _attrname, _attrvalue)
|
||||
|
||||
/*!
|
||||
* \brief Get the prefix of a namespace.
|
||||
* \param ns The namespace
|
||||
|
@ -248,6 +260,17 @@ struct ast_xml_node *ast_xml_node_get_parent(struct ast_xml_node *node);
|
|||
* \brief Dump the specified document to a file. */
|
||||
int ast_xml_doc_dump_file(FILE *output, struct ast_xml_doc *doc);
|
||||
|
||||
/*!
|
||||
* \brief Dump the specified document to a buffer
|
||||
*
|
||||
* \param doc The XML doc to dump
|
||||
* \param buffer A pointer to a char * to receive the address of the results
|
||||
* \param length A pointer to an int to receive the length of the results
|
||||
*
|
||||
* \note The result buffer must be freed with ast_xml_free_text().
|
||||
*/
|
||||
void ast_xml_doc_dump_memory(struct ast_xml_doc *doc, char **buffer, int *length);
|
||||
|
||||
/*!
|
||||
* \brief Free the XPath results
|
||||
* \param results The XPath results object to dispose of
|
||||
|
|
|
@ -722,11 +722,12 @@ struct ast_str *ast_variable_list_join(const struct ast_variable *head, const ch
|
|||
return local_str;
|
||||
}
|
||||
|
||||
struct ast_variable *ast_variable_list_from_string(const char *input, const char *item_separator,
|
||||
const char *name_value_separator)
|
||||
struct ast_variable *ast_variable_list_from_quoted_string(const char *input, const char *item_separator,
|
||||
const char *name_value_separator, const char *quote_str)
|
||||
{
|
||||
char item_sep;
|
||||
char nv_sep;
|
||||
char quote;
|
||||
struct ast_variable *new_list = NULL;
|
||||
struct ast_variable *new_var = NULL;
|
||||
char *item_string;
|
||||
|
@ -740,11 +741,22 @@ struct ast_variable *ast_variable_list_from_string(const char *input, const char
|
|||
|
||||
item_sep = ast_strlen_zero(item_separator) ? ',' : item_separator[0];
|
||||
nv_sep = ast_strlen_zero(name_value_separator) ? '=' : name_value_separator[0];
|
||||
quote = ast_strlen_zero(quote_str) ? '"' : quote_str[0];
|
||||
item_string = ast_strip(ast_strdupa(input));
|
||||
|
||||
while ((item = ast_strsep(&item_string, item_sep, AST_STRSEP_ALL))) {
|
||||
item_name = ast_strsep(&item, nv_sep, AST_STRSEP_ALL);
|
||||
item_value = ast_strsep(&item, nv_sep, AST_STRSEP_ALL);
|
||||
while ((item = ast_strsep_quoted(&item_string, item_sep, quote, AST_STRSEP_ALL))) {
|
||||
item_name = ast_strsep_quoted(&item, nv_sep, quote, AST_STRSEP_ALL);
|
||||
if (!item_name) {
|
||||
ast_variables_destroy(new_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
item_value = ast_strsep_quoted(&item, nv_sep, quote, AST_STRSEP_ALL);
|
||||
if (!item_value) {
|
||||
ast_variables_destroy(new_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new_var = ast_variable_new(item_name, item_value, "");
|
||||
if (!new_var) {
|
||||
ast_variables_destroy(new_list);
|
||||
|
@ -755,6 +767,12 @@ struct ast_variable *ast_variable_list_from_string(const char *input, const char
|
|||
return new_list;
|
||||
}
|
||||
|
||||
struct ast_variable *ast_variable_list_from_string(const char *input, const char *item_separator,
|
||||
const char *name_value_separator)
|
||||
{
|
||||
return ast_variable_list_from_quoted_string(input, item_separator, name_value_separator, NULL);
|
||||
}
|
||||
|
||||
const char *ast_config_option(struct ast_config *cfg, const char *cat, const char *var)
|
||||
{
|
||||
const char *tmp;
|
||||
|
|
|
@ -69,6 +69,10 @@ int ast_datastore_free(struct ast_datastore *datastore)
|
|||
{
|
||||
int res = 0;
|
||||
|
||||
if (!datastore) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Using the destroy function (if present) destroy the data */
|
||||
if (datastore->info->destroy != NULL && datastore->data != NULL) {
|
||||
datastore->info->destroy(datastore->data);
|
||||
|
|
|
@ -394,7 +394,9 @@ const char *ast_str_retrieve_variable(struct ast_str **str, ssize_t maxlen, stru
|
|||
return ret;
|
||||
}
|
||||
|
||||
void ast_str_substitute_variables_full(struct ast_str **buf, ssize_t maxlen, struct ast_channel *c, struct varshead *headp, const char *templ, size_t *used)
|
||||
void ast_str_substitute_variables_full2(struct ast_str **buf, ssize_t maxlen,
|
||||
struct ast_channel *c, struct varshead *headp, const char *templ,
|
||||
size_t *used, int use_both)
|
||||
{
|
||||
/* Substitutes variables into buf, based on string templ */
|
||||
const char *whereweare;
|
||||
|
@ -501,7 +503,8 @@ void ast_str_substitute_variables_full(struct ast_str **buf, ssize_t maxlen, str
|
|||
|
||||
/* Store variable name expression to lookup. */
|
||||
ast_str_set_substr(&substr1, 0, vars, len);
|
||||
ast_debug(5, "Evaluating '%s' (from '%s' len %d)\n", ast_str_buffer(substr1), vars, len);
|
||||
ast_debug(5, "Evaluating '%s' (from '%s' len %d)\n",
|
||||
ast_str_buffer(substr1), vars, len);
|
||||
|
||||
/* Substitute if necessary */
|
||||
if (needsub) {
|
||||
|
@ -511,7 +514,8 @@ void ast_str_substitute_variables_full(struct ast_str **buf, ssize_t maxlen, str
|
|||
continue;
|
||||
}
|
||||
}
|
||||
ast_str_substitute_variables_full(&substr2, 0, c, headp, ast_str_buffer(substr1), NULL);
|
||||
ast_str_substitute_variables_full2(&substr2, 0, c, headp,
|
||||
ast_str_buffer(substr1), NULL, use_both);
|
||||
finalvars = ast_str_buffer(substr2);
|
||||
} else {
|
||||
finalvars = ast_str_buffer(substr1);
|
||||
|
@ -520,31 +524,48 @@ void ast_str_substitute_variables_full(struct ast_str **buf, ssize_t maxlen, str
|
|||
parse_variable_name(finalvars, &offset, &offset2, &isfunction);
|
||||
if (isfunction) {
|
||||
/* Evaluate function */
|
||||
if (c || !headp) {
|
||||
res = -1;
|
||||
if (c) {
|
||||
res = ast_func_read2(c, finalvars, &substr3, 0);
|
||||
} else {
|
||||
ast_debug(2, "Function %s result is '%s' from channel\n",
|
||||
finalvars, res ? "" : ast_str_buffer(substr3));
|
||||
}
|
||||
if (!c || (c && res < 0 && use_both)) {
|
||||
struct varshead old;
|
||||
struct ast_channel *bogus;
|
||||
|
||||
bogus = ast_dummy_channel_alloc();
|
||||
if (bogus) {
|
||||
old = *ast_channel_varshead(bogus);
|
||||
*ast_channel_varshead(bogus) = *headp;
|
||||
if (headp) {
|
||||
*ast_channel_varshead(bogus) = *headp;
|
||||
}
|
||||
res = ast_func_read2(bogus, finalvars, &substr3, 0);
|
||||
/* Don't deallocate the varshead that was passed in */
|
||||
*ast_channel_varshead(bogus) = old;
|
||||
if (headp) {
|
||||
*ast_channel_varshead(bogus) = old;
|
||||
}
|
||||
ast_channel_unref(bogus);
|
||||
} else {
|
||||
ast_log(LOG_ERROR, "Unable to allocate bogus channel for function value substitution.\n");
|
||||
res = -1;
|
||||
}
|
||||
ast_debug(2, "Function %s result is '%s' from headp\n",
|
||||
finalvars, res ? "" : ast_str_buffer(substr3));
|
||||
}
|
||||
ast_debug(2, "Function %s result is '%s'\n",
|
||||
finalvars, res ? "" : ast_str_buffer(substr3));
|
||||
} else {
|
||||
/* Retrieve variable value */
|
||||
ast_str_retrieve_variable(&substr3, 0, c, headp, finalvars);
|
||||
res = 0;
|
||||
const char *result;
|
||||
if (c) {
|
||||
result = ast_str_retrieve_variable(&substr3, 0, c, NULL, finalvars);
|
||||
ast_debug(2, "Variable %s result is '%s' from channel\n",
|
||||
finalvars, S_OR(result, ""));
|
||||
}
|
||||
if (!c || (c && !result && use_both)) {
|
||||
result = ast_str_retrieve_variable(&substr3, 0, NULL, headp, finalvars);
|
||||
ast_debug(2, "Variable %s result is '%s' from headp\n",
|
||||
finalvars, S_OR(result, ""));
|
||||
}
|
||||
res = (result ? 0 : -1);
|
||||
}
|
||||
if (!res) {
|
||||
ast_str_substring(substr3, offset, offset2);
|
||||
|
@ -596,7 +617,8 @@ void ast_str_substitute_variables_full(struct ast_str **buf, ssize_t maxlen, str
|
|||
continue;
|
||||
}
|
||||
}
|
||||
ast_str_substitute_variables_full(&substr2, 0, c, headp, ast_str_buffer(substr1), NULL);
|
||||
ast_str_substitute_variables_full2(&substr2, 0, c, headp,
|
||||
ast_str_buffer(substr1), NULL, use_both);
|
||||
finalvars = ast_str_buffer(substr2);
|
||||
} else {
|
||||
finalvars = ast_str_buffer(substr1);
|
||||
|
@ -616,6 +638,12 @@ void ast_str_substitute_variables_full(struct ast_str **buf, ssize_t maxlen, str
|
|||
ast_free(substr3);
|
||||
}
|
||||
|
||||
void ast_str_substitute_variables_full(struct ast_str **buf, ssize_t maxlen,
|
||||
struct ast_channel *chan, struct varshead *headp, const char *templ, size_t *used)
|
||||
{
|
||||
ast_str_substitute_variables_full2(buf, maxlen, chan, headp, templ, used, 0);
|
||||
}
|
||||
|
||||
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
|
||||
{
|
||||
ast_str_substitute_variables_full(buf, maxlen, chan, NULL, templ, NULL);
|
||||
|
|
61
main/utils.c
61
main/utils.c
|
@ -1859,6 +1859,67 @@ char *ast_strsep(char **iss, const char sep, uint32_t flags)
|
|||
return st;
|
||||
}
|
||||
|
||||
char *ast_strsep_quoted(char **iss, const char sep, const char quote, uint32_t flags)
|
||||
{
|
||||
char *st = *iss;
|
||||
char *is;
|
||||
int inquote = 0;
|
||||
int found = 0;
|
||||
char stack[8];
|
||||
const char qstr[] = { quote };
|
||||
|
||||
if (ast_strlen_zero(st)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(stack, 0, sizeof(stack));
|
||||
|
||||
for(is = st; *is; is++) {
|
||||
if (*is == '\\') {
|
||||
if (*++is != '\0') {
|
||||
is++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (*is == quote) {
|
||||
if (*is == stack[inquote]) {
|
||||
stack[inquote--] = '\0';
|
||||
} else {
|
||||
if (++inquote >= sizeof(stack)) {
|
||||
return NULL;
|
||||
}
|
||||
stack[inquote] = *is;
|
||||
}
|
||||
}
|
||||
|
||||
if (*is == sep && !inquote) {
|
||||
*is = '\0';
|
||||
found = 1;
|
||||
*iss = is + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
*iss = NULL;
|
||||
}
|
||||
|
||||
if (flags & AST_STRSEP_STRIP) {
|
||||
st = ast_strip_quoted(st, qstr, qstr);
|
||||
}
|
||||
|
||||
if (flags & AST_STRSEP_TRIM) {
|
||||
st = ast_strip(st);
|
||||
}
|
||||
|
||||
if (flags & AST_STRSEP_UNESCAPE) {
|
||||
ast_unescape_quoted(st);
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
char *ast_unescape_semicolon(char *s)
|
||||
{
|
||||
char *e;
|
||||
|
|
|
@ -361,6 +361,11 @@ int ast_xml_doc_dump_file(FILE *output, struct ast_xml_doc *doc)
|
|||
return xmlDocDump(output, (xmlDocPtr)doc);
|
||||
}
|
||||
|
||||
void ast_xml_doc_dump_memory(struct ast_xml_doc *doc, char **buffer, int *length)
|
||||
{
|
||||
xmlDocDumpFormatMemory((xmlDocPtr)doc, (xmlChar **)buffer, length, 1);
|
||||
}
|
||||
|
||||
const char *ast_xml_node_get_name(struct ast_xml_node *node)
|
||||
{
|
||||
return (const char *) ((xmlNode *) node)->name;
|
||||
|
|
|
@ -1952,7 +1952,7 @@ AST_TEST_DEFINE(variable_list_from_string)
|
|||
|
||||
switch (cmd) {
|
||||
case TEST_INIT:
|
||||
info->name = "variable_list_from_string";
|
||||
info->name = "variable_list_from_quoted_string";
|
||||
info->category = "/main/config/";
|
||||
info->summary = "Test parsing a string into a variable list";
|
||||
info->description = info->summary;
|
||||
|
@ -1962,7 +1962,7 @@ AST_TEST_DEFINE(variable_list_from_string)
|
|||
}
|
||||
|
||||
parse_string = "abc = 'def', ghi = 'j,kl', mno='pq=r', stu = 'vwx=\"yz\", ABC = \"DEF\"'";
|
||||
list = ast_variable_list_from_string(parse_string, ",", "=");
|
||||
list = ast_variable_list_from_quoted_string(parse_string, ",", "=", "'");
|
||||
ast_test_validate(test, list != NULL);
|
||||
str = ast_variable_list_join(list, "|", "^", "@", NULL);
|
||||
|
||||
|
|
|
@ -385,6 +385,143 @@ AST_TEST_DEFINE(strsep_test)
|
|||
return AST_TEST_PASS;
|
||||
}
|
||||
|
||||
AST_TEST_DEFINE(strsep_quoted_test)
|
||||
{
|
||||
char *test1, *test2, *test3;
|
||||
|
||||
switch (cmd) {
|
||||
case TEST_INIT:
|
||||
info->name = "strsep_quoted";
|
||||
info->category = "/main/strings/";
|
||||
info->summary = "Test ast_strsep_quoted";
|
||||
info->description = "Test ast_strsep_quoted";
|
||||
return AST_TEST_NOT_RUN;
|
||||
case TEST_EXECUTE:
|
||||
break;
|
||||
}
|
||||
|
||||
test1 = ast_strdupa("ghi=jkl,mno=\"pqr,stu\",abc=def, vwx = yz1 , vwx = yz1 , "
|
||||
"\" vwx = yz1 \" , \" vwx , yz1 \",v'w'x, \"'x,v','x'\" , \" i\\'m a test\""
|
||||
", \" i\\'m a, test\", \" i\\'m a, test\", e\\,nd, end\\");
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', 0);
|
||||
ast_test_validate(test, 0 == strcmp("ghi=jkl", test2));
|
||||
|
||||
test3 = ast_strsep_quoted(&test2, '=', '"', 0);
|
||||
ast_test_validate(test, 0 == strcmp("ghi", test3));
|
||||
|
||||
test3 = ast_strsep_quoted(&test2, '=', '"', 0);
|
||||
ast_test_validate(test, 0 == strcmp("jkl", test3));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', 0);
|
||||
ast_test_validate(test, 0 == strcmp("mno=\"pqr,stu\"", test2));
|
||||
|
||||
test3 = ast_strsep_quoted(&test2, '=', '"', 0);
|
||||
ast_test_validate(test, 0 == strcmp("mno", test3));
|
||||
|
||||
test3 = ast_strsep_quoted(&test2, '=', '"', 0);
|
||||
ast_test_validate(test, 0 == strcmp("\"pqr,stu\"", test3));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', 0);
|
||||
ast_test_validate(test, 0 == strcmp("abc=def", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', 0);
|
||||
ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_TRIM);
|
||||
ast_test_validate(test, 0 == strcmp("vwx = yz1", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_STRIP);
|
||||
ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_STRIP | AST_STRSEP_TRIM);
|
||||
ast_test_validate(test, 0 == strcmp("vwx , yz1", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_STRIP | AST_STRSEP_TRIM);
|
||||
ast_test_validate(test, 0 == strcmp("v'w'x", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_TRIM);
|
||||
ast_test_validate(test, 0 == strcmp("\"'x,v','x'\"", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_TRIM);
|
||||
ast_test_validate(test, 0 == strcmp("\" i\\'m a test\"", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_TRIM | AST_STRSEP_UNESCAPE);
|
||||
ast_test_validate(test, 0 == strcmp("\" i'm a, test\"", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_ALL);
|
||||
ast_test_validate(test, 0 == strcmp("i'm a, test", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_TRIM | AST_STRSEP_UNESCAPE);
|
||||
ast_test_validate(test, 0 == strcmp("e,nd", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_TRIM | AST_STRSEP_UNESCAPE);
|
||||
ast_test_validate(test, 0 == strcmp("end", test2));
|
||||
|
||||
// Now use '|' as the quote character
|
||||
test1 = ast_strdupa("ghi=jkl,mno=|pqr,stu|,abc=def, vwx = yz1 , vwx = yz1 , "
|
||||
"| vwx = yz1 | , | vwx , yz1 |,v'w'x, |'x,v','x'| , | i\\'m a test|"
|
||||
", | i\\'m a, test|, | i\\'m a, test|, e\\,nd, end\\");
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', 0);
|
||||
ast_test_validate(test, 0 == strcmp("ghi=jkl", test2));
|
||||
|
||||
test3 = ast_strsep_quoted(&test2, '=', '|', 0);
|
||||
ast_test_validate(test, 0 == strcmp("ghi", test3));
|
||||
|
||||
test3 = ast_strsep_quoted(&test2, '=', '|', 0);
|
||||
ast_test_validate(test, 0 == strcmp("jkl", test3));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', 0);
|
||||
ast_test_validate(test, 0 == strcmp("mno=|pqr,stu|", test2));
|
||||
|
||||
test3 = ast_strsep_quoted(&test2, '=', '|', 0);
|
||||
ast_test_validate(test, 0 == strcmp("mno", test3));
|
||||
|
||||
test3 = ast_strsep_quoted(&test2, '=', '|', 0);
|
||||
ast_test_validate(test, 0 == strcmp("|pqr,stu|", test3));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', 0);
|
||||
ast_test_validate(test, 0 == strcmp("abc=def", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', 0);
|
||||
ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_TRIM);
|
||||
ast_test_validate(test, 0 == strcmp("vwx = yz1", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_STRIP);
|
||||
ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_STRIP | AST_STRSEP_TRIM);
|
||||
ast_test_validate(test, 0 == strcmp("vwx , yz1", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_STRIP | AST_STRSEP_TRIM);
|
||||
ast_test_validate(test, 0 == strcmp("v'w'x", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_TRIM);
|
||||
ast_test_validate(test, 0 == strcmp("|'x,v','x'|", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_TRIM);
|
||||
ast_test_validate(test, 0 == strcmp("| i\\'m a test|", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_TRIM | AST_STRSEP_UNESCAPE);
|
||||
ast_test_validate(test, 0 == strcmp("| i'm a, test|", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_ALL);
|
||||
ast_test_validate(test, 0 == strcmp("i'm a, test", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_TRIM | AST_STRSEP_UNESCAPE);
|
||||
ast_test_validate(test, 0 == strcmp("e,nd", test2));
|
||||
|
||||
test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_TRIM | AST_STRSEP_UNESCAPE);
|
||||
ast_test_validate(test, 0 == strcmp("end", test2));
|
||||
|
||||
|
||||
// nothing failed; we're all good!
|
||||
return AST_TEST_PASS;
|
||||
}
|
||||
|
||||
static int test_semi(char *string1, char *string2, int test_len)
|
||||
{
|
||||
char *test2 = NULL;
|
||||
|
@ -740,6 +877,7 @@ static int unload_module(void)
|
|||
AST_TEST_UNREGISTER(begins_with_test);
|
||||
AST_TEST_UNREGISTER(ends_with_test);
|
||||
AST_TEST_UNREGISTER(strsep_test);
|
||||
AST_TEST_UNREGISTER(strsep_quoted_test);
|
||||
AST_TEST_UNREGISTER(escape_semicolons_test);
|
||||
AST_TEST_UNREGISTER(escape_test);
|
||||
AST_TEST_UNREGISTER(strings_match);
|
||||
|
@ -754,6 +892,7 @@ static int load_module(void)
|
|||
AST_TEST_REGISTER(begins_with_test);
|
||||
AST_TEST_REGISTER(ends_with_test);
|
||||
AST_TEST_REGISTER(strsep_test);
|
||||
AST_TEST_REGISTER(strsep_quoted_test);
|
||||
AST_TEST_REGISTER(escape_semicolons_test);
|
||||
AST_TEST_REGISTER(escape_test);
|
||||
AST_TEST_REGISTER(strings_match);
|
||||
|
|
Loading…
Reference in New Issue