*/
char *ast_strip_quoted(char *s, const char *beg_quotes, const char *end_quotes);
+/*!
+ \brief Flags for ast_strsep
+ */
+enum ast_strsep_flags {
+ AST_STRSEP_STRIP = 0x01, /*!< Trim, then strip quotes. You may want to trim again */
+ AST_STRSEP_TRIM = 0x02, /*!< Trim leading and trailing whitespace */
+ AST_STRSEP_UNESCAPE = 0x04, /*!< Unescape '\' */
+ AST_STRSEP_ALL = 0x07, /*!< Trim, strip, unescape */
+};
+
+/*!
+ \brief Act like strsep but ignore separators inside quotes.
+ \param s Pointer to address of the the string to be processed.
+ Will be modified and can't be constant.
+ \param sep A single character delimiter.
+ \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.
+
+ This function acts like strsep with three exceptions...
+ The separator is a single character instead of a string.
+ Separators inside quotes are treated literally instead of like separators.
+ You can elect to have leading and trailing whitespace and quotes
+ stripped from the result and have '\' sequences unescaped.
+
+ Like strsep, ast_strsep maintains no internal state and you can call it
+ recursively using different separators on the same storage.
+
+ Also like strsep, for consistent results, consecutive separators are not
+ collapsed so you may get an empty string as a valid result.
+
+ Examples:
+ \code
+ char *mystr = ast_strdupa("abc=def,ghi='zzz=yyy,456',jkl");
+ char *token, *token2, *token3;
+
+ while((token = ast_strsep(&mystr, ',', AST_SEP_STRIP))) {
+ // 1st token will be aaa=def
+ // 2nd token will be ghi='zzz=yyy,456'
+ while((token2 = ast_strsep(&token, '=', AST_SEP_STRIP))) {
+ // 1st token2 will be ghi
+ // 2nd token2 will be zzz=yyy,456
+ while((token3 = ast_strsep(&token2, ',', AST_SEP_STRIP))) {
+ // 1st token3 will be zzz=yyy
+ // 2nd token3 will be 456
+ // and so on
+ }
+ }
+ // 3rd token will be jkl
+ }
+
+ \endcode
+ */
+char *ast_strsep(char **s, const char sep, uint32_t flags);
+
/*!
\brief Strip backslash for "escaped" semicolons,
the string to be stripped (will be modified).
return AST_TEST_PASS;
}
+AST_TEST_DEFINE(strsep_test)
+{
+ char *test1, *test2, *test3;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "strsep";
+ info->category = "/main/strings/";
+ info->summary = "Test ast_strsep";
+ info->description = "Test ast_strsep";
+ 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(&test1, ',', 0);
+ ast_test_validate(test, 0 == strcmp("ghi=jkl", test2));
+
+ test3 = ast_strsep(&test2, '=', 0);
+ ast_test_validate(test, 0 == strcmp("ghi", test3));
+
+ test3 = ast_strsep(&test2, '=', 0);
+ ast_test_validate(test, 0 == strcmp("jkl", test3));
+
+ test2 = ast_strsep(&test1, ',', 0);
+ ast_test_validate(test, 0 == strcmp("mno='pqr,stu'", test2));
+
+ test3 = ast_strsep(&test2, '=', 0);
+ ast_test_validate(test, 0 == strcmp("mno", test3));
+
+ test3 = ast_strsep(&test2, '=', 0);
+ ast_test_validate(test, 0 == strcmp("'pqr,stu'", test3));
+
+ test2 = ast_strsep(&test1, ',', 0);
+ ast_test_validate(test, 0 == strcmp("abc=def", test2));
+
+ test2 = ast_strsep(&test1, ',', 0);
+ ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
+
+ test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM);
+ ast_test_validate(test, 0 == strcmp("vwx = yz1", test2));
+
+ test2 = ast_strsep(&test1, ',', AST_STRSEP_STRIP);
+ ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
+
+ test2 = ast_strsep(&test1, ',', AST_STRSEP_STRIP | AST_STRSEP_TRIM);
+ ast_test_validate(test, 0 == strcmp("vwx , yz1", test2));
+
+ test2 = ast_strsep(&test1, ',', AST_STRSEP_STRIP | AST_STRSEP_TRIM);
+ ast_test_validate(test, 0 == strcmp("v\"w\"x", test2));
+
+ test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM);
+ ast_test_validate(test, 0 == strcmp("'\"x,v\",\"x\"'", test2));
+
+ test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM);
+ ast_test_validate(test, 0 == strcmp("\" i\\'m a test\"", test2));
+
+ test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM | AST_STRSEP_UNESCAPE);
+ ast_test_validate(test, 0 == strcmp("\" i'm a, test\"", test2));
+
+ test2 = ast_strsep(&test1, ',', AST_STRSEP_ALL);
+ ast_test_validate(test, 0 == strcmp("i'm a, test", test2));
+
+ test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM | AST_STRSEP_UNESCAPE);
+ ast_test_validate(test, 0 == strcmp("e,nd", test2));
+
+ test2 = ast_strsep(&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 unload_module(void)
{
AST_TEST_UNREGISTER(str_test);
AST_TEST_UNREGISTER(begins_with_test);
AST_TEST_UNREGISTER(ends_with_test);
+ AST_TEST_UNREGISTER(strsep_test);
return 0;
}
AST_TEST_REGISTER(str_test);
AST_TEST_REGISTER(begins_with_test);
AST_TEST_REGISTER(ends_with_test);
+ AST_TEST_REGISTER(strsep_test);
return AST_MODULE_LOAD_SUCCESS;
}