various fixes:

use linked list macros for managing backend list (inspired by bug #4258)
  use ast_copy_string instead of strncpy when appropriate
  minor fixes and formatting cleanup
  add AST_LIST_HEAD_STATIC and AST_LIST_REMOVE_CURRENT macros


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5659 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Kevin P. Fleming
2005-05-15 02:42:59 +00:00
parent 4515e94c39
commit 219541b5e0
2 changed files with 241 additions and 214 deletions

View File

@@ -39,13 +39,15 @@
to hold a list of the entries of type \a type. It does not actually
declare (allocate) a structure; to do that, either follow this
macro with the desired name of the instance you wish to declare,
or use the specified \a name to declare instances elsewhere. It is
frequently used as follows:
or use the specified \a name to declare instances elsewhere.
Example usage:
\code
static AST_LIST_HEAD(entry_list, entry) entries;
\endcode
This would define \a struct \a entry_list, and declare an instance of it named
\a entries, all intended to hold a list of type \a struct \a entry.
This would define \c struct \c entry_list, and declare an instance of it named
\a entries, all intended to hold a list of type \c struct \c entry.
*/
#define AST_LIST_HEAD(name, type) \
struct name { \
@@ -53,6 +55,32 @@ struct name { \
ast_mutex_t lock; \
}
/*!
\brief Defines a structure to be used to hold a list of specified type, statically initialized.
\param name This will be the name of the defined structure.
\param type This is the type of each list entry.
This macro creates a structure definition that can be used
to hold a list of the entries of type \a type, and allocates an instance
of it, initialized to be empty.
Example usage:
\code
static AST_LIST_HEAD_STATIC(entry_list, entry) entries;
\endcode
This would define \c struct \c entry_list, and declare an instance of it named
\a entries, all intended to hold a list of type \c struct \c entry.
*/
#define AST_LIST_HEAD_STATIC(name, type) \
struct name { \
struct type *first; \
ast_mutex_t lock; \
} name = { \
.first = NULL, \
.lock = AST_MUTEX_INIT_VALUE, \
};
/*!
\brief Initializes a list head structure with a specified first entry.
\param head This is a pointer to the list head structure
@@ -73,12 +101,14 @@ struct name { \
This macro declares a structure to be used to link list entries together.
It must be used inside the definition of the structure named in
\a type, as follows:
\code
struct list_entry {
...
AST_LIST_ENTRY(list_entry) list;
}
\endcode
The field name \a list here is arbitrary, and can be anything you wish.
*/
#define AST_LIST_ENTRY(type) \
@@ -159,6 +189,7 @@ struct { \
This macro is used to safely loop over (traverse) the entries in a list. It
uses a \a for loop, and supplies the enclosed code with a pointer to each list
entry as it loops. It is typically used as follows:
\code
static AST_LIST_HEAD(entry_list, list_entry) entries;
...
@@ -172,20 +203,39 @@ struct { \
AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list) {
(do something with current here)
}
AST_LIST_TRAVERSE_SAFE_END
AST_LIST_TRAVERSE_SAFE_END;
\endcode
It differs from AST_LIST_TRAVERSE in that the code inside the loop can modify
(or even free) the entry pointed to by the \a current pointer without affecting
the loop traversal.
It differs from AST_LIST_TRAVERSE() in that the code inside the loop can modify
(or even free, after calling AST_LIST_REMOVE_CURRENT()) the entry pointed to by
the \a current pointer without affecting the loop traversal.
*/
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \
typeof((head)->first) __list_next; \
typeof((head)->first) __list_prev = NULL; \
for ((var) = (head)->first, __list_next = (var) ? (var)->field.next : NULL; \
(var); \
(var) = __list_next, __list_next = (var) ? (var)->field.next : NULL \
__list_prev = (var), (var) = __list_next, \
__list_next = (var) ? (var)->field.next : NULL \
)
/*!
\brief Removes the \a current entry from a list during a traversal.
\param head This is a pointer to the list head structure
\param field This is the name of the field (declared using AST_LIST_ENTRY())
used to link entries of this list together.
\note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN()
block; it is used to unlink the current entry from the list without affecting
the list traversal (and without having to re-traverse the list to modify the
previous entry, if any).
*/
#define AST_LIST_REMOVE_CURRENT(head, field) \
if (__list_prev) \
__list_prev->field.next = __list_next; \
else \
(head)->first = __list_next;
/*!
\brief Closes a safe loop traversal block.
*/