1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-10-13 20:13:38 -04:00

Commands now use parser function to handle parameters

This commit is contained in:
James Booth 2012-11-18 02:40:49 +00:00
parent 0cec188eb5
commit 78dd79f6a0
4 changed files with 591 additions and 690 deletions

View File

@ -49,20 +49,25 @@ typedef char*(*autocomplete_func)(char *);
*
* cmd - The command string including leading '/'
* func - The function to execute for the command
* complete_func - Function to autcomplete parameters
* parser - The function used to parse arguments
* min_args - Minimum number of arguments
* max_args - Maximum number of arguments
* help - A help struct containing usage info etc
*/
struct cmd_t {
const gchar *cmd;
gboolean (*func)(const char * const inp, struct cmd_help_t help);
gboolean (*func)(gchar **args, struct cmd_help_t help);
gchar** (*parser)(const char * const inp, int min, int max);
int min_args;
int max_args;
struct cmd_help_t help;
};
static struct cmd_t * _cmd_get_command(const char * const command);
static void _update_presence(const jabber_presence_t presence,
const char * const show, const char * const inp);
static gboolean _cmd_set_boolean_preference(const char * const inp,
struct cmd_help_t help, const char * const cmd_str, const char * const display,
const char * const show, gchar **args);
static gboolean _cmd_set_boolean_preference(gchar **args, struct cmd_help_t help,
const char * const cmd_str, const char * const display,
void (*set_func)(gboolean));
static char *_cmd_complete(char *inp);
@ -86,37 +91,37 @@ static int _strtoi(char *str, int *saveptr, int min, int max);
gchar** _cmd_parse_args(const char * const inp, int min, int max, int *num);
// command prototypes
static gboolean _cmd_quit(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_help(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_about(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_prefs(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_who(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_connect(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_disconnect(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_sub(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_msg(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_tiny(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_close(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_join(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_beep(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_notify(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_log(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_priority(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_intype(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_flash(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_showsplash(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_chlog(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_history(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_states(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_set_outtype(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_vercheck(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_away(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_online(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_dnd(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_chat(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_xa(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_info(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_wins(const char * const inp, struct cmd_help_t help);
static gboolean _cmd_quit(gchar **args, struct cmd_help_t help);
static gboolean _cmd_help(gchar **args, struct cmd_help_t help);
static gboolean _cmd_about(gchar **args, struct cmd_help_t help);
static gboolean _cmd_prefs(gchar **args, struct cmd_help_t help);
static gboolean _cmd_who(gchar **args, struct cmd_help_t help);
static gboolean _cmd_connect(gchar **args, struct cmd_help_t help);
static gboolean _cmd_disconnect(gchar **args, struct cmd_help_t help);
static gboolean _cmd_sub(gchar **args, struct cmd_help_t help);
static gboolean _cmd_msg(gchar **args, struct cmd_help_t help);
static gboolean _cmd_tiny(gchar **args, struct cmd_help_t help);
static gboolean _cmd_close(gchar **args, struct cmd_help_t help);
static gboolean _cmd_join(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_beep(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_notify(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_log(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_priority(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_intype(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_flash(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_showsplash(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_chlog(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_history(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_states(gchar **args, struct cmd_help_t help);
static gboolean _cmd_set_outtype(gchar **args, struct cmd_help_t help);
static gboolean _cmd_vercheck(gchar **args, struct cmd_help_t help);
static gboolean _cmd_away(gchar **args, struct cmd_help_t help);
static gboolean _cmd_online(gchar **args, struct cmd_help_t help);
static gboolean _cmd_dnd(gchar **args, struct cmd_help_t help);
static gboolean _cmd_chat(gchar **args, struct cmd_help_t help);
static gboolean _cmd_xa(gchar **args, struct cmd_help_t help);
static gboolean _cmd_info(gchar **args, struct cmd_help_t help);
static gboolean _cmd_wins(gchar **args, struct cmd_help_t help);
/*
* The commands are broken down into three groups:
@ -127,7 +132,7 @@ static gboolean _cmd_wins(const char * const inp, struct cmd_help_t help);
static struct cmd_t main_commands[] =
{
{ "/help",
_cmd_help,
_cmd_help, parse_args, 0, 1,
{ "/help [list|area|command]", "Show help summary, or help on a specific area or command",
{ "/help [list|area|command]",
"-------------------------",
@ -142,7 +147,7 @@ static struct cmd_t main_commands[] =
NULL } } },
{ "/about",
_cmd_about,
_cmd_about, parse_args, 0, 0,
{ "/about", "About Profanity",
{ "/about",
"------",
@ -150,7 +155,7 @@ static struct cmd_t main_commands[] =
NULL } } },
{ "/connect",
_cmd_connect,
_cmd_connect, parse_args, 1, 1,
{ "/connect user@host", "Login to jabber.",
{ "/connect user@host",
"------------------",
@ -162,7 +167,7 @@ static struct cmd_t main_commands[] =
NULL } } },
{ "/disconnect",
_cmd_disconnect,
_cmd_disconnect, parse_args, 0, 0,
{ "/disconnect", "Logout of current jabber session.",
{ "/disconnect",
"------------------",
@ -171,7 +176,7 @@ static struct cmd_t main_commands[] =
NULL } } },
{ "/prefs",
_cmd_prefs,
_cmd_prefs, parse_args, 0, 0,
{ "/prefs", "Show current preferences.",
{ "/prefs",
"------",
@ -185,7 +190,7 @@ static struct cmd_t main_commands[] =
NULL } } },
{ "/msg",
_cmd_msg,
_cmd_msg, parse_args_with_freetext, 2, 2,
{ "/msg user@host mesg", "Send mesg to user.",
{ "/msg user@host mesg",
"-------------------",
@ -200,7 +205,7 @@ static struct cmd_t main_commands[] =
NULL } } },
{ "/info",
_cmd_info,
_cmd_info, parse_args, 1, 1,
{ "/info user@host", "Find out a contacts presence information.",
{ "/info user@host",
"---------------",
@ -209,7 +214,7 @@ static struct cmd_t main_commands[] =
NULL } } },
{ "/join",
_cmd_join,
_cmd_join, parse_args_with_freetext, 1, 2,
{ "/join room@server [nick]", "Join a chat room.",
{ "/join room@server [nick]",
"------------------------",
@ -223,7 +228,7 @@ static struct cmd_t main_commands[] =
NULL } } },
{ "/wins",
_cmd_wins,
_cmd_wins, parse_args, 0, 0,
{ "/wins", "List active windows.",
{ "/wins",
"-----",
@ -231,7 +236,7 @@ static struct cmd_t main_commands[] =
NULL } } },
{ "/sub",
_cmd_sub,
_cmd_sub, parse_args, 1, 2,
{ "/sub <add|del|req|show> [jid]", "Manage subscriptions.",
{ "/sub <add|del|req|show> [jid]",
"-----------------------------",
@ -247,7 +252,7 @@ static struct cmd_t main_commands[] =
NULL } } },
{ "/tiny",
_cmd_tiny,
_cmd_tiny, parse_args, 1, 1,
{ "/tiny url", "Send url as tinyurl in current chat.",
{ "/tiny url",
"---------",
@ -259,7 +264,7 @@ static struct cmd_t main_commands[] =
NULL } } },
{ "/who",
_cmd_who,
_cmd_who, parse_args, 0, 1,
{ "/who [status]", "Show contacts with chosen status.",
{ "/who [status]",
"-------------",
@ -274,7 +279,7 @@ static struct cmd_t main_commands[] =
NULL } } },
{ "/close",
_cmd_close,
_cmd_close, parse_args, 0, 0,
{ "/close", "Close current chat window.",
{ "/close",
"------",
@ -284,7 +289,7 @@ static struct cmd_t main_commands[] =
NULL } } },
{ "/quit",
_cmd_quit,
_cmd_quit, parse_args, 0, 0,
{ "/quit", "Quit Profanity.",
{ "/quit",
"-----",
@ -295,7 +300,7 @@ static struct cmd_t main_commands[] =
static struct cmd_t setting_commands[] =
{
{ "/beep",
_cmd_set_beep,
_cmd_set_beep, parse_args, 1, 1,
{ "/beep on|off", "Terminal beep on new messages.",
{ "/beep on|off",
"------------",
@ -309,7 +314,7 @@ static struct cmd_t setting_commands[] =
NULL } } },
{ "/notify",
_cmd_set_notify,
_cmd_set_notify, parse_args, 2, 2,
{ "/notify type value", "Control various desktop noficiations.",
{ "/notify type value",
"------------------",
@ -334,7 +339,7 @@ static struct cmd_t setting_commands[] =
NULL } } },
{ "/flash",
_cmd_set_flash,
_cmd_set_flash, parse_args, 1, 1,
{ "/flash on|off", "Terminal flash on new messages.",
{ "/flash on|off",
"-------------",
@ -348,7 +353,7 @@ static struct cmd_t setting_commands[] =
NULL } } },
{ "/intype",
_cmd_set_intype,
_cmd_set_intype, parse_args, 1, 1,
{ "/intype on|off", "Show when contact is typing.",
{ "/intype on|off",
"--------------",
@ -359,7 +364,7 @@ static struct cmd_t setting_commands[] =
NULL } } },
{ "/showsplash",
_cmd_set_showsplash,
_cmd_set_showsplash, parse_args, 1, 1,
{ "/showsplash on|off", "Splash logo on startup.",
{ "/showsplash on|off",
"------------------",
@ -370,7 +375,7 @@ static struct cmd_t setting_commands[] =
NULL } } },
{ "/vercheck",
_cmd_vercheck,
_cmd_vercheck, parse_args, 0, 1,
{ "/vercheck [on|off]", "Check for a new release.",
{ "/vercheck [on|off]",
"------------------",
@ -380,7 +385,7 @@ static struct cmd_t setting_commands[] =
NULL } } },
{ "/chlog",
_cmd_set_chlog,
_cmd_set_chlog, parse_args, 1, 1,
{ "/chlog on|off", "Chat logging to file",
{ "/chlog on|off",
"-------------",
@ -399,7 +404,7 @@ static struct cmd_t setting_commands[] =
NULL } } },
{ "/states",
_cmd_set_states,
_cmd_set_states, parse_args, 1, 1,
{ "/states on|off", "Send chat states during a chat session.",
{ "/states on|off",
"--------------",
@ -413,7 +418,7 @@ static struct cmd_t setting_commands[] =
NULL } } },
{ "/outtype",
_cmd_set_outtype,
_cmd_set_outtype, parse_args, 1, 1,
{ "/outtype on|off", "Send typing notification to recipient.",
{ "/outtype on|off",
"--------------",
@ -425,7 +430,7 @@ static struct cmd_t setting_commands[] =
NULL } } },
{ "/history",
_cmd_set_history,
_cmd_set_history, parse_args, 1, 1,
{ "/history on|off", "Chat history in message windows.",
{ "/history on|off",
"---------------",
@ -440,7 +445,7 @@ static struct cmd_t setting_commands[] =
NULL } } },
{ "/log",
_cmd_set_log,
_cmd_set_log, parse_args, 2, 2,
{ "/log maxsize <value>", "Manage system logging settings.",
{ "/log maxsize <value>",
"--------------------",
@ -452,7 +457,7 @@ static struct cmd_t setting_commands[] =
NULL } } },
{ "/priority",
_cmd_set_priority,
_cmd_set_priority, parse_args, 1, 1,
{ "/priority <value>", "Set priority for connection.",
{ "/priority <value>",
"--------------------",
@ -465,7 +470,7 @@ static struct cmd_t setting_commands[] =
static struct cmd_t presence_commands[] =
{
{ "/away",
_cmd_away,
_cmd_away, parse_args_with_freetext, 0, 1,
{ "/away [msg]", "Set status to away.",
{ "/away [msg]",
"-----------",
@ -476,7 +481,7 @@ static struct cmd_t presence_commands[] =
NULL } } },
{ "/chat",
_cmd_chat,
_cmd_chat, parse_args_with_freetext, 0, 1,
{ "/chat [msg]", "Set status to chat (available for chat).",
{ "/chat [msg]",
"-----------",
@ -488,8 +493,8 @@ static struct cmd_t presence_commands[] =
NULL } } },
{ "/dnd",
_cmd_dnd,
{ "/dnd [msg]", "Set status to dnd (do not disturb.",
_cmd_dnd, parse_args_with_freetext, 0, 1,
{ "/dnd [msg]", "Set status to dnd (do not disturb).",
{ "/dnd [msg]",
"----------",
"Set your status to \"dnd\", meaning \"do not disturb\",",
@ -500,7 +505,7 @@ static struct cmd_t presence_commands[] =
NULL } } },
{ "/online",
_cmd_online,
_cmd_online, parse_args_with_freetext, 0, 1,
{ "/online [msg]", "Set status to online.",
{ "/online [msg]",
"-------------",
@ -511,7 +516,7 @@ static struct cmd_t presence_commands[] =
NULL } } },
{ "/xa",
_cmd_xa,
_cmd_xa, parse_args_with_freetext, 0, 1,
{ "/xa [msg]", "Set status to xa (extended away).",
{ "/xa [msg]",
"---------",
@ -686,7 +691,20 @@ cmd_execute(const char * const command, const char * const inp)
struct cmd_t *cmd = _cmd_get_command(command);
if (cmd != NULL) {
return (cmd->func(inp, cmd->help));
gchar **args = cmd->parser(inp, cmd->min_args, cmd->max_args);
if (args == NULL) {
cons_show("Usage: %s", cmd->help.usage);
if (win_in_chat()) {
char usage[strlen(cmd->help.usage) + 8];
sprintf(usage, "Usage: %s", cmd->help.usage);
win_show(usage);
}
return TRUE;
} else {
gboolean result = cmd->func(args, cmd->help);
g_strfreev(args);
return result;
}
} else {
return cmd_execute_default(inp);
}
@ -832,16 +850,10 @@ _cmd_complete_parameters(char *input, int *size)
// The command functions
static gboolean
_cmd_connect(const char * const inp, struct cmd_help_t help)
_cmd_connect(gchar **args, struct cmd_help_t help)
{
gboolean result = FALSE;
int num_args = 0;
gchar **args = parse_args(inp, 1, 1, &num_args);
if (args == NULL) {
cons_show("Usage: %s", help.usage);
result = TRUE;
} else {
jabber_conn_status_t conn_status = jabber_get_connection_status();
if ((conn_status != JABBER_DISCONNECTED) && (conn_status != JABBER_STARTED)) {
@ -872,31 +884,20 @@ _cmd_connect(const char * const inp, struct cmd_help_t help)
result = TRUE;
}
}
g_strfreev(args);
return result;
}
static gboolean
_cmd_sub(const char * const inp, struct cmd_help_t help)
_cmd_sub(gchar **args, struct cmd_help_t help)
{
gboolean result = FALSE;
int num_args = 0;
gchar **args = parse_args(inp, 1, 2, &num_args);
if (args == NULL) {
cons_show("Usage: %s", help.usage);
result = TRUE;
} else {
jabber_conn_status_t conn_status = jabber_get_connection_status();
if (conn_status != JABBER_CONNECTED) {
cons_show("You are currently not connected.");
result = TRUE;
} else if (strlen(inp) < 6) {
cons_show("Usage: %s", help.usage);
result = TRUE;
} else {
char *subcmd, *jid, *bare_jid;
subcmd = args[0];
@ -929,14 +930,12 @@ _cmd_sub(const char * const inp, struct cmd_help_t help)
free(jid);
result = TRUE;
}
}
g_strfreev(args);
return result;
}
static gboolean
_cmd_disconnect(const char * const inp, struct cmd_help_t help)
_cmd_disconnect(gchar **args, struct cmd_help_t help)
{
if (jabber_get_connection_status() == JABBER_CONNECTED) {
char *jid = strdup(jabber_get_jid());
@ -953,7 +952,7 @@ _cmd_disconnect(const char * const inp, struct cmd_help_t help)
}
static gboolean
_cmd_quit(const char * const inp, struct cmd_help_t help)
_cmd_quit(gchar **args, struct cmd_help_t help)
{
log_info("Profanity is shutting down...");
exit(0);
@ -961,23 +960,16 @@ _cmd_quit(const char * const inp, struct cmd_help_t help)
}
static gboolean
_cmd_wins(const char * const inp, struct cmd_help_t help)
_cmd_wins(gchar **args, struct cmd_help_t help)
{
win_show_wins();
return TRUE;
}
static gboolean
_cmd_help(const char * const inp, struct cmd_help_t help)
_cmd_help(gchar **args, struct cmd_help_t help)
{
gboolean result = FALSE;
int num_args = 0;
gchar **args = parse_args(inp, 0, 1, &num_args);
if (args == NULL) {
cons_show("Usage: %s", help.usage);
result = TRUE;
} else {
int num_args = g_strv_length(args);
if (num_args == 0) {
cons_help();
} else if (strcmp(args[0], "list") == 0) {
@ -1044,15 +1036,11 @@ _cmd_help(const char * const inp, struct cmd_help_t help)
cons_show("");
}
result = TRUE;
}
g_strfreev(args);
return result;
return TRUE;
}
static gboolean
_cmd_about(const char * const inp, struct cmd_help_t help)
_cmd_about(gchar **args, struct cmd_help_t help)
{
cons_show("");
cons_about();
@ -1060,7 +1048,7 @@ _cmd_about(const char * const inp, struct cmd_help_t help)
}
static gboolean
_cmd_prefs(const char * const inp, struct cmd_help_t help)
_cmd_prefs(gchar **args, struct cmd_help_t help)
{
cons_prefs();
@ -1068,16 +1056,8 @@ _cmd_prefs(const char * const inp, struct cmd_help_t help)
}
static gboolean
_cmd_who(const char * const inp, struct cmd_help_t help)
_cmd_who(gchar **args, struct cmd_help_t help)
{
gboolean result = FALSE;
int num_args = 0;
gchar **args = parse_args(inp, 0, 1, &num_args);
if (args == NULL) {
cons_show("Usage: %s", help.usage);
result = TRUE;
} else {
jabber_conn_status_t conn_status = jabber_get_connection_status();
if (conn_status != JABBER_CONNECTED) {
@ -1185,24 +1165,12 @@ _cmd_who(const char * const inp, struct cmd_help_t help)
}
}
result = TRUE;
}
g_strfreev(args);
return result;
return TRUE;
}
static gboolean
_cmd_msg(const char * const inp, struct cmd_help_t help)
_cmd_msg(gchar **args, struct cmd_help_t help)
{
gboolean result = FALSE;
int num_args = 0;
gchar **args = parse_args_with_freetext(inp, 2, 2, &num_args);
if (args == NULL) {
cons_show("Usage: %s", help.usage);
result = TRUE;
} else {
char *usr = args[0];
char *msg = args[1];
@ -1220,24 +1188,12 @@ _cmd_msg(const char * const inp, struct cmd_help_t help)
}
}
result = TRUE;
}
g_strfreev(args);
return result;
return TRUE;
}
static gboolean
_cmd_info(const char * const inp, struct cmd_help_t help)
_cmd_info(gchar **args, struct cmd_help_t help)
{
gboolean result = FALSE;
int num_args = 0;
gchar **args = parse_args(inp, 1, 1, &num_args);
if (args == NULL) {
cons_show("Usage: %s", help.usage);
result = TRUE;
} else {
char *usr = args[0];
jabber_conn_status_t conn_status = jabber_get_connection_status();
@ -1245,33 +1201,19 @@ _cmd_info(const char * const inp, struct cmd_help_t help)
if (conn_status != JABBER_CONNECTED) {
cons_show("You are not currently connected.");
} else {
if (usr != NULL) {
win_show_status(usr);
} else {
cons_show("Usage: %s", help.usage);
}
}
result = TRUE;
}
g_strfreev(args);
return result;
return TRUE;
}
static gboolean
_cmd_join(const char * const inp, struct cmd_help_t help)
_cmd_join(gchar **args, struct cmd_help_t help)
{
gboolean result = FALSE;
int num_args = 0;
gchar **args = parse_args(inp, 1, 2, &num_args);
if (args == NULL) {
cons_show("Usage: %s", help.usage);
result = TRUE;
} else {
char *room = args[0];
char *nick = NULL;
int num_args = g_strv_length(args);
if (num_args == 2) {
nick = args[1];
}
@ -1280,9 +1222,6 @@ _cmd_join(const char * const inp, struct cmd_help_t help)
if (conn_status != JABBER_CONNECTED) {
cons_show("You are not currently connected.");
} else {
if (room == NULL) {
cons_show("Usage: %s", help.usage);
} else {
// if no nick, set to first part of jid
if (nick == NULL) {
@ -1294,31 +1233,13 @@ _cmd_join(const char * const inp, struct cmd_help_t help)
jabber_join(room, nick);
win_join_chat(room, nick);
}
}
result = TRUE;
}
g_strfreev(args);
return result;
return TRUE;
}
static gboolean
_cmd_tiny(const char * const inp, struct cmd_help_t help)
_cmd_tiny(gchar **args, struct cmd_help_t help)
{
gboolean result = FALSE;
int num_args = 0;
gchar **args = parse_args(inp, 1, 1, &num_args);
if (args == NULL) {
cons_show("Usage: %s", help.usage);
if (win_in_chat()) {
char usage[strlen(help.usage) + 8];
sprintf(usage, "Usage: %s", help.usage);
win_show(usage);
}
result = TRUE;
} else {
char *url = args[0];
if (!tinyurl_valid(url)) {
@ -1348,18 +1269,14 @@ _cmd_tiny(const char * const inp, struct cmd_help_t help)
cons_bad_show("Couldn't get tinyurl.");
}
} else {
cons_bad_command(inp);
cons_show("/tiny can only be used in chat windows");
}
result = TRUE;
}
g_strfreev(args);
return result;
return TRUE;
}
static gboolean
_cmd_close(const char * const inp, struct cmd_help_t help)
_cmd_close(gchar **args, struct cmd_help_t help)
{
if (win_in_groupchat()) {
char *room_jid = win_get_recipient();
@ -1381,44 +1298,36 @@ _cmd_close(const char * const inp, struct cmd_help_t help)
win_close_win();
} else {
cons_bad_command(inp);
cons_show("Cannot close console window.");
}
return TRUE;
}
static gboolean
_cmd_set_beep(const char * const inp, struct cmd_help_t help)
_cmd_set_beep(gchar **args, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/beep",
return _cmd_set_boolean_preference(args, help, "/beep",
"Sound", prefs_set_beep);
}
static gboolean
_cmd_set_states(const char * const inp, struct cmd_help_t help)
_cmd_set_states(gchar **args, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/states",
return _cmd_set_boolean_preference(args, help, "/states",
"Sending chat states", prefs_set_states);
}
static gboolean
_cmd_set_outtype(const char * const inp, struct cmd_help_t help)
_cmd_set_outtype(gchar **args, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/outtype",
return _cmd_set_boolean_preference(args, help, "/outtype",
"Sending typing notifications", prefs_set_outtype);
}
static gboolean
_cmd_set_notify(const char * const inp, struct cmd_help_t help)
_cmd_set_notify(gchar **args, struct cmd_help_t help)
{
gboolean result = FALSE;
int num_args = 0;
gchar **args = parse_args(inp, 2, 2, &num_args);
if (args == NULL) {
cons_show("Usage: %s", help.usage);
result = TRUE;
} else {
char *kind = args[0];
char *value = args[1];
@ -1463,24 +1372,12 @@ _cmd_set_notify(const char * const inp, struct cmd_help_t help)
}
}
result = TRUE;
}
g_strfreev(args);
return result;
return TRUE;
}
static gboolean
_cmd_set_log(const char * const inp, struct cmd_help_t help)
_cmd_set_log(gchar **args, struct cmd_help_t help)
{
gboolean result = FALSE;
int num_args = 0;
gchar **args = parse_args(inp, 2, 2, &num_args);
if (args == NULL) {
cons_show("Usage: %s", help.usage);
result = TRUE;
} else {
char *subcmd = args[0];
char *value = args[1];
int intval;
@ -1496,24 +1393,12 @@ _cmd_set_log(const char * const inp, struct cmd_help_t help)
/* TODO: make 'level' subcommand for debug level */
result = TRUE;
}
g_strfreev(args);
return result;
return TRUE;
}
static gboolean
_cmd_set_priority(const char * const inp, struct cmd_help_t help)
_cmd_set_priority(gchar **args, struct cmd_help_t help)
{
gboolean result = FALSE;
int num_args = 0;
gchar **args = parse_args(inp, 1, 1, &num_args);
if (args == NULL) {
cons_show("Usage: %s", help.usage);
result = TRUE;
} else {
char *value = args[0];
int intval;
@ -1527,92 +1412,90 @@ _cmd_set_priority(const char * const inp, struct cmd_help_t help)
cons_show("Priority set to %d.", intval);
}
result = TRUE;
}
g_strfreev(args);
return result;
return TRUE;
}
static gboolean
_cmd_vercheck(const char * const inp, struct cmd_help_t help)
_cmd_vercheck(gchar **args, struct cmd_help_t help)
{
if (strcmp(inp, "/vercheck") == 0) {
int num_args = g_strv_length(args);
if (num_args == 0) {
cons_check_version(TRUE);
return TRUE;
} else {
return _cmd_set_boolean_preference(inp, help, "/vercheck",
return _cmd_set_boolean_preference(args, help, "/vercheck",
"Version checking", prefs_set_vercheck);
}
}
static gboolean
_cmd_set_flash(const char * const inp, struct cmd_help_t help)
_cmd_set_flash(gchar **args, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/flash",
return _cmd_set_boolean_preference(args, help, "/flash",
"Screen flash", prefs_set_flash);
}
static gboolean
_cmd_set_intype(const char * const inp, struct cmd_help_t help)
_cmd_set_intype(gchar **args, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/intype",
return _cmd_set_boolean_preference(args, help, "/intype",
"Show contact typing", prefs_set_intype);
}
static gboolean
_cmd_set_showsplash(const char * const inp, struct cmd_help_t help)
_cmd_set_showsplash(gchar **args, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/showsplash",
return _cmd_set_boolean_preference(args, help, "/showsplash",
"Splash screen", prefs_set_showsplash);
}
static gboolean
_cmd_set_chlog(const char * const inp, struct cmd_help_t help)
_cmd_set_chlog(gchar **args, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/chlog",
return _cmd_set_boolean_preference(args, help, "/chlog",
"Chat logging", prefs_set_chlog);
}
static gboolean
_cmd_set_history(const char * const inp, struct cmd_help_t help)
_cmd_set_history(gchar **args, struct cmd_help_t help)
{
return _cmd_set_boolean_preference(inp, help, "/history",
return _cmd_set_boolean_preference(args, help, "/history",
"Chat history", prefs_set_history);
}
static gboolean
_cmd_away(const char * const inp, struct cmd_help_t help)
_cmd_away(gchar **args, struct cmd_help_t help)
{
_update_presence(PRESENCE_AWAY, "away", inp);
_update_presence(PRESENCE_AWAY, "away", args);
return TRUE;
}
static gboolean
_cmd_online(const char * const inp, struct cmd_help_t help)
_cmd_online(gchar **args, struct cmd_help_t help)
{
_update_presence(PRESENCE_ONLINE, "online", inp);
_update_presence(PRESENCE_ONLINE, "online", args);
return TRUE;
}
static gboolean
_cmd_dnd(const char * const inp, struct cmd_help_t help)
_cmd_dnd(gchar **args, struct cmd_help_t help)
{
_update_presence(PRESENCE_DND, "dnd", inp);
_update_presence(PRESENCE_DND, "dnd", args);
return TRUE;
}
static gboolean
_cmd_chat(const char * const inp, struct cmd_help_t help)
_cmd_chat(gchar **args, struct cmd_help_t help)
{
_update_presence(PRESENCE_CHAT, "chat", inp);
_update_presence(PRESENCE_CHAT, "chat", args);
return TRUE;
}
static gboolean
_cmd_xa(const char * const inp, struct cmd_help_t help)
_cmd_xa(gchar **args, struct cmd_help_t help)
{
_update_presence(PRESENCE_XA, "xa", inp);
_update_presence(PRESENCE_XA, "xa", args);
return TRUE;
}
@ -1620,13 +1503,12 @@ _cmd_xa(const char * const inp, struct cmd_help_t help)
static void
_update_presence(const jabber_presence_t presence,
const char * const show, const char * const inp)
const char * const show, gchar **args)
{
char *msg;
if (strlen(inp) > strlen(show) + 2) {
msg = strndup(inp+(strlen(show) + 2), strlen(inp)-(strlen(show) + 2));
} else {
msg = NULL;
char *msg = NULL;
int num_args = g_strv_length(args);
if (num_args == 1) {
msg = args[0];
}
jabber_conn_status_t conn_status = jabber_get_connection_status();
@ -1638,7 +1520,6 @@ _update_presence(const jabber_presence_t presence,
title_bar_set_status(presence);
if (msg != NULL) {
cons_show("Status set to %s, \"%s\"", show, msg);
free(msg);
} else {
cons_show("Status set to %s", show);
}
@ -1649,26 +1530,20 @@ _update_presence(const jabber_presence_t presence,
// helper function for boolean preference commands
static gboolean
_cmd_set_boolean_preference(const char * const inp, struct cmd_help_t help,
_cmd_set_boolean_preference(gchar **args, struct cmd_help_t help,
const char * const cmd_str, const char * const display,
void (*set_func)(gboolean))
{
GString *on = g_string_new(cmd_str);
g_string_append(on, " on");
GString *off = g_string_new(cmd_str);
g_string_append(off, " off");
GString *enabled = g_string_new(display);
g_string_append(enabled, " enabled.");
GString *disabled = g_string_new(display);
g_string_append(disabled, " disabled.");
if (strcmp(inp, on->str) == 0) {
if (strcmp(args[0], "on") == 0) {
cons_show(enabled->str);
set_func(TRUE);
} else if (strcmp(inp, off->str) == 0) {
} else if (strcmp(args[0], "off") == 0) {
cons_show(disabled->str);
set_func(FALSE);
} else {
@ -1677,8 +1552,6 @@ _cmd_set_boolean_preference(const char * const inp, struct cmd_help_t help,
cons_show(usage);
}
g_string_free(on, TRUE);
g_string_free(off, TRUE);
g_string_free(enabled, TRUE);
g_string_free(disabled, TRUE);

View File

@ -25,11 +25,32 @@
#include <glib.h>
/*
* Take a full line of input and return an array of strings representing
* the arguments of a command.
* If the number of arguments found is less than min, or more than max
* NULL is returned.
*
* inp - The line of input
* min - The minimum allowed number of arguments
* max - The maxmimum allowed number of arguments
*
* Returns - An NULL terminated array of strings representing the aguments
* of the command, or NULL if the validation fails.
*
* E.g. the following input line:
*
* /cmd arg1 arg2
*
* Will return a pointer to the following array:
*
* { "arg1", "arg2", NULL }
*
*/
gchar **
parse_args(const char * const inp, int min, int max, int *num)
parse_args(const char * const inp, int min, int max)
{
if (inp == NULL) {
*num = 0;
return NULL;
}
@ -66,24 +87,23 @@ parse_args(const char * const inp, int min, int max, int *num)
}
}
*num = g_slist_length(tokens) - 1;
int num = g_slist_length(tokens) - 1;
// if num args not valid return NULL
if ((*num < min) || (*num > max)) {
if ((num < min) || (num > max)) {
g_slist_free_full(tokens, free);
free(copy);
*num = 0;
return NULL;
// if min allowed is 0 and 0 found, return empty char* array
} else if (min == 0 && *num == 0) {
gchar **args = malloc((*num + 1) * sizeof(*args));
} else if (min == 0 && num == 0) {
gchar **args = malloc((num + 1) * sizeof(*args));
args[0] = NULL;
return args;
// otherwise return args array
} else {
gchar **args = malloc((*num + 1) * sizeof(*args));
gchar **args = malloc((num + 1) * sizeof(*args));
GSList *token = tokens;
token = g_slist_next(token);
int arg_count = 0;
@ -101,11 +121,36 @@ parse_args(const char * const inp, int min, int max, int *num)
}
}
/*
* Take a full line of input and return an array of strings representing
* the arguments of a command. This function handles when the last parameter
* to the command is free text e.g.
*
* /msg user@host here is a message
*
* If the number of arguments found is less than min, or more than max
* NULL is returned.
*
* inp - The line of input
* min - The minimum allowed number of arguments
* max - The maxmimum allowed number of arguments
*
* Returns - An NULL terminated array of strings representing the aguments
* of the command, or NULL if the validation fails.
*
* E.g. the following input line:
*
* /cmd arg1 arg2 some free text
*
* Will return a pointer to the following array:
*
* { "arg1", "arg2", "some free text", NULL }
*
*/
gchar **
parse_args_with_freetext(const char * const inp, int min, int max, int *num)
parse_args_with_freetext(const char * const inp, int min, int max)
{
if (inp == NULL) {
*num = 0;
return NULL;
}
@ -148,24 +193,23 @@ parse_args_with_freetext(const char * const inp, int min, int max, int *num)
}
}
*num = g_slist_length(tokens) - 1;
int num = g_slist_length(tokens) - 1;
// if num args not valid return NULL
if ((*num < min) || (*num > max)) {
if ((num < min) || (num > max)) {
g_slist_free_full(tokens, free);
free(copy);
*num = 0;
return NULL;
// if min allowed is 0 and 0 found, return empty char* array
} else if (min == 0 && *num == 0) {
gchar **args = malloc((*num + 1) * sizeof(*args));
} else if (min == 0 && num == 0) {
gchar **args = malloc((num + 1) * sizeof(*args));
args[0] = NULL;
return args;
// otherwise return args array
} else {
gchar **args = malloc((*num + 1) * sizeof(*args));
gchar **args = malloc((num + 1) * sizeof(*args));
GSList *token = tokens;
token = g_slist_next(token);
int arg_count = 0;

View File

@ -25,7 +25,7 @@
#include <glib.h>
gchar** parse_args(const char * const inp, int min, int max, int *num);
gchar** parse_args_with_freetext(const char * const inp, int min, int max, int *num);
gchar** parse_args(const char * const inp, int min, int max);
gchar** parse_args_with_freetext(const char * const inp, int min, int max);
#endif

View File

@ -7,8 +7,7 @@ void
parse_null_returns_null(void)
{
char *inp = NULL;
int num = 0;
gchar **result = parse_args(inp, 1, 2, &num);
gchar **result = parse_args(inp, 1, 2);
assert_is_null(result);
g_strfreev(result);
@ -18,8 +17,7 @@ void
parse_empty_returns_null(void)
{
char *inp = "";
int num = 0;
gchar **result = parse_args(inp, 1, 2, &num);
gchar **result = parse_args(inp, 1, 2);
assert_is_null(result);
g_strfreev(result);
@ -29,8 +27,7 @@ void
parse_space_returns_null(void)
{
char *inp = " ";
int num = 0;
gchar **result = parse_args(inp, 1, 2, &num);
gchar **result = parse_args(inp, 1, 2);
assert_is_null(result);
g_strfreev(result);
@ -40,8 +37,7 @@ void
parse_cmd_no_args_returns_null(void)
{
char *inp = "/cmd";
int num = 0;
gchar **result = parse_args(inp, 1, 2, &num);
gchar **result = parse_args(inp, 1, 2);
assert_is_null(result);
g_strfreev(result);
@ -51,8 +47,7 @@ void
parse_cmd_with_space_returns_null(void)
{
char *inp = "/cmd ";
int num = 0;
gchar **result = parse_args(inp, 1, 2, &num);
gchar **result = parse_args(inp, 1, 2);
assert_is_null(result);
g_strfreev(result);
@ -62,8 +57,7 @@ void
parse_cmd_with_too_few_returns_null(void)
{
char *inp = "/cmd arg1";
int num = 0;
gchar **result = parse_args(inp, 2, 3, &num);
gchar **result = parse_args(inp, 2, 3);
assert_is_null(result);
g_strfreev(result);
@ -73,8 +67,7 @@ void
parse_cmd_with_too_many_returns_null(void)
{
char *inp = "/cmd arg1 arg2 arg3 arg4";
int num = 0;
gchar **result = parse_args(inp, 1, 3, &num);
gchar **result = parse_args(inp, 1, 3);
assert_is_null(result);
g_strfreev(result);
@ -84,10 +77,9 @@ void
parse_cmd_one_arg(void)
{
char *inp = "/cmd arg1";
int num = 0;
gchar **result = parse_args(inp, 1, 2, &num);
gchar **result = parse_args(inp, 1, 2);
assert_int_equals(1, num);
assert_int_equals(1, g_strv_length(result));
assert_string_equals("arg1", result[0]);
g_strfreev(result);
}
@ -96,10 +88,9 @@ void
parse_cmd_two_args(void)
{
char *inp = "/cmd arg1 arg2";
int num = 0;
gchar **result = parse_args(inp, 1, 2, &num);
gchar **result = parse_args(inp, 1, 2);
assert_int_equals(2, num);
assert_int_equals(2, g_strv_length(result));
assert_string_equals("arg1", result[0]);
assert_string_equals("arg2", result[1]);
g_strfreev(result);
@ -109,10 +100,9 @@ void
parse_cmd_three_args(void)
{
char *inp = "/cmd arg1 arg2 arg3";
int num = 0;
gchar **result = parse_args(inp, 3, 3, &num);
gchar **result = parse_args(inp, 3, 3);
assert_int_equals(3, num);
assert_int_equals(3, g_strv_length(result));
assert_string_equals("arg1", result[0]);
assert_string_equals("arg2", result[1]);
assert_string_equals("arg3", result[2]);
@ -123,10 +113,9 @@ void
parse_cmd_three_args_with_spaces(void)
{
char *inp = " /cmd arg1 arg2 arg3 ";
int num = 0;
gchar **result = parse_args(inp, 3, 3, &num);
gchar **result = parse_args(inp, 3, 3);
assert_int_equals(3, num);
assert_int_equals(3, g_strv_length(result));
assert_string_equals("arg1", result[0]);
assert_string_equals("arg2", result[1]);
assert_string_equals("arg3", result[2]);
@ -137,10 +126,9 @@ void
parse_cmd_with_freetext(void)
{
char *inp = "/cmd this is some free text";
int num = 0;
gchar **result = parse_args_with_freetext(inp, 1, 1, &num);
gchar **result = parse_args_with_freetext(inp, 1, 1);
assert_int_equals(1, num);
assert_int_equals(1, g_strv_length(result));
assert_string_equals("this is some free text", result[0]);
g_strfreev(result);
}
@ -149,10 +137,9 @@ void
parse_cmd_one_arg_with_freetext(void)
{
char *inp = "/cmd arg1 this is some free text";
int num = 0;
gchar **result = parse_args_with_freetext(inp, 1, 2, &num);
gchar **result = parse_args_with_freetext(inp, 1, 2);
assert_int_equals(2, num);
assert_int_equals(2, g_strv_length(result));
assert_string_equals("arg1", result[0]);
assert_string_equals("this is some free text", result[1]);
g_strfreev(result);
@ -162,10 +149,9 @@ void
parse_cmd_two_args_with_freetext(void)
{
char *inp = "/cmd arg1 arg2 this is some free text";
int num = 0;
gchar **result = parse_args_with_freetext(inp, 1, 3, &num);
gchar **result = parse_args_with_freetext(inp, 1, 3);
assert_int_equals(3, num);
assert_int_equals(3, g_strv_length(result));
assert_string_equals("arg1", result[0]);
assert_string_equals("arg2", result[1]);
assert_string_equals("this is some free text", result[2]);
@ -176,10 +162,9 @@ void
parse_cmd_min_zero(void)
{
char *inp = "/cmd";
int num = 0;
gchar **result = parse_args(inp, 0, 2, &num);
gchar **result = parse_args(inp, 0, 2);
assert_int_equals(0, num);
assert_int_equals(0, g_strv_length(result));
assert_is_null(result[0]);
g_strfreev(result);
}
@ -188,10 +173,9 @@ void
parse_cmd_min_zero_with_freetext(void)
{
char *inp = "/cmd";
int num = 0;
gchar **result = parse_args_with_freetext(inp, 0, 2, &num);
gchar **result = parse_args_with_freetext(inp, 0, 2);
assert_int_equals(0, num);
assert_int_equals(0, g_strv_length(result));
assert_is_null(result[0]);
g_strfreev(result);
}