mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +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) { | ||||
| 			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; | ||||
|   | ||||
| @@ -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); | ||||
| 	} | ||||
|   | ||||
| @@ -147,6 +147,50 @@ struct {								\ | ||||
| #define AST_LIST_TRAVERSE(head,var,field) 				\ | ||||
| 	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 =					\ | ||||
|   | ||||
							
								
								
									
										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) { | ||||
| 		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); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user