46 const char short_string1[] =
"apple";
47 const char short_string2[] =
"banana";
48 char short_string_cat[30];
49 const char long_string1[] =
"applebananapeachmangocherrypeargrapeplumlimetangerinepomegranategravel";
50 const char long_string2[] =
"passionuglinectarinepineapplekiwilemonpaintthinner";
51 char long_string_cat[200];
52 char string_limit_cat[11];
53 const int string_limit = 5;
55 enum ast_test_result_state res = AST_TEST_PASS;
59 info->name =
"str_test";
60 info->category =
"/main/strings/";
61 info->summary =
"Test dynamic string operations";
62 info->description =
"Test setting and appending stack and heap-allocated strings";
63 return AST_TEST_NOT_RUN;
67 snprintf(short_string_cat,
sizeof(short_string_cat),
"%s%s", short_string1, short_string2);
68 snprintf(long_string_cat,
sizeof(long_string_cat),
"%s%s", long_string1, long_string2);
69 snprintf(string_limit_cat, string_limit,
"%s", long_string1);
70 strncat(string_limit_cat, long_string2, string_limit);
72 if (!(stack_str = ast_str_alloca(15))) {
73 ast_test_status_update(
test,
"Failed to allocate an ast_str on the stack\n");
78 ast_test_status_update(
test,
"Failed to allocate an ast_str on the heap\n");
92 if (
ast_str_set(&stack_str, 0,
"%s", short_string1) < 0) {
93 ast_test_status_update(
test,
"Error setting stack string\n");
98 ast_test_status_update(
test,
"ast_str_set failed for stack string. Expected '%s' but"
105 ast_test_status_update(
test,
"Error appending to stack string\n");
110 ast_test_status_update(
test,
"ast_str_set failed for stack string. Expected '%s'"
111 "but instead got %s\n", short_string_cat,
ast_str_buffer(stack_str));
118 ast_test_status_update(
test,
"ast_str_reset resulted in non-zero length for stack_str\n");
124 if (
ast_str_set(&stack_str, -1,
"%s", long_string1) < 0) {
125 ast_test_status_update(
test,
"Error setting stack string with long input\n");
130 ast_test_status_update(
test,
"Stack string not set to what is expected.\n");
136 ast_test_status_update(
test,
"Error appending long string to full stack string buffer\n");
141 ast_test_status_update(
test,
"Stack string not set to what is expected.\n");
154 if (
ast_str_set(&heap_str, 0,
"%s", short_string1) < 0) {
155 ast_test_status_update(
test,
"Error setting heap string\n");
160 ast_test_status_update(
test,
"ast_str_set failed for heap string. Expected '%s' but"
167 ast_test_status_update(
test,
"Error appending to heap string\n");
172 ast_test_status_update(
test,
"ast_str_set failed for stack string. Expected '%s'"
173 "but instead got %s\n", short_string_cat,
ast_str_buffer(stack_str));
180 ast_test_status_update(
test,
"ast_str_reset resulted in non-zero length for stack_str\n");
186 if (
ast_str_set(&heap_str, -1,
"%s", long_string1) < 0) {
187 ast_test_status_update(
test,
"Error setting heap string with long input\n");
192 ast_test_status_update(
test,
"Heap string changed size during ast_str_set when it was"
193 "instructed not to. Was %d and now is %d\n", current_size, (
int)
ast_str_size(heap_str));
198 ast_test_status_update(
test,
"Heap string not set to what is expected.\n");
205 ast_test_status_update(
test,
"Error appending long string to full heap string buffer\n");
210 ast_test_status_update(
test,
"Heap string changed size during ast_str_append when it was"
211 "instructed not to. Was %d and now is %d\n", current_size, (
int)
ast_str_size(heap_str));
216 ast_test_status_update(
test,
"Heap string not set to what is expected.\n");
223 if (
ast_str_set(&heap_str, 0,
"%s", long_string1) < 0) {
224 ast_test_status_update(
test,
"Error setting heap string with long input\n");
229 ast_test_status_update(
test,
"Heap string does not contain what was expected. Expected %s"
236 ast_test_status_update(
test,
"Error setting heap string with long input\n");
241 ast_test_status_update(
test,
"Heap string does not contain what was expected. Expected %s"
242 "but have %s instead\n", long_string_cat,
ast_str_buffer(heap_str));
256 info->name =
"begins_with";
257 info->category =
"/main/strings/";
258 info->summary =
"Test ast_begins_with";
259 info->description =
"Test ast_begins_with";
260 return AST_TEST_NOT_RUN;
278 return AST_TEST_PASS;
285 info->name =
"ends_with";
286 info->category =
"/main/strings/";
287 info->summary =
"Test ast_ends_with";
288 info->description =
"Test ast_ends_with";
289 return AST_TEST_NOT_RUN;
308 return AST_TEST_PASS;
313 char *
test1, *test2, *test3;
317 info->name =
"strsep";
318 info->category =
"/main/strings/";
319 info->summary =
"Test ast_strsep";
320 info->description =
"Test ast_strsep";
321 return AST_TEST_NOT_RUN;
326 test1 =
ast_strdupa(
"ghi=jkl,mno='pqr,stu',abc=def, vwx = yz1 , vwx = yz1 , '"
327 " vwx = yz1 ' , ' vwx , yz1 ',v\"w\"x, '\"x,v\",\"x\"' , \" i\\'m a test\""
328 ", \" i\\'m a, test\", \" i\\'m a, test\", e\\,nd, end\\");
331 ast_test_validate(
test, 0 == strcmp(
"ghi=jkl", test2));
334 ast_test_validate(
test, 0 == strcmp(
"ghi", test3));
337 ast_test_validate(
test, 0 == strcmp(
"jkl", test3));
340 ast_test_validate(
test, 0 == strcmp(
"mno='pqr,stu'", test2));
343 ast_test_validate(
test, 0 == strcmp(
"mno", test3));
346 ast_test_validate(
test, 0 == strcmp(
"'pqr,stu'", test3));
349 ast_test_validate(
test, 0 == strcmp(
"abc=def", test2));
352 ast_test_validate(
test, 0 == strcmp(
" vwx = yz1 ", test2));
355 ast_test_validate(
test, 0 == strcmp(
"vwx = yz1", test2));
358 ast_test_validate(
test, 0 == strcmp(
" vwx = yz1 ", test2));
361 ast_test_validate(
test, 0 == strcmp(
"vwx , yz1", test2));
364 ast_test_validate(
test, 0 == strcmp(
"v\"w\"x", test2));
367 ast_test_validate(
test, 0 == strcmp(
"'\"x,v\",\"x\"'", test2));
370 ast_test_validate(
test, 0 == strcmp(
"\" i\\'m a test\"", test2));
373 ast_test_validate(
test, 0 == strcmp(
"\" i'm a, test\"", test2));
376 ast_test_validate(
test, 0 == strcmp(
"i'm a, test", test2));
379 ast_test_validate(
test, 0 == strcmp(
"e,nd", test2));
382 ast_test_validate(
test, 0 == strcmp(
"end", test2));
385 return AST_TEST_PASS;
390 char *test1, *test2, *test3;
394 info->name =
"strsep_quoted";
395 info->category =
"/main/strings/";
396 info->summary =
"Test ast_strsep_quoted";
397 info->description =
"Test ast_strsep_quoted";
398 return AST_TEST_NOT_RUN;
403 test1 =
ast_strdupa(
"ghi=jkl,mno=\"pqr,stu\",abc=def, vwx = yz1 , vwx = yz1 , "
404 "\" vwx = yz1 \" , \" vwx , yz1 \",v'w'x, \"'x,v','x'\" , \" i\\'m a test\""
405 ", \" i\\'m a, test\", \" i\\'m a, test\", e\\,nd, end\\");
408 ast_test_validate(
test, 0 == strcmp(
"ghi=jkl", test2));
411 ast_test_validate(
test, 0 == strcmp(
"ghi", test3));
414 ast_test_validate(
test, 0 == strcmp(
"jkl", test3));
417 ast_test_validate(
test, 0 == strcmp(
"mno=\"pqr,stu\"", test2));
420 ast_test_validate(
test, 0 == strcmp(
"mno", test3));
423 ast_test_validate(
test, 0 == strcmp(
"\"pqr,stu\"", test3));
426 ast_test_validate(
test, 0 == strcmp(
"abc=def", test2));
429 ast_test_validate(
test, 0 == strcmp(
" vwx = yz1 ", test2));
432 ast_test_validate(
test, 0 == strcmp(
"vwx = yz1", test2));
435 ast_test_validate(
test, 0 == strcmp(
" vwx = yz1 ", test2));
438 ast_test_validate(
test, 0 == strcmp(
"vwx , yz1", test2));
441 ast_test_validate(
test, 0 == strcmp(
"v'w'x", test2));
444 ast_test_validate(
test, 0 == strcmp(
"\"'x,v','x'\"", test2));
447 ast_test_validate(
test, 0 == strcmp(
"\" i\\'m a test\"", test2));
450 ast_test_validate(
test, 0 == strcmp(
"\" i'm a, test\"", test2));
453 ast_test_validate(
test, 0 == strcmp(
"i'm a, test", test2));
456 ast_test_validate(
test, 0 == strcmp(
"e,nd", test2));
459 ast_test_validate(
test, 0 == strcmp(
"end", test2));
462 test1 =
ast_strdupa(
"ghi=jkl,mno=|pqr,stu|,abc=def, vwx = yz1 , vwx = yz1 , "
463 "| vwx = yz1 | , | vwx , yz1 |,v'w'x, |'x,v','x'| , | i\\'m a test|"
464 ", | i\\'m a, test|, | i\\'m a, test|, e\\,nd, end\\");
467 ast_test_validate(
test, 0 == strcmp(
"ghi=jkl", test2));
470 ast_test_validate(
test, 0 == strcmp(
"ghi", test3));
473 ast_test_validate(
test, 0 == strcmp(
"jkl", test3));
476 ast_test_validate(
test, 0 == strcmp(
"mno=|pqr,stu|", test2));
479 ast_test_validate(
test, 0 == strcmp(
"mno", test3));
482 ast_test_validate(
test, 0 == strcmp(
"|pqr,stu|", test3));
485 ast_test_validate(
test, 0 == strcmp(
"abc=def", test2));
488 ast_test_validate(
test, 0 == strcmp(
" vwx = yz1 ", test2));
491 ast_test_validate(
test, 0 == strcmp(
"vwx = yz1", test2));
494 ast_test_validate(
test, 0 == strcmp(
" vwx = yz1 ", test2));
497 ast_test_validate(
test, 0 == strcmp(
"vwx , yz1", test2));
500 ast_test_validate(
test, 0 == strcmp(
"v'w'x", test2));
503 ast_test_validate(
test, 0 == strcmp(
"|'x,v','x'|", test2));
506 ast_test_validate(
test, 0 == strcmp(
"| i\\'m a test|", test2));
509 ast_test_validate(
test, 0 == strcmp(
"| i'm a, test|", test2));
512 ast_test_validate(
test, 0 == strcmp(
"i'm a, test", test2));
515 ast_test_validate(
test, 0 == strcmp(
"e,nd", test2));
518 ast_test_validate(
test, 0 == strcmp(
"end", test2));
522 return AST_TEST_PASS;
525 static int test_semi(
char *string1,
char *string2,
int test_len)
532 }
else if (test_len == 0) {
536 if (test2 != NULL && strcmp(string2, test2) == 0) {
547 info->name =
"escape_semicolons";
548 info->category =
"/main/strings/";
549 info->summary =
"Test ast_escape_semicolons";
550 info->description =
"Test ast_escape_semicolons";
551 return AST_TEST_NOT_RUN;
557 ast_test_validate(
test, test_semi(
"this is a ;test",
"this is a \\;test", 18));
558 ast_test_validate(
test, test_semi(
";",
"\\;", 3));
563 ast_test_validate(
test, test_semi(
";",
"", 0));
564 ast_test_validate(
test, test_semi(
";",
"", 1));
565 ast_test_validate(
test, test_semi(
";",
"", 2));
566 ast_test_validate(
test, test_semi(
"x",
"", 0));
567 ast_test_validate(
test, test_semi(
"x",
"", 1));
570 ast_test_validate(
test, test_semi(
"xx;xx",
"x", 2));
571 ast_test_validate(
test, test_semi(
"xx;xx",
"xx", 3));
576 ast_test_validate(
test, test_semi(
"xx;xx",
"xx", 4));
578 ast_test_validate(
test, test_semi(
"xx;xx",
"xx\\;", 5));
579 ast_test_validate(
test, test_semi(
"xx;xx",
"xx\\;x", 6));
580 ast_test_validate(
test, test_semi(
"xx;xx",
"xx\\;xx", 7));
581 ast_test_validate(
test, test_semi(
"xx;xx",
"xx\\;xx", 8));
584 ast_test_validate(
test, test_semi(
"xx;xx;this is a test",
"xx\\;xx\\;this is a test", 32));
585 ast_test_validate(
test, test_semi(
";;;;;",
"\\;\\;\\;\\;\\;", 32));
586 ast_test_validate(
test, test_semi(
";;;;;",
"\\;\\;\\;\\;", 10));
587 ast_test_validate(
test, test_semi(
";;;;;",
"\\;\\;\\;\\;\\;", 11));
588 ast_test_validate(
test, test_semi(
";;\\;;;",
"\\;\\;\\\\;\\;\\;", 32));
590 return AST_TEST_PASS;
597 #define TEST_ESCAPE(s, to_escape, expected) \
598 !strcmp(ast_escape(buf, s, ARRAY_LEN(buf), to_escape), expected)
600 #define TEST_ESCAPE_C(s, expected) \
601 !strcmp(ast_escape_c(buf, s, ARRAY_LEN(buf)), expected)
603 #define TEST_ESCAPE_ALLOC(s, to_escape, expected) \
606 char *a_buf = ast_escape_alloc(s, to_escape); \
608 res = !strcmp(a_buf, expected); \
614 #define TEST_ESCAPE_C_ALLOC(s, expected) \
617 char *a_buf = ast_escape_c_alloc(s); \
619 res = !strcmp(a_buf, expected); \
627 info->name =
"escape";
628 info->category =
"/main/strings/";
629 info->summary =
"Test ast_escape";
630 info->description =
"Test escaping values in a string";
631 return AST_TEST_NOT_RUN;
636 ast_test_validate(
test, TEST_ESCAPE(
"null escape", NULL,
"null escape"));
637 ast_test_validate(
test, TEST_ESCAPE(
"empty escape",
"",
"empty escape"));
638 ast_test_validate(
test, TEST_ESCAPE(
"",
"Z",
""));
639 ast_test_validate(
test, TEST_ESCAPE(
"no matching escape",
"Z",
"no matching escape"));
640 ast_test_validate(
test, TEST_ESCAPE(
"escape Z",
"Z",
"escape \\Z"));
641 ast_test_validate(
test, TEST_ESCAPE(
"Z",
"Z",
"\\Z"));
642 ast_test_validate(
test, TEST_ESCAPE(
";;",
";",
"\\;\\;"));
643 ast_test_validate(
test, TEST_ESCAPE(
"escape \n",
"\n",
"escape \\n"));
644 ast_test_validate(
test, TEST_ESCAPE(
"escape \n again \n",
"\n",
"escape \\n again \\n"));
646 ast_test_validate(
test, TEST_ESCAPE_C(
"",
""));
647 ast_test_validate(
test, TEST_ESCAPE_C(
"escape \a\b\f\n\r\t\v\\\'\"\?",
648 "escape \\a\\b\\f\\n\\r\\t\\v\\\\\\\'\\\"\\?"));
650 ast_test_validate(
test, TEST_ESCAPE_ALLOC(
"",
"Z",
""));
651 ast_test_validate(
test, TEST_ESCAPE_ALLOC(
"Z",
"Z",
"\\Z"));
652 ast_test_validate(
test, TEST_ESCAPE_ALLOC(
"a",
"Z",
"a"));
654 ast_test_validate(
test, TEST_ESCAPE_C_ALLOC(
"",
""));
655 ast_test_validate(
test, TEST_ESCAPE_C_ALLOC(
"\n",
"\\n"));
656 ast_test_validate(
test, TEST_ESCAPE_C_ALLOC(
"a",
"a"));
658 return AST_TEST_PASS;
665 info->name =
"strings_match";
666 info->category =
"/main/strings/";
667 info->summary =
"Test ast_strings_match";
668 info->description =
"Test ast_strings_match";
669 return AST_TEST_NOT_RUN;
720 return AST_TEST_PASS;
737 info->name =
"temp_strings";
738 info->category =
"/main/strings/";
739 info->summary =
"Test ast_str_temp_buffer";
740 info->description =
"Test ast_str_temp_buffer";
741 return AST_TEST_NOT_RUN;
746 snprintf(return_buffer, 128,
"%s %s %s %s %s",
754 ast_test_validate(
test,
ast_strings_match(return_buffer,
"=",
"<str1> <str2> <B> ccccccccccccc <ww>"));
756 ast_free(return_buffer);
757 return AST_TEST_PASS;
764 info->name =
"in_delimited_string";
765 info->category =
"/main/strings/";
766 info->summary =
"Test ast_in_delimited_string";
767 info->description = info->summary;
768 return AST_TEST_NOT_RUN;
871 return AST_TEST_PASS;
874 static int unload_module(
void)
876 AST_TEST_UNREGISTER(str_test);
877 AST_TEST_UNREGISTER(begins_with_test);
878 AST_TEST_UNREGISTER(ends_with_test);
879 AST_TEST_UNREGISTER(strsep_test);
880 AST_TEST_UNREGISTER(strsep_quoted_test);
881 AST_TEST_UNREGISTER(escape_semicolons_test);
882 AST_TEST_UNREGISTER(escape_test);
883 AST_TEST_UNREGISTER(strings_match);
884 AST_TEST_UNREGISTER(temp_strings);
885 AST_TEST_UNREGISTER(in_delimited_string);
889 static int load_module(
void)
891 AST_TEST_REGISTER(str_test);
892 AST_TEST_REGISTER(begins_with_test);
893 AST_TEST_REGISTER(ends_with_test);
894 AST_TEST_REGISTER(strsep_test);
895 AST_TEST_REGISTER(strsep_quoted_test);
896 AST_TEST_REGISTER(escape_semicolons_test);
897 AST_TEST_REGISTER(escape_test);
898 AST_TEST_REGISTER(strings_match);
899 AST_TEST_REGISTER(temp_strings);
900 AST_TEST_REGISTER(in_delimited_string);
Asterisk main include file. File version handling, generic pbx functions.
String manipulation functions.
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
static int force_inline attribute_pure ast_ends_with(const char *str, const char *suffix)
Checks whether a string ends with another.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
char * ast_escape_semicolons(const char *string, char *outbuf, int buflen)
Escape semicolons found in a string.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
static void cleanup(void)
Clean up any old apps that we don't need any more.
#define ast_strdupa(s)
duplicate a string in memory from the stack
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
#define ast_malloc(len)
A wrapper for malloc()
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Support for dynamic strings.
char * ast_strsep_quoted(char **s, const char sep, const char quote, uint32_t flags)
Like ast_strsep() except you can specify a specific quote character.
static const char * str_appender(struct ast_str **buf, char *a)
Function that needs a temporary ast_str.
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
int ast_in_delimited_string(const char *needle, const char *haystack, char delim)
Check if there is an exact match for 'needle' between delimiters in 'haystack'.
#define AST_TEST_DEFINE(hdr)
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
int ast_strings_match(const char *left, const char *op, const char *right)
Compares 2 strings using realtime-style operators.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.