Convert open-coded linked list in indications to the AST_LIST_* macros. This
[asterisk/asterisk.git] / main / indications.c
index edde12a..e1ec4e2 100644 (file)
@@ -432,7 +432,7 @@ struct ind_tone_zone_sound *ast_get_indication_tone(const struct ind_tone_zone *
        }
 
        /* 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 @@ struct ind_tone_zone_sound *ast_get_indication_tone(const struct ind_tone_zone *
        return ts;
 }
 
-/* helper function to delete a tone_zone in its entirety */
-static inline void free_zone(struct ind_tone_zone* zone)
+static inline void clear_zone_sound(struct ind_tone_zone_sound *ts)
 {
-       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;
+       /* 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 @@ int ast_register_indication_country(struct ind_tone_zone *zone)
                /* 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 @@ int ast_unregister_indication_country(const char *country)
                /* 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 @@ int ast_unregister_indication_country(const char *country)
  * 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 @@ int ast_register_indication(struct ind_tone_zone *zone, const char *indication,
 /* 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 @@ int ast_unregister_indication(struct ind_tone_zone *zone, const char *indication
                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;