more list macro conversion (issue #6361, plus documentation for new macro)
authorKevin P. Fleming <kpfleming@digium.com>
Tue, 14 Feb 2006 22:44:20 +0000 (22:44 +0000)
committerKevin P. Fleming <kpfleming@digium.com>
Tue, 14 Feb 2006 22:44:20 +0000 (22:44 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@10067 65c4cc65-6c06-0410-ace0-fbb531ad65f3

cli.c
include/asterisk/cli.h
include/asterisk/linkedlists.h

diff --git a/cli.c b/cli.c
index fcdb417..16b606e 100644 (file)
--- 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 <markster@digium.com>
  *
@@ -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 <module name>\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);
index f5bb100..884d4c1 100644 (file)
@@ -29,6 +29,8 @@ extern "C" {
 
 #include <stdarg.h>
 
+#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;
 };
 
 
index 2d73f82..4f60366 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Asterisk -- An open source telephony toolkit.
  *
- * Copyright (C) 1999 - 2005, Digium, Inc.
+ * Copyright (C) 1999 - 2006, Digium, Inc.
  *
  * Mark Spencer <markster@digium.com>
  * Kevin P. Fleming <kpfleming@digium.com>
@@ -314,6 +314,26 @@ struct {                                                           \
                (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.
  */
 #define AST_LIST_TRAVERSE_SAFE_END  }