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/


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@155284 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.6.2
Sean Bright 17 years ago
parent 90e573c373
commit 1d09d193e7

@ -40,9 +40,9 @@
first tone description not preceeded by !. Duration is first tone description not preceeded by !. Duration is
specified in milliseconds */ specified in milliseconds */
struct ind_tone_zone_sound { struct ind_tone_zone_sound {
struct ind_tone_zone_sound *next; /*!< next element */
const char *name; /*!< Identifing name */ const char *name; /*!< Identifing name */
const char *data; /*!< Actual zone description */ const char *data; /*!< Actual zone description */
AST_LIST_ENTRY(ind_tone_zone_sound) list;
}; };
struct ind_tone_zone { struct ind_tone_zone {
@ -52,7 +52,7 @@ struct ind_tone_zone {
char description[40]; /*!< Description */ char description[40]; /*!< Description */
int nrringcadence; /*!< # registered ringcadence elements */ int nrringcadence; /*!< # registered ringcadence elements */
int *ringcadence; /*!< Ring cadence */ 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 */ /*! \brief set the default tone country */
@ -62,6 +62,8 @@ int ast_set_indication_country(const char *country);
struct ind_tone_zone *ast_get_indication_zone(const char *country); 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 */ /*! \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); 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. */ /*! \brief add a new country, if country exists, it will be replaced. */
int ast_register_indication_country(struct ind_tone_zone *country); int ast_register_indication_country(struct ind_tone_zone *country);

@ -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 */ /* 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)) if (!strcasecmp(ts->name, indication))
break; break;
} }
@ -442,15 +442,21 @@ struct ind_tone_zone_sound *ast_get_indication_tone(const struct ind_tone_zone *
return ts; return ts;
} }
/* helper function to delete a tone_zone in its entirety */ static inline void clear_zone_sound(struct ind_tone_zone_sound *ts)
static inline void free_zone(struct ind_tone_zone* zone)
{ {
while (zone->tones) { /* Deconstify the 'const char *'s so the compiler doesn't complain. (but it's safe) */
struct ind_tone_zone_sound *tmp = zone->tones->next; ast_free((char *) ts->name);
ast_free((void *)zone->tones->name); ast_free((char *) ts->data);
ast_free((void *)zone->tones->data); }
ast_free(zone->tones);
zone->tones = tmp; /*! \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) if (zone->ringcadence)
@ -477,7 +483,7 @@ int ast_register_indication_country(struct ind_tone_zone *zone)
/* Remove from the linked list */ /* Remove from the linked list */
AST_RWLIST_REMOVE_CURRENT(list); AST_RWLIST_REMOVE_CURRENT(list);
/* Finally free the zone itself */ /* Finally free the zone itself */
free_zone(tz); ast_destroy_indication_zone(tz);
break; break;
} }
AST_RWLIST_TRAVERSE_SAFE_END; AST_RWLIST_TRAVERSE_SAFE_END;
@ -512,7 +518,7 @@ int ast_unregister_indication_country(const char *country)
/* Remove from the list */ /* Remove from the list */
AST_RWLIST_REMOVE_CURRENT(list); AST_RWLIST_REMOVE_CURRENT(list);
ast_verb(3, "Unregistered indication country '%s'\n", tz->country); ast_verb(3, "Unregistered indication country '%s'\n", tz->country);
free_zone(tz); ast_destroy_indication_zone(tz);
res = 0; res = 0;
} }
AST_RWLIST_TRAVERSE_SAFE_END; AST_RWLIST_TRAVERSE_SAFE_END;
@ -525,37 +531,39 @@ int ast_unregister_indication_country(const char *country)
* exists, it will be replaced. */ * exists, it will be replaced. */
int ast_register_indication(struct ind_tone_zone *zone, const char *indication, const char *tonelist) 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 */ /* is it an alias? stop */
if (zone->alias[0]) if (zone->alias[0])
return -1; return -1;
AST_RWLIST_WRLOCK(&tone_zones); AST_RWLIST_WRLOCK(&tone_zones);
for (ps=NULL,ts=zone->tones; ts; ps=ts,ts=ts->next) {
if (!strcasecmp(indication,ts->name)) { AST_LIST_TRAVERSE(&zone->tones, ts, list) {
/* indication already there, replace */ if (!strcasecmp(indication, ts->name)) {
ast_free((void*)ts->name); clear_zone_sound(ts);
ast_free((void*)ts->data); found = 1;
break; break;
} }
} }
if (!ts) { if (!ts) {
/* not there, we have to add */ /* not there, we have to add */
if (!(ts = ast_malloc(sizeof(*ts)))) { if (!(ts = ast_calloc(1, sizeof(*ts)))) {
AST_RWLIST_UNLOCK(&tone_zones); AST_RWLIST_UNLOCK(&tone_zones);
return -2; return -2;
} }
ts->next = NULL;
} }
if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) { if (!(ts->name = ast_strdup(indication)) || !(ts->data = ast_strdup(tonelist))) {
ast_free(ts);
AST_RWLIST_UNLOCK(&tone_zones); AST_RWLIST_UNLOCK(&tone_zones);
return -2; return -2;
} }
if (ps)
ps->next = ts; if (!found) {
else AST_LIST_INSERT_TAIL(&zone->tones, ts, list);
zone->tones = ts; }
AST_RWLIST_UNLOCK(&tone_zones); AST_RWLIST_UNLOCK(&tone_zones);
return 0; 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 */ /* remove an existing country's indication. Both country and indication must exist */
int ast_unregister_indication(struct ind_tone_zone *zone, const char *indication) 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; int res = -1;
/* is it an alias? stop */ /* is it an alias? stop */
@ -571,27 +579,18 @@ int ast_unregister_indication(struct ind_tone_zone *zone, const char *indication
return -1; return -1;
AST_RWLIST_WRLOCK(&tone_zones); AST_RWLIST_WRLOCK(&tone_zones);
ts = zone->tones;
while (ts) { AST_LIST_TRAVERSE_SAFE_BEGIN(&zone->tones, ts, list) {
if (!strcasecmp(indication,ts->name)) { if (!strcasecmp(indication, ts->name)) {
/* indication found */ AST_LIST_REMOVE_CURRENT(list);
tmp = ts->next; clear_zone_sound(ts);
if (ps)
ps->next = tmp;
else
zone->tones = tmp;
ast_free((void*)ts->name);
ast_free((void*)ts->data);
ast_free(ts); ast_free(ts);
ts = tmp;
res = 0; res = 0;
} break;
else {
/* next zone please */
ps = ts;
ts = ts->next;
} }
} }
AST_LIST_TRAVERSE_SAFE_END;
/* indication not found, goodbye */ /* indication not found, goodbye */
AST_RWLIST_UNLOCK(&tone_zones); AST_RWLIST_UNLOCK(&tone_zones);
return res; return res;

@ -216,7 +216,7 @@ static char *handle_cli_indication_show(struct ast_cli_entry *e, int cmd, struct
int i, j; int i, j;
for (i = 2; i < a->argc; i++) { for (i = 2; i < a->argc; i++) {
if (strcasecmp(tz->country, a->argv[i]) == 0 && !tz->alias[0]) { 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) { if (!found_country) {
found_country = 1; found_country = 1;
ast_cli(a->fd, "Country Indication PlayList\n"); ast_cli(a->fd, "Country Indication PlayList\n");
@ -230,8 +230,9 @@ static char *handle_cli_indication_show(struct ast_cli_entry *e, int cmd, struct
j--; j--;
ast_copy_string(buf + j, "\n", sizeof(buf) - j); ast_copy_string(buf + j, "\n", sizeof(buf) - j);
ast_cli(a->fd, "%s", buf); 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); ast_cli(a->fd, "%-7.7s %-15.15s %s\n", tz->country, ts->name, ts->data);
}
break; break;
} }
} }
@ -276,23 +277,6 @@ static int handle_stopplaytones(struct ast_channel *chan, void *data)
return 0; 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 */ /*! \brief load indications module */
static int ind_load_module(int reload) static int ind_load_module(int reload)
{ {
@ -347,7 +331,7 @@ static int ind_load_module(int reload)
} }
if (!(tmp = ast_realloc(tones->ringcadence, (tones->nrringcadence + 1) * sizeof(int)))) { if (!(tmp = ast_realloc(tones->ringcadence, (tones->nrringcadence + 1) * sizeof(int)))) {
ast_config_destroy(cfg); ast_config_destroy(cfg);
free_zone(tones); ast_destroy_indication_zone(tones);
return -1; return -1;
} }
tones->ringcadence = tmp; tones->ringcadence = tmp;
@ -364,50 +348,49 @@ static int ind_load_module(int reload)
struct ind_tone_zone* azone; struct ind_tone_zone* azone;
if (!(azone = ast_calloc(1, sizeof(*azone)))) { if (!(azone = ast_calloc(1, sizeof(*azone)))) {
ast_config_destroy(cfg); ast_config_destroy(cfg);
free_zone(tones); ast_destroy_indication_zone(tones);
return -1; return -1;
} }
ast_copy_string(azone->country, country, sizeof(azone->country)); ast_copy_string(azone->country, country, sizeof(azone->country));
ast_copy_string(azone->alias, cxt, sizeof(azone->alias)); ast_copy_string(azone->alias, cxt, sizeof(azone->alias));
if (ast_register_indication_country(azone)) { if (ast_register_indication_country(azone)) {
ast_log(LOG_WARNING, "Unable to register indication alias at line %d.\n",v->lineno); 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 */ /* next item */
country = strsep(&c,","); country = strsep(&c,",");
} }
} else { } else {
struct ind_tone_zone_sound *ts;
/* add tone to country */ /* add tone to country */
struct ind_tone_zone_sound *ps,*ts; AST_LIST_TRAVERSE(&tones->tones, ts, list) {
for (ps=NULL,ts=tones->tones; ts; ps=ts, ts=ts->next) { if (!strcasecmp(v->name, ts->name)) {
if (strcasecmp(v->name,ts->name)==0) {
/* already there */ /* 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; goto out;
} }
} }
/* not there, add it to the back */ /* not there, add it to the back */
if (!(ts = ast_malloc(sizeof(*ts)))) { if (!(ts = ast_calloc(1, sizeof(*ts)))) {
ast_config_destroy(cfg); ast_config_destroy(cfg);
return -1; return -1;
} }
ts->next = NULL;
ts->name = ast_strdup(v->name); ts->name = ast_strdup(v->name);
ts->data = ast_strdup(v->value); ts->data = ast_strdup(v->value);
if (ps)
ps->next = ts; AST_LIST_INSERT_TAIL(&tones->tones, ts, list);
else
tones->tones = ts;
} }
out: v = v->next; 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)) { if (ast_register_indication_country(tones)) {
ast_log(LOG_WARNING, "Unable to register indication at line %d.\n",v->lineno); ast_log(LOG_WARNING, "Unable to register indication at line %d.\n",v->lineno);
free_zone(tones); ast_destroy_indication_zone(tones);
} }
} else { } else {
free_zone(tones); ast_destroy_indication_zone(tones);
} }
cxt = ast_category_browse(cfg, cxt); cxt = ast_category_browse(cfg, cxt);

Loading…
Cancel
Save