templatecmd.c
changeset 0 1c4eb7aed6c2
child 1 9eb794ebef85
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templatecmd.c	Sat Dec 05 22:32:55 2009 +0200
@@ -0,0 +1,214 @@
+
+/* Copyright 2009 Myhailo Danylenko
+ *
+ * This file is part of mcabber-templatecmd
+ *
+ * mcabber-templatecmd is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+
+#include <glib.h>
+#include <gmodule.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "compl.h"
+#include "commands.h"
+#include "utils.h"
+#include "logprint.h"
+
+typedef struct {
+	gchar    *name;
+	gchar    *template;
+	int       maxarg;
+	gboolean  stararg;
+} tcmd_t;
+
+static GSList *template_commands = NULL;
+
+static void tcmd_callback (char *arg, gpointer udata)
+{
+	tcmd_t   *tcmd     = (tcmd_t *) udata;
+	char    **args     = NULL;
+	GString  *command  = g_string_new (NULL);
+	char     *template = tcmd -> template;
+	char     *p;
+
+	if (tcmd -> maxarg > 0)
+		args = split_arg (arg, tcmd -> maxarg, TRUE);
+
+	for (p = template; *p; ++p) {
+		if (*p != '$' || !*(p + 1) || !strchr ("*$0123456789", *(p + 1))) {
+			g_string_append_c (command, *p);
+			continue;
+		}
+
+		++p;
+
+		if (*p == '*')
+			g_string_append (command, arg);
+		else if (*p == '$')
+			g_string_append_c (command, '$');
+		else {
+			int argnum = atoi (p);
+
+			if (argnum == 0)
+				g_string_append (command, tcmd -> name);
+			else if (args[argnum - 1])
+				g_string_append (command, args[argnum - 1]);
+
+			while (*(p + 1) && strchr ("0123456789", *(p + 1)))
+				++p;
+		}
+	}
+
+	{
+		char *cmd = g_string_free (command, FALSE);
+		process_command (cmd, 1);
+		g_free (cmd);
+	}
+
+	if (args)
+		free_arg_lst (args);
+}
+
+static void do_templatecmd (char *arg)
+{
+	if (!*arg) { // list tcmds
+
+		GSList *tel;
+
+		for (tel = template_commands; tel; tel = tel -> next) {
+			tcmd_t *tcmd = (tcmd_t *) tel -> data;
+			scr_LogPrint (LPRINT_NORMAL, "Templatecmd %s = %s", tcmd -> name, tcmd -> template);
+		}
+
+	} else {
+
+		char *nend = strchr (arg, '=');
+
+		if (!nend) { // show tcmd
+
+			GSList *tel;
+
+			for (tel = template_commands; tel; tel = tel -> next) {
+				tcmd_t *tcmd = (tcmd_t *) tel -> data;
+
+				if (!strcmp (arg, tcmd -> name)) {
+					scr_LogPrint (LPRINT_NORMAL, "Templatecmd %s = %s", tcmd -> name, tcmd -> template);
+					return;
+				}
+			}
+
+			scr_LogPrint (LPRINT_NORMAL, "No template with such name.");
+
+		} else if (nend == arg) // error
+
+			scr_LogPrint (LPRINT_NORMAL, "You must specify command name.");
+
+		else { // new/modify tcmd
+
+			GSList *tel;
+			tcmd_t *template_command = NULL;
+			char   *astart           = nend + 1;
+			int     len;
+
+			for (--nend; nend > arg && *nend == ' '; --nend);
+			len = nend + 1 - arg;
+
+			for (tel = template_commands; tel; tel = tel -> next) {
+				tcmd_t *tcmd = (tcmd_t *) tel -> data;
+
+				if (!strncmp (arg, tcmd -> name, len)) {
+					template_command = tcmd;
+					break;
+				}
+			}
+
+			for (;*astart && *astart == ' '; ++astart);
+
+			if (!*astart) { // delete tcmd
+				if (template_command) {
+					cmd_del (template_command -> name);
+					template_commands = g_slist_remove (template_commands, template_command);
+					g_free (template_command -> name);
+					g_free (template_command -> template);
+					g_free (template_command);
+				}
+				return;
+			}
+
+			if (!template_command) {
+				template_command = g_new (tcmd_t, 1);
+				template_command -> name = g_strndup (arg, len);
+			} else
+				g_free (template_command -> template);
+
+			template_command -> template = g_strdup (astart);
+
+			{
+				int      maxarg  = -1;
+				gboolean stararg = FALSE;
+
+				for (astart = strchr (astart, '$'); astart; astart = strchr (astart, '$')) {
+					++astart;
+
+					if (!*astart)
+						break;
+
+					if (strchr ("0123456789", *astart)) {
+						int anum = atoi (astart);
+
+						if (maxarg < anum)
+							maxarg = anum;
+
+					} else if (*astart == '*')
+						stararg = TRUE;
+				}
+
+				template_command -> maxarg  = maxarg;
+				template_command -> stararg = stararg;
+			}
+
+			template_commands = g_slist_append (template_commands, template_command);
+
+			cmd_add (template_command -> name, "", 0, 0, (void (*) (char *arg)) tcmd_callback, template_command);
+		}
+	}
+}
+
+
+const gchar *g_module_check_init (GModule *module)
+{
+	cmd_add ("templatecmd", "", COMPL_CMD, COMPL_CMD, do_templatecmd, NULL);
+
+	return NULL;
+}
+
+void g_module_unload (GModule *module)
+{
+	GSList *tel;
+
+	cmd_del ("templatecmd");
+
+	for (tel = template_commands; tel; tel = tel -> next) {
+		tcmd_t *template_command = (tcmd_t *) tel -> data;
+		cmd_del (template_command -> name);
+		g_free (template_command -> name);
+		g_free (template_command -> template);
+		g_free (template_command);
+	}
+
+	g_slist_free (template_commands);
+}
+
+/* vim: se ts=4 sw=4: */