mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-23 14:44:28 +00:00
List improvements from kpfleming (bugs #3166,#3140)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4629 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -191,7 +191,7 @@ static int del_identifier(int identifier,int identifier_type) {
|
|||||||
AST_LIST_TRAVERSE(headp,i,entries) {
|
AST_LIST_TRAVERSE(headp,i,entries) {
|
||||||
if ((i->identifier==identifier) &&
|
if ((i->identifier==identifier) &&
|
||||||
(i->identifier_type==identifier_type)) {
|
(i->identifier_type==identifier_type)) {
|
||||||
AST_LIST_REMOVE(headp,i,ast_PGSQL_id,entries);
|
AST_LIST_REMOVE(headp,i,entries);
|
||||||
free(i);
|
free(i);
|
||||||
found=1;
|
found=1;
|
||||||
break;
|
break;
|
||||||
|
@@ -673,7 +673,7 @@ void ast_channel_free(struct ast_channel *chan)
|
|||||||
/* no need to lock the list, as the channel is already locked */
|
/* no need to lock the list, as the channel is already locked */
|
||||||
|
|
||||||
while (!AST_LIST_EMPTY(headp)) { /* List Deletion. */
|
while (!AST_LIST_EMPTY(headp)) { /* List Deletion. */
|
||||||
vardata = AST_LIST_REMOVE_HEAD(headp, ast_var_t, entries);
|
vardata = AST_LIST_REMOVE_HEAD(headp, entries);
|
||||||
/* printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata)); */
|
/* printf("deleting var %s=%s\n",ast_var_name(vardata),ast_var_value(vardata)); */
|
||||||
ast_var_delete(vardata);
|
ast_var_delete(vardata);
|
||||||
}
|
}
|
||||||
|
@@ -147,6 +147,50 @@ struct { \
|
|||||||
#define AST_LIST_TRAVERSE(head,var,field) \
|
#define AST_LIST_TRAVERSE(head,var,field) \
|
||||||
for((var) = (head)->first; (var); (var) = (var)->field.next)
|
for((var) = (head)->first; (var); (var) = (var)->field.next)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Loops safely over (traverses) the entries in a list.
|
||||||
|
\param head This is a pointer to the list head structure
|
||||||
|
\param var This is the name of the variable that will hold a pointer to the
|
||||||
|
current list entry on each iteration. It must be declared before calling
|
||||||
|
this macro.
|
||||||
|
\param field This is the name of the field (declared using AST_LIST_ENTRY())
|
||||||
|
used to link entries of this list together.
|
||||||
|
|
||||||
|
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;
|
||||||
|
...
|
||||||
|
struct list_entry {
|
||||||
|
...
|
||||||
|
AST_LIST_ENTRY(list_entry) list;
|
||||||
|
}
|
||||||
|
...
|
||||||
|
struct list_entry *current;
|
||||||
|
...
|
||||||
|
AST_LIST_TRAVERSE_SAFE_BEGIN(&entries, current, list_entry, list) {
|
||||||
|
(do something with current here)
|
||||||
|
}
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field) { \
|
||||||
|
typeof((head)->first) __list_next; \
|
||||||
|
for ((var) = (head)->first, __list_next = (var) ? (var)->field.next : NULL; \
|
||||||
|
(var); \
|
||||||
|
(var) = __list_next, __list_next = (var) ? (var)->field.next : NULL \
|
||||||
|
)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Closes a safe loop traversal block.
|
||||||
|
*/
|
||||||
|
#define AST_LIST_TRAVERSE_SAFE_END }
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Initializes a list head structure.
|
\brief Initializes a list head structure.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
@@ -188,34 +232,32 @@ struct { \
|
|||||||
\brief Inserts a list entry at the tail of a list.
|
\brief Inserts a list entry at the tail of a list.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
\param elm This is a pointer to the entry to be inserted.
|
\param elm This is a pointer to the entry to be inserted.
|
||||||
\param type This is the type of each list entry.
|
|
||||||
\param field This is the name of the field (declared using AST_LIST_ENTRY())
|
\param field This is the name of the field (declared using AST_LIST_ENTRY())
|
||||||
used to link entries of this list together.
|
used to link entries of this list together.
|
||||||
*/
|
*/
|
||||||
#define AST_LIST_INSERT_TAIL(head, elm, type, field) do { \
|
#define AST_LIST_INSERT_TAIL(head, elm, field) do { \
|
||||||
struct type *curelm = (head)->first; \
|
typeof(elm) curelm = (head)->first; \
|
||||||
if(!curelm) { \
|
if (!curelm) { \
|
||||||
AST_LIST_INSERT_HEAD(head, elm, field); \
|
AST_LIST_INSERT_HEAD(head, elm, field); \
|
||||||
} else { \
|
} else { \
|
||||||
while ( curelm->field.next!=NULL ) { \
|
while (curelm->field.next!=NULL) { \
|
||||||
curelm=curelm->field.next; \
|
curelm=curelm->field.next; \
|
||||||
} \
|
} \
|
||||||
AST_LIST_INSERT_AFTER(curelm,elm,field); \
|
AST_LIST_INSERT_AFTER(curelm, elm, field); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Removes and returns the head entry from a list.
|
\brief Removes and returns the head entry from a list.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
\param type This is the type of each list entry.
|
|
||||||
\param field This is the name of the field (declared using AST_LIST_ENTRY())
|
\param field This is the name of the field (declared using AST_LIST_ENTRY())
|
||||||
used to link entries of this list together.
|
used to link entries of this list together.
|
||||||
|
|
||||||
Removes the head entry from the list, and returns a pointer to it. The
|
Removes the head entry from the list, and returns a pointer to it. The
|
||||||
forward-link pointer in the returned entry is \b not cleared.
|
forward-link pointer in the returned entry is \b not cleared.
|
||||||
*/
|
*/
|
||||||
#define AST_LIST_REMOVE_HEAD(head, type, field) ({ \
|
#define AST_LIST_REMOVE_HEAD(head, field) ({ \
|
||||||
struct type *cur = (head)->first; \
|
typeof((head)->first) cur = (head)->first; \
|
||||||
(head)->first = (head)->first->field.next; \
|
(head)->first = (head)->first->field.next; \
|
||||||
cur; \
|
cur; \
|
||||||
})
|
})
|
||||||
@@ -224,17 +266,16 @@ struct { \
|
|||||||
\brief Removes a specific entry from a list.
|
\brief Removes a specific entry from a list.
|
||||||
\param head This is a pointer to the list head structure
|
\param head This is a pointer to the list head structure
|
||||||
\param elm This is a pointer to the entry to be removed.
|
\param elm This is a pointer to the entry to be removed.
|
||||||
\param type This is the type of each list entry.
|
|
||||||
\param field This is the name of the field (declared using AST_LIST_ENTRY())
|
\param field This is the name of the field (declared using AST_LIST_ENTRY())
|
||||||
used to link entries of this list together.
|
used to link entries of this list together.
|
||||||
\warning The removed entry is \b not freed nor modified in any way.
|
\warning The removed entry is \b not freed nor modified in any way.
|
||||||
*/
|
*/
|
||||||
#define AST_LIST_REMOVE(head, elm, type, field) do { \
|
#define AST_LIST_REMOVE(head, elm, field) do { \
|
||||||
if ((head)->first == (elm)) { \
|
if ((head)->first == (elm)) { \
|
||||||
AST_LIST_REMOVE_HEAD((head), type, field); \
|
AST_LIST_REMOVE_HEAD((head), field); \
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
struct type *curelm = (head)->first; \
|
typeof(elm) curelm = (head)->first; \
|
||||||
while( curelm->field.next != (elm) ) \
|
while( curelm->field.next != (elm) ) \
|
||||||
curelm = curelm->field.next; \
|
curelm = curelm->field.next; \
|
||||||
curelm->field.next = \
|
curelm->field.next = \
|
||||||
|
4
pbx.c
4
pbx.c
@@ -5052,7 +5052,7 @@ void pbx_builtin_setvar_helper(struct ast_channel *chan, char *name, char *value
|
|||||||
AST_LIST_TRAVERSE (headp, newvariable, entries) {
|
AST_LIST_TRAVERSE (headp, newvariable, entries) {
|
||||||
if (strcasecmp(ast_var_name(newvariable), name) == 0) {
|
if (strcasecmp(ast_var_name(newvariable), name) == 0) {
|
||||||
/* there is already such a variable, delete it */
|
/* there is already such a variable, delete it */
|
||||||
AST_LIST_REMOVE(headp, newvariable, ast_var_t, entries);
|
AST_LIST_REMOVE(headp, newvariable, entries);
|
||||||
ast_var_delete(newvariable);
|
ast_var_delete(newvariable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -5155,7 +5155,7 @@ void pbx_builtin_clear_globals(void)
|
|||||||
{
|
{
|
||||||
struct ast_var_t *vardata;
|
struct ast_var_t *vardata;
|
||||||
while (!AST_LIST_EMPTY(&globals)) {
|
while (!AST_LIST_EMPTY(&globals)) {
|
||||||
vardata = AST_LIST_REMOVE_HEAD(&globals, ast_var_t, entries);
|
vardata = AST_LIST_REMOVE_HEAD(&globals, entries);
|
||||||
ast_var_delete(vardata);
|
ast_var_delete(vardata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -551,7 +551,7 @@ static int dundi_lookup_local(struct dundi_result *dr, struct dundi_mapping *map
|
|||||||
AST_LIST_INSERT_HEAD(&headp, newvariable, entries);
|
AST_LIST_INSERT_HEAD(&headp, newvariable, entries);
|
||||||
pbx_substitute_variables_varshead(&headp, map->dest, dr[anscnt].dest, sizeof(dr[anscnt].dest));
|
pbx_substitute_variables_varshead(&headp, map->dest, dr[anscnt].dest, sizeof(dr[anscnt].dest));
|
||||||
while (!AST_LIST_EMPTY(&headp)) { /* List Deletion. */
|
while (!AST_LIST_EMPTY(&headp)) { /* List Deletion. */
|
||||||
newvariable = AST_LIST_REMOVE_HEAD(&headp, ast_var_t, entries);
|
newvariable = AST_LIST_REMOVE_HEAD(&headp, entries);
|
||||||
ast_var_delete(newvariable);
|
ast_var_delete(newvariable);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
@@ -81,7 +81,7 @@ static char *loopback_helper(char *buf, int buflen, const char *exten, const cha
|
|||||||
pbx_substitute_variables_varshead(&headp, data, buf, buflen);
|
pbx_substitute_variables_varshead(&headp, data, buf, buflen);
|
||||||
/* Substitute variables */
|
/* Substitute variables */
|
||||||
while (!AST_LIST_EMPTY(&headp)) { /* List Deletion. */
|
while (!AST_LIST_EMPTY(&headp)) { /* List Deletion. */
|
||||||
newvariable = AST_LIST_REMOVE_HEAD(&headp, ast_var_t, entries);
|
newvariable = AST_LIST_REMOVE_HEAD(&headp, entries);
|
||||||
ast_var_delete(newvariable);
|
ast_var_delete(newvariable);
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
|
Reference in New Issue
Block a user