--- a/cmdopts.diff Tue Feb 26 01:22:22 2013 +0200
+++ b/cmdopts.diff Tue Feb 26 23:51:38 2013 +0200
@@ -15,13 +15,195 @@
* -n(--dryrun) switch for debugging purposes
* /group uses parser
* /say uses parser
- * say_cmd()'s second argument is now LmMessageSubType
+ * say_cmd()'s second argument is now of new type msgtype_t
* /msay uses parser
* scr_multi* now store multiline in utf8
+ * /buffer uses parser
+ * fix help for /buffer date
+diff -r 92fa48ef53c9 mcabber/doc/help/cs/hlp_buffer.txt
+--- a/mcabber/doc/help/cs/hlp_buffer.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/cs/hlp_buffer.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -25,7 +25,7 @@
+ Přesune se o [n] řádků nahoru (výchozí: polovina obrazovky).
+ /buffer down [n]
+ Přesune se o [n] řádků dolů (výchozí: polovina obrazovky).
+-/buffer date [datum]
++/buffer date datum
+ Přesune se na první řádek po datu [datum] (formát: "RRRR-mm-dd").
+ /buffer % n
+ Přesune se na procentuální pozici n%.
+diff -r 92fa48ef53c9 mcabber/doc/help/cs/hlp_del.txt
+--- a/mcabber/doc/help/cs/hlp_del.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/cs/hlp_del.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -1,4 +1,4 @@
+
+- /DEL
++ /DEL [-n|--dryrun] [jid]
+
+ Smaže aktuální kontakt ze seznamu kontaktů (rosteru) a zruší povolení oznamování o stavu daného kontaktu (autorizaci) na obou stranách.
+diff -r 92fa48ef53c9 mcabber/doc/help/de/hlp_buffer.txt
+--- a/mcabber/doc/help/de/hlp_buffer.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/de/hlp_buffer.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -25,7 +25,7 @@
+ Scrollt den Puffer um n Zeilen hoch. Gibt man keine Zahl an, scrollt er um einen halben Bildschirm
+ /buffer down [n]
+ Scrollt den Puffer um n Zeilen runter. Gibt man keine Zahl an, scrollt er um einen halben Bildschirm
+-/buffer date [date]
++/buffer date date
+ Springe zu der ersten Zeile nach dem Datum, welches im Format "JJJJ-mm-tt" anstatt [date] angegeben werden muss
+ /buffer % n
+ Springe zur Position "n" im Chatpuffer
+diff -r 92fa48ef53c9 mcabber/doc/help/de/hlp_del.txt
+--- a/mcabber/doc/help/de/hlp_del.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/de/hlp_del.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -1,4 +1,4 @@
+
+- /DEL
++ /DEL [-n|--dryrun] [jid]
+
+ Löscht den gerade ausgewählten Buddy vom Roster. Außerdem werden die automatischen Presence Benachrichtigungen vom/zum Buddy gestoppt.
+diff -r 92fa48ef53c9 mcabber/doc/help/en/hlp_buffer.txt
+--- a/mcabber/doc/help/en/hlp_buffer.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/en/hlp_buffer.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -25,7 +25,7 @@
+ Scroll the buffer up [n] lines (default: half a screen)
+ /buffer down [n]
+ Scroll the buffer down [n] lines (default: half a screen)
+-/buffer date [date]
++/buffer date date
+ Jump to the first line after the specified [date] in the chat buffer (date format: "YYYY-mm-dd")
+ /buffer % n
+ Jump to position %n of the buddy chat buffer
+diff -r 92fa48ef53c9 mcabber/doc/help/en/hlp_del.txt
+--- a/mcabber/doc/help/en/hlp_del.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/en/hlp_del.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -1,4 +1,4 @@
+
+- /DEL
++ /DEL [-n|--dryrun] [jid]
+
+-Delete the current buddy from our roster, unsubscribe from its presence notification and unsubscribe it from ours.
++Delete the current buddy or one, specified with [jid] from our roster, unsubscribe from its presence notification and unsubscribe it from ours.
+diff -r 92fa48ef53c9 mcabber/doc/help/fr/hlp_buffer.txt
+--- a/mcabber/doc/help/fr/hlp_buffer.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/fr/hlp_buffer.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -25,7 +25,7 @@
+ Défile vers le haut de [n] lignes (par défaut un demi écran)
+ /buffer down [n]
+ Défile vers le bas de [n] lignes (par défaut un demi écran)
+-/buffer date [date]
++/buffer date date
+ Va à la première ligne après la [date] dans le tampon actuel (format: "aaaa-mm-jj")
+ /buffer % n
+ Va à la position n% du tampon
+diff -r 92fa48ef53c9 mcabber/doc/help/fr/hlp_del.txt
+--- a/mcabber/doc/help/fr/hlp_del.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/fr/hlp_del.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -1,4 +1,4 @@
+
+- /DEL
++ /DEL [-n|--dryrun] [jid]
+
+ Supprime le contact sélectionné du roster, supprime notre abonnement à ses notifications de présence et supprime son abonnement aux nôtres.
+diff -r 92fa48ef53c9 mcabber/doc/help/it/hlp_buffer.txt
+--- a/mcabber/doc/help/it/hlp_buffer.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/it/hlp_buffer.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -25,7 +25,7 @@
+ Fa scorrere indietro il buffer di [n] linee (default: metà schermo)
+ /buffer down [n]
+ Fa scorrere avanti il buffer di [n] linee (default: metà schermo)
+-/buffer date [data]
++/buffer date data
+ Salta alla prima linea successiva alla [data] specificata nel buffer di chat (formato della data: "YYYY-mm-dd")
+ /buffer % n
+ Salta alla posizione %n del buffer di chat corrente
+diff -r 92fa48ef53c9 mcabber/doc/help/it/hlp_del.txt
+--- a/mcabber/doc/help/it/hlp_del.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/it/hlp_del.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -1,4 +1,4 @@
+
+- /DEL
++ /DEL [-n|--dryrun] [jid]
+
+ Elimina il contatto corrente dal roster, cancellando la sottoscrizione alle reciproche notifiche della propria presenza.
+diff -r 92fa48ef53c9 mcabber/doc/help/nl/hlp_buffer.txt
+--- a/mcabber/doc/help/nl/hlp_buffer.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/nl/hlp_buffer.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -25,7 +25,7 @@
+ Scroll de buffer [n] regels omhoog (standaard: een half scherm)
+ /buffer down [n]
+ Scroll de buffer [n] regels omlaag (standaard: een half scherm)
+-/buffer date [datum]
++/buffer date datum
+ Spring naar de eerste regel na de aangeduide [datum] in de chat buffer (datum formaat: "YYYY-mm-dd")
+ /buffer % n
+ Spring naar positie %n in de buddy chat buffer
+diff -r 92fa48ef53c9 mcabber/doc/help/nl/hlp_del.txt
+--- a/mcabber/doc/help/nl/hlp_del.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/nl/hlp_del.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -1,4 +1,4 @@
+
+- /DEL
++ /DEL [-n|--dryrun] [jid]
+
+ Verwijder de actieve buddy uit ons roster, en zet het wederzijds toezenden van status veranderingen stop.
+diff -r 92fa48ef53c9 mcabber/doc/help/pl/hlp_del.txt
+--- a/mcabber/doc/help/pl/hlp_del.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/pl/hlp_del.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -1,4 +1,4 @@
+
+- /DEL
++ /DEL [-n|--dryrun] [jid]
+
+ Usuwa aktualnie zaznaczoną osobę z rostera, usuwa subskrypcję powiadomienia dostępności u danej osoby oraz u nas.
+diff -r 92fa48ef53c9 mcabber/doc/help/ru/hlp_buffer.txt
+--- a/mcabber/doc/help/ru/hlp_buffer.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/ru/hlp_buffer.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -25,7 +25,7 @@
+ Перемещает на [n] строк вверх в буфере (истории переписки) (по умолчанию: половина экрана)
+ /buffer down [n]
+ Перемещает на [n] строк вниз в буфере (истории переписки) (по умолчанию: половина экрана)
+-/buffer date [date]
++/buffer date date
+ Перемещает в первой строке после определенной даты [date] в буфере (истории переписки) (формат даты: "год-месяц-день", для примера "2006-01-01")
+ /buffer % n
+ Перемещает на позицию %n в текущем буфере (истории переписки)
+diff -r 92fa48ef53c9 mcabber/doc/help/ru/hlp_del.txt
+--- a/mcabber/doc/help/ru/hlp_del.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/ru/hlp_del.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -1,4 +1,4 @@
+
+- /DEL
++ /DEL [-n|--dryrun] [jid]
+
+-Удаляет текущего пользователя из списка контактов, отключает уведомления о его статусе и отключает уведомления пользователя о вашем статусе.
++Удаляет текущего пользователя (или указанного с помощью jid) из списка контактов, отключает уведомления о его статусе и отключает уведомление пользователя о вашем статусе.
+diff -r 92fa48ef53c9 mcabber/doc/help/uk/hlp_buffer.txt
+--- a/mcabber/doc/help/uk/hlp_buffer.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/uk/hlp_buffer.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -25,7 +25,7 @@
+ Посунути буфер вверх на n рядків (якщо не вказано - пів екрану).
+ /buffer down [n]
+ Посунути буфер вниз на n рядків (якщо не вказано - пів екрану).
+-/buffer date [дата]
++/buffer date дата
+ Перейти до першого повідомлення після дати (дата вигляду РРРР-ММ-ДД).
+ /buffer % процент
+ Перейти до вказаної у процентах позиції.
+diff -r 92fa48ef53c9 mcabber/doc/help/uk/hlp_del.txt
+--- a/mcabber/doc/help/uk/hlp_del.txt Sun Jan 27 00:40:37 2013 +0200
++++ b/mcabber/doc/help/uk/hlp_del.txt Tue Feb 26 23:50:10 2013 +0200
+@@ -1,4 +1,4 @@
+
+- /DEL
++ /DEL [-n|--dryrun] [jid]
+
+-Потерти поточний контакт зі списку. На додачу відписатися від його повідомлень про статус і відписати його від ваших.
++Потерти поточний контакт (або контакт, що має вказаний jid) зі списку. Також відписатися від його сповіщень про статус і відписати його від ваших.
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 Tue Feb 26 01:21:26 2013 +0200
++++ b/mcabber/mcabber/commands.c Tue Feb 26 23:50:10 2013 +0200
@@ -502,7 +502,9 @@
if (!iscmd && scr_get_multimode() == 2
&& (strncasecmp(xpline, mkcmdstr("msay "), strlen(mkcmdstr("msay "))))) {
@@ -43,7 +225,7 @@
+ scr_append_multiline(utf8);
else
- say_cmd((char*)line, 0);
-+ say_cmd(utf8, LM_MESSAGE_SUB_TYPE_NOT_SET);
++ say_cmd(utf8, msgtype_not_set);
+ g_free(utf8);
return 0;
}
@@ -75,7 +257,7 @@
} else { // Display a note
struct annotation *note = xmpp_get_storage_rosternotes(bjid, FALSE);
if (note) {
-@@ -819,175 +818,253 @@
+@@ -819,175 +818,228 @@
/* All these do_*() functions will be called with a "arg" parameter */
/* (with arg not null) */
@@ -92,7 +274,6 @@
- if (!subcmd || !*subcmd) {
- scr_LogPrint(LPRINT_NORMAL, "Missing parameter.");
- free_arg_lst(paramlst);
-- return;
+ enum roster_scmd_t {
+ roster_scmd_bottom, roster_scmd_top, roster_scmd_up, roster_scmd_down,
+ roster_scmd_group_prev, roster_scmd_group_next,
@@ -107,19 +288,19 @@
+ roster_scmd_hide, roster_scmd_show, roster_scmd_toggle,
+ } subcmd;
+#define ROSTER_SCMD_NOARG(NAME) \
-+ { 0, #NAME, { NULL, NULL, NULL, NULL }, (gpointer)roster_scmd_##NAME }
++ { #NAME, NULL, NULL, NULL, (gpointer)roster_scmd_##NAME, 0 }
+// all of them have at most one argument
+#define ROSTER_SCMD(NAME, FLAGS, VALUE) \
-+ { 0, #NAME, { NULL, \
-+ (cmdarg_t[1]){ \
-+ { CMDOPT_LAST | FLAGS, { .arg = VALUE } } \
-+ }, NULL, NULL }, (gpointer)roster_scmd_##NAME }
++ { #NAME, NULL, \
++ (cmdarg_t[1]){{ CMDOPT_LAST | FLAGS, { .arg = VALUE } }}, \
++ NULL, (gpointer)roster_scmd_##NAME, 0 }
+ cmdopts_t options = {
++ "roster",
+ NULL,
+ (cmdarg_t[1]){
+ { CMDOPT_REQUIRED | CMDOPT_SUBCOMMAND | CMDOPT_LAST, { .cmd = NULL } }
+ },
-+ (subcmd_t[23]){
++ (cmdopts_t[23]){
+ ROSTER_SCMD_NOARG(bottom),
+ ROSTER_SCMD_NOARG(top),
+ ROSTER_SCMD(up, 0, "1"), // num lines
@@ -142,27 +323,22 @@
+ ROSTER_SCMD(resource_unlock, 0, NULL), // resource/jid
+ ROSTER_SCMD_NOARG(hide),
+ ROSTER_SCMD_NOARG(show),
-+ { CMDOPT_LAST, "toggle", { NULL, NULL, NULL, NULL },
-+ (gpointer)roster_scmd_toggle },
++ { "toggle", NULL, NULL, NULL, (gpointer)roster_scmd_toggle,
++ CMDOPT_LAST },
+ },
+ NULL,
+ };
+ gchar *arg;
+
-+ {
-+ const char *error = cmdopts_parse (args, &options);
-+ if (error != NULL) {
-+ scr_log_print (LPRINT_NORMAL, error);
-+ return;
-+ }
++ if (cmdopts_parse(args, &options))
+ return;
++
++ subcmd = (enum roster_scmd_t) (options.args[0].value.cmd -> userdata);
++ if (options.args[0].value.cmd -> args != NULL) {
++ arg = options.args[0].value.cmd -> args[0].value.arg;
}
- if (!strcasecmp(subcmd, "top")) {
-+ subcmd = (enum roster_scmd_t) (options.args[0].value.cmd -> userdata);
-+ if (options.args[0].value.cmd -> options.args != NULL) {
-+ arg = options.args[0].value.cmd -> options.args[0].value.arg;
-+ }
-+
+ if (subcmd == roster_scmd_top) {
scr_roster_top();
update_roster = TRUE;
@@ -221,111 +397,42 @@
- if (!arg || !*arg) {
- scr_LogPrint(LPRINT_NORMAL, "What name or JID are you looking for?");
- free_arg_lst(paramlst);
+- return;
+- }
+ } else if (subcmd == roster_scmd_search) {
-+ scr_roster_search(arg);
-+ update_roster = TRUE;
+ scr_roster_search(arg);
+ update_roster = TRUE;
+- } else if (!strcasecmp(subcmd, "up")) {
+ } else if (subcmd == roster_scmd_up) {
-+ roster_updown(-1, arg);
+ roster_updown(-1, arg);
+- } else if (!strcasecmp(subcmd, "down")) {
+ } else if (subcmd == roster_scmd_down) {
-+ roster_updown(1, arg);
+ roster_updown(1, arg);
+- } else if (!strcasecmp(subcmd, "group_prev")) {
+ } else if (subcmd == roster_scmd_group_prev) {
-+ scr_roster_prev_group();
+ scr_roster_prev_group();
+- } else if (!strcasecmp(subcmd, "group_next")) {
+ } else if (subcmd == roster_scmd_group_next) {
-+ scr_roster_next_group();
+ scr_roster_next_group();
+- } else if (!strcasecmp(subcmd, "note")) {
+ } else if (subcmd == roster_scmd_note) {
-+ roster_note(arg);
+ roster_note(arg);
+- } else if (!strcasecmp(subcmd, "resource_lock")) {
+ } else if (subcmd == roster_scmd_resource_lock) {
-+ roster_resourcelock(arg, TRUE);
+ roster_resourcelock(arg, TRUE);
+- } else if (!strcasecmp(subcmd, "resource_unlock")) {
+ } else { // roster_scmd_resource_unlock
-+ roster_resourcelock(arg, FALSE);
+ roster_resourcelock(arg, FALSE);
+- } else
+- scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
+- free_arg_lst(paramlst);
+ }
+
+ cmdopts_free(&options);
-+}
-+
-+void do_color(char *arg)
-+{
-+ enum color_scmd_t {
-+ color_scmd_roster,
-+ color_scmd_mucnick,
-+ color_scmd_muc,
-+ } subcmd;
-+ cmdopts_t options = {
-+ NULL,
-+ (cmdarg_t[1]){
-+ { CMDOPT_REQUIRED | CMDOPT_SUBCOMMAND | CMDOPT_LAST, { .cmd = NULL } },
-+ },
-+ (subcmd_t[3]){
-+ { 0, "roster",
-+ {
-+ NULL,
-+ (cmdarg_t[3]){
-+ { CMDOPT_REQUIRED, { .arg = NULL } }, // status mask or "clear"
-+ { 0, { .arg = NULL } }, // jid mask
-+ { CMDOPT_LAST, { .arg = NULL } }, // color
-+ },
-+ NULL,
-+ NULL,
-+ },
-+ (gpointer)color_scmd_roster,
-+ },
-+ { 0, "muc",
-+ {
-+ NULL,
-+ (cmdarg_t[2]){
-+ { CMDOPT_REQUIRED, { .arg = NULL } }, // jid
-+ { CMDOPT_LAST, { .arg = "on" } }, // on/off/preset/-
-+ },
-+ NULL,
-+ NULL,
-+ },
-+ (gpointer)color_scmd_muc,
-+ },
-+ { CMDOPT_LAST, "mucnick",
-+ {
-+ NULL,
-+ (cmdarg_t[2]){
-+ { CMDOPT_REQUIRED, { .arg = NULL } }, // nick
-+ { CMDOPT_REQUIRED | CMDOPT_LAST, { .arg = NULL } }, // color
-+ },
-+ NULL,
-+ NULL,
-+ },
-+ (gpointer)color_scmd_mucnick,
-+ },
-+ },
-+ NULL,
-+ };
-+
-+ {
-+ const char *error = cmdopts_parse(arg, &options);
-+ if (error != NULL) {
-+ scr_log_print(LPRINT_NORMAL, error);
- return;
- }
-- scr_roster_search(arg);
-- update_roster = TRUE;
-- } else if (!strcasecmp(subcmd, "up")) {
-- roster_updown(-1, arg);
-- } else if (!strcasecmp(subcmd, "down")) {
-- roster_updown(1, arg);
-- } else if (!strcasecmp(subcmd, "group_prev")) {
-- scr_roster_prev_group();
-- } else if (!strcasecmp(subcmd, "group_next")) {
-- scr_roster_next_group();
-- } else if (!strcasecmp(subcmd, "note")) {
-- roster_note(arg);
-- } else if (!strcasecmp(subcmd, "resource_lock")) {
-- roster_resourcelock(arg, TRUE);
-- } else if (!strcasecmp(subcmd, "resource_unlock")) {
-- roster_resourcelock(arg, FALSE);
-- } else
-- scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
-- free_arg_lst(paramlst);
--}
--
--void do_color(char *arg)
--{
+ }
+
+ void do_color(char *arg)
+ {
- char **paramlst;
- char *subcmd;
-
@@ -336,8 +443,46 @@
- if (!subcmd || !*subcmd) {
- scr_LogPrint(LPRINT_NORMAL, "Missing parameter.");
- free_arg_lst(paramlst);
-- return;
- }
++ enum color_scmd_t {
++ color_scmd_roster,
++ color_scmd_mucnick,
++ color_scmd_muc,
++ } subcmd;
++ cmdopts_t options = {
++ "color",
++ NULL,
++ (cmdarg_t[1]){
++ { CMDOPT_REQUIRED | CMDOPT_SUBCOMMAND | CMDOPT_LAST, { .cmd = NULL } },
++ },
++ (cmdopts_t[3]){
++ { "roster", NULL,
++ (cmdarg_t[3]){
++ { CMDOPT_REQUIRED, { .arg = NULL } }, // status mask or "clear"
++ { 0, { .arg = NULL } }, // jid mask
++ { CMDOPT_LAST, { .arg = NULL } }, // color
++ },
++ NULL, (gpointer)color_scmd_roster, 0,
++ },
++ { "muc", NULL,
++ (cmdarg_t[2]){
++ { CMDOPT_REQUIRED, { .arg = NULL } }, // jid
++ { CMDOPT_LAST, { .arg = "on" } }, // on/off/preset/-
++ },
++ NULL, (gpointer)color_scmd_muc, 0,
++ },
++ { "mucnick", NULL,
++ (cmdarg_t[2]){
++ { CMDOPT_REQUIRED, { .arg = NULL } }, // nick
++ { CMDOPT_REQUIRED | CMDOPT_LAST, { .arg = NULL } }, // color
++ },
++ NULL, (gpointer)color_scmd_mucnick, CMDOPT_LAST,
++ },
++ },
++ };
++
++ if (cmdopts_parse(arg, &options))
+ return;
+- }
-
- if (!strcasecmp(subcmd, "roster")) {
- char *status, *wildcard, *color;
@@ -352,9 +497,9 @@
+ subcmd = (enum color_scmd_t) options.args[0].value.cmd -> userdata;
+
+ if (subcmd == color_scmd_roster) {
-+ const gchar *status = options.cmds[0].options.args[0].value.arg;
-+ const gchar *wildcard = options.cmds[0].options.args[1].value.arg;
-+ const gchar *color = options.cmds[0].options.args[2].value.arg;
++ const gchar *status = options.cmds[0].args[0].value.arg;
++ const gchar *wildcard = options.cmds[0].args[1].value.arg;
++ const gchar *color = options.cmds[0].args[2].value.arg;
+ if (!strcmp(status, "clear")) { // Not a color command, clear all
scr_roster_clear_color();
update_roster = TRUE;
@@ -396,8 +541,8 @@
- scr_LogPrint(LPRINT_NORMAL, "Unknown coloring mode");
- }
+ } else if (subcmd == color_scmd_muc) {
-+ const gchar *muc = options.cmds[1].options.args[0].value.arg;
-+ const gchar *mode = options.cmds[1].options.args[1].value.arg;
++ const gchar *muc = options.cmds[1].args[0].value.arg;
++ const gchar *mode = options.cmds[1].args[1].value.arg;
+ if (!strcmp(muc, "."))
+ if (!(muc = CURRENT_JID))
+ scr_LogPrint(LPRINT_NORMAL, "No JID selected");
@@ -431,8 +576,8 @@
- scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
- free_arg_lst(paramlst);
+ } else { // color_scmd_mucnick
-+ const gchar *nick = options.cmds[2].options.args[0].value.arg;
-+ const gchar *color = options.cmds[2].options.args[1].value.arg;
++ const gchar *nick = options.cmds[2].args[0].value.arg;
++ const gchar *color = options.cmds[2].args[1].value.arg;
+ scr_muc_nick_color(nick, color);
+ }
+
@@ -454,7 +599,7 @@
enum imstatus st;
if (!xmpp_is_online())
-@@ -1000,15 +1077,15 @@
+@@ -1000,15 +1052,15 @@
if (!recipient)
scr_check_auto_away(TRUE);
@@ -475,7 +620,7 @@
if (!strcasecmp(status, IMSTATUS_OFFLINE)) st = offline;
else if (!strcasecmp(status, IMSTATUS_ONLINE)) st = available;
else if (!strcasecmp(status, IMSTATUS_AVAILABLE)) st = available;
-@@ -1020,65 +1097,87 @@
+@@ -1020,64 +1072,76 @@
else if (!strcasecmp(status, IMSTATUS_NOTAVAILABLE)) st = notavail;
else if (!strcasecmp(status, IMSTATUS_FREE4CHAT)) st = freeforchat;
else if (!strcasecmp(status, "message")) {
@@ -511,6 +656,7 @@
{
- if (!*arg) {
+ cmdopts_t options = {
++ "status",
+ NULL,
+ (cmdarg_t[2]){
+ // status
@@ -519,16 +665,10 @@
+ { CMDOPT_CATCHALL | CMDOPT_PLAIN | CMDOPT_LAST, { .arg = NULL } },
+ },
+ NULL,
-+ NULL,
+ };
+
-+ {
-+ const char *error = cmdopts_parse(arg, &options);
-+ if (error != NULL) {
-+ scr_log_print(LPRINT_NORMAL, error);
-+ return;
-+ }
-+ }
++ if (cmdopts_parse(arg, &options))
++ return;
+
+ if (options.args[0].value.arg == NULL) {
const char *sm = xmpp_getstatusmsg();
@@ -550,6 +690,7 @@
{
- char **paramlst;
+ cmdopts_t options = {
++ "status_to",
+ NULL,
+ (cmdarg_t[3]){
+ // jid
@@ -560,7 +701,6 @@
+ { CMDOPT_CATCHALL | CMDOPT_PLAIN | CMDOPT_LAST, { .arg = "" } },
+ },
+ NULL,
-+ NULL,
+ };
char *fjid, *st, *msg;
- char *jid_utf8 = NULL;
@@ -574,24 +714,18 @@
- scr_LogPrint(LPRINT_NORMAL,
- "Please specify both a Jabber ID and a status.");
- free_arg_lst(paramlst);
-- return;
+
-+ {
-+ const char *error = cmdopts_parse(arg, &options);
-+ if (error != NULL) {
-+ scr_log_print(LPRINT_NORMAL, error);
-+ return;
-+ }
- }
-
++ if (cmdopts_parse(arg, &options))
+ return;
+- }
++
+ fjid = options.args[0].value.arg;
+ st = options.args[1].value.arg;
+ msg = options.args[2].value.arg;
-+
+
// Allow things like /status_to "" away
if (!*fjid || !strcmp(fjid, "."))
- fjid = NULL;
-@@ -1086,15 +1185,13 @@
+@@ -1086,15 +1150,13 @@
if (fjid) {
// The JID has been specified. Quick check...
if (check_jid_syntax(fjid)) {
@@ -608,7 +742,7 @@
}
} else {
// Add the current buddy
-@@ -1105,144 +1202,205 @@
+@@ -1105,144 +1167,190 @@
}
if (fjid) {
@@ -637,6 +771,7 @@
- char *id, *nick;
- char *jid_utf8 = NULL;
+ cmdopts_t options = {
++ "add",
+ NULL,
+ (cmdarg_t[2]){
+ // jid
@@ -645,7 +780,6 @@
+ { CMDOPT_CATCHALL | CMDOPT_PLAIN | CMDOPT_LAST, { .arg = NULL } },
+ },
+ NULL,
-+ NULL,
+ };
+ gchar *jid, *nick;
@@ -664,13 +798,8 @@
- id = NULL;
-
- if (id) {
-+ {
-+ const char *error = cmdopts_parse(arg, &options);
-+ if (error) {
-+ scr_log_print(LPRINT_NORMAL, error);
-+ return;
-+ }
-+ }
++ if (cmdopts_parse(arg, &options))
++ return;
+
+ jid = options.args[0].value.arg;
+ nick = options.args[1].value.arg;
@@ -729,6 +858,7 @@
- scr_LogPrint(LPRINT_NORMAL, "This action does not require a parameter; "
- "the currently-selected buddy will be deleted.");
+ cmdopts_t options = {
++ "del",
+ (cmdopt_t[1]){
+ { CMDOPT_SWITCH | CMDOPT_LAST, 'n', "dryrun", { .swc = 0 } },
+ },
@@ -736,7 +866,6 @@
+ { CMDOPT_LAST, { .arg = "." } }, // jid
+ },
+ NULL,
-+ NULL,
+ };
+ gchar *jid;
+ gpointer buddy;
@@ -746,30 +875,9 @@
return;
}
-- if (!current_buddy)
-- return;
-- bjid = buddy_getjid(BUDDATA(current_buddy));
-- if (!bjid)
-- return;
--
-- if (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_ROOM) {
-- // This is a chatroom
-- if (buddy_getinsideroom(BUDDATA(current_buddy))) {
-- scr_LogPrint(LPRINT_NORMAL, "You haven't left this room!");
-+ {
-+ const char *error = cmdopts_parse(arg, &options);
-+ if (error) {
-+ scr_log_print(LPRINT_NORMAL, error);
- return;
- }
- }
-
-- // Close the buffer
-- scr_buffer_purge(1, NULL);
--
-- scr_LogPrint(LPRINT_LOGNORM, "Removing <%s>...", bjid);
-- xmpp_delbuddy(bjid);
-- scr_update_buddy_window();
++ if (cmdopts_parse(arg, &options))
++ return;
++
+ jid = options.args[0].value.arg;
+
+ if (jid && (!*jid || !strcmp(jid, ".")))
@@ -824,37 +932,66 @@
+ }
+
+ cmdopts_free(&options);
- }
-
- static void do_group(char *arg)
- {
++}
++
++static void do_group(char *arg)
++{
+ enum group_scmd_t {
+ group_scmd_unfold = 0,
+ group_scmd_fold = 1,
+ group_scmd_toggle = -1,
+ } subcmd;
+ cmdopts_t options = {
++ "group",
+ NULL,
+ (cmdarg_t[1]){
+ { CMDOPT_REQUIRED | CMDOPT_SUBCOMMAND | CMDOPT_LAST, { .cmd = NULL } },
+ },
+ // all of them have one argument - group name
+#define GROUP_SUBCMD(NAME, REALNAME, FLAGS) \
-+ { FLAGS, #NAME, { NULL, (cmdarg_t[1]){ \
++ { #NAME, NULL, (cmdarg_t[1]){ \
+ { CMDOPT_CATCHALL | CMDOPT_PLAIN | CMDOPT_LAST, { .arg = NULL } }, \
-+ }, NULL, NULL }, (gpointer)group_scmd_##REALNAME }
-+ (subcmd_t[5]){
++ }, NULL, (gpointer)group_scmd_##REALNAME, FLAGS }
++ (cmdopts_t[5]){
+ GROUP_SUBCMD(expand, unfold, 0),
+ GROUP_SUBCMD(unfold, unfold, 0),
+ GROUP_SUBCMD(shrink, fold, 0),
+ GROUP_SUBCMD(fold, fold, 0),
+ GROUP_SUBCMD(toggle, toggle, CMDOPT_LAST),
+ },
-+ NULL,
+ };
+ gchar *name;
- gpointer group = NULL;
- guint leave_buddywindow;
++ gpointer group = NULL;
++ guint leave_buddywindow;
++
+ if (!current_buddy)
+ return;
+- bjid = buddy_getjid(BUDDATA(current_buddy));
+- if (!bjid)
++
++ if (cmdopts_parse(arg, &options))
+ return;
+-
+- if (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_ROOM) {
+- // This is a chatroom
+- if (buddy_getinsideroom(BUDDATA(current_buddy))) {
+- scr_LogPrint(LPRINT_NORMAL, "You haven't left this room!");
+- return;
+- }
+- }
+-
+- // Close the buffer
+- scr_buffer_purge(1, NULL);
+-
+- scr_LogPrint(LPRINT_LOGNORM, "Removing <%s>...", bjid);
+- xmpp_delbuddy(bjid);
+- scr_update_buddy_window();
+-}
+-
+-static void do_group(char *arg)
+-{
+- gpointer group = NULL;
+- guint leave_buddywindow;
- char **paramlst;
- char *subcmd;
- enum { group_toggle = -1, group_unfold = 0, group_fold = 1 } group_state = 0;
@@ -863,10 +1000,10 @@
- scr_LogPrint(LPRINT_NORMAL, "Missing parameter.");
- return;
- }
-
- if (!current_buddy)
- return;
-
+-
+- if (!current_buddy)
+- return;
+-
- paramlst = split_arg(arg, 2, 0); // subcmd, [arg]
- subcmd = *paramlst;
- arg = *(paramlst+1);
@@ -883,18 +1020,12 @@
- else {
- scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
- goto do_group_return;
-+ {
-+ const char *error = cmdopts_parse(arg, &options);
-+ if (error) {
-+ scr_log_print(LPRINT_NORMAL, error);
-+ return;
-+ }
- }
+- }
-
- if (arg && *arg) {
+
+ subcmd = (enum group_scmd_t) options.args[0].value.cmd -> userdata;
-+ name = options.args[0].value.cmd -> options.args[0].value.arg;
++ name = options.args[0].value.cmd -> args[0].value.arg;
+
+ if (name && *name) {
GSList *roster_elt;
@@ -905,7 +1036,7 @@
if (roster_elt)
group = buddy_getgroup(roster_elt->data);
} else {
-@@ -1264,16 +1422,16 @@
+@@ -1264,20 +1372,20 @@
goto do_group_return;
}
@@ -925,7 +1056,20 @@
}
static int send_message_to(const char *fjid, const char *msg, const char *subj,
-@@ -1299,8 +1457,7 @@
+- LmMessageSubType type_overwrite, bool quiet)
++ msgtype_t msg_type, bool quiet)
+ {
+ char *bare_jid, *rp;
+ char *hmsg;
+@@ -1285,6 +1393,7 @@
+ gint retval = 0;
+ int isroom;
+ gpointer xep184 = NULL;
++ LmMessageSubType type_overwrite = LM_MESSAGE_SUB_TYPE_NOT_SET;
+
+ if (!xmpp_is_online()) {
+ scr_LogPrint(LPRINT_NORMAL, "You are not connected.");
+@@ -1299,11 +1408,15 @@
return 1;
}
if (check_jid_syntax((char*)fjid)) {
@@ -935,7 +1079,30 @@
return 1;
}
-@@ -1382,30 +1539,9 @@
++ if (msg_type == msgtype_normal)
++ type_overwrite = LM_MESSAGE_SUB_TYPE_NORMAL;
++ else if (msg_type == msgtype_headline)
++ type_overwrite = LM_MESSAGE_SUB_TYPE_HEADLINE;
++
+ // We must use the bare jid in hk_message_out()
+ rp = strchr(fjid, JID_RESOURCE_SEPARATOR);
+ if (rp)
+@@ -1354,8 +1467,7 @@
+ // send_message(msg, subj, type_overwrite)
+ // Write the message in the buddy's window and send the message on
+ // the network.
+-static void send_message(const char *msg, const char *subj,
+- LmMessageSubType type_overwrite)
++static void send_message(const char *msg, const char *subj, msgtype_t msgtype)
+ {
+ const char *bjid;
+ char *jid;
+@@ -1378,34 +1490,13 @@
+ else
+ jid = g_strdup(bjid);
+
+- send_message_to(jid, msg, subj, type_overwrite, FALSE);
++ send_message_to(jid, msg, subj, msgtype, FALSE);
g_free(jid);
}
@@ -960,14 +1127,14 @@
-}
-
-void say_cmd(char *arg, int parse_flags)
-+void say_cmd(char *arg, LmMessageSubType msgtype)
++void say_cmd(char *arg, msgtype_t msgtype)
{
gpointer bud;
- LmMessageSubType msgtype = LM_MESSAGE_SUB_TYPE_NOT_SET;
scr_set_chatmode(TRUE);
scr_show_buddy_window();
-@@ -1424,80 +1560,150 @@
+@@ -1424,80 +1515,131 @@
}
buddy_setflags(bud, ROSTER_FLAG_LOCK, TRUE);
@@ -981,6 +1148,7 @@
static void do_say(char *arg) {
- say_cmd(arg, 1);
+ cmdopts_t options = {
++ "say",
+ (cmdopt_t[2]){
+ { CMDOPT_SWITCH, 'n', "normal", { .swc = 0 } },
+ { CMDOPT_SWITCH | CMDOPT_LAST, 'h', "headline", { .swc = 0 } },
@@ -990,25 +1158,18 @@
+ { .arg = NULL } },
+ },
+ NULL,
-+ NULL,
+ };
-+ LmMessageSubType mtype = LM_MESSAGE_SUB_TYPE_NOT_SET;
++ msgtype_t msgtype = msgtype_not_set;
++
++ if (cmdopts_parse(arg, &options))
++ return;
+
-+ {
-+ const char *error = cmdopts_parse(arg, &options);
-+ if (error != NULL) {
-+ scr_log_print(LPRINT_NORMAL, error);
-+ return;
-+ }
-+ }
++ if (options.opts[0].value.swc)
++ msgtype = msgtype_normal;
++ else if (options.opts[1].value.swc)
++ msgtype = msgtype_headline;
+
-+ if (options.opts[0].value.swc) {
-+ mtype = LM_MESSAGE_SUB_TYPE_NORMAL;
-+ } else if (options.opts[1].value.swc) {
-+ mtype = LM_MESSAGE_SUB_TYPE_HEADLINE;
-+ }
-+
-+ say_cmd(options.args[0].value.arg, mtype);
++ say_cmd(options.args[0].value.arg, msgtype);
+
+ cmdopts_free(&options);
}
@@ -1037,85 +1198,78 @@
+ msay_scmd_abort,
+ } subcmd;
+ cmdopts_t options = {
++ "msay",
+ NULL,
+ (cmdarg_t[1]){
+ // subcommand
+ { CMDOPT_SUBCOMMAND | CMDOPT_REQUIRED | CMDOPT_LAST, { .cmd = NULL } },
+ },
-+ (subcmd_t[7]){
-+ { 0, "begin",
-+ { NULL,
-+ (cmdarg_t[1]){
-+ // subject
-+ { CMDOPT_CATCHALL | CMDOPT_PLAIN | CMDOPT_LAST, { .arg = NULL } },
-+ },
-+ NULL, NULL, }, (gpointer)msay_scmd_begin },
-+ { 0, "verbatim",
-+ { NULL,
-+ (cmdarg_t[1]){
-+ // subject
-+ { CMDOPT_CATCHALL | CMDOPT_PLAIN | CMDOPT_LAST, { .arg = NULL } },
-+ },
-+ NULL, NULL },
-+ (gpointer)msay_scmd_verbatim },
-+ { 0, "send",
-+ { (cmdopt_t[2]){
-+ { CMDOPT_SWITCH, 'n', "normal", { .swc = 0 } },
-+ { CMDOPT_SWITCH | CMDOPT_LAST, 'h', "headline", { .swc = 0 } },
-+ },
-+ NULL, NULL, NULL }, (gpointer)msay_scmd_send },
-+ { 0, "send_to",
-+ { (cmdopt_t[2]){
-+ { CMDOPT_SWITCH, 'n', "normal", { .swc = 0 } },
-+ { CMDOPT_SWITCH | CMDOPT_LAST, 'h', "headline", { .swc = 0 } },
-+ },
-+ (cmdarg_t[1]){
-+ // jid
-+ { CMDOPT_REQUIRED | CMDOPT_LAST, { .arg = NULL } },
-+ },
-+ NULL, NULL }, (gpointer)msay_scmd_send_to },
-+ { 0, "toggle",
-+ { NULL, NULL, NULL, NULL },
-+ (gpointer)msay_scmd_toggle },
-+ { 0, "toggle_verbatim",
-+ { NULL, NULL, NULL, NULL },
-+ (gpointer)msay_scmd_toggle_verbatim },
-+ { CMDOPT_LAST, "abort",
-+ { NULL, NULL, NULL, NULL },
-+ (gpointer)msay_scmd_abort },
++ (cmdopts_t[7]){
++ { "begin", NULL,
++ (cmdarg_t[1]){
++ // subject
++ { CMDOPT_CATCHALL | CMDOPT_PLAIN | CMDOPT_LAST, { .arg = NULL } },
++ },
++ NULL, (gpointer)msay_scmd_begin, 0 },
++ { "verbatim", NULL,
++ (cmdarg_t[1]){
++ // subject
++ { CMDOPT_CATCHALL | CMDOPT_PLAIN | CMDOPT_LAST, { .arg = NULL } },
++ },
++ NULL, (gpointer)msay_scmd_verbatim, 0 },
++ { "send",
++ (cmdopt_t[2]){
++ { CMDOPT_SWITCH, 'n', "normal", { .swc = 0 } },
++ { CMDOPT_SWITCH | CMDOPT_LAST, 'h', "headline", { .swc = 0 } },
++ },
++ NULL, NULL, (gpointer)msay_scmd_send, 0 },
++ { "send_to",
++ (cmdopt_t[2]){
++ { CMDOPT_SWITCH, 'n', "normal", { .swc = 0 } },
++ { CMDOPT_SWITCH | CMDOPT_LAST, 'h', "headline", { .swc = 0 } },
++ },
++ (cmdarg_t[1]){
++ // jid
++ { CMDOPT_REQUIRED | CMDOPT_LAST, { .arg = NULL } },
++ },
++ NULL, (gpointer)msay_scmd_send_to, 0 },
++ { "toggle", NULL, NULL, NULL, (gpointer)msay_scmd_toggle, 0 },
++ { "toggle_verbatim", NULL, NULL, NULL,
++ (gpointer)msay_scmd_toggle_verbatim, 0 },
++ { "abort", NULL, NULL, NULL, (gpointer)msay_scmd_abort, CMDOPT_LAST },
+ },
-+ NULL,
+ };
+ const char *msg;
+
-+ {
-+ const char *error = cmdopts_parse(arg, &options);
-+ if (error != NULL) {
-+ scr_log_print(LPRINT_NORMAL, error);
-+ return;
-+ }
- }
-
-- if (!strcasecmp(subcmd, "toggle")) {
++ if (cmdopts_parse(arg, &options))
++ return;
++
+ subcmd = (enum msay_scmd_t) options.args[0].value.cmd -> userdata;
+
+ if (subcmd == msay_scmd_toggle) {
- if (scr_get_multimode())
-- subcmd = "send";
++ if (scr_get_multimode())
+ subcmd = msay_scmd_send;
- else
-- subcmd = "begin";
-- } else if (!strcasecmp(subcmd, "toggle_verbatim")) {
++ else
+ subcmd = msay_scmd_begin;
+ } else if (subcmd == msay_scmd_toggle_verbatim) {
- if (scr_get_multimode())
-- subcmd = "send";
++ if (scr_get_multimode())
+ subcmd = msay_scmd_send;
- else
-- subcmd = "verbatim";
++ else
+ subcmd = msay_scmd_verbatim;
}
+- if (!strcasecmp(subcmd, "toggle")) {
+- if (scr_get_multimode())
+- subcmd = "send";
+- else
+- subcmd = "begin";
+- } else if (!strcasecmp(subcmd, "toggle_verbatim")) {
+- if (scr_get_multimode())
+- subcmd = "send";
+- else
+- subcmd = "verbatim";
+- }
+-
- if (!strcasecmp(subcmd, "abort")) {
+ if (subcmd == msay_scmd_abort) {
if (scr_get_multimode())
@@ -1130,7 +1284,7 @@
- scr_set_multimode(2, subj_utf8);
- verbat = TRUE;
+ } else if (subcmd == msay_scmd_begin || subcmd == msay_scmd_verbatim) {
-+ gchar *subject = options.args[0].value.cmd -> options.args[0].value.arg;
++ gchar *subject = options.args[0].value.cmd -> args[0].value.arg;
+
+ if (subcmd == msay_scmd_verbatim) {
+ scr_set_multimode(2, subject);
@@ -1161,7 +1315,7 @@
if (!scr_get_multimode()) {
scr_LogPrint(LPRINT_NORMAL, "No message to send. "
-@@ -1508,49 +1714,47 @@
+@@ -1508,49 +1650,47 @@
scr_set_chatmode(TRUE);
scr_show_buddy_window();
@@ -1203,15 +1357,15 @@
- send_message(msg_utf8, scr_get_multimode_subj(), scan_mtype(&arg));
- g_free(msg_utf8);
+ if ((msg = scr_get_multiline())) {
-+ LmMessageSubType msg_type = LM_MESSAGE_SUB_TYPE_NOT_SET;
++ msgtype_t msg_type = msgtype_not_set;
+
-+ if (options.args[0].value.cmd -> options.opts[0].value.swc) // n
-+ msg_type = LM_MESSAGE_SUB_TYPE_NORMAL;
-+ else if (options.args[0].value.cmd -> options.opts[1].value.swc) // h
-+ msg_type = LM_MESSAGE_SUB_TYPE_HEADLINE;
++ if (options.args[0].value.cmd -> opts[0].value.swc) // n
++ msg_type = msgtype_normal;
++ else if (options.args[0].value.cmd -> opts[1].value.swc) // h
++ msg_type = msgtype_headline;
+
+ if (subcmd == msay_scmd_send_to) {
-+ const char *jid = options.cmds[3].options.args[0].value.arg;
++ const char *jid = options.cmds[3].args[0].value.arg;
+
+ // Let's send to the specified JID. We leave now if there
+ // has been an error (so we don't leave multi-line mode).
@@ -1247,24 +1401,30 @@
}
// load_message_from_file(filename)
-@@ -1634,130 +1838,110 @@
+@@ -1566,7 +1706,7 @@
+ char *next_utf8_char;
+ size_t len;
+
+- fd = fopen(filename, "r");
++ fd = fopen(filename, "r"); // FIXME g_from_utf8
+
+ if (!fd || fstat(fileno(fd), &buf)) {
+ scr_LogPrint(LPRINT_LOGNORM, "Cannot open message file (%s)", filename);
+@@ -1634,130 +1774,103 @@
static void do_say_to(char *arg)
{
- char **paramlst;
- char *fjid, *msg_utf8;
-+ char *fjid;
- char *msg;
+- char *msg;
- char *unescaped_msg = NULL;
- char *uncompletedfjid = NULL;
- char *file = NULL;
-+ char *file;
-+ gchar *freeme = NULL; // fjid
-+ gchar *freeme2 = NULL; // msg
- LmMessageSubType msg_type = LM_MESSAGE_SUB_TYPE_NOT_SET;
+- LmMessageSubType msg_type = LM_MESSAGE_SUB_TYPE_NOT_SET;
- bool quiet = FALSE;
- bool eval = FALSE;
+ cmdopts_t options = {
++ "say_to",
+ (cmdopt_t[5]){
+ { CMDOPT_SWITCH, 'n', "normal", { .swc = 0 } },
+ { CMDOPT_SWITCH, 'h', "headline", { .swc = 0 } },
@@ -1279,8 +1439,11 @@
+ { CMDOPT_LAST | CMDOPT_PLAIN | CMDOPT_CATCHALL, { .arg = NULL } },
+ },
+ NULL,
-+ NULL,
+ };
++ char *fjid, *msg, *file;
++ gchar *freeme = NULL; // fjid
++ gchar *freeme2 = NULL; // msg
++ msgtype_t msg_type = msgtype_not_set;
if (!xmpp_is_online()) {
scr_LogPrint(LPRINT_NORMAL, "You are not connected.");
@@ -1293,15 +1456,10 @@
- if (!*paramlst) { // No parameter?
- scr_LogPrint(LPRINT_NORMAL, "Please specify a Jabber ID.");
- free_arg_lst(paramlst);
-- return;
-+ { // parse arguments
-+ const char *error = cmdopts_parse(arg, &options);
-+ if (error != NULL) {
-+ scr_log_print(LPRINT_NORMAL, error);
-+ return;
-+ }
- }
-
++ if (cmdopts_parse(arg, &options))
+ return;
+- }
+-
- // Check for an option parameter
- while (*paramlst) {
- if (!strcmp(*paramlst, "-q")) {
@@ -1341,10 +1499,11 @@
- fjid = *paramlst;
- msg = *(paramlst+1);
-
-+ if (options.opts[0].value.swc)
-+ msg_type = LM_MESSAGE_SUB_TYPE_NORMAL;
-+ else if (options.opts[1].value.swc)
-+ msg_type = LM_MESSAGE_SUB_TYPE_HEADLINE;
++
++ if (options.opts[0].value.swc) // n
++ msg_type = msgtype_normal;
++ else if (options.opts[1].value.swc) // h
++ msg_type = msgtype_headline;
+
+ fjid = options.args[0].value.arg;
+ msg = options.args[1].value.arg;
@@ -1438,10 +1597,377 @@
}
// buffer_updown(updown, nblines)
+@@ -1775,27 +1888,10 @@
+ scr_buffer_scroll_up_down(updown, nblines);
+ }
+
+-static void buffer_search(int direction, char *arg)
+-{
+- if (!arg || !*arg) {
+- scr_LogPrint(LPRINT_NORMAL, "Missing parameter.");
+- return;
+- }
+-
+- scr_buffer_search(direction, arg);
+-}
+-
+ static void buffer_date(char *date)
+ {
+ time_t t;
+
+- if (!date || !*date) {
+- scr_LogPrint(LPRINT_NORMAL, "Missing parameter.");
+- return;
+- }
+-
+- strip_arg_special_chars(date);
+-
+ t = from_iso8601(date, 0);
+ if (t)
+ scr_buffer_date(t);
+@@ -1804,98 +1900,156 @@
+ "not correctly formatted or invalid.");
+ }
+
+-static void buffer_percent(char *arg1, char *arg2)
++// XXX % command before was able to handle %50
++static void do_buffer(char *arg)
+ {
+- // Basically, user has typed "%arg1 arg2"
+- // "%50" -> arg1 = 50, arg2 null pointer
+- // "% 50" -> arg1 = \0, arg2 = 50
+-
+- if (!*arg1 && (!arg2 || !*arg2)) { // No value
+- scr_LogPrint(LPRINT_NORMAL, "Missing parameter.");
++ enum buffer_scmd_t {
++ buffer_scmd_close, buffer_scmd_close_all,
++ buffer_scmd_clear, buffer_scmd_purge,
++ buffer_scmd_list,
++ buffer_scmd_top, buffer_scmd_bottom, buffer_scmd_up, buffer_scmd_down,
++ buffer_scmd_date, buffer_scmd_percent, buffer_scmd_readmark,
++ buffer_scmd_search_backward, buffer_scmd_search_forward,
++ buffer_scmd_scroll_lock, buffer_scmd_scroll_unlock,
++ buffer_scmd_scroll_toggle,
++ buffer_scmd_save,
++ } subcmd;
++ cmdopts_t options = {
++ "buffer",
++ NULL,
++ (cmdarg_t[1]){
++ { CMDOPT_REQUIRED | CMDOPT_SUBCOMMAND | CMDOPT_LAST, { .cmd = NULL } },
++ },
++ (cmdopts_t[18]){
++ { "close",
++ (cmdopt_t[1]){
++ { CMDOPT_SWITCH | CMDOPT_LAST, 'a', "all", { .swc = 0 } }
++ },
++ (cmdarg_t[1]){
++ { CMDOPT_LAST, { .cmd = NULL } } // jid
++ },
++ NULL, (gpointer)buffer_scmd_close, 0 },
++ { "close_all", NULL, NULL, NULL, (gpointer)buffer_scmd_close_all, 0 },
++ { "clear", NULL, NULL, NULL, (gpointer)buffer_scmd_clear, 0 },
++ { "purge", NULL,
++ (cmdarg_t[1]){
++ { CMDOPT_LAST, { .arg = NULL } }, // jid
++ },
++ NULL, (gpointer)buffer_scmd_purge, 0 },
++ { "list", NULL, NULL, NULL, (gpointer)buffer_scmd_list, 0 },
++ { "top", NULL, NULL, NULL, (gpointer)buffer_scmd_top, 0 },
++ { "bottom", NULL, NULL, NULL, (gpointer)buffer_scmd_bottom, 0 },
++ { "up", NULL,
++ (cmdarg_t[1]){
++ { CMDOPT_LAST, { .arg = "1" } }, // lines
++ },
++ NULL, (gpointer)buffer_scmd_up, 0 },
++ { "down", NULL,
++ (cmdarg_t[1]){
++ { CMDOPT_LAST, { .arg = "1" } }, // lines
++ },
++ NULL, (gpointer)buffer_scmd_down, 0 },
++ { "date", NULL,
++ (cmdarg_t[1]){
++ // date
++ { CMDOPT_CATCHALL | CMDOPT_REQUIRED | CMDOPT_LAST, { .arg = "1" } },
++ },
++ NULL, (gpointer)buffer_scmd_date, 0 },
++ { "%", NULL,
++ (cmdarg_t[1]){
++ { CMDOPT_REQUIRED | CMDOPT_LAST, { .arg = "100" } }, // percent
++ },
++ NULL, (gpointer)buffer_scmd_percent, 0 },
++ { "readmark", NULL, NULL, NULL, (gpointer)buffer_scmd_readmark, 0 },
++ { "search_backward", NULL,
++ (cmdarg_t[1]){
++ { CMDOPT_REQUIRED | CMDOPT_CATCHALL | CMDOPT_LAST,
++ { .arg = NULL } },
++ },
++ NULL, (gpointer)buffer_scmd_search_backward, 0 },
++ { "search_forward", NULL,
++ (cmdarg_t[1]){
++ { CMDOPT_REQUIRED | CMDOPT_CATCHALL | CMDOPT_LAST,
++ { .arg = NULL } },
++ },
++ NULL, (gpointer)buffer_scmd_search_forward, 0 },
++ { "scroll_lock", NULL, NULL, NULL,
++ (gpointer)buffer_scmd_scroll_lock, 0 },
++ { "scroll_unlock", NULL, NULL, NULL,
++ (gpointer)buffer_scmd_scroll_unlock, 0 },
++ { "scroll_toggle", NULL, NULL, NULL,
++ (gpointer)buffer_scmd_scroll_toggle, 0 },
++ { "save", NULL,
++ (cmdarg_t[1]){
++ { CMDOPT_REQUIRED | CMDOPT_CATCHALL | CMDOPT_PLAIN | CMDOPT_LAST,
++ { .arg = NULL } },
++ },
++ NULL, (gpointer)buffer_scmd_save, CMDOPT_LAST },
++ },
++ };
++
++ if (!current_buddy)
++ return;
++
++ if (cmdopts_parse(arg, &options))
++ return;
++
++ subcmd = (enum buffer_scmd_t) options.args[0].value.cmd -> userdata;
++
++ if (subcmd == buffer_scmd_close && options.cmds[0].opts[0].value.swc)
++ subcmd = buffer_scmd_close_all;
++
++ if (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_GROUP &&
++ subcmd != buffer_scmd_close_all) {
++ scr_LogPrint(LPRINT_NORMAL, "Groups have no buffer.");
++ cmdopts_free(&options);
+ return;
+ }
+
+- if (*arg1 && arg2 && *arg2) { // Two values
+- scr_LogPrint(LPRINT_NORMAL, "Wrong parameters.");
+- return;
++ if (subcmd == buffer_scmd_top) {
++ scr_buffer_top_bottom(-1);
++ } else if (subcmd == buffer_scmd_bottom) {
++ scr_buffer_top_bottom(1);
++ } else if (subcmd == buffer_scmd_clear) {
++ scr_buffer_clear();
++ } else if (subcmd == buffer_scmd_close) {
++ scr_buffer_purge(1, options.cmds[0].args[0].value.arg);
++ } else if (subcmd == buffer_scmd_close_all) {
++ scr_buffer_purge_all(1);
++ } else if (subcmd == buffer_scmd_purge) {
++ scr_buffer_purge(0, options.cmds[3].args[0].value.arg);
++ } else if (subcmd == buffer_scmd_scroll_lock) {
++ scr_buffer_scroll_lock(1);
++ } else if (subcmd == buffer_scmd_scroll_unlock) {
++ scr_buffer_scroll_lock(0);
++ } else if (subcmd == buffer_scmd_scroll_toggle) {
++ scr_buffer_scroll_lock(-1);
++ } else if (subcmd == buffer_scmd_up) {
++ buffer_updown(-1, options.cmds[6].args[0].value.arg);
++ } else if (subcmd == buffer_scmd_down) {
++ buffer_updown(1, options.cmds[7].args[0].value.arg);
++ } else if (subcmd == buffer_scmd_search_backward) {
++ scr_buffer_search(-1, options.cmds[11].args[0].value.arg);
++ } else if (subcmd == buffer_scmd_search_forward) {
++ scr_buffer_search(1, options.cmds[12].args[0].value.arg);
++ } else if (subcmd == buffer_scmd_date) {
++ buffer_date(options.cmds[8].args[0].value.arg);
++ } else if (subcmd == buffer_scmd_percent) {
++ scr_buffer_percent(atoi(options.cmds[9].args[0].value.arg));
++ } else if (subcmd == buffer_scmd_save) {
++ scr_buffer_dump(options.cmds[17].args[0].value.arg);
++ } else if (subcmd == buffer_scmd_list) {
++ scr_buffer_list();
++ } else { // buffer_scmd_readmark
++ scr_buffer_jump_readmark();
+ }
+
+- scr_buffer_percent(atoi((*arg1 ? arg1 : arg2)));
+-}
+-
+-static void do_buffer(char *arg)
+-{
+- char **paramlst;
+- char *subcmd;
+-
+- if (!current_buddy)
+- return;
+-
+- paramlst = split_arg(arg, 2, 1); // subcmd, arg
+- subcmd = *paramlst;
+- arg = *(paramlst+1);
+-
+- if (!subcmd || !*subcmd) {
+- scr_LogPrint(LPRINT_NORMAL, "Missing parameter.");
+- free_arg_lst(paramlst);
+- return;
+- }
+-
+- if (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_GROUP &&
+- strcasecmp(subcmd, "close_all")) {
+- scr_LogPrint(LPRINT_NORMAL, "Groups have no buffer.");
+- free_arg_lst(paramlst);
+- return;
+- }
+-
+- if (!strcasecmp(subcmd, "top")) {
+- scr_buffer_top_bottom(-1);
+- } else if (!strcasecmp(subcmd, "bottom")) {
+- scr_buffer_top_bottom(1);
+- } else if (!strcasecmp(subcmd, "clear")) {
+- scr_buffer_clear();
+- } else if (!strcasecmp(subcmd, "close")) {
+- scr_buffer_purge(1, arg);
+- } else if (!strcasecmp(subcmd, "close_all")) {
+- scr_buffer_purge_all(1);
+- } else if (!strcasecmp(subcmd, "purge")) {
+- scr_buffer_purge(0, arg);
+- } else if (!strcasecmp(subcmd, "scroll_lock")) {
+- scr_buffer_scroll_lock(1);
+- } else if (!strcasecmp(subcmd, "scroll_unlock")) {
+- scr_buffer_scroll_lock(0);
+- } else if (!strcasecmp(subcmd, "scroll_toggle")) {
+- scr_buffer_scroll_lock(-1);
+- } else if (!strcasecmp(subcmd, "up")) {
+- buffer_updown(-1, arg);
+- } else if (!strcasecmp(subcmd, "down")) {
+- buffer_updown(1, arg);
+- } else if (!strcasecmp(subcmd, "search_backward")) {
+- strip_arg_special_chars(arg);
+- buffer_search(-1, arg);
+- } else if (!strcasecmp(subcmd, "search_forward")) {
+- strip_arg_special_chars(arg);
+- buffer_search(1, arg);
+- } else if (!strcasecmp(subcmd, "date")) {
+- buffer_date(arg);
+- } else if (*subcmd == '%') {
+- buffer_percent(subcmd+1, arg);
+- } else if (!strcasecmp(subcmd, "save")) {
+- scr_buffer_dump(arg);
+- } else if (!strcasecmp(subcmd, "list")) {
+- scr_buffer_list();
+- } else if (!strcasecmp(subcmd, "readmark")) {
+- scr_buffer_jump_readmark();
+- } else {
+- scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
+- }
+-
+- free_arg_lst(paramlst);
++ cmdopts_free(&options);
+ }
+
+ static void do_clear(char *arg) // Alias for "buffer clear"
+ {
+- do_buffer("clear");
++ scr_buffer_clear();
+ }
+
+ static void do_info(char *arg)
+@@ -2033,29 +2187,20 @@
+ }
+ }
+
++enum room_names_style_t {
++ room_names_style_normal = 0,
++ room_names_style_detail,
++ room_names_style_short,
++ room_names_style_quiet,
++ room_names_style_compact,
++};
++
+ // room_names() is a variation of do_info(), for chatrooms only
+-static void room_names(gpointer bud, char *arg)
++static void room_names(gpointer bud, enum room_names_style_t style)
+ {
+ const char *bjid;
+ char *buffer;
+ GSList *resources, *p_res;
+- enum { style_normal = 0, style_detail, style_short,
+- style_quiet, style_compact } style = 0;
+-
+- if (*arg) {
+- if (!strcasecmp(arg, "--short"))
+- style = style_short;
+- else if (!strcasecmp(arg, "--quiet"))
+- style = style_quiet;
+- else if (!strcasecmp(arg, "--detail"))
+- style = style_detail;
+- else if (!strcasecmp(arg, "--compact"))
+- style = style_compact;
+- else {
+- scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
+- return;
+- }
+- }
+
+ // Enter chat mode
+ scr_set_chatmode(TRUE);
+@@ -2075,12 +2220,12 @@
+ rstatus = buddy_getstatus(bud, p_res->data);
+ rst_msg = buddy_getstatusmsg(bud, p_res->data);
+
+- if (style == style_short) {
++ if (style == room_names_style_short) {
+ snprintf(buffer, 4095, "[%c] %s%s%s", imstatus2char[rstatus],
+ (char*)p_res->data,
+ rst_msg ? " -- " : "", rst_msg ? rst_msg : "");
+ scr_WriteIncomingMessage(bjid, buffer, 0, HBB_PREFIX_INFO, 0);
+- } else if (style == style_compact) {
++ } else if (style == room_names_style_compact) {
+ enum imrole role = buddy_getrole(bud, p_res->data);
+ enum imaffiliation affil = buddy_getaffil(bud, p_res->data);
+ bool showaffil = (affil != affil_none);
+@@ -2096,12 +2241,12 @@
+ snprintf(buffer, 4095, "[%c] %s", imstatus2char[rstatus],
+ (char*)p_res->data);
+ scr_WriteIncomingMessage(bjid, buffer, 0, HBB_PREFIX_INFO, 0);
+- if (rst_msg && style != style_quiet) {
++ if (rst_msg && style != room_names_style_quiet) {
+ snprintf(buffer, 4095, "Status message: %s", rst_msg);
+ scr_WriteIncomingMessage(bjid, buffer,
+ 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+ }
+- if (style == style_detail) {
++ if (style == room_names_style_detail) {
+ enum imrole role = buddy_getrole(bud, p_res->data);
+ enum imaffiliation affil = buddy_getaffil(bud, p_res->data);
+
+@@ -2874,7 +3019,7 @@
+ fjid_utf8 = g_strdup_printf("%s/%s", buddy_getjid(bud), nick_utf8);
+ g_free (nick_utf8);
+ msg = to_utf8(arg);
+- send_message_to(fjid_utf8, msg, NULL, LM_MESSAGE_SUB_TYPE_NOT_SET, FALSE);
++ send_message_to(fjid_utf8, msg, NULL, msgtype_not_set, FALSE);
+ g_free(fjid_utf8);
+ g_free(msg);
+ free_arg_lst(paramlst);
+@@ -3347,7 +3492,7 @@
+ cmd_room_leave(bud, arg);
+ } else if (!strcasecmp(subcmd, "names")) {
+ if ((arg = check_room_subcommand(arg, FALSE, bud)) != NULL)
+- room_names(bud, arg);
++ room_names(bud, room_names_style_normal); // FIXME
+ } else if (!strcasecmp(subcmd, "nick")) {
+ if ((arg = check_room_subcommand(arg, FALSE, bud)) != NULL)
+ room_nick(bud, arg);
diff -r 92fa48ef53c9 mcabber/mcabber/commands.h
--- a/mcabber/mcabber/commands.h Sun Jan 27 00:40:37 2013 +0200
-+++ b/mcabber/mcabber/commands.h Tue Feb 26 01:21:26 2013 +0200
-@@ -29,8 +29,9 @@
++++ b/mcabber/mcabber/commands.h Tue Feb 26 23:50:10 2013 +0200
+@@ -14,6 +14,12 @@
+ gpointer userdata;
+ } cmd;
+
++typedef enum {
++ msgtype_not_set,
++ msgtype_normal,
++ msgtype_headline,
++} msgtype_t;
++
+ void cmd_init(void);
+ cmd *cmd_get(const char *command);
+ int process_line(const char *line);
+@@ -29,8 +35,9 @@
void cmd_room_whois(gpointer bud, const char *nick, guint interactive);
void cmd_room_leave(gpointer bud, char *arg);
@@ -1449,13 +1975,13 @@
-void say_cmd(char *arg, int parse_flags);
+void cmd_setstatus(const char *recipient,
+ const char *status, const char *message);
-+void say_cmd(char *arg, LmMessageSubType msg_type);
++void say_cmd(char *arg, msgtype_t msgtype);
#endif /* __MCABBER_COMMANDS_H__ */
diff -r 92fa48ef53c9 mcabber/mcabber/roster.c
--- a/mcabber/mcabber/roster.c Sun Jan 27 00:40:37 2013 +0200
-+++ b/mcabber/mcabber/roster.c Tue Feb 26 01:21:26 2013 +0200
++++ b/mcabber/mcabber/roster.c Tue Feb 26 23:50:10 2013 +0200
@@ -1586,13 +1586,14 @@
// Look for a buddy whose name or jid contains string.
// Search begins at current_buddy; if no match is found in the the buddylist,
@@ -1496,8 +2022,8 @@
}
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 Tue Feb 26 01:21:26 2013 +0200
-@@ -555,6 +555,317 @@
++++ b/mcabber/mcabber/utils.c Tue Feb 26 23:50:10 2013 +0200
+@@ -555,6 +555,318 @@
*str = tolower(*str);
}
@@ -1689,7 +2215,7 @@
+ } else { // command argument
+ if (argument -> flags & CMDOPT_SUBCOMMAND) {
+ gboolean found = FALSE;
-+ subcmd_t *subcommand = options -> cmds;
++ cmdopts_t *subcommand = options -> cmds;
+ if (subcommand) {
+ do {
+ if (!g_strcmp0(s, subcommand -> name)) {
@@ -1700,7 +2226,7 @@
+ }
+ if (found) {
+ argument -> value.cmd = subcommand;
-+ error = cmdopts_parse_internal(p, e, &(subcommand -> options));
++ error = cmdopts_parse_internal(p, e, subcommand);
+ break;
+ } else {
+ error = "Unknown subcommand";
@@ -1786,6 +2312,7 @@
+ options -> freeme = utf8;
+ error = cmdopts_parse_internal(utf8, e, options);
+ if (error) {
++ scr_log_print(LPRINT_NORMAL, "%s: %s", options -> name, error);
+ cmdopts_free(options);
+ }
+ return error;
@@ -1794,7 +2321,7 @@
+void cmdopts_free(cmdopts_t *options)
+{
+ cmdopt_t *option = options -> opts;
-+ subcmd_t *subcommand = options -> cmds;
++ cmdopts_t *subcommand = options -> cmds;
+ if (option) {
+ do {
+ if ((option -> flags & (CMDOPT_CATCHALL|CMDOPT_SWITCH)) == CMDOPT_CATCHALL) {
@@ -1805,7 +2332,7 @@
+ }
+ if (subcommand) {
+ do {
-+ cmdopts_free(&(subcommand -> options));
++ cmdopts_free(subcommand);
+ } while (!(subcommand++ -> flags & CMDOPT_LAST));
+ }
+ g_free(options -> freeme);
@@ -1817,8 +2344,8 @@
// 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 Tue Feb 26 01:21:26 2013 +0200
-@@ -43,6 +43,101 @@
++++ b/mcabber/mcabber/utils.h Tue Feb 26 23:50:10 2013 +0200
+@@ -43,6 +43,97 @@
char **split_arg(const char *arg, unsigned int n, int dontstriplast);
void free_arg_lst(char **arglst);
@@ -1881,7 +2408,6 @@
+// - we call callback
+// - we free resources
+typedef struct cmdopts_struct cmdopts_t;
-+typedef struct subcmd_struct subcmd_t;
+typedef union {
+ GSList *multiopt;
+ gchar *opt;
@@ -1894,24 +2420,21 @@
+ cmdopt_value_t value;
+} cmdopt_t;
+typedef union {
-+ gchar *arg;
-+ subcmd_t *cmd;
++ gchar *arg;
++ cmdopts_t *cmd;
+} cmdarg_value_t;
+typedef struct {
+ guint flags;
+ cmdarg_value_t value;
+} cmdarg_t;
+struct cmdopts_struct {
-+ cmdopt_t *opts;
-+ cmdarg_t *args;
-+ subcmd_t *cmds;
-+ gchar *freeme; // private
-+};
-+struct subcmd_struct {
-+ guint flags;
+ const char *name;
-+ cmdopts_t options;
-+ gpointer userdata; // unused, for user convenience
++ cmdopt_t *opts;
++ cmdarg_t *args;
++ cmdopts_t *cmds;
++ gpointer userdata; // unused, for user's convenience
++ guint flags; // only meaningful for subcommands
++ gchar *freeme; // private
+};
+
+const char *cmdopts_parse (const char *arg, cmdopts_t *options);
@@ -1922,7 +2445,7 @@
char *ut_unescape_tabs_cr(const char *text);
diff -r 92fa48ef53c9 mcabber/mcabber/xmpp_iq.c
--- a/mcabber/mcabber/xmpp_iq.c Sun Jan 27 00:40:37 2013 +0200
-+++ b/mcabber/mcabber/xmpp_iq.c Tue Feb 26 01:21:26 2013 +0200
++++ b/mcabber/mcabber/xmpp_iq.c Tue Feb 26 23:50:10 2013 +0200
@@ -289,10 +289,7 @@
if (value) {
for (s = adhoc_status_list; !s->name || strcmp(s->name, value); s++);