aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2005-01-01 21:26:37 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2005-01-01 21:26:37 +0000
commit7e69743ca3c2b43fb91fedfe21b60811c25d1ffe (patch)
tree184bdb93f104282b1ba02051f30eb58fda6c4c09
parent35203c4a661339f87eac939a524d18f217d836e8 (diff)
List improvements from kpfleming (bugs #3166,#3140)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@4629 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-xapps/app_sql_postgres.c2
-rwxr-xr-xchannel.c2
-rwxr-xr-xinclude/asterisk/linkedlists.h67
-rwxr-xr-xpbx.c4
-rwxr-xr-xpbx/pbx_dundi.c2
-rwxr-xr-xpbx/pbx_loopback.c2
6 files changed, 60 insertions, 19 deletions
diff --git a/apps/app_sql_postgres.c b/apps/app_sql_postgres.c
index f2e99dea4..ddbd1ca73 100755
--- a/apps/app_sql_postgres.c
+++ b/apps/app_sql_postgres.c
@@ -191,7 +191,7 @@ static int del_identifier(int identifier,int identifier_type) {
AST_LIST_TRAVERSE(headp,i,entries) {
if ((i->identifier==identifier) &&
(i->identifier_type==identifier_type)) {
- AST_LIST_REMOVE(headp,i,ast_PGSQL_id,entries);
+ AST_LIST_REMOVE(headp,i,entries);
free(i);
found=1;
break;
diff --git a/channel.c b/channel.c
index fb3edd312..307e95ab0 100755
--- a/channel.c
+++ b/channel.c
@@ -673,7 +673,7 @@ void ast_channel_free(struct ast_channel *chan)
/* no need to lock the list, as the channel is already locked */
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)); */
ast_var_delete(vardata);
}
diff --git a/include/asterisk/linkedlists.h b/include/asterisk/linkedlists.h
index 5e306fe37..bf2009635 100755
--- a/include/asterisk/linkedlists.h
+++ b/include/asterisk/linkedlists.h
@@ -148,6 +148,50 @@ struct { \
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.
\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.
\param head This is a pointer to the list head structure
\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())
used to link entries of this list together.
*/
-#define AST_LIST_INSERT_TAIL(head, elm, type, field) do { \
- struct type *curelm = (head)->first; \
- if(!curelm) { \
+#define AST_LIST_INSERT_TAIL(head, elm, field) do { \
+ typeof(elm) curelm = (head)->first; \
+ if (!curelm) { \
AST_LIST_INSERT_HEAD(head, elm, field); \
} else { \
- while ( curelm->field.next!=NULL ) { \
+ while (curelm->field.next!=NULL) { \
curelm=curelm->field.next; \
} \
- AST_LIST_INSERT_AFTER(curelm,elm,field); \
+ AST_LIST_INSERT_AFTER(curelm, elm, field); \
} \
} while (0)
/*!
\brief Removes and returns the head entry from a list.
\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())
used to link entries of this list together.
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.
*/
-#define AST_LIST_REMOVE_HEAD(head, type, field) ({ \
- struct type *cur = (head)->first; \
+#define AST_LIST_REMOVE_HEAD(head, field) ({ \
+ typeof((head)->first) cur = (head)->first; \
(head)->first = (head)->first->field.next; \
cur; \
})
@@ -224,17 +266,16 @@ struct { \
\brief Removes a specific entry from a list.
\param head This is a pointer to the list head structure
\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())
used to link entries of this list together.
\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)) { \
- AST_LIST_REMOVE_HEAD((head), type, field); \
+ AST_LIST_REMOVE_HEAD((head), field); \
} \
else { \
- struct type *curelm = (head)->first; \
+ typeof(elm) curelm = (head)->first; \
while( curelm->field.next != (elm) ) \
curelm = curelm->field.next; \
curelm->field.next = \
diff --git a/pbx.c b/pbx.c
index 46b990fc5..1c76ac4ac 100755
--- a/pbx.c
+++ b/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) {
if (strcasecmp(ast_var_name(newvariable), name) == 0) {
/* 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);
break;
}
@@ -5155,7 +5155,7 @@ void pbx_builtin_clear_globals(void)
{
struct ast_var_t *vardata;
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);
}
}
diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c
index d0cab9c7d..6274aa89f 100755
--- a/pbx/pbx_dundi.c
+++ b/pbx/pbx_dundi.c
@@ -551,7 +551,7 @@ static int dundi_lookup_local(struct dundi_result *dr, struct dundi_mapping *map
AST_LIST_INSERT_HEAD(&headp, newvariable, entries);
pbx_substitute_variables_varshead(&headp, map->dest, dr[anscnt].dest, sizeof(dr[anscnt].dest));
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);
}
} else
diff --git a/pbx/pbx_loopback.c b/pbx/pbx_loopback.c
index 16b854099..0868cd7c4 100755
--- a/pbx/pbx_loopback.c
+++ b/pbx/pbx_loopback.c
@@ -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);
/* Substitute variables */
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);
}
return buf;