[asterisk-commits] seanbright: trunk r155284 - in /trunk: include/asterisk/ main/ res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Nov 7 10:18:53 CST 2008


Author: seanbright
Date: Fri Nov  7 10:18:52 2008
New Revision: 155284

URL: http://svn.digium.com/view/asterisk?view=rev&rev=155284
Log:
Convert open-coded linked list in indications to the AST_LIST_* macros.  This
cleans the code up some and should make it more maintainable as time goes on.

Reviewed by Russell, Kevin, Mark M., and Tilghman via ReviewBoard:
	http://reviewboard.digium.com/r/34/

Modified:
    trunk/include/asterisk/indications.h
    trunk/main/indications.c
    trunk/res/res_indications.c

Modified: trunk/include/asterisk/indications.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/indications.h?view=diff&rev=155284&r1=155283&r2=155284
==============================================================================
--- trunk/include/asterisk/indications.h (original)
+++ trunk/include/asterisk/indications.h Fri Nov  7 10:18:52 2008
@@ -40,9 +40,9 @@
 	   first tone description not preceeded by !. Duration is
 	   specified in milliseconds */
 struct ind_tone_zone_sound {
-	struct ind_tone_zone_sound *next;	/*!< next element */
 	const char *name;			/*!< Identifing name */
 	const char *data;			/*!< Actual zone description */
+	AST_LIST_ENTRY(ind_tone_zone_sound) list;
 };
 
 struct ind_tone_zone {
@@ -52,7 +52,7 @@
 	char description[40];				/*!< Description */
 	int  nrringcadence;				/*!< # registered ringcadence elements */
 	int *ringcadence;				/*!< Ring cadence */
-	struct ind_tone_zone_sound *tones;		/*!< The known tones for this zone */
+	AST_LIST_HEAD_NOLOCK(, ind_tone_zone_sound) tones;		/*!< The known tones for this zone */
 };
 
 /*! \brief set the default tone country */
@@ -62,6 +62,8 @@
 struct ind_tone_zone *ast_get_indication_zone(const char *country);
 /*! \brief locate a tone_zone_sound, given the tone_zone. if tone_zone == NULL, use the default tone_zone */
 struct ind_tone_zone_sound *ast_get_indication_tone(const struct ind_tone_zone *zone, const char *indication);
+/*! \brief deallocate the passed tone zone */
+void ast_destroy_indication_zone(struct ind_tone_zone *zone);
 
 /*! \brief add a new country, if country exists, it will be replaced. */
 int ast_register_indication_country(struct ind_tone_zone *country);

Modified: trunk/main/indications.c
URL: http://svn.digium.com/view/asterisk/trunk/main/indications.c?view=diff&rev=155284&r1=155283&r2=155284
==============================================================================
--- trunk/main/indications.c (original)
+++ trunk/main/indications.c Fri Nov  7 10:18:52 2008
@@ -432,7 +432,7 @@
 	}
 
 	/* Look through list of tones in the zone searching for the right one */
-	for (ts = zone->tones; ts; ts = ts->next) {
+	AST_LIST_TRAVERSE(&zone->tones, ts, list) {
 		if (!strcasecmp(ts->name, indication))
 			break;
 	}
@@ -442,15 +442,21 @@
 	return ts;
 }
 
-/* helper function to delete a tone_zone in its entirety */
-static inline void free_zone(struct ind_tone_zone* zone)
-{
-	while (zone->tones) {
-		struct ind_tone_zone_sound *tmp = zone->tones->next;
-		ast_free((void *)zone->tones->name);
-		ast_free((void *)zone->tones->data);
-		ast_free(zone->tones);
-		zone->tones = tmp;
+static inline void clear_zone_sound(struct ind_tone_zone_sound *ts)
+{
+	/* Deconstify the 'const char *'s so the compiler doesn't complain. (but it's safe) */
+	ast_free((char *) ts->name);
+	ast_free((char *) ts->data);
+}
+
+/*! \brief deallocate the passed tone zone */
+void ast_destroy_indication_zone(struct ind_tone_zone *zone)
+{
+	struct ind_tone_zone_sound *current;
+
+	while ((current = AST_LIST_REMOVE_HEAD(&zone->tones, list))) {
+		clear_zone_sound(current);
+		ast_free(current);
 	}
 
 	if (zone->ringcadence)
@@ -477,7 +483,7 @@
 		/* Remove from the linked list */
 		AST_RWLIST_REMOVE_CURRENT(list);
 		/* Finally free the zone itself */
-		free_zone(tz);
+		ast_destroy_indication_zone(tz);
 		break;
 	}
 	AST_RWLIST_TRAVERSE_SAFE_END;
@@ -512,7 +518,7 @@
 		/* Remove from the list */
 		AST_RWLIST_REMOVE_CURRENT(list);
 		ast_verb(3, "Unregistered indication country '%s'\n", tz->country);
-		free_zone(tz);
+		ast_destroy_indication_zone(tz);
 		res = 0;
 	}
 	AST_RWLIST_TRAVERSE_SAFE_END;
@@ -525,37 +531,39 @@
  * exists, it will be replaced. */
 int ast_register_indication(struct ind_tone_zone *zone, const char *indication, const char *tonelist)
 {
-	struct ind_tone_zone_sound *ts, *ps;
+	struct ind_tone_zone_sound *ts;
+	int found = 0;
 
 	/* is it an alias? stop */
 	if (zone->alias[0])
 		return -1;
 
 	AST_RWLIST_WRLOCK(&tone_zones);
-	for (ps=NULL,ts=zone->tones; ts; ps=ts,ts=ts->next) {
-		if (!strcasecmp(indication,ts->name)) {
-			/* indication already there, replace */
-			ast_free((void*)ts->name);
-			ast_free((void*)ts->data);
+
+	AST_LIST_TRAVERSE(&zone->tones, ts, list) {
+		if (!strcasecmp(indication, ts->name)) {
+			clear_zone_sound(ts);
+			found = 1;
 			break;
 		}
 	}
 	if (!ts) {
 		/* not there, we have to add */
-		if (!(ts = ast_malloc(sizeof(*ts)))) {
+		if (!(ts = ast_calloc(1, sizeof(*ts)))) {
 			AST_RWLIST_UNLOCK(&tone_zones);
 			return -2;
 		}
-		ts->next = NULL;
 	}
 	if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) {
+		ast_free(ts);
 		AST_RWLIST_UNLOCK(&tone_zones);
 		return -2;
 	}
-	if (ps)
-		ps->next = ts;
-	else
-		zone->tones = ts;
+
+	if (!found) {
+		AST_LIST_INSERT_TAIL(&zone->tones, ts, list);
+	}
+
 	AST_RWLIST_UNLOCK(&tone_zones);
 	return 0;
 }
@@ -563,7 +571,7 @@
 /* remove an existing country's indication. Both country and indication must exist */
 int ast_unregister_indication(struct ind_tone_zone *zone, const char *indication)
 {
-	struct ind_tone_zone_sound *ts,*ps = NULL, *tmp;
+	struct ind_tone_zone_sound *ts;
 	int res = -1;
 
 	/* is it an alias? stop */
@@ -571,27 +579,18 @@
 		return -1;
 
 	AST_RWLIST_WRLOCK(&tone_zones);
-	ts = zone->tones;
-	while (ts) {
-		if (!strcasecmp(indication,ts->name)) {
-			/* indication found */
-			tmp = ts->next;
-			if (ps)
-				ps->next = tmp;
-			else
-				zone->tones = tmp;
-			ast_free((void*)ts->name);
-			ast_free((void*)ts->data);
+
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, ts, list) {
+		if (!strcasecmp(indication, ts->name)) {
+			AST_LIST_REMOVE_CURRENT(list);
+			clear_zone_sound(ts);
 			ast_free(ts);
-			ts = tmp;
 			res = 0;
-		}
-		else {
-			/* next zone please */
-			ps = ts;
-			ts = ts->next;
-		}
-	}
+			break;
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END;
+
 	/* indication not found, goodbye */
 	AST_RWLIST_UNLOCK(&tone_zones);
 	return res;

Modified: trunk/res/res_indications.c
URL: http://svn.digium.com/view/asterisk/trunk/res/res_indications.c?view=diff&rev=155284&r1=155283&r2=155284
==============================================================================
--- trunk/res/res_indications.c (original)
+++ trunk/res/res_indications.c Fri Nov  7 10:18:52 2008
@@ -216,7 +216,7 @@
 		int i, j;
 		for (i = 2; i < a->argc; i++) {
 			if (strcasecmp(tz->country, a->argv[i]) == 0 && !tz->alias[0]) {
-				struct ind_tone_zone_sound* ts;
+				struct ind_tone_zone_sound *ts;
 				if (!found_country) {
 					found_country = 1;
 					ast_cli(a->fd, "Country Indication      PlayList\n");
@@ -230,8 +230,9 @@
 					j--;
 				ast_copy_string(buf + j, "\n", sizeof(buf) - j);
 				ast_cli(a->fd, "%s", buf);
-				for (ts = tz->tones; ts; ts = ts->next)
+				AST_LIST_TRAVERSE(&tz->tones, ts, list) {
 					ast_cli(a->fd, "%-7.7s %-15.15s %s\n", tz->country, ts->name, ts->data);
+				}
 				break;
 			}
 		}
@@ -274,23 +275,6 @@
 {
 	ast_playtones_stop(chan);
 	return 0;
-}
-
-/* helper function to delete a tone_zone in its entirety */
-static inline void free_zone(struct ind_tone_zone* zone)
-{
-	while (zone->tones) {
-		struct ind_tone_zone_sound *tmp = zone->tones->next;
-		ast_free((void *)zone->tones->name);
-		ast_free((void *)zone->tones->data);
-		ast_free(zone->tones);
-		zone->tones = tmp;
-	}
-
-	if (zone->ringcadence)
-		ast_free(zone->ringcadence);
-
-	ast_free(zone);
 }
 
 /*! \brief load indications module */
@@ -347,7 +331,7 @@
 					}					
 					if (!(tmp = ast_realloc(tones->ringcadence, (tones->nrringcadence + 1) * sizeof(int)))) {
 						ast_config_destroy(cfg);
-						free_zone(tones);
+						ast_destroy_indication_zone(tones);
 						return -1;
 					}
 					tones->ringcadence = tmp;
@@ -364,50 +348,49 @@
 					struct ind_tone_zone* azone;
 					if (!(azone = ast_calloc(1, sizeof(*azone)))) {
 						ast_config_destroy(cfg);
-						free_zone(tones);
+						ast_destroy_indication_zone(tones);
 						return -1;
 					}
 					ast_copy_string(azone->country, country, sizeof(azone->country));
 					ast_copy_string(azone->alias, cxt, sizeof(azone->alias));
 					if (ast_register_indication_country(azone)) {
 						ast_log(LOG_WARNING, "Unable to register indication alias at line %d.\n",v->lineno);
-						free_zone(tones);
+						ast_destroy_indication_zone(tones);
 					}
 					/* next item */
 					country = strsep(&c,",");
 				}
 			} else {
+				struct ind_tone_zone_sound *ts;
+
 				/* add tone to country */
-				struct ind_tone_zone_sound *ps,*ts;
-				for (ps=NULL,ts=tones->tones; ts; ps=ts, ts=ts->next) {
-					if (strcasecmp(v->name,ts->name)==0) {
+				AST_LIST_TRAVERSE(&tones->tones, ts, list) {
+					if (!strcasecmp(v->name, ts->name)) {
 						/* already there */
-						ast_log(LOG_NOTICE,"Duplicate entry '%s', skipped.\n",v->name);
+						ast_log(LOG_NOTICE, "Duplicate entry '%s' skipped.\n", v->name);
 						goto out;
 					}
 				}
-				/* not there, add it to the back */				
-				if (!(ts = ast_malloc(sizeof(*ts)))) {
+
+				/* not there, add it to the back */
+				if (!(ts = ast_calloc(1, sizeof(*ts)))) {
 					ast_config_destroy(cfg);
 					return -1;
 				}
-				ts->next = NULL;
 				ts->name = ast_strdup(v->name);
 				ts->data = ast_strdup(v->value);
-				if (ps)
-					ps->next = ts;
-				else
-					tones->tones = ts;
+
+				AST_LIST_INSERT_TAIL(&tones->tones, ts, list);
 			}
 out:			v = v->next;
 		}
-		if (tones->description[0] || tones->alias[0] || tones->tones) {
+		if (tones->description[0] || tones->alias[0] || !AST_LIST_EMPTY(&tones->tones)) {
 			if (ast_register_indication_country(tones)) {
 				ast_log(LOG_WARNING, "Unable to register indication at line %d.\n",v->lineno);
-				free_zone(tones);
+				ast_destroy_indication_zone(tones);
 			}
 		} else {
-			free_zone(tones);
+			ast_destroy_indication_zone(tones);
 		}
 
 		cxt = ast_category_browse(cfg, cxt);




More information about the asterisk-commits mailing list