mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-08 19:08:14 +00:00
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
This commit is contained in:
87
cli.c
87
cli.c
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Asterisk -- An open source telephony toolkit.
|
* Asterisk -- An open source telephony toolkit.
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999 - 2005, Digium, Inc.
|
* Copyright (C) 1999 - 2006, Digium, Inc.
|
||||||
*
|
*
|
||||||
* Mark Spencer <markster@digium.com>
|
* Mark Spencer <markster@digium.com>
|
||||||
*
|
*
|
||||||
@@ -77,9 +77,7 @@ void ast_cli(int fd, char *fmt, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AST_MUTEX_DEFINE_STATIC(clilock);
|
static AST_LIST_HEAD_STATIC(helpers, ast_cli_entry);
|
||||||
|
|
||||||
struct ast_cli_entry *helpers = NULL;
|
|
||||||
|
|
||||||
static char load_help[] =
|
static char load_help[] =
|
||||||
"Usage: load <module name>\n"
|
"Usage: load <module name>\n"
|
||||||
@@ -946,7 +944,7 @@ static struct ast_cli_entry *find_cli(char *const cmds[], int exact)
|
|||||||
int match;
|
int match;
|
||||||
struct ast_cli_entry *e=NULL;
|
struct ast_cli_entry *e=NULL;
|
||||||
|
|
||||||
for (e=helpers;e;e=e->next) {
|
AST_LIST_TRAVERSE(&helpers, e, list) {
|
||||||
match = 1;
|
match = 1;
|
||||||
for (y=0;match && cmds[y]; y++) {
|
for (y=0;match && cmds[y]; y++) {
|
||||||
if (!e->cmda[y] && !exact)
|
if (!e->cmda[y] && !exact)
|
||||||
@@ -1025,72 +1023,47 @@ static char *find_best(char *argv[])
|
|||||||
|
|
||||||
int ast_cli_unregister(struct ast_cli_entry *e)
|
int ast_cli_unregister(struct ast_cli_entry *e)
|
||||||
{
|
{
|
||||||
struct ast_cli_entry *cur, *l=NULL;
|
if (e->inuse) {
|
||||||
ast_mutex_lock(&clilock);
|
ast_log(LOG_WARNING, "Can't remove command that is in use\n");
|
||||||
cur = helpers;
|
} else {
|
||||||
while(cur) {
|
AST_LIST_LOCK(&helpers);
|
||||||
if (e == cur) {
|
AST_LIST_REMOVE(&helpers, e, list);
|
||||||
if (e->inuse) {
|
AST_LIST_UNLOCK(&helpers);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
ast_mutex_unlock(&clilock);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ast_cli_register(struct ast_cli_entry *e)
|
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] ="";
|
char fulle[80] ="", fulltst[80] ="";
|
||||||
static int len;
|
static int len;
|
||||||
|
|
||||||
ast_mutex_lock(&clilock);
|
AST_LIST_LOCK(&helpers);
|
||||||
join2(fulle, sizeof(fulle), e->cmda);
|
join2(fulle, sizeof(fulle), e->cmda);
|
||||||
|
|
||||||
if (find_cli(e->cmda, -1)) {
|
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);
|
ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", fulle);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (cur = helpers; cur; cur = cur->next) {
|
AST_LIST_TRAVERSE_SAFE_BEGIN(&helpers, cur, list) {
|
||||||
join2(fulltst, sizeof(fulltst), cur->cmda);
|
join2(fulltst, sizeof(fulltst), cur->cmda);
|
||||||
len = strlen(fulltst);
|
len = strlen(fulltst);
|
||||||
if (strlen(fulle) < len)
|
if (strlen(fulle) < len)
|
||||||
len = strlen(fulle);
|
len = strlen(fulle);
|
||||||
if (strncasecmp(fulle, fulltst, len) < 0) {
|
if (strncasecmp(fulle, fulltst, len) < 0) {
|
||||||
if (l) {
|
AST_LIST_INSERT_BEFORE_CURRENT(&helpers, e, list);
|
||||||
e->next = l->next;
|
|
||||||
l->next = e;
|
|
||||||
} else {
|
|
||||||
e->next = helpers;
|
|
||||||
helpers = e;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
l = cur;
|
|
||||||
}
|
}
|
||||||
|
AST_LIST_TRAVERSE_SAFE_END;
|
||||||
|
|
||||||
if (!cur) {
|
if (!cur)
|
||||||
if (l)
|
AST_LIST_INSERT_TAIL(&helpers, e, list);
|
||||||
l->next = e;
|
|
||||||
else
|
|
||||||
helpers = e;
|
|
||||||
e->next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ast_mutex_unlock(&clilock);
|
AST_LIST_UNLOCK(&helpers);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1122,7 +1095,7 @@ static int help_workhorse(int fd, char *match[])
|
|||||||
char *fullcmd = NULL;
|
char *fullcmd = NULL;
|
||||||
struct ast_cli_entry *e, *e1, *e2;
|
struct ast_cli_entry *e, *e1, *e2;
|
||||||
e1 = builtins;
|
e1 = builtins;
|
||||||
e2 = helpers;
|
e2 = AST_LIST_FIRST(&helpers);
|
||||||
if (match)
|
if (match)
|
||||||
join(matchstr, sizeof(matchstr), match, 0);
|
join(matchstr, sizeof(matchstr), match, 0);
|
||||||
while(e1->cmda[0] || e2) {
|
while(e1->cmda[0] || e2) {
|
||||||
@@ -1136,7 +1109,7 @@ static int help_workhorse(int fd, char *match[])
|
|||||||
e = e2;
|
e = e2;
|
||||||
fullcmd = fullcmd2;
|
fullcmd = fullcmd2;
|
||||||
/* Increment by going to next */
|
/* Increment by going to next */
|
||||||
e2 = e2->next;
|
e2 = AST_LIST_NEXT(e2, list);
|
||||||
} else {
|
} else {
|
||||||
/* Use e1 */
|
/* Use e1 */
|
||||||
e = 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))) {
|
if ((dup = parse_args(text, &x, argv, sizeof(argv) / sizeof(argv[0]), &tws))) {
|
||||||
join(matchstr, sizeof(matchstr), argv, tws);
|
join(matchstr, sizeof(matchstr), argv, tws);
|
||||||
if (lock)
|
if (lock)
|
||||||
ast_mutex_lock(&clilock);
|
AST_LIST_LOCK(&helpers);
|
||||||
e1 = builtins;
|
e1 = builtins;
|
||||||
e2 = helpers;
|
e2 = AST_LIST_FIRST(&helpers);
|
||||||
while(e1->cmda[0] || e2) {
|
while(e1->cmda[0] || e2) {
|
||||||
if (e2)
|
if (e2)
|
||||||
join(fullcmd2, sizeof(fullcmd2), e2->cmda, tws);
|
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;
|
e = e2;
|
||||||
fullcmd = fullcmd2;
|
fullcmd = fullcmd2;
|
||||||
/* Increment by going to next */
|
/* Increment by going to next */
|
||||||
e2 = e2->next;
|
e2 = AST_LIST_NEXT(e2, list);
|
||||||
} else {
|
} else {
|
||||||
/* Use e1 */
|
/* Use e1 */
|
||||||
e = e1;
|
e = e1;
|
||||||
@@ -1355,7 +1328,7 @@ static char *__ast_cli_generator(const char *text, const char *word, int state,
|
|||||||
matchnum++;
|
matchnum++;
|
||||||
if (matchnum > state) {
|
if (matchnum > state) {
|
||||||
if (lock)
|
if (lock)
|
||||||
ast_mutex_unlock(&clilock);
|
AST_LIST_UNLOCK(&helpers);
|
||||||
free(dup);
|
free(dup);
|
||||||
return strdup(res);
|
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);
|
fullcmd = e->generator(matchstr, word, (!ast_strlen_zero(word) ? (x - 1) : (x)), state);
|
||||||
if (fullcmd) {
|
if (fullcmd) {
|
||||||
if (lock)
|
if (lock)
|
||||||
ast_mutex_unlock(&clilock);
|
AST_LIST_UNLOCK(&helpers);
|
||||||
free(dup);
|
free(dup);
|
||||||
return fullcmd;
|
return fullcmd;
|
||||||
}
|
}
|
||||||
@@ -1376,7 +1349,7 @@ static char *__ast_cli_generator(const char *text, const char *word, int state,
|
|||||||
|
|
||||||
}
|
}
|
||||||
if (lock)
|
if (lock)
|
||||||
ast_mutex_unlock(&clilock);
|
AST_LIST_UNLOCK(&helpers);
|
||||||
free(dup);
|
free(dup);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1402,11 +1375,11 @@ int ast_cli_command(int fd, const char *s)
|
|||||||
|
|
||||||
/* We need at least one entry, or ignore */
|
/* We need at least one entry, or ignore */
|
||||||
if (x > 0) {
|
if (x > 0) {
|
||||||
ast_mutex_lock(&clilock);
|
AST_LIST_LOCK(&helpers);
|
||||||
e = find_cli(argv, 0);
|
e = find_cli(argv, 0);
|
||||||
if (e)
|
if (e)
|
||||||
e->inuse++;
|
e->inuse++;
|
||||||
ast_mutex_unlock(&clilock);
|
AST_LIST_UNLOCK(&helpers);
|
||||||
if (e) {
|
if (e) {
|
||||||
switch(e->handler(fd, x, argv)) {
|
switch(e->handler(fd, x, argv)) {
|
||||||
case RESULT_SHOWUSAGE:
|
case RESULT_SHOWUSAGE:
|
||||||
@@ -1416,9 +1389,9 @@ int ast_cli_command(int fd, const char *s)
|
|||||||
} else
|
} else
|
||||||
ast_cli(fd, "No such command '%s' (type 'help' for help)\n", find_best(argv));
|
ast_cli(fd, "No such command '%s' (type 'help' for help)\n", find_best(argv));
|
||||||
if (e) {
|
if (e) {
|
||||||
ast_mutex_lock(&clilock);
|
AST_LIST_LOCK(&helpers);
|
||||||
e->inuse--;
|
e->inuse--;
|
||||||
ast_mutex_unlock(&clilock);
|
AST_LIST_UNLOCK(&helpers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(dup);
|
free(dup);
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ extern "C" {
|
|||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "asterisk/linkedlists.h"
|
||||||
|
|
||||||
void ast_cli(int fd, char *fmt, ...)
|
void ast_cli(int fd, char *fmt, ...)
|
||||||
__attribute__ ((format (printf, 2, 3)));
|
__attribute__ ((format (printf, 2, 3)));
|
||||||
|
|
||||||
@@ -67,10 +69,10 @@ struct ast_cli_entry {
|
|||||||
until a NULL is returned.
|
until a NULL is returned.
|
||||||
*/
|
*/
|
||||||
char *(*generator)(const char *line, const char *word, int pos, int n);
|
char *(*generator)(const char *line, const char *word, int pos, int n);
|
||||||
/*! For linking */
|
|
||||||
struct ast_cli_entry *next;
|
|
||||||
/*! For keeping track of usage */
|
/*! For keeping track of usage */
|
||||||
int inuse;
|
int inuse;
|
||||||
|
/*! For linking */
|
||||||
|
AST_LIST_ENTRY(ast_cli_entry) list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Asterisk -- An open source telephony toolkit.
|
* Asterisk -- An open source telephony toolkit.
|
||||||
*
|
*
|
||||||
* Copyright (C) 1999 - 2005, Digium, Inc.
|
* Copyright (C) 1999 - 2006, Digium, Inc.
|
||||||
*
|
*
|
||||||
* Mark Spencer <markster@digium.com>
|
* Mark Spencer <markster@digium.com>
|
||||||
* Kevin P. Fleming <kpfleming@digium.com>
|
* Kevin P. Fleming <kpfleming@digium.com>
|
||||||
@@ -313,6 +313,26 @@ struct { \
|
|||||||
if (!__list_next) \
|
if (!__list_next) \
|
||||||
(head)->last = __list_prev;
|
(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.
|
\brief Closes a safe loop traversal block.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user