mirror of
https://github.com/irssi/irssi.git
synced 2026-08-11 04:43:34 +02:00
Changed option handling in /commands. Irssi will now complain about
unknown options and missing option arguments. Renamed /SERVER -add, -remove and -list to /SERVER ADD, REMOVE and LIST. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@365 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
ca4226cca6
commit
a5d31a195d
34 changed files with 949 additions and 576 deletions
|
|
@ -66,6 +66,7 @@ void command_free(COMMAND_REC *rec)
|
|||
signal_emit("commandlist remove", 1, rec);
|
||||
|
||||
g_free_not_null(rec->category);
|
||||
g_strfreev(rec->options);
|
||||
g_free(rec->cmd);
|
||||
g_free(rec);
|
||||
}
|
||||
|
|
@ -93,7 +94,7 @@ void command_unbind(const char *cmd, SIGNAL_FUNC func)
|
|||
}
|
||||
}
|
||||
|
||||
void command_runsub(const char *cmd, const char *data, void *p1, void *p2)
|
||||
void command_runsub(const char *cmd, const char *data, void *server, void *item)
|
||||
{
|
||||
char *subcmd, *defcmd, *args;
|
||||
|
||||
|
|
@ -106,30 +107,101 @@ void command_runsub(const char *cmd, const char *data, void *p1, void *p2)
|
|||
while (*args == ' ') args++;
|
||||
|
||||
g_strdown(subcmd);
|
||||
if (!signal_emit(subcmd, 3, args, p1, p2)) {
|
||||
if (!signal_emit(subcmd, 3, args, server, item)) {
|
||||
defcmd = g_strdup_printf("default command %s", cmd);
|
||||
if (!signal_emit(defcmd, 3, data, p1, p2))
|
||||
signal_emit("unknown command", 3, strchr(subcmd, ' ')+1, p1, p2);
|
||||
if (!signal_emit(defcmd, 3, data, server, item))
|
||||
signal_emit("unknown command", 3, strchr(subcmd, ' ')+1, server, item);
|
||||
g_free(defcmd);
|
||||
}
|
||||
g_free(subcmd);
|
||||
}
|
||||
|
||||
COMMAND_REC *command_find(const char *command)
|
||||
COMMAND_REC *command_find(const char *cmd)
|
||||
{
|
||||
GSList *tmp;
|
||||
int len;
|
||||
|
||||
g_return_val_if_fail(cmd != NULL, NULL);
|
||||
|
||||
for (tmp = commands; tmp != NULL; tmp = tmp->next) {
|
||||
COMMAND_REC *rec = tmp->data;
|
||||
|
||||
if (g_strcasecmp(rec->cmd, command) == 0)
|
||||
if (g_strcasecmp(rec->cmd, cmd) == 0)
|
||||
return rec;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define iscmdtype(c) \
|
||||
((c) == '-' || (c) == '+' || (c) == '@')
|
||||
|
||||
static GSList *optlist_find(GSList *optlist, const char *option)
|
||||
{
|
||||
while (optlist != NULL) {
|
||||
char *name = optlist->data;
|
||||
if (iscmdtype(*name)) name++;
|
||||
|
||||
if (g_strcasecmp(name, option) == 0)
|
||||
return optlist;
|
||||
|
||||
optlist = optlist->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void command_set_options(const char *cmd, const char *options)
|
||||
{
|
||||
COMMAND_REC *rec;
|
||||
char **optlist, **tmp, *name, *str;
|
||||
GSList *list, *oldopt;
|
||||
|
||||
g_return_if_fail(cmd != NULL);
|
||||
g_return_if_fail(options != NULL);
|
||||
|
||||
rec = command_find(cmd);
|
||||
g_return_if_fail(rec != NULL);
|
||||
|
||||
optlist = g_strsplit(options, " ", -1);
|
||||
|
||||
if (rec->options == NULL) {
|
||||
/* first call - use specified args directly */
|
||||
rec->options = optlist;
|
||||
return;
|
||||
}
|
||||
|
||||
/* save old options to linked list */
|
||||
list = NULL;
|
||||
for (tmp = rec->options; *tmp != NULL; tmp++)
|
||||
list = g_slist_append(list, g_strdup(*tmp));
|
||||
g_strfreev(rec->options);
|
||||
|
||||
/* merge the options */
|
||||
for (tmp = optlist; *tmp != NULL; tmp++) {
|
||||
name = iscmdtype(**tmp) ? (*tmp)+1 : *tmp;
|
||||
|
||||
oldopt = optlist_find(list, name);
|
||||
if (oldopt != NULL) {
|
||||
/* already specified - overwrite old defination */
|
||||
g_free(oldopt->data);
|
||||
oldopt->data = g_strdup(*tmp);
|
||||
} else {
|
||||
/* new option, append to list */
|
||||
list = g_slist_append(list, g_strdup(*tmp));
|
||||
}
|
||||
}
|
||||
g_strfreev(optlist);
|
||||
|
||||
/* linked list -> string[] */
|
||||
g_free(rec->options);
|
||||
str = gslist_to_string(list, " ");
|
||||
rec->options = g_strsplit(str, " ", -1);
|
||||
g_free(str);
|
||||
|
||||
g_slist_foreach(list, (GFunc) g_free, NULL);
|
||||
g_slist_free(list);
|
||||
}
|
||||
|
||||
char *cmd_get_param(char **data)
|
||||
{
|
||||
char *pos;
|
||||
|
|
@ -146,7 +218,7 @@ char *cmd_get_param(char **data)
|
|||
return pos;
|
||||
}
|
||||
|
||||
char *cmd_get_quoted_param(char **data)
|
||||
static char *cmd_get_quoted_param(char **data)
|
||||
{
|
||||
char *pos, quote;
|
||||
|
||||
|
|
@ -171,67 +243,7 @@ char *cmd_get_quoted_param(char **data)
|
|||
return pos;
|
||||
}
|
||||
|
||||
static char *get_opt_args(char **data)
|
||||
{
|
||||
/* -cmd1 -cmd2 -cmd3 ... */
|
||||
char *p, *ret;
|
||||
int stopnext;
|
||||
|
||||
g_return_val_if_fail(data != NULL, NULL);
|
||||
g_return_val_if_fail(*data != NULL, NULL);
|
||||
|
||||
stopnext = FALSE;
|
||||
ret = NULL;
|
||||
for (p = *data;;) {
|
||||
if (*p != '-' || stopnext) {
|
||||
if (p == *data) return "";
|
||||
|
||||
ret = *data;
|
||||
*data = p;
|
||||
|
||||
while (isspace(p[-1]) && p > ret) p--;
|
||||
if (*p != '\0') *p = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (p[1] == '-') {
|
||||
/* -- argument means end of arguments even if
|
||||
next word starts with - */
|
||||
stopnext = TRUE;
|
||||
}
|
||||
|
||||
while (!isspace(*p) && *p != '\0') p++;
|
||||
while (isspace(*p)) p++;
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_params_pack(char ***subargs, char *end, char *start, char *newstart)
|
||||
{
|
||||
char ***tmp;
|
||||
char *data;
|
||||
int bufsize, datalen, len;
|
||||
|
||||
bufsize = (int) (end-newstart)+1;
|
||||
|
||||
data = g_malloc(bufsize); datalen = 0;
|
||||
for (tmp = subargs; *tmp != NULL; tmp++) {
|
||||
if (**tmp < start || **tmp > end)
|
||||
continue;
|
||||
|
||||
len = strlen(**tmp)+1;
|
||||
if (datalen+len > bufsize)
|
||||
g_error("cmd_params_pack() : buffer overflow!");
|
||||
|
||||
memcpy(data+datalen, **tmp, len);
|
||||
**tmp = newstart+datalen;
|
||||
datalen += len;
|
||||
}
|
||||
|
||||
g_memmove(newstart, data, datalen);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
int arg_find(char **array, const char *item)
|
||||
static int option_find(char **array, const char *item)
|
||||
{
|
||||
char **tmp;
|
||||
int index;
|
||||
|
|
@ -241,101 +253,83 @@ int arg_find(char **array, const char *item)
|
|||
|
||||
index = 0;
|
||||
for (tmp = array; *tmp != NULL; tmp++, index++) {
|
||||
if (g_strcasecmp(*tmp + (**tmp == '@'), item) == 0)
|
||||
if (g_strcasecmp(*tmp + iscmdtype(**tmp), item) == 0)
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int get_multi_args(char **data, int checkonly, va_list va)
|
||||
static int get_cmd_options(char **data, int ignore_unknown,
|
||||
const char *cmd, GHashTable *options)
|
||||
{
|
||||
/* -cmd1 arg1 -cmd2 "argument two" -cmd3 */
|
||||
GString *returnargs;
|
||||
char **args, **arglist, *arg, *origdata;
|
||||
char **nextarg, ***subargs;
|
||||
int eat, pos;
|
||||
COMMAND_REC *rec;
|
||||
char *option, *arg, **optlist;
|
||||
int pos;
|
||||
|
||||
eat = 0;
|
||||
args = (char **) va_arg(va, char **);
|
||||
g_return_val_if_fail(args != NULL && *args != NULL && **args != '\0', 0);
|
||||
/* get option definations */
|
||||
rec = cmd == NULL ? NULL : command_find(cmd);
|
||||
optlist = rec == NULL ? NULL : rec->options;
|
||||
|
||||
arglist = g_strsplit(*args, " ", -1);
|
||||
eat = strarray_length(arglist);
|
||||
|
||||
subargs = g_new(char **, eat+1);
|
||||
for (pos = 0; pos < eat; pos++) {
|
||||
subargs[pos] = (char **) va_arg(va, char **);
|
||||
if (subargs[pos] == NULL) {
|
||||
g_free(subargs);
|
||||
g_warning("get_multi_args() : subargument == NULL");
|
||||
return eat;
|
||||
}
|
||||
*subargs[pos] = "";
|
||||
}
|
||||
subargs[eat] = NULL;
|
||||
|
||||
origdata = *data;
|
||||
returnargs = g_string_new(NULL);
|
||||
nextarg = NULL;
|
||||
option = NULL; pos = -1;
|
||||
for (;;) {
|
||||
if (**data == '-') {
|
||||
if (option != NULL && *optlist[pos] == '+') {
|
||||
/* required argument missing! */
|
||||
*data = optlist[pos] + 1;
|
||||
return CMDERR_OPTION_ARG_MISSING;
|
||||
}
|
||||
|
||||
(*data)++;
|
||||
if (**data == '-') {
|
||||
/* -- argument means end of arguments even
|
||||
/* -- option means end of options even
|
||||
if next word starts with - */
|
||||
(*data)++;
|
||||
while (isspace(**data)) (*data)++;
|
||||
break;
|
||||
}
|
||||
|
||||
arg = cmd_get_param(data);
|
||||
g_string_sprintfa(returnargs, "-%s ", arg);
|
||||
option = cmd_get_param(data);
|
||||
|
||||
/* check if this argument can have parameter */
|
||||
pos = arg_find(arglist, arg);
|
||||
nextarg = pos == -1 ? NULL : subargs[pos];
|
||||
/* check if this option can have argument */
|
||||
pos = optlist == NULL ? -1 : option_find(optlist, option);
|
||||
if (pos == -1 && !ignore_unknown) {
|
||||
/* unknown option! */
|
||||
*data = option;
|
||||
return CMDERR_OPTION_UNKNOWN;
|
||||
}
|
||||
if (pos != -1) {
|
||||
/* if we used a shortcut of parameter, put
|
||||
the whole parameter name in options table */
|
||||
option = optlist[pos] + iscmdtype(*optlist[pos]);
|
||||
}
|
||||
if (options != NULL) g_hash_table_insert(options, option, "");
|
||||
|
||||
if (pos == -1 || !iscmdtype(*optlist[pos]))
|
||||
option = NULL;
|
||||
|
||||
while (isspace(**data)) (*data)++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nextarg == NULL)
|
||||
if (option == NULL)
|
||||
break;
|
||||
|
||||
if (*arglist[pos] == '@' && !isdigit(**data))
|
||||
if (*optlist[pos] == '@' && !isdigit(**data))
|
||||
break; /* expected a numeric argument */
|
||||
|
||||
/* save the sub-argument to `nextarg' */
|
||||
/* save the argument */
|
||||
arg = cmd_get_quoted_param(data);
|
||||
*nextarg = arg; nextarg = NULL;
|
||||
if (options != NULL) {
|
||||
g_hash_table_remove(options, option);
|
||||
g_hash_table_insert(options, option, arg);
|
||||
}
|
||||
option = NULL;
|
||||
|
||||
while (isspace(**data)) (*data)++;
|
||||
}
|
||||
|
||||
if (!checkonly) {
|
||||
/* ok, this is a bit stupid. this will pack the arguments in
|
||||
`data' like "-arg1 subarg -arg2 sub2\0" ->
|
||||
"-arg1 -arg2\0subarg\0sub2\0" this is because it's easier
|
||||
to free only _one_ string instead of two (`args') when
|
||||
using PARAM_FLAG_MULTIARGS. */
|
||||
if (returnargs->len == 0)
|
||||
*args = "";
|
||||
else {
|
||||
cmd_params_pack(subargs, **data == '\0' ? *data : (*data)-1,
|
||||
origdata, origdata+returnargs->len);
|
||||
|
||||
g_string_truncate(returnargs, returnargs->len-1);
|
||||
strcpy(origdata, returnargs->str);
|
||||
*args = origdata;
|
||||
}
|
||||
}
|
||||
|
||||
g_string_free(returnargs, TRUE);
|
||||
g_strfreev(arglist);
|
||||
g_free(subargs);
|
||||
|
||||
return eat;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *cmd_get_callfuncs(const char *data, int *count, va_list *args)
|
||||
|
|
@ -356,34 +350,38 @@ char *cmd_get_callfuncs(const char *data, int *count, va_list *args)
|
|||
return ret;
|
||||
}
|
||||
|
||||
char *cmd_get_params(const char *data, int count, ...)
|
||||
typedef struct {
|
||||
char *data;
|
||||
GHashTable *options;
|
||||
} CMD_TEMP_REC;
|
||||
|
||||
int cmd_get_params(const char *data, gpointer *free_me, int count, ...)
|
||||
{
|
||||
CMD_TEMP_REC *rec;
|
||||
GHashTable **opthash;
|
||||
char **str, *arg, *datad, *old;
|
||||
va_list args;
|
||||
int cnt, eat, len;
|
||||
int cnt, error, len;
|
||||
|
||||
g_return_val_if_fail(data != NULL, NULL);
|
||||
g_return_val_if_fail(data != NULL, FALSE);
|
||||
|
||||
va_start(args, count);
|
||||
|
||||
/* get the length of the arguments in string */
|
||||
if ((count & (PARAM_FLAG_MULTIARGS|PARAM_FLAG_OPTARGS)) == 0)
|
||||
/* get the length of the options in string */
|
||||
if ((count & PARAM_FLAG_OPTIONS) == 0)
|
||||
len = 0;
|
||||
else {
|
||||
old = datad = g_strdup(data);
|
||||
if (count & PARAM_FLAG_MULTIARGS)
|
||||
get_multi_args(&datad, TRUE, args);
|
||||
else
|
||||
get_opt_args(&datad);
|
||||
get_cmd_options(&datad, TRUE, NULL, NULL);
|
||||
len = (int) (datad-old);
|
||||
g_free(old);
|
||||
}
|
||||
|
||||
/* send the text to custom functions to handle - skip arguments */
|
||||
/* send the text to custom functions to handle - skip options */
|
||||
old = datad = cmd_get_callfuncs(data+len, &count, &args);
|
||||
|
||||
if (len > 0) {
|
||||
/* put the arguments + the new data to one string */
|
||||
/* put the options + the new data to one string */
|
||||
datad = g_malloc(len+1 + strlen(old)+1);
|
||||
memcpy(datad, data, len);
|
||||
datad[len] = ' ';
|
||||
|
|
@ -393,20 +391,25 @@ char *cmd_get_params(const char *data, int count, ...)
|
|||
old = datad;
|
||||
}
|
||||
|
||||
rec = g_new0(CMD_TEMP_REC, 1);
|
||||
rec->data = old;
|
||||
*free_me = rec;
|
||||
|
||||
/* and now handle the string */
|
||||
error = FALSE;
|
||||
cnt = PARAM_WITHOUT_FLAGS(count);
|
||||
while (cnt-- > 0) {
|
||||
if (count & PARAM_FLAG_MULTIARGS) {
|
||||
eat = get_multi_args(&datad, FALSE, args)+1;
|
||||
count &= ~PARAM_FLAG_MULTIARGS;
|
||||
if (count & PARAM_FLAG_OPTIONS) {
|
||||
arg = (char *) va_arg(args, char *);
|
||||
opthash = (GHashTable **) va_arg(args, GHashTable **);
|
||||
|
||||
cnt -= eat-1;
|
||||
while (eat-- > 0)
|
||||
str = (char **) va_arg(args, char **);
|
||||
rec->options = *opthash = g_hash_table_new((GHashFunc) g_istr_hash, (GCompareFunc) g_istr_equal);
|
||||
error = get_cmd_options(&datad, count & PARAM_FLAG_UNKNOWN_OPTIONS, arg, *opthash);
|
||||
if (error) break;
|
||||
|
||||
count &= ~PARAM_FLAG_OPTIONS;
|
||||
cnt++;
|
||||
continue;
|
||||
} else if (count & PARAM_FLAG_OPTARGS) {
|
||||
arg = get_opt_args(&datad);
|
||||
count &= ~PARAM_FLAG_OPTARGS;
|
||||
} else if (cnt == 0 && count & PARAM_FLAG_GETREST) {
|
||||
/* get rest */
|
||||
arg = datad;
|
||||
|
|
@ -421,7 +424,24 @@ char *cmd_get_params(const char *data, int count, ...)
|
|||
}
|
||||
va_end(args);
|
||||
|
||||
return old;
|
||||
if (error) {
|
||||
signal_emit("error command", 2, GINT_TO_POINTER(error), datad);
|
||||
signal_stop();
|
||||
|
||||
cmd_params_free(rec);
|
||||
*free_me = NULL;
|
||||
}
|
||||
|
||||
return !error;
|
||||
}
|
||||
|
||||
void cmd_params_free(void *free_me)
|
||||
{
|
||||
CMD_TEMP_REC *rec = free_me;
|
||||
|
||||
if (rec->options != NULL) g_hash_table_destroy(rec->options);
|
||||
g_free(rec->data);
|
||||
g_free(rec);
|
||||
}
|
||||
|
||||
void cmd_get_add_func(CMD_GET_FUNC func)
|
||||
|
|
|
|||
|
|
@ -6,10 +6,13 @@
|
|||
typedef struct {
|
||||
char *category;
|
||||
char *cmd;
|
||||
}
|
||||
COMMAND_REC;
|
||||
char **options;
|
||||
} COMMAND_REC;
|
||||
|
||||
enum {
|
||||
CMDERR_OPTION_UNKNOWN = -2, /* unknown -option */
|
||||
CMDERR_OPTION_ARG_MISSING = -1, /* argument missing for -option */
|
||||
|
||||
CMDERR_ERRNO, /* get the error from errno */
|
||||
CMDERR_NOT_ENOUGH_PARAMS, /* not enough parameters given */
|
||||
CMDERR_NOT_CONNECTED, /* not connected to IRC server */
|
||||
|
|
@ -20,7 +23,7 @@ enum {
|
|||
};
|
||||
|
||||
#define cmd_return_error(a) { signal_emit("error command", 1, GINT_TO_POINTER(a)); signal_stop(); return; }
|
||||
#define cmd_param_error(a) { g_free(params); cmd_return_error(a); }
|
||||
#define cmd_param_error(a) { cmd_params_free(free_arg); cmd_return_error(a); }
|
||||
|
||||
extern GSList *commands;
|
||||
extern char *current_command;
|
||||
|
|
@ -29,12 +32,29 @@ void command_bind_to(int pos, const char *cmd, const char *category, SIGNAL_FUNC
|
|||
#define command_bind(a, b, c) command_bind_to(1, a, b, c)
|
||||
#define command_bind_first(a, b, c) command_bind_to(0, a, b, c)
|
||||
#define command_bind_last(a, b, c) command_bind_to(2, a, b, c)
|
||||
|
||||
void command_unbind(const char *cmd, SIGNAL_FUNC func);
|
||||
|
||||
void command_runsub(const char *cmd, const char *data, void *p1, void *p2);
|
||||
/* Run subcommand, `cmd' contains the base command, first word in `data'
|
||||
contains the subcommand */
|
||||
void command_runsub(const char *cmd, const char *data, void *server, void *item);
|
||||
|
||||
COMMAND_REC *command_find(const char *command);
|
||||
COMMAND_REC *command_find(const char *cmd);
|
||||
|
||||
/* Specify options that command can accept. `options' contains list of
|
||||
options separated with space, each option can contain a special
|
||||
char in front of it:
|
||||
|
||||
'-': optional argument
|
||||
'+': argument required
|
||||
'@': optional numeric argument
|
||||
|
||||
for example if options = "save -file +nick", you can use
|
||||
/command -save -file [<filename>] -nick <nickname>
|
||||
|
||||
You can call this command multiple times for same command, options
|
||||
will be merged. If there's any conflicts with option types, the last
|
||||
call will override the previous */
|
||||
void command_set_options(const char *cmd, const char *options);
|
||||
|
||||
/* count can have these flags: */
|
||||
#define PARAM_WITHOUT_FLAGS(a) ((a) & 0x00ffffff)
|
||||
|
|
@ -42,30 +62,40 @@ COMMAND_REC *command_find(const char *command);
|
|||
#define PARAM_FLAG_NOQUOTES 0x01000000
|
||||
/* final argument gets all the rest of the arguments */
|
||||
#define PARAM_FLAG_GETREST 0x02000000
|
||||
/* optional arguments (-cmd -cmd2 -cmd3) */
|
||||
#define PARAM_FLAG_OPTARGS 0x04000000
|
||||
/* arguments can have arguments too. Example:
|
||||
/* command contains options - first you need to specify them with
|
||||
command_set_options() function. Example:
|
||||
|
||||
-cmd arg -noargcmd -cmd2 "another arg -optnumarg rest of the text
|
||||
-cmd requiredarg -noargcmd -cmd2 "another arg" -optnumarg rest of text
|
||||
|
||||
You would call this with:
|
||||
|
||||
args = "cmd cmd2 @optnumarg";
|
||||
cmd_get_params(data, 5 | PARAM_FLAG_MULTIARGS | PARAM_FLAG_GETREST,
|
||||
&args, &arg_cmd, &arg_cmd2, &arg_optnum, &rest);
|
||||
// only once in init
|
||||
command_set_options("mycmd", "+cmd noargcmd -cmd2 @optnumarg");
|
||||
|
||||
The variables are filled as following:
|
||||
GHashTable *optlist;
|
||||
|
||||
args = "-cmd -noargcmd -cmd2 -optnumarg"
|
||||
arg_cmd = "arg"
|
||||
arg_cmd2 = "another arg"
|
||||
rest = "rest of the text"
|
||||
arg_optnum = "" - this is because "rest" isn't a numeric value
|
||||
cmd_get_params(data, &free_me, 1 | PARAM_FLAG_OPTIONS |
|
||||
PARAM_FLAG_GETREST, "mycmd", &optlist, &rest);
|
||||
|
||||
The optlist hash table is filled:
|
||||
|
||||
"cmd" = "requiredarg"
|
||||
"noargcmd" = ""
|
||||
"cmd2" = "another arg"
|
||||
"optnumarg" = "" - this is because "rest" isn't a numeric value
|
||||
*/
|
||||
#define PARAM_FLAG_MULTIARGS 0x08000000
|
||||
#define PARAM_FLAG_OPTIONS 0x04000000
|
||||
/* don't complain about unknown options */
|
||||
#define PARAM_FLAG_UNKNOWN_OPTIONS 0x08000000
|
||||
|
||||
char *cmd_get_param(char **data);
|
||||
char *cmd_get_params(const char *data, int count, ...);
|
||||
/* get parameters from command - you should point free_me somewhere and
|
||||
cmd_params_free() it after you don't use any of the parameters anymore.
|
||||
|
||||
Returns TRUE if all ok, FALSE if error occured. */
|
||||
int cmd_get_params(const char *data, gpointer *free_me, int count, ...);
|
||||
|
||||
void cmd_params_free(void *free_me);
|
||||
|
||||
typedef char* (*CMD_GET_FUNC) (const char *data, int *count, va_list *args);
|
||||
void cmd_get_add_func(CMD_GET_FUNC func);
|
||||
|
|
|
|||
|
|
@ -247,7 +247,8 @@ void *gslist_foreach_find(GSList *list, FOREACH_FIND_FUNC func, void *data)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
char *gslist_to_string(GSList *list, int offset, const char *delimiter)
|
||||
/* `list' contains pointer to structure with a char* to string. */
|
||||
char *gslistptr_to_string(GSList *list, int offset, const char *delimiter)
|
||||
{
|
||||
GString *str;
|
||||
char **data, *ret;
|
||||
|
|
@ -266,6 +267,41 @@ char *gslist_to_string(GSList *list, int offset, const char *delimiter)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* `list' contains char* */
|
||||
char *gslist_to_string(GSList *list, const char *delimiter)
|
||||
{
|
||||
GString *str;
|
||||
char *ret;
|
||||
|
||||
str = g_string_new(NULL);
|
||||
while (list != NULL) {
|
||||
if (str->len != 0) g_string_append(str, delimiter);
|
||||
g_string_append(str, list->data);
|
||||
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
ret = str->str;
|
||||
g_string_free(str, FALSE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void hash_save_key(char *key, void *value, GSList **list)
|
||||
{
|
||||
*list = g_slist_append(*list, key);
|
||||
}
|
||||
|
||||
/* save all keys in hash table to linked list - you shouldn't remove any
|
||||
items while using this list, use g_slist_free() after you're done with it */
|
||||
GSList *hashtable_get_keys(GHashTable *hash)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
list = NULL;
|
||||
g_hash_table_foreach(hash, (GHFunc) hash_save_key, &list);
|
||||
return list;
|
||||
}
|
||||
|
||||
GList *glist_find_string(GList *list, const char *key)
|
||||
{
|
||||
for (list = list; list != NULL; list = list->next)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,15 @@ GList *glist_find_string(GList *list, const char *key);
|
|||
GList *glist_find_icase_string(GList *list, const char *key);
|
||||
|
||||
void *gslist_foreach_find(GSList *list, FOREACH_FIND_FUNC func, void *data);
|
||||
char *gslist_to_string(GSList *list, int offset, const char *delimiter);
|
||||
|
||||
/* `list' contains pointer to structure with a char* to string. */
|
||||
char *gslistptr_to_string(GSList *list, int offset, const char *delimiter);
|
||||
/* `list' contains char* */
|
||||
char *gslist_to_string(GSList *list, const char *delimiter);
|
||||
|
||||
/* save all keys in hash table to linked list - you shouldn't remove any
|
||||
items while using this list, use g_slist_free() after you're done with it */
|
||||
GSList *hashtable_get_keys(GHashTable *hash);
|
||||
|
||||
/* strstr() with case-ignoring */
|
||||
char *stristr(const char *data, const char *key);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue