From ff7a90829d623f89208e2f60402c3a321b8dbe35 Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Tue, 14 Feb 2006 22:44:20 +0000 Subject: more list macro conversion (issue #6361, plus documentation for new macro) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@10067 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- cli.c | 87 +++++++++++++++--------------------------- include/asterisk/cli.h | 6 ++- include/asterisk/linkedlists.h | 22 ++++++++++- 3 files changed, 55 insertions(+), 60 deletions(-) diff --git a/cli.c b/cli.c index fcdb41779..16b606eaa 100644 --- a/cli.c +++ b/cli.c @@ -1,7 +1,7 @@ /* * Asterisk -- An open source telephony toolkit. * - * Copyright (C) 1999 - 2005, Digium, Inc. + * Copyright (C) 1999 - 2006, Digium, Inc. * * Mark Spencer * @@ -77,9 +77,7 @@ void ast_cli(int fd, char *fmt, ...) } } -AST_MUTEX_DEFINE_STATIC(clilock); - -struct ast_cli_entry *helpers = NULL; +static AST_LIST_HEAD_STATIC(helpers, ast_cli_entry); static char load_help[] = "Usage: load \n" @@ -946,7 +944,7 @@ static struct ast_cli_entry *find_cli(char *const cmds[], int exact) int match; struct ast_cli_entry *e=NULL; - for (e=helpers;e;e=e->next) { + AST_LIST_TRAVERSE(&helpers, e, list) { match = 1; for (y=0;match && cmds[y]; y++) { if (!e->cmda[y] && !exact) @@ -1025,72 +1023,47 @@ static char *find_best(char *argv[]) int ast_cli_unregister(struct ast_cli_entry *e) { - struct ast_cli_entry *cur, *l=NULL; - ast_mutex_lock(&clilock); - cur = helpers; - while(cur) { - if (e == cur) { - if (e->inuse) { - ast_log(LOG_WARNING, "Can't remove command that is in use\n"); - } else { - /* Rewrite */ - if (l) - l->next = e->next; - else - helpers = e->next; - e->next = NULL; - break; - } - } - l = cur; - cur = cur->next; + if (e->inuse) { + ast_log(LOG_WARNING, "Can't remove command that is in use\n"); + } else { + AST_LIST_LOCK(&helpers); + AST_LIST_REMOVE(&helpers, e, list); + AST_LIST_UNLOCK(&helpers); } - ast_mutex_unlock(&clilock); return 0; } int ast_cli_register(struct ast_cli_entry *e) { - struct ast_cli_entry *cur, *l=NULL; + struct ast_cli_entry *cur; char fulle[80] ="", fulltst[80] =""; static int len; - ast_mutex_lock(&clilock); + AST_LIST_LOCK(&helpers); join2(fulle, sizeof(fulle), e->cmda); if (find_cli(e->cmda, -1)) { - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", fulle); return -1; } - for (cur = helpers; cur; cur = cur->next) { + AST_LIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) { join2(fulltst, sizeof(fulltst), cur->cmda); len = strlen(fulltst); if (strlen(fulle) < len) len = strlen(fulle); if (strncasecmp(fulle, fulltst, len) < 0) { - if (l) { - e->next = l->next; - l->next = e; - } else { - e->next = helpers; - helpers = e; - } + AST_LIST_INSERT_BEFORE_CURRENT(&helpers, e, list); break; } - l = cur; } + AST_LIST_TRAVERSE_SAFE_END; - if (!cur) { - if (l) - l->next = e; - else - helpers = e; - e->next = NULL; - } + if (!cur) + AST_LIST_INSERT_TAIL(&helpers, e, list); - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); return 0; } @@ -1122,7 +1095,7 @@ static int help_workhorse(int fd, char *match[]) char *fullcmd = NULL; struct ast_cli_entry *e, *e1, *e2; e1 = builtins; - e2 = helpers; + e2 = AST_LIST_FIRST(&helpers); if (match) join(matchstr, sizeof(matchstr), match, 0); while(e1->cmda[0] || e2) { @@ -1136,7 +1109,7 @@ static int help_workhorse(int fd, char *match[]) e = e2; fullcmd = fullcmd2; /* Increment by going to next */ - e2 = e2->next; + e2 = AST_LIST_NEXT(e2, list); } else { /* Use e1 */ e = e1; @@ -1322,9 +1295,9 @@ static char *__ast_cli_generator(const char *text, const char *word, int state, if ((dup = parse_args(text, &x, argv, sizeof(argv) / sizeof(argv[0]), &tws))) { join(matchstr, sizeof(matchstr), argv, tws); if (lock) - ast_mutex_lock(&clilock); + AST_LIST_LOCK(&helpers); e1 = builtins; - e2 = helpers; + e2 = AST_LIST_FIRST(&helpers); while(e1->cmda[0] || e2) { if (e2) join(fullcmd2, sizeof(fullcmd2), e2->cmda, tws); @@ -1336,7 +1309,7 @@ static char *__ast_cli_generator(const char *text, const char *word, int state, e = e2; fullcmd = fullcmd2; /* Increment by going to next */ - e2 = e2->next; + e2 = AST_LIST_NEXT(e2, list); } else { /* Use e1 */ e = e1; @@ -1355,7 +1328,7 @@ static char *__ast_cli_generator(const char *text, const char *word, int state, matchnum++; if (matchnum > state) { if (lock) - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); free(dup); return strdup(res); } @@ -1368,7 +1341,7 @@ static char *__ast_cli_generator(const char *text, const char *word, int state, fullcmd = e->generator(matchstr, word, (!ast_strlen_zero(word) ? (x - 1) : (x)), state); if (fullcmd) { if (lock) - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); free(dup); return fullcmd; } @@ -1376,7 +1349,7 @@ static char *__ast_cli_generator(const char *text, const char *word, int state, } if (lock) - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); free(dup); } return NULL; @@ -1402,11 +1375,11 @@ int ast_cli_command(int fd, const char *s) /* We need at least one entry, or ignore */ if (x > 0) { - ast_mutex_lock(&clilock); + AST_LIST_LOCK(&helpers); e = find_cli(argv, 0); if (e) e->inuse++; - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); if (e) { switch(e->handler(fd, x, argv)) { case RESULT_SHOWUSAGE: @@ -1416,9 +1389,9 @@ int ast_cli_command(int fd, const char *s) } else ast_cli(fd, "No such command '%s' (type 'help' for help)\n", find_best(argv)); if (e) { - ast_mutex_lock(&clilock); + AST_LIST_LOCK(&helpers); e->inuse--; - ast_mutex_unlock(&clilock); + AST_LIST_UNLOCK(&helpers); } } free(dup); diff --git a/include/asterisk/cli.h b/include/asterisk/cli.h index f5bb10070..884d4c166 100644 --- a/include/asterisk/cli.h +++ b/include/asterisk/cli.h @@ -29,6 +29,8 @@ extern "C" { #include +#include "asterisk/linkedlists.h" + void ast_cli(int fd, char *fmt, ...) __attribute__ ((format (printf, 2, 3))); @@ -67,10 +69,10 @@ struct ast_cli_entry { until a NULL is returned. */ char *(*generator)(const char *line, const char *word, int pos, int n); - /*! For linking */ - struct ast_cli_entry *next; /*! For keeping track of usage */ int inuse; + /*! For linking */ + AST_LIST_ENTRY(ast_cli_entry) list; }; diff --git a/include/asterisk/linkedlists.h b/include/asterisk/linkedlists.h index 2d73f8258..4f60366d5 100644 --- a/include/asterisk/linkedlists.h +++ b/include/asterisk/linkedlists.h @@ -1,7 +1,7 @@ /* * Asterisk -- An open source telephony toolkit. * - * Copyright (C) 1999 - 2005, Digium, Inc. + * Copyright (C) 1999 - 2006, Digium, Inc. * * Mark Spencer * Kevin P. Fleming @@ -313,6 +313,26 @@ struct { \ if (!__list_next) \ (head)->last = __list_prev; +/*! + \brief Inserts a list entry before the current entry during a traversal. + \param head This is a pointer to the list head structure + \param elm This is a pointer to the entry to be inserted. + \param field This is the name of the field (declared using AST_LIST_ENTRY()) + used to link entries of this list together. + + \note This macro can \b only be used inside an AST_LIST_TRAVERSE_SAFE_BEGIN() + block. + */ +#define AST_LIST_INSERT_BEFORE_CURRENT(head, elm, field) do { \ + if (__list_prev) { \ + (elm)->field.next = __list_prev->field.next; \ + __list_prev->field.next = elm; \ + } else { \ + (elm)->field.next = (head)->first; \ + (head)->first = (elm); \ + } \ +} while (0) + /*! \brief Closes a safe loop traversal block. */ -- cgit v1.2.3