54 static int list_expect(
struct test_llist *test_list,
const char *expect,
struct ast_str **buf)
66 static int dbl_list_expect_forward(
struct test_dbl_llist *test_list,
const char *expect,
struct ast_str **buf)
78 static int dbl_list_expect_reverse(
struct test_dbl_llist *test_list,
const char *expect,
struct ast_str **buf)
82 int len = strlen(expect);
92 if (len != strlen(str)) {
95 for (idx = 0; idx < len; ++idx) {
96 if (expect[idx] != str[len - idx - 1]) {
103 #define MATCH_OR_FAIL(list, val, retbuf) \
104 if (list_expect(list, val, &retbuf)) { \
105 ast_test_status_update(test, "Expected: %s, Got: %s\n", val, ast_str_buffer(retbuf)); \
106 return AST_TEST_FAIL; \
109 #define MATCH_OR_FAIL_DBL(list, val, retbuf) \
110 if (dbl_list_expect_forward(list, val, &retbuf)) { \
111 ast_test_status_update(test, "Expected: %s, Got: %s\n", val, ast_str_buffer(retbuf)); \
112 return AST_TEST_FAIL; \
114 if (dbl_list_expect_reverse(list, val, &retbuf)) { \
115 ast_test_status_update(test, "Expected reverse of: %s, Got: %s\n", val, ast_str_buffer(retbuf)); \
116 return AST_TEST_FAIL; \
119 #define ELEM_OR_FAIL(x,y) \
121 ast_test_status_update(test, "Expected: %s, Got: %s\n", (x)->name, (y)->name); \
122 return AST_TEST_FAIL; \
134 info->name =
"ll_tests";
135 info->category =
"/main/linkedlists/";
136 info->summary =
"single linked list unit test";
138 "Test the single linked list API";
139 return AST_TEST_NOT_RUN;
145 return AST_TEST_FAIL;
149 return AST_TEST_FAIL;
151 memset(bogus, 0,
sizeof(*bogus));
154 ast_test_status_update(
test,
"AST_LIST_REMOVE should safely return NULL for missing element from empty list\n");
155 return AST_TEST_FAIL;
160 MATCH_OR_FAIL(&test_list,
"A", buf);
162 MATCH_OR_FAIL(&test_list,
"BA", buf);
164 MATCH_OR_FAIL(&test_list,
"A", buf);
166 MATCH_OR_FAIL(&test_list,
"", buf);
168 ast_test_status_update(
test,
"Somehow removed an item from the head of a list that didn't exist\n");
169 return AST_TEST_FAIL;
171 MATCH_OR_FAIL(&test_list,
"", buf);
176 ast_test_status_update(
test,
"List should be empty\n");
177 return AST_TEST_FAIL;
183 MATCH_OR_FAIL(&test_list,
"A", buf);
185 MATCH_OR_FAIL(&test_list,
"AB", buf);
187 MATCH_OR_FAIL(&test_list,
"ABC", buf);
189 MATCH_OR_FAIL(&test_list,
"ABCD", buf);
191 ast_test_status_update(
test,
"AST_LIST_REMOVE should safely return NULL for missing element\n");
192 return AST_TEST_FAIL;
196 ast_test_status_update(
test,
"AST_LIST_REMOVE should safely return NULL for element set to NULL\n");
197 return AST_TEST_FAIL;
200 MATCH_OR_FAIL(&test_list,
"ACD", buf);
202 MATCH_OR_FAIL(&test_list,
"AC", buf);
204 MATCH_OR_FAIL(&test_list,
"C", buf);
206 MATCH_OR_FAIL(&test_list,
"", buf);
208 ast_test_status_update(
test,
"List should be empty\n");
209 return AST_TEST_FAIL;
212 ast_test_status_update(
test,
"AST_LIST_REMOVE should safely return NULL asked to remove a NULL pointer from an empty list\n");
213 return AST_TEST_FAIL;
219 MATCH_OR_FAIL(&test_list,
"A", buf);
221 MATCH_OR_FAIL(&test_list,
"AC", buf);
223 MATCH_OR_FAIL(&test_list,
"ABC", buf);
225 MATCH_OR_FAIL(&test_list,
"ABCD", buf);
237 ast_test_status_update(
test,
"List should be empty after traversing and removal. It wasn't.\n");
238 return AST_TEST_FAIL;
244 MATCH_OR_FAIL(&test_list,
"A", buf);
246 MATCH_OR_FAIL(&test_list,
"AB", buf);
248 MATCH_OR_FAIL(&other_list,
"C", buf);
250 MATCH_OR_FAIL(&other_list,
"CD", buf);
252 MATCH_OR_FAIL(&test_list,
"ABCD", buf);
253 MATCH_OR_FAIL(&other_list,
"", buf);
259 ast_test_status_update(
test,
"List should be empty after traversing and removal. It wasn't.\n");
260 return AST_TEST_FAIL;
266 MATCH_OR_FAIL(&test_list,
"A", buf);
268 MATCH_OR_FAIL(&test_list,
"AD", buf);
270 MATCH_OR_FAIL(&other_list,
"B", buf);
272 MATCH_OR_FAIL(&other_list,
"BC", buf);
274 MATCH_OR_FAIL(&test_list,
"ABCD", buf);
275 MATCH_OR_FAIL(&other_list,
"", buf);
281 ast_test_status_update(
test,
"List should be empty after traversing and removal. It wasn't.\n");
282 return AST_TEST_FAIL;
288 MATCH_OR_FAIL(&test_list,
"A", buf);
290 MATCH_OR_FAIL(&test_list,
"AB", buf);
292 MATCH_OR_FAIL(&other_list,
"C", buf);
294 MATCH_OR_FAIL(&other_list,
"CD", buf);
296 MATCH_OR_FAIL(&test_list,
"ABCD", buf);
297 MATCH_OR_FAIL(&other_list,
"", buf);
303 ast_test_status_update(
test,
"List should be empty after traversing and removal. It wasn't.\n");
304 return AST_TEST_FAIL;
310 MATCH_OR_FAIL(&test_list,
"A", buf);
312 MATCH_OR_FAIL(&test_list,
"AD", buf);
316 MATCH_OR_FAIL(&test_list,
"ABD", buf);
318 MATCH_OR_FAIL(&test_list,
"ABCD", buf);
320 MATCH_OR_FAIL(&test_list,
"ABC", buf);
324 MATCH_OR_FAIL(&test_list,
"ABC", buf);
330 ast_test_status_update(
test,
"List should be empty after traversing and removal. It wasn't.\n");
331 return AST_TEST_FAIL;
334 return AST_TEST_PASS;
346 info->name =
"double_ll_tests";
347 info->category =
"/main/linkedlists/";
348 info->summary =
"double linked list unit test";
350 "Test the double linked list API";
351 return AST_TEST_NOT_RUN;
357 return AST_TEST_FAIL;
363 ast_test_status_update(
test,
"AST_DLLIST_REMOVE_VERIFY should safely return NULL for missing element from empty list\n");
364 return AST_TEST_FAIL;
369 MATCH_OR_FAIL_DBL(&test_list,
"A", buf);
371 MATCH_OR_FAIL_DBL(&test_list,
"BA", buf);
373 MATCH_OR_FAIL_DBL(&test_list,
"A", buf);
375 MATCH_OR_FAIL_DBL(&test_list,
"", buf);
377 ast_test_status_update(
test,
"Somehow removed an item from the head of a list that didn't exist\n");
378 return AST_TEST_FAIL;
380 MATCH_OR_FAIL_DBL(&test_list,
"", buf);
385 ast_test_status_update(
test,
"List should be empty\n");
386 return AST_TEST_FAIL;
392 MATCH_OR_FAIL_DBL(&test_list,
"A", buf);
394 MATCH_OR_FAIL_DBL(&test_list,
"AB", buf);
396 MATCH_OR_FAIL_DBL(&test_list,
"ABC", buf);
398 MATCH_OR_FAIL_DBL(&test_list,
"ABCD", buf);
400 ast_test_status_update(
test,
"AST_DLLIST_REMOVE_VERIFY should safely return NULL for missing element\n");
401 return AST_TEST_FAIL;
405 ast_test_status_update(
test,
"AST_DLLIST_REMOVE_VERIFY should safely return NULL for element set to NULL\n");
406 return AST_TEST_FAIL;
409 MATCH_OR_FAIL_DBL(&test_list,
"ACD", buf);
411 MATCH_OR_FAIL_DBL(&test_list,
"AC", buf);
413 MATCH_OR_FAIL_DBL(&test_list,
"C", buf);
415 MATCH_OR_FAIL_DBL(&test_list,
"", buf);
417 ast_test_status_update(
test,
"List should be empty\n");
418 return AST_TEST_FAIL;
421 ast_test_status_update(
test,
"AST_DLLIST_REMOVE_VERIFY should safely return NULL asked to remove a NULL pointer from an empty list\n");
422 return AST_TEST_FAIL;
428 MATCH_OR_FAIL_DBL(&test_list,
"A", buf);
430 MATCH_OR_FAIL_DBL(&test_list,
"AC", buf);
432 MATCH_OR_FAIL_DBL(&test_list,
"ABC", buf);
434 MATCH_OR_FAIL_DBL(&test_list,
"ABCD", buf);
436 MATCH_OR_FAIL_DBL(&test_list,
"ABC", buf);
438 MATCH_OR_FAIL_DBL(&test_list,
"AB", buf);
440 MATCH_OR_FAIL_DBL(&test_list,
"ABD", buf);
442 MATCH_OR_FAIL_DBL(&test_list,
"ABCD", buf);
444 MATCH_OR_FAIL_DBL(&test_list,
"BCD", buf);
446 MATCH_OR_FAIL_DBL(&test_list,
"ABCD", buf);
459 ast_test_status_update(
test,
"List should be empty after traversing and removal. It wasn't.\n");
460 return AST_TEST_FAIL;
466 MATCH_OR_FAIL_DBL(&test_list,
"A", buf);
468 MATCH_OR_FAIL_DBL(&test_list,
"AB", buf);
470 MATCH_OR_FAIL_DBL(&other_list,
"C", buf);
472 MATCH_OR_FAIL_DBL(&other_list,
"CD", buf);
474 MATCH_OR_FAIL_DBL(&test_list,
"ABCD", buf);
475 MATCH_OR_FAIL_DBL(&other_list,
"", buf);
481 ast_test_status_update(
test,
"List should be empty after traversing and removal. It wasn't.\n");
482 return AST_TEST_FAIL;
491 MATCH_OR_FAIL_DBL(&test_list,
"A", buf);
493 MATCH_OR_FAIL_DBL(&test_list,
"AD", buf);
497 MATCH_OR_FAIL_DBL(&test_list,
"ABD", buf);
499 MATCH_OR_FAIL_DBL(&test_list,
"ABCD", buf);
501 MATCH_OR_FAIL_DBL(&test_list,
"ABC", buf);
505 MATCH_OR_FAIL_DBL(&test_list,
"ABC", buf);
511 ast_test_status_update(
test,
"List should be empty after traversing and removal. It wasn't.\n");
512 return AST_TEST_FAIL;
516 MATCH_OR_FAIL_DBL(&test_list,
"B", buf);
518 MATCH_OR_FAIL_DBL(&test_list,
"BD", buf);
522 MATCH_OR_FAIL_DBL(&test_list,
"ABD", buf);
524 MATCH_OR_FAIL_DBL(&test_list,
"ABCD", buf);
526 MATCH_OR_FAIL_DBL(&test_list,
"ACD", buf);
530 MATCH_OR_FAIL_DBL(&test_list,
"ACD", buf);
536 ast_test_status_update(
test,
"List should be empty after traversing and removal. It wasn't.\n");
537 return AST_TEST_FAIL;
541 MATCH_OR_FAIL_DBL(&test_list,
"B", buf);
545 MATCH_OR_FAIL_DBL(&test_list,
"AB", buf);
547 MATCH_OR_FAIL_DBL(&test_list,
"ABD", buf);
549 MATCH_OR_FAIL_DBL(&test_list,
"ABCD", buf);
551 MATCH_OR_FAIL_DBL(&test_list,
"ACD", buf);
555 MATCH_OR_FAIL_DBL(&test_list,
"ACD", buf);
561 ast_test_status_update(
test,
"List should be empty after traversing and removal. It wasn't.\n");
562 return AST_TEST_FAIL;
571 MATCH_OR_FAIL_DBL(&test_list,
"A", buf);
573 MATCH_OR_FAIL_DBL(&test_list,
"AD", buf);
577 MATCH_OR_FAIL_DBL(&test_list,
"ABD", buf);
579 MATCH_OR_FAIL_DBL(&test_list,
"ABCD", buf);
581 MATCH_OR_FAIL_DBL(&test_list,
"ABC", buf);
585 MATCH_OR_FAIL_DBL(&test_list,
"ABC", buf);
591 ast_test_status_update(
test,
"List should be empty after traversing and removal. It wasn't.\n");
592 return AST_TEST_FAIL;
596 MATCH_OR_FAIL_DBL(&test_list,
"B", buf);
598 MATCH_OR_FAIL_DBL(&test_list,
"BD", buf);
602 MATCH_OR_FAIL_DBL(&test_list,
"ABD", buf);
604 MATCH_OR_FAIL_DBL(&test_list,
"ABCD", buf);
606 MATCH_OR_FAIL_DBL(&test_list,
"ACD", buf);
610 MATCH_OR_FAIL_DBL(&test_list,
"ACD", buf);
616 ast_test_status_update(
test,
"List should be empty after traversing and removal. It wasn't.\n");
617 return AST_TEST_FAIL;
621 MATCH_OR_FAIL_DBL(&test_list,
"B", buf);
625 MATCH_OR_FAIL_DBL(&test_list,
"AB", buf);
627 MATCH_OR_FAIL_DBL(&test_list,
"ABD", buf);
629 MATCH_OR_FAIL_DBL(&test_list,
"ABCD", buf);
631 MATCH_OR_FAIL_DBL(&test_list,
"ACD", buf);
635 MATCH_OR_FAIL_DBL(&test_list,
"ACD", buf);
641 ast_test_status_update(
test,
"List should be empty after traversing and removal. It wasn't.\n");
642 return AST_TEST_FAIL;
645 return AST_TEST_PASS;
648 static int unload_module(
void)
650 AST_TEST_UNREGISTER(single_ll_tests);
651 AST_TEST_UNREGISTER(double_ll_tests);
655 static int load_module(
void)
657 AST_TEST_REGISTER(single_ll_tests);
658 AST_TEST_REGISTER(double_ll_tests);
#define AST_DLLIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_INSERT_LIST_AFTER(head, list, elm, field)
Inserts a whole list after a specific entry in a list.
#define AST_DLLIST_TRAVERSE_BACKWARDS(head, var, field)
Loops over (traverses) the entries in a list in reverse order, starting at the end.
Asterisk main include file. File version handling, generic pbx functions.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
#define AST_DLLIST_INSERT_BEFORE(head, listelm, elm, field)
Inserts a list entry before a given entry.
String manipulation functions.
#define AST_DLLIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define AST_DLLIST_REMOVE_VERIFY(head, elm, field)
Removes a specific node from a list if it is in the list.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
#define AST_DLLIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_DLLIST_INSERT_AFTER(head, listelm, elm, field)
Inserts a list entry after a given entry.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
#define AST_DLLIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_DLLIST_INSERT_AFTER_CURRENT(elm, field)
Inserts a list node after the current node during a traversal.
#define AST_LIST_INSERT_AFTER(head, listelm, elm, field)
Inserts a list entry after a given entry.
#define AST_DLLIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_DLLIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
A set of macros to manage doubly-linked lists.
#define AST_DLLIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_DLLIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
A set of macros to manage forward-linked lists.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_DLLIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list node before the current node during a traversal.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define AST_DLLIST_APPEND_DLLIST(head, list, field)
Appends a whole list to the tail of a list.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Support for dynamic strings.
#define AST_LIST_LAST(head)
Returns the last entry contained in a list.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define AST_DLLIST_EMPTY(head)
Checks whether the specified list contains any entries.
Support for logging to various files, console and syslog Configuration in file logger.conf.
#define AST_DLLIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
#define AST_DLLIST_TRAVERSE_BACKWARDS_SAFE_END
Closes a safe loop traversal block.
#define AST_DLLIST_PREV(elm, field)
Returns the previous entry in the list before the given entry.
#define AST_DLLIST_REMOVE_TAIL(head, field)
Removes and returns the tail node from a list.
#define AST_TEST_DEFINE(hdr)
#define AST_DLLIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list entry before the current entry during a traversal.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
#define AST_DLLIST_FIRST(head)
Returns the first entry contained in a list.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define AST_DLLIST_LAST(head)
Returns the last entry contained in a list.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
#define AST_DLLIST_ENTRY(type)
Declare previous/forward links inside a list entry.
#define AST_LIST_APPEND_LIST(head, list, field)
Appends a whole list to the tail of a list.