--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cmdopts.diff Sun Feb 24 04:47:32 2013 +0200
@@ -0,0 +1,416 @@
+# HG changeset patch
+# Parent 92fa48ef53c909928706ab4c51518953339a38e4
+Unified command option parsing
+
+diff -r 92fa48ef53c9 mcabber/mcabber/utils.c
+--- a/mcabber/mcabber/utils.c Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/mcabber/utils.c Sun Feb 24 04:24:14 2013 +0200
+@@ -555,6 +555,311 @@
+ *str = tolower(*str);
+ }
+
++// FURTHER TODO:
++// Allow to specify catchall argument in the middle of string (requires some reverse parser)
++// Better error messages (caller frees them)
++// --help generates error with short usage, based on info in options struct
++
++// in_space -> in_space, in_optstart, in_argstart
++// in_optstart -> in_shortoptend, in_longoptstart, in_argstart ('-')
++// in_shortoptend -> in_space, error
++// in_longoptstart -> in_longopt, in_space, in_argstart ('---')
++// in_longopt -> in_longopt, in_space, error
++// in_argstart -> in_arg, success
++// in_arg -> in_arg, in_space, error
++
++// arguments: rw buffer in utf8, end of buffer pointer, options description struct
++static const char *cmdopts_parse_internal(gchar *arg, gchar *e, cmdopts_t *options)
++{
++ // parser state
++ enum {
++ in_space,
++ in_optstart,
++ in_shortoptstart,
++ in_shortoptend,
++ in_longoptstart,
++ in_longopt,
++ in_argstart,
++ in_arg,
++ } state = in_space;
++ // current pointer, start of object pointer
++ gchar *p, *s;
++ //
++ gboolean quotes = FALSE;
++ gboolean opts_ended = FALSE;
++ // option, for which argument is currently parsed
++ cmdopt_t *option = NULL;
++ // argument, that we currently parse
++ cmdarg_t *argument = NULL;
++ // flags of option/argument
++ guint flags = 0;
++ // error message to return
++ const char *error = NULL;
++
++ p = arg;
++ // we allow parser to do one extra run on final '\0'
++ while (p <= e && error == NULL) {
++ if (state == in_space) { // space between args/options
++ if (*p == ' ' || *p == '\0') { // still space
++ p ++;
++ } else if (*p == '-' && !opts_ended) { // option
++ state = in_optstart;
++ p ++;
++ } else { // argument
++ if (!option) {
++ opts_ended = TRUE;
++ }
++ s = p;
++ state = in_argstart;
++ }
++ } else if (state == in_optstart) { // long/short option
++ if (*p == ' ' || *p == '\0') { // argument '-'
++ opts_ended = TRUE;
++ s = p - 1;
++ state = in_argstart;
++ } else if (*p == '-') { // long option
++ state = in_longoptstart;
++ p ++;
++ } else { // short option
++ s = p;
++ state = in_shortoptend;
++ p ++;
++ }
++ } else if (state == in_shortoptend) { // short option
++ if (*p == ' ' || *p == '\0') { // option really ended
++ gboolean found = FALSE;
++ option = options -> opts;
++ if (option) {
++ do {
++ if (option -> shortopt == *s) {
++ found = TRUE;
++ break;
++ }
++ } while ((!(option++ -> flags & CMDOPT_LAST)) && !found);
++ }
++ if (found) { // option is known
++ if (option -> flags & CMDOPT_SWITCH) { // it is switch
++ if (option -> flags & CMDOPT_CATCHALL) {
++ option -> value.swc ++;
++ } else {
++ option -> value.swc = !option -> value.swc;
++ }
++ option = NULL;
++ } else { // it is option
++ if (*p == '\0') {
++ error = "Short option argument not specified";
++ }
++ }
++ state = in_space;
++ p ++;
++ } else { // option is unknown
++ error = "Unknown short option";
++ }
++ } else { // short option not ended
++ error = "Extra characters at short option end";
++ }
++ } else if (state == in_longoptstart) { // long option initialization
++ if (*p == ' ' || *p == '\0') { // end of options '--'
++ opts_ended = TRUE;
++ state = in_space;
++ p ++;
++ } else if (*p == '-') { // argument, starting with '---'
++ opts_ended = TRUE;
++ s = p - 2;
++ state = in_argstart;
++ } else { // it is long option
++ s = p;
++ state = in_longopt;
++ p ++;
++ }
++ } else if (state == in_longopt) { // long option name
++ if (*p == ' ' || *p == '\0') { // long option ended
++ gboolean found = FALSE;
++ gboolean eof = *p == '\0';
++ *p = '\0';
++ option = options -> opts;
++ if (option) {
++ do {
++ if (!g_strcmp0 (option -> longopt, s)) {
++ found = TRUE;
++ break;
++ }
++ } while ((!(option++ -> flags & CMDOPT_LAST)) && !found);
++ }
++ if (found) { // option is known
++ if (option -> flags & CMDOPT_SWITCH) { // it is switch
++ if (option -> flags & CMDOPT_CATCHALL) {
++ option -> value.swc ++;
++ } else {
++ option -> value.swc = !option -> value.swc;
++ }
++ option = NULL;
++ } else { // it is option
++ if (eof) {
++ error = "Long option argument not specified";
++ }
++ }
++ state = in_space;
++ p ++;
++ } else { // option is unknown
++ error = "Unknown long option";
++ }
++ } else { // still long option
++ p ++;
++ }
++ } else if (state == in_argstart) { // option/command argument initialization
++ if (option) {
++ flags = option -> flags & ~CMDOPT_CATCHALL; // catchall in options indicates multi-options
++ } else {
++ if (!argument) {
++ argument = options -> args;
++ }
++ if (!argument) { // no need to parse arguments at all
++ break;
++ }
++ flags = argument -> flags;
++ if ((flags & CMDOPT_CATCHALL) && (flags & CMDOPT_PLAIN)) { // can finish right away
++ argument -> value.arg = s;
++ break;
++ }
++ }
++ quotes = FALSE;
++ state = in_arg;
++ } else if (state == in_arg) { // option/command argument value
++ if (*p == '\0' && quotes) { // end of line in quotes
++ error = "Unfinished quoted argument";
++ } else if ((*p == ' ' && (!quotes) && !(flags & CMDOPT_CATCHALL)) || *p == '\0') { // argument ended
++ if (*p != '\0') {
++ *p = '\0';
++ p ++;
++ }
++ if (option) { // option argument
++ if (option -> flags & CMDOPT_CATCHALL) { // multi-value option
++ option -> value.multiopt = g_slist_append (option -> value.multiopt, s);
++ } else { // single-value option
++ option -> value.opt = s;
++ }
++ option = NULL;
++ } else { // command argument
++ if (argument -> flags & CMDOPT_SUBCOMMAND) {
++ gboolean found = FALSE;
++ subcmd_t *subcommand = options -> cmds;
++ if (subcommand) {
++ do {
++ if (!g_strcmp0(s, subcommand -> name)) {
++ found = TRUE;
++ break;
++ }
++ } while (!(subcommand++ -> flags & CMDOPT_LAST));
++ }
++ if (found) {
++ argument -> value.cmd = subcommand;
++ error = cmdopts_parse_internal(p, e, subcommand -> options);
++ break;
++ } else {
++ error = "Unknown subcommand";
++ }
++ } else {
++ argument -> value.arg = s;
++ if (argument -> flags & CMDOPT_LAST) { // last argument
++ break;
++ }
++ argument ++;
++ }
++ }
++ state = in_space;
++ p ++;
++ } else if (*p == '\\' && !(flags & CMDOPT_PLAIN)) { // next char escape
++ memmove(p, p+1, e-(p+1));
++ e --;
++ if (*p == '\0') {
++ error = "Escape at the end of line";
++ }
++ p ++;
++ } else if (*p == '"' && !(flags & CMDOPT_PLAIN)) { // quotation start/end
++ memmove(p, p+1, e-(p+1));
++ e --;
++ quotes = !quotes;
++ } else { // still argument
++ p ++;
++ }
++ }
++ }
++
++ // check required flags on options
++ if (error == NULL && options -> opts) {
++ option = options -> opts;
++ do {
++ if (option -> flags & CMDOPT_REQUIRED) {
++ if (option -> flags & CMDOPT_SWITCH) {
++ // no way to check trigger switches, but no point in it as well
++ if (option -> flags & CMDOPT_CATCHALL && option -> value.swc == 0) {
++ error = "Required switch is not specified";
++ break;
++ }
++ } else {
++ if ((option -> flags & CMDOPT_CATCHALL && option -> value.multiopt == NULL) ||
++ ((!(option -> flags & CMDOPT_CATCHALL)) && option -> value.opt == NULL)) {
++ error = "Required option is not specified";
++ break;
++ }
++ }
++ }
++ } while (!(option++ -> flags & CMDOPT_LAST));
++ }
++
++ // check required flags on arguments
++ if (error == NULL && options -> args) {
++ argument = options -> args;
++ do {
++ if (argument -> flags & CMDOPT_REQUIRED) {
++ if (argument -> flags & CMDOPT_SUBCOMMAND && argument -> value.cmd == NULL) {
++ error = "Subcommand is not specified";
++ break;
++ }
++ } else {
++ if ((!(argument -> flags & CMDOPT_SUBCOMMAND)) && argument -> value.arg == NULL) {
++ error = "Required argument is not specified";
++ break;
++ }
++ }
++ } while (!(argument++ -> flags & CMDOPT_LAST));
++ }
++
++ return error;
++}
++
++const char *cmdopts_parse(const char *arg, cmdopts_t *options)
++{
++ gchar *utf8 = to_utf8(arg);
++ gchar *e;
++
++ for (e = utf8; *e; e++);
++ options -> freeme = utf8;
++ return cmdopts_parse_internal(utf8, e, options);
++}
++
++void cmdopts_free(cmdopts_t *options)
++{
++ cmdopt_t *option = options -> opts;
++ subcmd_t *subcommand = options -> cmds;
++ if (option) {
++ do {
++ if ((option -> flags & (CMDOPT_CATCHALL|CMDOPT_SWITCH)) == CMDOPT_CATCHALL) {
++ g_slist_free(option -> value.multiopt);
++ option -> value.multiopt = NULL;
++ }
++ } while (!(option++ -> flags & CMDOPT_LAST));
++ }
++ if (subcommand) {
++ do {
++ cmdopts_free(subcommand -> options);
++ } while (!(subcommand++ -> flags & CMDOPT_LAST));
++ }
++ g_free(options -> freeme);
++ options -> freeme = NULL;
++}
++
+ // strip_arg_special_chars(string)
+ // Remove quotes and backslashes before an escaped quote
+ // Only quotes need a backslash
+diff -r 92fa48ef53c9 mcabber/mcabber/utils.h
+--- a/mcabber/mcabber/utils.h Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/mcabber/utils.h Sun Feb 24 04:24:14 2013 +0200
+@@ -43,6 +43,93 @@
+ char **split_arg(const char *arg, unsigned int n, int dontstriplast);
+ void free_arg_lst(char **arglst);
+
++// error cmdopts_parse (argstring, optionlist)
++// Function parses command argument string according to provided list of
++// options and arguments. If in this process it encounters an error, it
++// returns error string (that should be displayed and g_free'd afterwards).
++// Note: For now returned error is constant string, that shouldn't be freed,
++// but we're getting there.
++// After processing you should free freeme and any GSList values of catchall
++// options (only lists itself, not values). For your convenience, there is
++// cmdopts_free(), that does exactly that.
++// The function recognizes four kinds of expressions:
++// - Options with arguments in a form '-f bar' or '--foo bar'
++// - Switches without arguments in a form '-f' or '--foo'
++// - End-of-options marker '--'
++// - Individual arguments ('-' and '---' are considered arguments too)
++// To define command line syntax, you pass cmdopts_t struct, that contains
++// two contiguous lists of cmdopt_t and cmdarg_t structs accordingly. The
++// last struct in list must have CMDOPT_LAST flag set.
++// You can specify your own default values, they will be replaced/appended
++// if needed.
++// You can omit specifying longopt or shortopt (put NULL or '\0' there).
++// Note: returned values and arguments are already converted to utf8.
++
++// Flags:
++// Only applies to options, defined if option does not have argument.
++#define CMDOPT_SWITCH ( 0<<1 )
++// Don't process quotes and escapes in argument (applies to option arguments too).
++#define CMDOPT_PLAIN ( 1<<1 )
++// For options - put all encountered values into GSList value.multiopt
++// instead of overwriting value.opt.
++// For switches - increment value.swc instead of logical flipping.
++// For arguments - grab the rest of the line without splitting on spaces.
++// Implicitly last argument.
++#define CMDOPT_CATCHALL ( 2<<1 )
++// Option/argument must have value.
++#define CMDOPT_REQUIRED ( 3<<1 )
++// Last entry in struct sequence.
++#define CMDOPT_LAST ( 4<<1 )
++// Argument only, argument is the name for subcommand.
++// Implicitly last argument.
++#define CMDOPT_SUBCOMMAND ( 5<<1 )
++
++// thoughts about future:
++// command struct contains cmdopts
++// cmdopt/cmdarg struct contains argument type, that implies completion id and argument correctness checks
++// cmdopt/cmdarg struct contains default value
++// when building completion for command, we allow options (if not before --)
++// would be good to have 'subcommands' mcabber commands
++//
++// so, the process of command execution looks like:
++// - we walk through the options, set default values
++// - we parse argument string, populating options
++// - we check for required options availability
++// - we call callback
++// - we free resources
++typedef struct cmdopts_struct cmdopts_t;
++typedef struct {
++ guint flags;
++ const char *name;
++ cmdopts_t *options;
++} subcmd_t;
++typedef struct {
++ guint flags;
++ char shortopt;
++ const char *longopt;
++ union {
++ GSList *multiopt;
++ gchar *opt;
++ guint swc;
++ } value;
++} cmdopt_t;
++typedef struct {
++ guint flags;
++ union {
++ gchar *arg;
++ subcmd_t *cmd;
++ } value;
++} cmdarg_t;
++struct cmdopts_struct {
++ cmdopt_t *opts;
++ cmdarg_t *args;
++ subcmd_t *cmds;
++ gchar *freeme;
++};
++
++const char *cmdopts_parse (const char *arg, cmdopts_t *options);
++void cmdopts_free(cmdopts_t *options);
++
+ void replace_nl_with_dots(char *bufstr);
+ char *ut_expand_tabs(const char *text);
+ char *ut_unescape_tabs_cr(const char *text);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/move-rename-jid.diff Sun Feb 24 04:47:32 2013 +0200
@@ -0,0 +1,156 @@
+# HG changeset patch
+# Parent 92fa48ef53c909928706ab4c51518953339a38e4
+
+diff -r 92fa48ef53c9 mcabber/mcabber/commands.c
+--- a/mcabber/mcabber/commands.c Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/mcabber/commands.c Thu Feb 21 02:40:11 2013 +0200
+@@ -2143,6 +2143,7 @@
+ }
+ }
+
++// /rename [-j jid] name
+ static void do_rename(char *arg)
+ {
+ gpointer bud;
+@@ -2151,9 +2152,43 @@
+ char *newname, *p;
+ char *name_utf8;
+
+- if (!current_buddy)
+- return;
+- bud = BUDDATA(current_buddy);
++ if (arg[0] == '-' && arg[1] == 'j' && arg[2] == ' ') {
++ GSList *found;
++ char *jid;
++ char **args = split_arg(arg, 3, 1); // option, jid, group
++ if (!args[1] || !*args[1]) {
++ scr_log_print(LPRINT_NORMAL, "Option -j requires a jid argument.");
++ free_arg_lst(args);
++ return;
++ }
++ jid = to_utf8(args[1]);
++ if (check_jid_syntax(jid)) {
++ scr_log_print(LPRINT_NORMAL, "You must specify a valid jid!");
++ g_free(jid);
++ free_arg_lst(args);
++ return;
++ }
++ found = roster_find (jid, jidsearch, ROSTER_TYPE_USER |
++ ROSTER_TYPE_ROOM | ROSTER_TYPE_AGENT);
++ if (!found) {
++ scr_log_print(LPRINT_NORMAL, "No buddy with jid %s in roster!", jid);
++ g_free(jid);
++ free_arg_lst(args);
++ return;
++ }
++ g_free(jid);
++ bud = found->data;
++ if (args[2]) // split_arg can return NULL here
++ newname = g_strdup(args[2]);
++ else
++ newname = g_strdup("");
++ free_arg_lst(args);
++ } else {
++ if (!current_buddy)
++ return;
++ bud = BUDDATA(current_buddy);
++ newname = g_strdup(arg);
++ }
+
+ bjid = buddy_getjid(bud);
+ group = buddy_getgroupname(bud);
+@@ -2162,11 +2197,13 @@
+
+ if (type & ROSTER_TYPE_SPECIAL) {
+ scr_LogPrint(LPRINT_NORMAL, "You can't rename this item.");
++ g_free(newname);
+ return;
+ }
+
+- if (!*arg && !(type & ROSTER_TYPE_GROUP)) {
++ if ((!newname || !*newname) && !(type & ROSTER_TYPE_GROUP)) {
+ scr_LogPrint(LPRINT_NORMAL, "Please specify a new name.");
++ g_free(newname);
+ return;
+ }
+
+@@ -2181,7 +2218,6 @@
+ // }
+ //}
+
+- newname = g_strdup(arg);
+ // Remove trailing space
+ for (p = newname; *p; p++) ;
+ while (p > newname && *p == ' ') *p = 0;
+@@ -2221,6 +2257,7 @@
+ update_roster = TRUE;
+ }
+
++// /move [-j jid] groupname
+ static void do_move(char *arg)
+ {
+ gpointer bud;
+@@ -2229,9 +2266,43 @@
+ char *newgroupname, *p;
+ char *group_utf8;
+
+- if (!current_buddy)
+- return;
+- bud = BUDDATA(current_buddy);
++ if (arg[0] == '-' && arg[1] == 'j' && arg[2] == ' ') {
++ GSList *found;
++ char *jid;
++ char **args = split_arg(arg, 3, 1); // option, jid, group
++ if (!args[1] || !*args[1]) {
++ scr_log_print(LPRINT_NORMAL, "Option -j requires a jid argument.");
++ free_arg_lst(args);
++ return;
++ }
++ jid = to_utf8(args[1]);
++ if (check_jid_syntax(jid)) {
++ scr_log_print(LPRINT_NORMAL, "You must specify a valid jid!");
++ g_free(jid);
++ free_arg_lst(args);
++ return;
++ }
++ found = roster_find (jid, jidsearch, ROSTER_TYPE_USER |
++ ROSTER_TYPE_ROOM | ROSTER_TYPE_AGENT);
++ if (!found) {
++ scr_log_print(LPRINT_NORMAL, "No buddy with jid %s in roster!", jid);
++ g_free(jid);
++ free_arg_lst(args);
++ return;
++ }
++ g_free(jid);
++ bud = found->data;
++ if (args[2]) // split_arg can return NULL here
++ newgroupname = g_strdup(args[2]);
++ else
++ newgroupname = g_strdup("");
++ free_arg_lst(args);
++ } else {
++ if (!current_buddy)
++ return;
++ bud = BUDDATA(current_buddy);
++ newgroupname = g_strdup(arg);
++ }
+
+ bjid = buddy_getjid(bud);
+ name = buddy_getname(bud);
+@@ -2242,14 +2313,15 @@
+
+ if (type & ROSTER_TYPE_GROUP) {
+ scr_LogPrint(LPRINT_NORMAL, "You can't move groups!");
++ g_free(newgroupname);
+ return;
+ }
+ if (type & ROSTER_TYPE_SPECIAL) {
+ scr_LogPrint(LPRINT_NORMAL, "You can't move this item.");
++ g_free(newgroupname);
+ return;
+ }
+
+- newgroupname = g_strdup(arg);
+ // Remove trailing space
+ for (p = newgroupname; *p; p++) ;
+ while (p > newgroupname && *p == ' ') *p-- = 0;
--- a/separate-extcmd.diff Fri Jan 18 11:32:15 2013 +0200
+++ b/separate-extcmd.diff Sun Feb 24 04:47:32 2013 +0200
@@ -2,7 +2,7 @@
diff -r 75d573fb8845 mcabber/mcabber/Makefile.am
--- a/mcabber/mcabber/Makefile.am Fri Jan 18 11:23:51 2013 +0200
-+++ b/mcabber/mcabber/Makefile.am Fri Jan 18 11:30:51 2013 +0200
++++ b/mcabber/mcabber/Makefile.am Sun Jan 27 00:38:57 2013 +0200
@@ -7,7 +7,7 @@
xmpp.c xmpp.h xmpp_helper.c xmpp_helper.h xmpp_defines.h \
xmpp_iq.c xmpp_iq.h xmpp_iqrequest.c xmpp_iqrequest.h \
@@ -22,7 +22,7 @@
if OTR
diff -r 75d573fb8845 mcabber/mcabber/extcmd.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/mcabber/mcabber/extcmd.c Fri Jan 18 11:30:51 2013 +0200
++++ b/mcabber/mcabber/extcmd.c Sun Jan 27 00:38:57 2013 +0200
@@ -0,0 +1,152 @@
+/*
+ * extcmd.c -- External event handler command
@@ -178,7 +178,7 @@
+/* vim: set expandtab cindent cinoptions=>2\:2(0 ts=2 sw=2: For Vim users... */
diff -r 75d573fb8845 mcabber/mcabber/extcmd.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
-+++ b/mcabber/mcabber/extcmd.h Fri Jan 18 11:30:51 2013 +0200
++++ b/mcabber/mcabber/extcmd.h Sun Jan 27 00:38:57 2013 +0200
@@ -0,0 +1,15 @@
+#ifndef __MCABBER_EXTCMD_H__
+#define __MCABBER_EXTCMD_H__ 1
@@ -197,7 +197,7 @@
+#endif
diff -r 75d573fb8845 mcabber/mcabber/hooks.c
--- a/mcabber/mcabber/hooks.c Fri Jan 18 11:23:51 2013 +0200
-+++ b/mcabber/mcabber/hooks.c Fri Jan 18 11:30:51 2013 +0200
++++ b/mcabber/mcabber/hooks.c Sun Jan 27 00:38:57 2013 +0200
@@ -24,6 +24,7 @@
#include <string.h>
#include <sys/types.h>
@@ -466,7 +466,7 @@
/* vim: set expandtab cindent cinoptions=>2\:2(0 sw=2 ts=2: For Vim users... */
diff -r 75d573fb8845 mcabber/mcabber/hooks.h
--- a/mcabber/mcabber/hooks.h Fri Jan 18 11:23:51 2013 +0200
-+++ b/mcabber/mcabber/hooks.h Fri Jan 18 11:30:51 2013 +0200
++++ b/mcabber/mcabber/hooks.h Sun Jan 27 00:38:57 2013 +0200
@@ -66,9 +66,6 @@
guint hk_subscription(LmMessageSubType mstype, const gchar *bjid,
const gchar *msg);
@@ -479,8 +479,8 @@
/* vim: set expandtab cindent cinoptions=>2\:2(0 sw=2 ts=2: For Vim users... */
diff -r 75d573fb8845 mcabber/mcabber/main.c
--- a/mcabber/mcabber/main.c Fri Jan 18 11:23:51 2013 +0200
-+++ b/mcabber/mcabber/main.c Fri Jan 18 11:30:51 2013 +0200
-@@ -19,17 +19,15 @@
++++ b/mcabber/mcabber/main.c Sun Jan 27 00:38:57 2013 +0200
+@@ -19,14 +19,18 @@
* USA
*/
@@ -492,20 +492,22 @@
-#include <termios.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-+#include <stdio.h> // fprintf, fileno, fgets, puts
-+#include <stdlib.h> // exit, getenv
-+#include <unistd.h> // tcsetattr, tcgetattr, getopt
-+#include <string.h> // strchr, strlen, memset
-+#include <signal.h> // signal
-+#include <termios.h> // tcsetattr, tcgetattr
++#include <stdio.h> // fprintf, fileno, fgets, puts
++#include <stdlib.h> // exit, getenv
++#include <unistd.h> // tcsetattr, tcgetattr, getopt
++#include <string.h> // strchr, strlen, memset
++#include <signal.h> // signal
++#include <termios.h> // tcsetattr, tcgetattr
++#include <sys/types.h> // waitpid
++#include <sys/wait.h> // waitpid
++#include <glib.h>
++#include <config.h>
++#include <poll.h> // POLLIN, POLLERR, POLLPRI
++
#include <glib.h>
#include <config.h>
--#include <poll.h>
-+#include <poll.h> // POLLIN, POLLERR, POLLPRI
-
- #include "caps.h"
- #include "screen.h"
-@@ -44,6 +42,7 @@
+ #include <poll.h>
+@@ -44,6 +48,7 @@
#include "xmpp.h"
#include "help.h"
#include "events.h"
@@ -513,47 +515,34 @@
#ifndef MODULES_ENABLE
# include "fifo.h"
-@@ -58,10 +57,6 @@
- # include "hgcset.h"
- #endif
-
--#ifndef WAIT_ANY
--# define WAIT_ANY -1
--#endif
--
- static unsigned int terminate_ui;
- GMainContext *main_context;
-
-@@ -98,23 +93,7 @@
+@@ -348,10 +353,10 @@
+ case 'h':
+ case '?':
+ printf("Usage: %s [-h|-V|-f mcabberrc_file]\n\n", argv[0]);
+- return (c == 'h' ? 0 : -1);
++ return (c == 'h' ? EXIT_SUCCESS : EXIT_FAILURE);
+ case 'V':
+ compile_options();
+- return 0;
++ return EXIT_SUCCESS;
+ case 'f':
+ configFile = g_strdup(optarg);
+ break;
+@@ -360,7 +365,7 @@
- void sig_handler(int signum)
- {
-- if (signum == SIGCHLD) {
-- int status;
-- pid_t pid;
-- do {
-- pid = waitpid (WAIT_ANY, &status, WNOHANG);
-- // Check the exit status value if 'eventcmd_checkstatus' is set
-- if (settings_opt_get_int("eventcmd_checkstatus")) {
-- if (pid > 0) {
-- // exit status 2 -> beep
-- if (WIFEXITED(status) && WEXITSTATUS(status) == 2) {
-- scr_beep();
-- }
-- }
-- }
-- } while (pid > 0);
-- signal(SIGCHLD, sig_handler);
-- } else if (signum == SIGTERM) {
-+ if (signum == SIGTERM) {
- mcabber_terminate("Killed by SIGTERM");
- } else if (signum == SIGINT) {
- mcabber_terminate("Killed by SIGINT");
-@@ -332,7 +311,6 @@
+ if (optind < argc) {
+ fprintf(stderr, "Usage: %s [-h|-V|-f mcabberrc_file]\n\n", argv[0]);
+- return -1;
++ return EXIT_FAILURE;
+ }
- signal(SIGTERM, sig_handler);
- signal(SIGINT, sig_handler);
-- signal(SIGCHLD, sig_handler);
- #ifdef USE_SIGWINCH
- signal(SIGWINCH, sig_handler);
- #endif
+ /* Initialize command system, roster and default key bindings */
+@@ -529,7 +534,7 @@
+
+ printf("\n\nThanks for using mcabber!\n");
+
+- return 0;
++ return EXIT_SUCCESS;
+ }
+
+ /* vim: set expandtab cindent cinoptions=>2\:2(0 sw=2 ts=2: For Vim users... */
--- a/series Fri Jan 18 11:32:15 2013 +0200
+++ b/series Sun Feb 24 04:47:32 2013 +0200
@@ -10,5 +10,7 @@
add-cmake.diff
use-gslice.diff
timeformat.diff
+cmdopts.diff
+move-rename-jid.diff
templates.diff
dynamic-layout.diff