19 #ifndef _ASTERISK_VECTOR_H 20 #define _ASTERISK_VECTOR_H 44 #define AST_VECTOR(name, type) \ 56 AST_VECTOR(ast_vector_const_string,
const char *);
84 const char *
input,
const char *delim,
int flags,
85 int (*excludes_cmp)(
const char *s1,
const char *s2));
93 #define AST_VECTOR_RW(name, type) \ 113 #define AST_VECTOR_INIT(vec, size) ({ \ 114 size_t __size = (size); \ 115 size_t alloc_size = __size * sizeof(*((vec)->elems)); \ 116 (vec)->elems = alloc_size ? ast_calloc(1, alloc_size) : NULL; \ 117 (vec)->current = 0; \ 118 if ((vec)->elems) { \ 119 (vec)->max = __size; \ 123 (alloc_size == 0 || (vec)->elems != NULL) ? 0 : -1; \ 140 #define AST_VECTOR_STEAL_ELEMENTS(vec) ({ \ 141 typeof((vec)->elems) __elems = (vec)->elems; \ 142 AST_VECTOR_INIT((vec), 0); \ 158 #define AST_VECTOR_RW_INIT(vec, size) ({ \ 160 if (AST_VECTOR_INIT(vec, size) == 0) { \ 161 res = ast_rwlock_init(&(vec)->lock); \ 174 #define AST_VECTOR_FREE(vec) do { \ 175 ast_free((vec)->elems); \ 176 (vec)->elems = NULL; \ 178 (vec)->current = 0; \ 189 #define AST_VECTOR_PTR_FREE(vec) do { \ 190 AST_VECTOR_FREE(vec); \ 202 #define AST_VECTOR_RW_FREE(vec) do { \ 203 AST_VECTOR_FREE(vec); \ 204 ast_rwlock_destroy(&(vec)->lock); \ 215 #define AST_VECTOR_RW_PTR_FREE(vec) do { \ 216 AST_VECTOR_RW_FREE(vec); \ 223 #define __make_room(idx, vec) ({ \ 226 if ((idx) >= (vec)->max) { \ 227 size_t new_max = ((idx) + 1) * 2; \ 228 typeof((vec)->elems) new_elems = ast_calloc(1, \ 229 new_max * sizeof(*new_elems)); \ 231 if ((vec)->elems) { \ 232 memcpy(new_elems, (vec)->elems, \ 233 (vec)->current * sizeof(*new_elems)); \ 234 ast_free((vec)->elems); \ 236 (vec)->elems = new_elems; \ 237 (vec)->max = new_max; \ 256 #define AST_VECTOR_APPEND(vec, elem) ({ \ 259 if (__make_room((vec)->current, vec) != 0) { \ 263 (vec)->elems[(vec)->current++] = (elem); \ 284 #define AST_VECTOR_REPLACE(vec, idx, elem) ({ \ 287 if (__make_room((idx), vec) != 0) { \ 291 (vec)->elems[(idx)] = (elem); \ 292 if (((idx) + 1) > (vec)->current) { \ 293 (vec)->current = (idx) + 1; \ 309 #define AST_VECTOR_DEFAULT(vec, size, value) ({ \ 311 typeof((size)) __size = (size) ? (size) : AST_VECTOR_SIZE(vec); \ 313 for (idx = 0; idx < __size; ++idx) { \ 314 res = AST_VECTOR_REPLACE(vec, idx, value); \ 338 #define AST_VECTOR_INSERT_AT(vec, idx, elem) ({ \ 342 if (__make_room(((idx) > (vec)->current ? (idx) : (vec)->current), vec) != 0) { \ 346 if ((vec)->current > 0 && (idx) < (vec)->current) { \ 347 __move = ((vec)->current - (idx)) * sizeof(typeof((vec)->elems[0])); \ 348 memmove(&(vec)->elems[(idx) + 1], &(vec)->elems[(idx)], __move); \ 350 (vec)->elems[(idx)] = (elem); \ 351 (vec)->current = ((idx) > (vec)->current ? (idx) : (vec)->current) + 1; \ 371 #define AST_VECTOR_ADD_SORTED(vec, elem, cmp) ({ \ 373 size_t __idx = (vec)->current; \ 374 typeof(elem) __elem = (elem); \ 376 if (__make_room((vec)->current, vec) != 0) { \ 380 while (__idx > 0 && (cmp((vec)->elems[__idx - 1], __elem) > 0)) { \ 381 (vec)->elems[__idx] = (vec)->elems[__idx - 1]; \ 384 (vec)->elems[__idx] = __elem; \ 396 #define AST_VECTOR_SORT(vec, cmp) ({ \ 397 qsort((vec)->elems, (vec)->current, sizeof(typeof((vec)->elems[0])), cmp); \ 412 #define AST_VECTOR_REMOVE(vec, idx, preserve_ordered) ({ \ 413 typeof((vec)->elems[0]) res; \ 414 size_t __idx = (idx); \ 415 ast_assert(__idx < (vec)->current); \ 416 res = (vec)->elems[__idx]; \ 417 if ((preserve_ordered)) { \ 419 __move = ((vec)->current - (__idx) - 1) * sizeof(typeof((vec)->elems[0])); \ 420 memmove(&(vec)->elems[__idx], &(vec)->elems[__idx + 1], __move); \ 423 (vec)->elems[__idx] = (vec)->elems[--(vec)->current]; \ 438 #define AST_VECTOR_REMOVE_UNORDERED(vec, idx) \ 439 AST_VECTOR_REMOVE(vec, idx, 0) 448 #define AST_VECTOR_REMOVE_ORDERED(vec, idx) \ 449 AST_VECTOR_REMOVE(vec, idx, 1) 461 #define AST_VECTOR_REMOVE_ALL_CMP_UNORDERED(vec, value, cmp, cleanup) ({ \ 464 typeof(value) __value = (value); \ 465 for (idx = 0; idx < (vec)->current; ) { \ 466 if (cmp((vec)->elems[idx], __value)) { \ 467 cleanup((vec)->elems[idx]); \ 468 AST_VECTOR_REMOVE_UNORDERED((vec), idx); \ 488 #define AST_VECTOR_REMOVE_CMP_UNORDERED(vec, value, cmp, cleanup) ({ \ 491 typeof(value) __value = (value); \ 492 for (idx = 0; idx < (vec)->current; ++idx) { \ 493 if (cmp((vec)->elems[idx], __value)) { \ 494 cleanup((vec)->elems[idx]); \ 495 AST_VECTOR_REMOVE_UNORDERED((vec), idx); \ 513 #define AST_VECTOR_REMOVE_ALL_CMP_ORDERED(vec, value, cmp, cleanup) ({ \ 516 typeof(value) __value = (value); \ 517 for (idx = 0; idx < (vec)->current; ) { \ 518 if (cmp((vec)->elems[idx], __value)) { \ 519 cleanup((vec)->elems[idx]); \ 520 AST_VECTOR_REMOVE_ORDERED((vec), idx); \ 540 #define AST_VECTOR_REMOVE_CMP_ORDERED(vec, value, cmp, cleanup) ({ \ 543 typeof(value) __value = (value); \ 544 for (idx = 0; idx < (vec)->current; ++idx) { \ 545 if (cmp((vec)->elems[idx], __value)) { \ 546 cleanup((vec)->elems[idx]); \ 547 AST_VECTOR_REMOVE_ORDERED((vec), idx); \ 564 #define AST_VECTOR_ELEM_DEFAULT_CMP(elem, value) ((elem) == (value)) 573 #define AST_VECTOR_ELEM_CLEANUP_NOOP(elem) 585 #define AST_VECTOR_REMOVE_ELEM_UNORDERED(vec, elem, cleanup) ({ \ 586 AST_VECTOR_REMOVE_CMP_UNORDERED((vec), (elem), \ 587 AST_VECTOR_ELEM_DEFAULT_CMP, cleanup); \ 600 #define AST_VECTOR_REMOVE_ELEM_ORDERED(vec, elem, cleanup) ({ \ 601 AST_VECTOR_REMOVE_CMP_ORDERED((vec), (elem), \ 602 AST_VECTOR_ELEM_DEFAULT_CMP, cleanup); \ 611 #define AST_VECTOR_SIZE(vec) (vec)->current 619 #define AST_VECTOR_MAX_SIZE(vec) (vec)->max 627 #define AST_VECTOR_RESET(vec, cleanup) ({ \ 628 AST_VECTOR_CALLBACK_VOID(vec, cleanup); \ 629 (vec)->current = 0; \ 640 #define AST_VECTOR_COMPACT(vec) ({ \ 643 size_t new_max = (vec)->current; \ 644 if (new_max == 0) { \ 645 ast_free((vec)->elems); \ 646 (vec)->elems = NULL; \ 648 } else if ((vec)->max > new_max) { \ 649 typeof((vec)->elems) new_elems = ast_realloc( \ 651 new_max * sizeof(*new_elems)); \ 653 (vec)->elems = new_elems; \ 654 (vec)->max = new_max; \ 670 #define AST_VECTOR_GET_ADDR(vec, idx) ({ \ 671 size_t __idx = (idx); \ 672 ast_assert(__idx < (vec)->current); \ 673 &(vec)->elems[__idx]; \ 682 #define AST_VECTOR_GET(vec, idx) ({ \ 683 size_t __idx = (idx); \ 684 ast_assert(__idx < (vec)->current); \ 685 (vec)->elems[__idx]; \ 698 #define AST_VECTOR_GET_INDEX_NTH(vec, nth, value, cmp) ({ \ 701 typeof(nth) __nth = (nth); \ 702 typeof(value) __value = (value); \ 703 for (idx = 0; idx < (vec)->current; ++idx) { \ 704 if (cmp((vec)->elems[idx], __value) && !(--__nth)) { \ 721 #define AST_VECTOR_GET_INDEX(vec, value, cmp) \ 722 AST_VECTOR_GET_INDEX_NTH(vec, 1, value, cmp) 733 #define AST_VECTOR_GET_CMP(vec, value, cmp) ({ \ 736 typeof(value) __value = (value); \ 737 for (idx = 0; idx < (vec)->current; ++idx) { \ 738 if (cmp((vec)->elems[idx], __value)) { \ 739 res = &(vec)->elems[idx]; \ 754 #define AST_VECTOR_MATCH_ALL(element) (CMP_MATCH) 768 #define AST_VECTOR_CALLBACK(vec, callback, default_value, ...) ({ \ 770 typeof((vec)->elems[0]) res = default_value; \ 771 for (idx = 0; idx < (vec)->current; idx++) { \ 772 int rc = callback((vec)->elems[idx], ##__VA_ARGS__); \ 773 if (rc & CMP_MATCH) { \ 774 res = (vec)->elems[idx]; \ 777 if (rc & CMP_STOP) { \ 832 #define AST_VECTOR_CALLBACK_MULTIPLE(vec, callback, ...) ({ \ 834 typeof((vec)) new_vec; \ 836 new_vec = ast_malloc(sizeof(*new_vec)); \ 840 if (AST_VECTOR_INIT(new_vec, AST_VECTOR_SIZE((vec))) != 0) { \ 845 for (idx = 0; idx < (vec)->current; idx++) { \ 846 int rc = callback((vec)->elems[idx], ##__VA_ARGS__); \ 847 if (rc & CMP_MATCH) { \ 848 AST_VECTOR_APPEND(new_vec, (vec)->elems[idx]); \ 850 if (rc & CMP_STOP) { \ 865 #define AST_VECTOR_CALLBACK_VOID(vec, callback, ...) ({ \ 867 for (idx = 0; idx < (vec)->current; idx++) { \ 868 callback((vec)->elems[idx], ##__VA_ARGS__); \ 880 #define AST_VECTOR_RW_RDLOCK(vec) ast_rwlock_rdlock(&(vec)->lock) 890 #define AST_VECTOR_RW_WRLOCK(vec) ast_rwlock_wrlock(&(vec)->lock) 900 #define AST_VECTOR_RW_UNLOCK(vec) ast_rwlock_unlock(&(vec)->lock) 910 #define AST_VECTOR_RW_RDLOCK_TRY(vec) ast_rwlock_tryrdlock(&(vec)->lock) 920 #define AST_VECTOR_RW_WRLOCK_TRY(vec) ast_rwlock_trywrlock(&(vec)->lock) 930 #define AST_VECTOR_RW_RDLOCK_TIMED(vec, timespec) ast_rwlock_timedrdlock(&(vec)->lock, timespec) 940 #define AST_VECTOR_RW_WRLOCK_TIMED(vec, timespec) ast_rwlock_timedwrlock(&(vec)->lock, timespec) Asterisk locking-related definitions:
static int input(yyscan_t yyscanner)
#define AST_VECTOR(name, type)
Define a vector structure.
int ast_vector_string_split(struct ast_vector_string *dest, const char *input, const char *delim, int flags, int(*excludes_cmp)(const char *s1, const char *s2))
Append a string vector by splitting a string.
ast_vector_string_split_flags