Asterisk - The Open Source Telephony Project GIT-master-a358458
test_strings.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2010, Digium, Inc.
5 *
6 * Mark Michelson <mmichelson@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*!
20 * \file
21 * \brief Dynamic string tests
22 *
23 * \author Mark Michelson <mmichelson@digium.com>
24 *
25 * This module will run some dynamic string tests.
26 *
27 * \ingroup tests
28 */
29
30/*** MODULEINFO
31 <depend>TEST_FRAMEWORK</depend>
32 <support_level>core</support_level>
33 ***/
34
35#include "asterisk.h"
36
37#include "asterisk/test.h"
38#include "asterisk/utils.h"
39#include "asterisk/strings.h"
40#include "asterisk/module.h"
41
43{
44 struct ast_str *stack_str;
45 struct ast_str *heap_str;
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;
54 int current_size;
56
57 switch (cmd) {
58 case TEST_INIT:
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;
64 case TEST_EXECUTE:
65 break;
66 }
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);
71
72 if (!(stack_str = ast_str_alloca(15))) {
73 ast_test_status_update(test, "Failed to allocate an ast_str on the stack\n");
74 return AST_TEST_FAIL;
75 }
76
77 if (!(heap_str = ast_str_create(15))) {
78 ast_test_status_update(test, "Failed to allocate an ast_str on the heap\n");
79 }
80
81 /* Stack string tests:
82 * Part 1: Basic tests
83 * a. set a small string
84 * b. append a small string
85 * c. clear a string
86 * Part 2: Advanced tests
87 * a. Set a string that is larger than our allocation
88 * b. Append a string that is larger than our allocation
89 */
90
91 /* Part 1a */
92 if (ast_str_set(&stack_str, 0, "%s", short_string1) < 0) {
93 ast_test_status_update(test, "Error setting stack string\n");
94 res = AST_TEST_FAIL;
95 goto cleanup;
96 }
97 if (strcmp(ast_str_buffer(stack_str), short_string1)) {
98 ast_test_status_update(test, "ast_str_set failed for stack string. Expected '%s' but"
99 "instead got %s\n", short_string1, ast_str_buffer(stack_str));
100 res = AST_TEST_FAIL;
101 goto cleanup;
102 }
103 /* Part 1b */
104 if (ast_str_append(&stack_str, 0, "%s", short_string2) < 0) {
105 ast_test_status_update(test, "Error appending to stack string\n");
106 res = AST_TEST_FAIL;
107 goto cleanup;
108 }
109 if (strcmp(ast_str_buffer(stack_str), short_string_cat)) {
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));
112 res = AST_TEST_FAIL;
113 goto cleanup;
114 }
115 /* Part 1c */
116 ast_str_reset(stack_str);
117 if (ast_str_strlen(stack_str) != 0) {
118 ast_test_status_update(test, "ast_str_reset resulted in non-zero length for stack_str\n");
119 res = AST_TEST_FAIL;
120 goto cleanup;
121 }
122
123 /* Part 2a */
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");
126 res = AST_TEST_FAIL;
127 goto cleanup;
128 }
129 if (strncmp(ast_str_buffer(stack_str), long_string1, ast_str_strlen(stack_str))) {
130 ast_test_status_update(test, "Stack string not set to what is expected.\n");
131 res = AST_TEST_FAIL;
132 goto cleanup;
133 }
134 /* Part 2b */
135 if (ast_str_append(&stack_str, -1, "%s", long_string2) < 0) {
136 ast_test_status_update(test, "Error appending long string to full stack string buffer\n");
137 res = AST_TEST_FAIL;
138 goto cleanup;
139 }
140 if (strncmp(ast_str_buffer(stack_str), long_string_cat, ast_str_strlen(stack_str))) {
141 ast_test_status_update(test, "Stack string not set to what is expected.\n");
142 res = AST_TEST_FAIL;
143 goto cleanup;
144 }
145
146 /* Heap string tests
147 *
148 * All stack string tests from part 1.
149 * All stack string tests 2a and 2b.
150 * Tests 2a and 2b from stack string tests, passing 0 as max_len
151 * instead of -1. This allows for the buffer to grow.
152 */
153 /* Part 1a */
154 if (ast_str_set(&heap_str, 0, "%s", short_string1) < 0) {
155 ast_test_status_update(test, "Error setting heap string\n");
156 res = AST_TEST_FAIL;
157 goto cleanup;
158 }
159 if (strcmp(ast_str_buffer(heap_str), short_string1)) {
160 ast_test_status_update(test, "ast_str_set failed for heap string. Expected '%s' but"
161 "instead got %s\n", short_string1, ast_str_buffer(heap_str));
162 res = AST_TEST_FAIL;
163 goto cleanup;
164 }
165 /* Part 1b */
166 if (ast_str_append(&heap_str, 0, "%s", short_string2) < 0) {
167 ast_test_status_update(test, "Error appending to heap string\n");
168 res = AST_TEST_FAIL;
169 goto cleanup;
170 }
171 if (strcmp(ast_str_buffer(heap_str), short_string_cat)) {
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));
174 res = AST_TEST_FAIL;
175 goto cleanup;
176 }
177 /* Part 1c */
178 ast_str_reset(heap_str);
179 if (ast_str_strlen(heap_str) != 0) {
180 ast_test_status_update(test, "ast_str_reset resulted in non-zero length for stack_str\n");
181 res = AST_TEST_FAIL;
182 goto cleanup;
183 }
184 /* Part 2a with -1 arg */
185 current_size = ast_str_size(heap_str);
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");
188 res = AST_TEST_FAIL;
189 goto cleanup;
190 }
191 if (current_size != ast_str_size(heap_str)) {
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));
194 res = AST_TEST_FAIL;
195 goto cleanup;
196 }
197 if (strncmp(ast_str_buffer(heap_str), long_string1, ast_str_strlen(heap_str))) {
198 ast_test_status_update(test, "Heap string not set to what is expected.\n");
199 res = AST_TEST_FAIL;
200 goto cleanup;
201 }
202 /* Part 2b with -1 arg */
203 current_size = ast_str_size(heap_str);
204 if (ast_str_append(&heap_str, -1, "%s", long_string2) < 0) {
205 ast_test_status_update(test, "Error appending long string to full heap string buffer\n");
206 res = AST_TEST_FAIL;
207 goto cleanup;
208 }
209 if (current_size != ast_str_size(heap_str)) {
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));
212 res = AST_TEST_FAIL;
213 goto cleanup;
214 }
215 if (strncmp(ast_str_buffer(heap_str), long_string_cat, ast_str_strlen(heap_str))) {
216 ast_test_status_update(test, "Heap string not set to what is expected.\n");
217 res = AST_TEST_FAIL;
218 goto cleanup;
219 }
220 /* reset string before continuing */
221 ast_str_reset(heap_str);
222 /* Part 2a with 0 arg */
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");
225 res = AST_TEST_FAIL;
226 goto cleanup;
227 }
228 if (strcmp(ast_str_buffer(heap_str), long_string1)) {
229 ast_test_status_update(test, "Heap string does not contain what was expected. Expected %s"
230 "but have %s instead\n", long_string1, ast_str_buffer(heap_str));
231 res = AST_TEST_FAIL;
232 goto cleanup;
233 }
234 /* Part 2b with 0 arg */
235 if (ast_str_append(&heap_str, 0, "%s", long_string2) < 0) {
236 ast_test_status_update(test, "Error setting heap string with long input\n");
237 res = AST_TEST_FAIL;
238 goto cleanup;
239 }
240 if (strcmp(ast_str_buffer(heap_str), long_string_cat)) {
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));
243 res = AST_TEST_FAIL;
244 goto cleanup;
245 }
246
247cleanup:
248 ast_free(heap_str);
249 return res;
250}
251
252AST_TEST_DEFINE(begins_with_test)
253{
254 switch (cmd) {
255 case TEST_INIT:
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;
261 case TEST_EXECUTE:
262 break;
263 }
264
265 // prefixes
266 ast_test_validate(test, 1 == ast_begins_with("foobar", "foobar"));
267 ast_test_validate(test, 1 == ast_begins_with("foobar", "foo"));
268 ast_test_validate(test, 1 == ast_begins_with("foobar", ""));
269 ast_test_validate(test, 1 == ast_begins_with("", ""));
270
271 // not prefixes
272 ast_test_validate(test, 0 == ast_begins_with("foobar", "bang"));
273 ast_test_validate(test, 0 == ast_begins_with("foobar", "foobat"));
274 ast_test_validate(test, 0 == ast_begins_with("boo", "boom"));
275 ast_test_validate(test, 0 == ast_begins_with("", "blitz"));
276
277 // nothing failed; we're all good!
278 return AST_TEST_PASS;
279}
280
281AST_TEST_DEFINE(ends_with_test)
282{
283 switch (cmd) {
284 case TEST_INIT:
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;
290 case TEST_EXECUTE:
291 break;
292 }
293
294 // prefixes
295 ast_test_validate(test, 1 == ast_ends_with("foobar", "foobar"));
296 ast_test_validate(test, 1 == ast_ends_with("foobar", "bar"));
297 ast_test_validate(test, 1 == ast_ends_with("foobar", ""));
298 ast_test_validate(test, 1 == ast_ends_with("", ""));
299
300 // not suffixes
301 ast_test_validate(test, 0 == ast_ends_with("bar", "bbar"));
302 ast_test_validate(test, 0 == ast_ends_with("foobar", "bang"));
303 ast_test_validate(test, 0 == ast_ends_with("foobar", "foobat"));
304 ast_test_validate(test, 0 == ast_ends_with("boo", "boom"));
305 ast_test_validate(test, 0 == ast_ends_with("", "blitz"));
306
307 // nothing failed; we're all good!
308 return AST_TEST_PASS;
309}
310
311AST_TEST_DEFINE(strsep_test)
312{
313 char *test1, *test2, *test3;
314
315 switch (cmd) {
316 case TEST_INIT:
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;
322 case TEST_EXECUTE:
323 break;
324 }
325
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\\");
329
330 test2 = ast_strsep(&test1, ',', 0);
331 ast_test_validate(test, 0 == strcmp("ghi=jkl", test2));
332
333 test3 = ast_strsep(&test2, '=', 0);
334 ast_test_validate(test, 0 == strcmp("ghi", test3));
335
336 test3 = ast_strsep(&test2, '=', 0);
337 ast_test_validate(test, 0 == strcmp("jkl", test3));
338
339 test2 = ast_strsep(&test1, ',', 0);
340 ast_test_validate(test, 0 == strcmp("mno='pqr,stu'", test2));
341
342 test3 = ast_strsep(&test2, '=', 0);
343 ast_test_validate(test, 0 == strcmp("mno", test3));
344
345 test3 = ast_strsep(&test2, '=', 0);
346 ast_test_validate(test, 0 == strcmp("'pqr,stu'", test3));
347
348 test2 = ast_strsep(&test1, ',', 0);
349 ast_test_validate(test, 0 == strcmp("abc=def", test2));
350
351 test2 = ast_strsep(&test1, ',', 0);
352 ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
353
354 test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM);
355 ast_test_validate(test, 0 == strcmp("vwx = yz1", test2));
356
357 test2 = ast_strsep(&test1, ',', AST_STRSEP_STRIP);
358 ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
359
361 ast_test_validate(test, 0 == strcmp("vwx , yz1", test2));
362
364 ast_test_validate(test, 0 == strcmp("v\"w\"x", test2));
365
366 test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM);
367 ast_test_validate(test, 0 == strcmp("'\"x,v\",\"x\"'", test2));
368
369 test2 = ast_strsep(&test1, ',', AST_STRSEP_TRIM);
370 ast_test_validate(test, 0 == strcmp("\" i\\'m a test\"", test2));
371
373 ast_test_validate(test, 0 == strcmp("\" i'm a, test\"", test2));
374
375 test2 = ast_strsep(&test1, ',', AST_STRSEP_ALL);
376 ast_test_validate(test, 0 == strcmp("i'm a, test", test2));
377
379 ast_test_validate(test, 0 == strcmp("e,nd", test2));
380
382 ast_test_validate(test, 0 == strcmp("end", test2));
383
384 // nothing failed; we're all good!
385 return AST_TEST_PASS;
386}
387
388AST_TEST_DEFINE(strsep_quoted_test)
389{
390 char *test1, *test2, *test3;
391
392 switch (cmd) {
393 case TEST_INIT:
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;
399 case TEST_EXECUTE:
400 break;
401 }
402
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\\");
406
407 test2 = ast_strsep_quoted(&test1, ',', '"', 0);
408 ast_test_validate(test, 0 == strcmp("ghi=jkl", test2));
409
410 test3 = ast_strsep_quoted(&test2, '=', '"', 0);
411 ast_test_validate(test, 0 == strcmp("ghi", test3));
412
413 test3 = ast_strsep_quoted(&test2, '=', '"', 0);
414 ast_test_validate(test, 0 == strcmp("jkl", test3));
415
416 test2 = ast_strsep_quoted(&test1, ',', '"', 0);
417 ast_test_validate(test, 0 == strcmp("mno=\"pqr,stu\"", test2));
418
419 test3 = ast_strsep_quoted(&test2, '=', '"', 0);
420 ast_test_validate(test, 0 == strcmp("mno", test3));
421
422 test3 = ast_strsep_quoted(&test2, '=', '"', 0);
423 ast_test_validate(test, 0 == strcmp("\"pqr,stu\"", test3));
424
425 test2 = ast_strsep_quoted(&test1, ',', '"', 0);
426 ast_test_validate(test, 0 == strcmp("abc=def", test2));
427
428 test2 = ast_strsep_quoted(&test1, ',', '"', 0);
429 ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
430
431 test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_TRIM);
432 ast_test_validate(test, 0 == strcmp("vwx = yz1", test2));
433
434 test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_STRIP);
435 ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
436
438 ast_test_validate(test, 0 == strcmp("vwx , yz1", test2));
439
441 ast_test_validate(test, 0 == strcmp("v'w'x", test2));
442
443 test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_TRIM);
444 ast_test_validate(test, 0 == strcmp("\"'x,v','x'\"", test2));
445
446 test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_TRIM);
447 ast_test_validate(test, 0 == strcmp("\" i\\'m a test\"", test2));
448
450 ast_test_validate(test, 0 == strcmp("\" i'm a, test\"", test2));
451
452 test2 = ast_strsep_quoted(&test1, ',', '"', AST_STRSEP_ALL);
453 ast_test_validate(test, 0 == strcmp("i'm a, test", test2));
454
456 ast_test_validate(test, 0 == strcmp("e,nd", test2));
457
459 ast_test_validate(test, 0 == strcmp("end", test2));
460
461 // Now use '|' as the quote character
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\\");
465
466 test2 = ast_strsep_quoted(&test1, ',', '|', 0);
467 ast_test_validate(test, 0 == strcmp("ghi=jkl", test2));
468
469 test3 = ast_strsep_quoted(&test2, '=', '|', 0);
470 ast_test_validate(test, 0 == strcmp("ghi", test3));
471
472 test3 = ast_strsep_quoted(&test2, '=', '|', 0);
473 ast_test_validate(test, 0 == strcmp("jkl", test3));
474
475 test2 = ast_strsep_quoted(&test1, ',', '|', 0);
476 ast_test_validate(test, 0 == strcmp("mno=|pqr,stu|", test2));
477
478 test3 = ast_strsep_quoted(&test2, '=', '|', 0);
479 ast_test_validate(test, 0 == strcmp("mno", test3));
480
481 test3 = ast_strsep_quoted(&test2, '=', '|', 0);
482 ast_test_validate(test, 0 == strcmp("|pqr,stu|", test3));
483
484 test2 = ast_strsep_quoted(&test1, ',', '|', 0);
485 ast_test_validate(test, 0 == strcmp("abc=def", test2));
486
487 test2 = ast_strsep_quoted(&test1, ',', '|', 0);
488 ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
489
490 test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_TRIM);
491 ast_test_validate(test, 0 == strcmp("vwx = yz1", test2));
492
493 test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_STRIP);
494 ast_test_validate(test, 0 == strcmp(" vwx = yz1 ", test2));
495
497 ast_test_validate(test, 0 == strcmp("vwx , yz1", test2));
498
500 ast_test_validate(test, 0 == strcmp("v'w'x", test2));
501
502 test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_TRIM);
503 ast_test_validate(test, 0 == strcmp("|'x,v','x'|", test2));
504
505 test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_TRIM);
506 ast_test_validate(test, 0 == strcmp("| i\\'m a test|", test2));
507
509 ast_test_validate(test, 0 == strcmp("| i'm a, test|", test2));
510
511 test2 = ast_strsep_quoted(&test1, ',', '|', AST_STRSEP_ALL);
512 ast_test_validate(test, 0 == strcmp("i'm a, test", test2));
513
515 ast_test_validate(test, 0 == strcmp("e,nd", test2));
516
518 ast_test_validate(test, 0 == strcmp("end", test2));
519
520
521 // nothing failed; we're all good!
522 return AST_TEST_PASS;
523}
524
525static int test_semi(char *string1, char *string2, int test_len)
526{
527 char *test2 = NULL;
528
529 if (test_len > 0) {
530 test2 = ast_alloca(test_len);
531 *test2 = '\0';
532 } else if (test_len == 0) {
533 test2 = "";
534 }
535 ast_escape_semicolons(string1, test2, test_len);
536 if (test2 != NULL && strcmp(string2, test2) == 0) {
537 return 1;
538 } else {
539 return 0;
540 }
541}
542
543AST_TEST_DEFINE(escape_semicolons_test)
544{
545 switch (cmd) {
546 case TEST_INIT:
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;
552 case TEST_EXECUTE:
553 break;
554 }
555
556
557 ast_test_validate(test, test_semi("this is a ;test", "this is a \\;test", 18));
558 ast_test_validate(test, test_semi(";", "\\;", 3));
559
560 /* The following tests should return empty because there's not enough room to output
561 * an escaped ; or even a single character.
562 */
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));
568
569 /* At least some output should be produced now. */
570 ast_test_validate(test, test_semi("xx;xx", "x", 2));
571 ast_test_validate(test, test_semi("xx;xx", "xx", 3));
572
573 /* There's still not enough room to output \; so
574 * don't even print the \
575 */
576 ast_test_validate(test, test_semi("xx;xx", "xx", 4));
577
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));
582
583 /* Random stuff */
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));
589
590 return AST_TEST_PASS;
591}
592
593AST_TEST_DEFINE(escape_test)
594{
595 char buf[128];
596
597#define TEST_ESCAPE(s, to_escape, expected) \
598 !strcmp(ast_escape(buf, s, ARRAY_LEN(buf), to_escape), expected)
599
600#define TEST_ESCAPE_C(s, expected) \
601 !strcmp(ast_escape_c(buf, s, ARRAY_LEN(buf)), expected)
602
603#define TEST_ESCAPE_ALLOC(s, to_escape, expected) \
604 ({ \
605 int res = 0; \
606 char *a_buf = ast_escape_alloc(s, to_escape); \
607 if (a_buf) { \
608 res = !strcmp(a_buf, expected); \
609 ast_free(a_buf); \
610 } \
611 res; \
612 })
613
614#define TEST_ESCAPE_C_ALLOC(s, expected) \
615 ({ \
616 int res = 0; \
617 char *a_buf = ast_escape_c_alloc(s); \
618 if (a_buf) { \
619 res = !strcmp(a_buf, expected); \
620 ast_free(a_buf); \
621 } \
622 res; \
623 })
624
625 switch (cmd) {
626 case TEST_INIT:
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;
632 case TEST_EXECUTE:
633 break;
634 }
635
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"));
645
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\\\\\\\'\\\"\\?"));
649
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"));
653
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"));
657
658 return AST_TEST_PASS;
659}
660
661AST_TEST_DEFINE(strings_match)
662{
663 switch (cmd) {
664 case TEST_INIT:
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;
670 case TEST_EXECUTE:
671 break;
672 }
673
674 ast_test_validate(test, ast_strings_match("aaa", NULL, "aaa"));
675 ast_test_validate(test, ast_strings_match("aaa", "", "aaa"));
676 ast_test_validate(test, ast_strings_match("aaa", "=", "aaa"));
677 ast_test_validate(test, !ast_strings_match("aaa", "!=", "aaa"));
678 ast_test_validate(test, !ast_strings_match("aaa", NULL, "aba"));
679 ast_test_validate(test, !ast_strings_match("aaa", "", "aba"));
680 ast_test_validate(test, !ast_strings_match("aaa", "=", "aba"));
681 ast_test_validate(test, ast_strings_match("aaa", "!=", "aba"));
682
683 ast_test_validate(test, ast_strings_match("aaa", "<=", "aba"));
684 ast_test_validate(test, ast_strings_match("aaa", "<=", "aaa"));
685 ast_test_validate(test, !ast_strings_match("aaa", "<", "aaa"));
686
687 ast_test_validate(test, !ast_strings_match("aaa", ">=", "aba"));
688 ast_test_validate(test, ast_strings_match("aaa", ">=", "aaa"));
689 ast_test_validate(test, !ast_strings_match("aaa", ">", "aaa"));
690
691 ast_test_validate(test, !ast_strings_match("aaa", "=", "aa"));
692 ast_test_validate(test, ast_strings_match("aaa", ">", "aa"));
693 ast_test_validate(test, !ast_strings_match("aaa", "<", "aa"));
694
695 ast_test_validate(test, ast_strings_match("1", "=", "1"));
696 ast_test_validate(test, !ast_strings_match("1", "!=", "1"));
697 ast_test_validate(test, !ast_strings_match("2", "=", "1"));
698 ast_test_validate(test, ast_strings_match("2", ">", "1"));
699 ast_test_validate(test, ast_strings_match("2", ">=", "1"));
700 ast_test_validate(test, ast_strings_match("2", ">", "1.9888"));
701 ast_test_validate(test, ast_strings_match("2.9", ">", "1"));
702 ast_test_validate(test, ast_strings_match("2", ">", "1"));
703 ast_test_validate(test, ast_strings_match("2.999", "<", "3"));
704 ast_test_validate(test, ast_strings_match("2", ">", "#"));
705
706 ast_test_validate(test, ast_strings_match("abcccc", "like", "%a%c"));
707 ast_test_validate(test, !ast_strings_match("abcccx", "like", "%a%c"));
708 ast_test_validate(test, ast_strings_match("abcccc", "regex", "a[bc]+c"));
709 ast_test_validate(test, !ast_strings_match("abcccx", "regex", "^a[bxdfgtc]+c$"));
710
711 ast_test_validate(test, !ast_strings_match("neener-93joe", "LIKE", "%blah-%"));
712 ast_test_validate(test, ast_strings_match("blah-93joe", "LIKE", "%blah-%"));
713
714 ast_test_validate(test, !ast_strings_match("abcccx", "regex", NULL));
715 ast_test_validate(test, !ast_strings_match("abcccx", NULL, NULL));
716 ast_test_validate(test, !ast_strings_match(NULL, "regex", NULL));
717 ast_test_validate(test, !ast_strings_match(NULL, NULL, "abc"));
718 ast_test_validate(test, !ast_strings_match(NULL, NULL, NULL));
719
720 return AST_TEST_PASS;
721}
722
723/*!
724 * \brief Function that needs a temporary ast_str
725 */
726static const char *str_appender(struct ast_str**buf, char *a)
727{
728 ast_str_append(buf, 0, "<%s>", a);
729 return ast_str_buffer(*buf);
730}
731
732AST_TEST_DEFINE(temp_strings)
733{
734 char *return_buffer = ast_malloc(128);
735 switch (cmd) {
736 case TEST_INIT:
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;
742 case TEST_EXECUTE:
743 break;
744 }
745
746 snprintf(return_buffer, 128, "%s %s %s %s %s",
747 ast_str_tmp(12, str_appender(&STR_TMP, "str1")),
748 ast_str_tmp(12, str_appender(&STR_TMP, "str2")),
749 ast_str_tmp(12, str_appender(&STR_TMP, "B")),
750 "ccccccccccccc",
751 ast_str_tmp(12, str_appender(&STR_TMP, "ww"))
752 );
753
754 ast_test_validate(test, ast_strings_match(return_buffer, "=", "<str1> <str2> <B> ccccccccccccc <ww>"));
755
756 ast_free(return_buffer);
757 return AST_TEST_PASS;
758}
759
760AST_TEST_DEFINE(in_delimited_string)
761{
762 switch (cmd) {
763 case TEST_INIT:
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;
769 case TEST_EXECUTE:
770 break;
771 }
772
773 /* Single letter */
774 ast_test_validate(test, ast_in_delimited_string("a", "a,b", ','));
775 ast_test_validate(test, ast_in_delimited_string("b", "a,b", ','));
776
777 ast_test_validate(test, !ast_in_delimited_string("c", "a,b", ','));
778 ast_test_validate(test, !ast_in_delimited_string("aa", "a,b", ','));
779 ast_test_validate(test, !ast_in_delimited_string("bb", "a,b", ','));
780 ast_test_validate(test, !ast_in_delimited_string("a,", "a,b", ','));
781 ast_test_validate(test, !ast_in_delimited_string(",b", "a,b", ','));
782 ast_test_validate(test, !ast_in_delimited_string("a,b", "a,b", ','));
783
784 /* Bad delimiter (ends up being just a strcmp) */
785 ast_test_validate(test, !ast_in_delimited_string("a", "a,b", '#'));
786 ast_test_validate(test, !ast_in_delimited_string("b", "a,b", '#'));
787
788 ast_test_validate(test, !ast_in_delimited_string("c", "a,b", '#'));
789 ast_test_validate(test, !ast_in_delimited_string("aa", "a,b", '#'));
790 ast_test_validate(test, !ast_in_delimited_string("bb", "a,b", '#'));
791 ast_test_validate(test, !ast_in_delimited_string("a,", "a,b", '#'));
792 ast_test_validate(test, !ast_in_delimited_string(",b", "a,b", '#'));
793
794 ast_test_validate(test, ast_in_delimited_string("a,b", "a,b", '#'));
795
796 /* Multi letter */
797 ast_test_validate(test, ast_in_delimited_string("abc", "abc,def", ','));
798 ast_test_validate(test, ast_in_delimited_string("def", "abc,def", ','));
799
800 ast_test_validate(test, !ast_in_delimited_string("a", "abc,def", ','));
801 ast_test_validate(test, !ast_in_delimited_string("b", "abc,def", ','));
802 ast_test_validate(test, !ast_in_delimited_string("c", "abc,def", ','));
803
804 ast_test_validate(test, !ast_in_delimited_string("d", "abc,def", ','));
805 ast_test_validate(test, !ast_in_delimited_string("e", "abc,def", ','));
806 ast_test_validate(test, !ast_in_delimited_string("f", "abc,def", ','));
807
808 ast_test_validate(test, !ast_in_delimited_string("abc,", "abc,def", ','));
809 ast_test_validate(test, !ast_in_delimited_string(",def", "abc,def", ','));
810 ast_test_validate(test, !ast_in_delimited_string("abc,def", "abc,def", ','));
811
812 /* Embedded */
813 ast_test_validate(test, ast_in_delimited_string("abc", "abcdef,abc", ','));
814 ast_test_validate(test, ast_in_delimited_string("abcdef", "abcdef,abc", ','));
815
816 ast_test_validate(test, !ast_in_delimited_string("abc", "abcdef,def", ','));
817 ast_test_validate(test, !ast_in_delimited_string("def", "abcdef,abc", ','));
818 ast_test_validate(test, !ast_in_delimited_string("def", "abcdefghi,abc", ','));
819
820 /* NULL and empty values */
821 ast_test_validate(test, !ast_in_delimited_string(NULL, "abc,def", ','));
822
823 ast_test_validate(test, ast_in_delimited_string("abc", ",abc,def", ','));
824 ast_test_validate(test, ast_in_delimited_string("abc", "abc,def,", ','));
825 ast_test_validate(test, ast_in_delimited_string("abc", "abc,,def,", ','));
826 ast_test_validate(test, ast_in_delimited_string("def", "abc,,def", ','));
827 ast_test_validate(test, ast_in_delimited_string("def", ",abc,,def,", ','));
828
829 ast_test_validate(test, ast_in_delimited_string("", ",abc,def", ','));
830 ast_test_validate(test, ast_in_delimited_string("", "abc,def,", ','));
831 ast_test_validate(test, ast_in_delimited_string("", "abc,,def,", ','));
832 ast_test_validate(test, !ast_in_delimited_string("", "abc,def", ','));
833
834 /* Multi word */
835 ast_test_validate(test, ast_in_delimited_string("abc", "abc,def,ghi", ','));
836 ast_test_validate(test, ast_in_delimited_string("def", "abc,def,ghi", ','));
837 ast_test_validate(test, ast_in_delimited_string("ghi", "abc,def,ghi", ','));
838
839 ast_test_validate(test, !ast_in_delimited_string("a", "abc,def,ghi", ','));
840 ast_test_validate(test, !ast_in_delimited_string("d", "abc,def,ghi", ','));
841 ast_test_validate(test, !ast_in_delimited_string("g", "abc,def,ghi", ','));
842
843 ast_test_validate(test, !ast_in_delimited_string("ab", "abc,def,ghi", ','));
844 ast_test_validate(test, !ast_in_delimited_string("de", "abc,def,ghi", ','));
845 ast_test_validate(test, !ast_in_delimited_string("gh", "abc,def,ghi", ','));
846
847
848 /* With leading spaces */
849 ast_test_validate(test, ast_in_delimited_string("abc", " abc", ','));
850 ast_test_validate(test, ast_in_delimited_string("abc", " abc, def", ','));
851 ast_test_validate(test, ast_in_delimited_string("def", " abc, def", ','));
852 ast_test_validate(test, ast_in_delimited_string("abc", " abc, def, ghi", ','));
853 ast_test_validate(test, ast_in_delimited_string("def", " abc, def, ghi", ','));
854 ast_test_validate(test, ast_in_delimited_string("ghi", " abc, def, ghi", ','));
855
856 ast_test_validate(test, ast_in_delimited_string("abc", " abc", ','));
857 ast_test_validate(test, ast_in_delimited_string("abc", " abc, def", ','));
858 ast_test_validate(test, ast_in_delimited_string("def", " abc, def", ','));
859 ast_test_validate(test, ast_in_delimited_string("abc", " abc, def, ghi", ','));
860 ast_test_validate(test, ast_in_delimited_string("def", " abc, def, ghi", ','));
861 ast_test_validate(test, ast_in_delimited_string("ghi", " abc, def, ghi", ','));
862
863 /* With leading spaces and space as a delimiter */
864 ast_test_validate(test, ast_in_delimited_string("abc", " abc", ' '));
865 ast_test_validate(test, ast_in_delimited_string("abc", " abc def", ' '));
866 ast_test_validate(test, ast_in_delimited_string("def", " abc def", ' '));
867 ast_test_validate(test, ast_in_delimited_string("abc", " abc def ghi", ' '));
868 ast_test_validate(test, ast_in_delimited_string("def", " abc def ghi", ' '));
869 ast_test_validate(test, ast_in_delimited_string("ghi", " abc def ghi", ' '));
870
871 return AST_TEST_PASS;
872}
873
874static int unload_module(void)
875{
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);
886 return 0;
887}
888
889static int load_module(void)
890{
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);
902}
903
904AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dynamic string test module");
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:567
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
def info(msg)
static void * cleanup(void *unused)
Definition: pbx_realtime.c:124
#define NULL
Definition: resample.c:96
String manipulation functions.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
static int force_inline attribute_pure ast_ends_with(const char *str, const char *suffix)
Checks whether a string ends with another.
Definition: strings.h:116
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.
Definition: utils.c:1899
#define ast_str_tmp(init_len, __expr)
Provides a temporary ast_str and returns a copy of its buffer.
Definition: strings.h:1189
@ AST_STRSEP_ALL
Definition: strings.h:258
@ AST_STRSEP_TRIM
Definition: strings.h:256
@ AST_STRSEP_UNESCAPE
Definition: strings.h:257
@ AST_STRSEP_STRIP
Definition: strings.h:255
#define ast_str_alloca(init_len)
Definition: strings.h:848
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition: strings.h:693
int ast_strings_match(const char *left, const char *op, const char *right)
Compares 2 strings using realtime-style operators.
Definition: strings.c:247
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'.
Definition: strings.c:433
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
size_t ast_str_strlen(const struct ast_str *buf)
Returns the current length of the string stored within buf.
Definition: strings.h:730
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition: strings.h:97
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:742
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: utils.c:1835
Support for dynamic strings.
Definition: strings.h:623
Test Framework API.
@ TEST_INIT
Definition: test.h:200
@ TEST_EXECUTE
Definition: test.h:201
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
ast_test_result_state
Definition: test.h:193
@ AST_TEST_PASS
Definition: test.h:195
@ AST_TEST_FAIL
Definition: test.h:196
@ AST_TEST_NOT_RUN
Definition: test.h:194
static struct test_val a
static const char * str_appender(struct ast_str **buf, char *a)
Function that needs a temporary ast_str.
Definition: test_strings.c:726
#define TEST_ESCAPE_ALLOC(s, to_escape, expected)
static int test_semi(char *string1, char *string2, int test_len)
Definition: test_strings.c:525
AST_TEST_DEFINE(str_test)
Definition: test_strings.c:42
#define TEST_ESCAPE_C(s, expected)
#define TEST_ESCAPE(s, to_escape, expected)
static int load_module(void)
Definition: test_strings.c:889
static int unload_module(void)
Definition: test_strings.c:874
#define TEST_ESCAPE_C_ALLOC(s, expected)
Utility functions.
char * ast_escape_semicolons(const char *string, char *outbuf, int buflen)
Escape semicolons found in a string.
Definition: utils.c:811