This adds an implementation hooks using a RB tree to store the name of the
hook and the command-list it uses.  These will be accessed via commands to
add/remove hooks.
---
 hooks.c   |  114 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 session.c |    2 ++
 tmux.c    |    2 ++
 tmux.h    |   23 +++++++++++++
 4 files changed, 141 insertions(+)
 create mode 100644 hooks.c

diff --git a/hooks.c b/hooks.c
new file mode 100644
index 0000000..dfc4088
--- /dev/null
+++ b/hooks.c
@@ -0,0 +1,114 @@
+/* $Id$ */
+
+/*
+ * Copyright (c) 2012 Thomas Adam <tho...@xteddy.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <stdlib.h>
+
+#include <string.h>
+
+#include "tmux.h"
+
+RB_GENERATE(hooks, hook, entry, hooks_cmp);
+
+int
+hooks_cmp(struct hook *hook1, struct hook *hook2)
+{
+       return (strcmp(hook1->name, hook2->name));
+}
+
+void
+hooks_init(struct hooks *hooks, struct hooks *copy)
+{
+       RB_INIT(hooks);
+
+       if (copy != NULL)
+               hooks_copy(copy, hooks);
+}
+
+void
+hooks_copy(struct hooks *src, struct hooks *dst)
+{
+       struct hook     *h;
+
+       RB_FOREACH(h, hooks, src)
+               hooks_add(dst, h->name, h->cmdlist);
+}
+
+void
+hooks_free(struct hooks *hooks)
+{
+       struct hook     *h, *h2;
+
+       RB_FOREACH_SAFE(h, hooks, hooks, h2)
+               hooks_remove(hooks, h);
+}
+
+void
+hooks_add(struct hooks *hooks, const char *name, struct cmd_list *cmdlist)
+{
+       struct hook     *h;
+
+       if ((h = hooks_find(hooks, (char *)name)) != NULL)
+               hooks_remove(hooks, h);
+
+       h = xcalloc(1, sizeof *h);
+       h->name = xstrdup(name);
+       h->cmdlist = cmdlist;
+       h->cmdlist->references++;
+
+       RB_INSERT(hooks, hooks, h);
+}
+
+void
+hooks_remove(struct hooks *hooks, struct hook *h)
+{
+       if (h == NULL)
+               return;
+
+       RB_REMOVE(hooks, hooks, h);
+       cmd_list_free(h->cmdlist);
+       free(h->name);
+       free(h);
+}
+
+struct hook *
+hooks_find(struct hooks *hooks, const char *name)
+{
+       struct hook      h;
+
+       if (name == NULL)
+               return (NULL);
+
+       h.name = (char *)name;
+
+       return (RB_FIND(hooks, hooks, &h));
+}
+
+void
+hooks_run(struct hook *hook, struct cmd_q *cmdq)
+{
+       struct cmd      *cmd;
+
+       if (hook == NULL)
+               return;
+
+       TAILQ_FOREACH(cmd, &hook->cmdlist->list, qentry)
+               cmd->entry->exec(cmd, cmdq);
+}
diff --git a/session.c b/session.c
index 74eb06a..b75d459 100644
--- a/session.c
+++ b/session.c
@@ -104,6 +104,7 @@ session_create(const char *name, const char *cmd, const 
char *cwd,
        TAILQ_INIT(&s->lastw);
        RB_INIT(&s->windows);
 
+       hooks_init(&s->hooks, &global_hooks);
        options_init(&s->options, &global_s_options);
        environ_init(&s->environ);
        if (env != NULL)
@@ -160,6 +161,7 @@ session_destroy(struct session *s)
        session_group_remove(s);
        environ_free(&s->environ);
        options_free(&s->options);
+       hooks_free(&s->hooks);
 
        while (!TAILQ_EMPTY(&s->lastw))
                winlink_stack_remove(&s->lastw, TAILQ_FIRST(&s->lastw));
diff --git a/tmux.c b/tmux.c
index 8ea91eb..662867d 100644
--- a/tmux.c
+++ b/tmux.c
@@ -37,6 +37,7 @@ struct options         global_options;        /* server 
options */
 struct options  global_s_options;      /* session options */
 struct options  global_w_options;      /* window options */
 struct environ  global_environ;
+struct hooks    global_hooks;
 
 struct event_base *ev_base;
 
@@ -321,6 +322,7 @@ main(int argc, char **argv)
                        flags |= IDENTIFY_UTF8;
        }
 
+       hooks_init(&global_hooks, NULL);
        environ_init(&global_environ);
        for (var = environ; *var != NULL; var++)
                environ_put(&global_environ, *var);
diff --git a/tmux.h b/tmux.h
index 9c91d6a..096b8ce 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1075,6 +1075,14 @@ struct environ_entry {
 };
 RB_HEAD(environ, environ_entry);
 
+/* Hooks. */
+struct hook {
+       char            *name;
+       struct cmd_list *cmdlist;
+       RB_ENTRY(hook)   entry;
+};
+RB_HEAD(hooks, hook);
+
 /* Client session. */
 struct session_group {
        TAILQ_HEAD(, session) sessions;
@@ -1100,6 +1108,7 @@ struct session {
        struct winlink_stack lastw;
        struct winlinks  windows;
 
+       struct hooks     hooks;
        struct options   options;
 
 #define SESSION_UNATTACHED 0x1 /* not attached to any clients */
@@ -1501,6 +1510,7 @@ RB_HEAD(format_tree, format_entry);
 #define CMD_BUFFER_USAGE "[-b buffer-index]"
 
 /* tmux.c */
+extern struct hooks   global_hooks;
 extern struct options global_options;
 extern struct options global_s_options;
 extern struct options global_w_options;
@@ -1548,6 +1558,17 @@ void              format_winlink(
 void            format_window_pane(struct format_tree *, struct window_pane *);
 void            format_paste_buffer(struct format_tree *, struct paste_buffer 
*);
 
+/* hooks.c */
+int             hooks_cmp(struct hook *, struct hook *);
+RB_PROTOTYPE(hooks, hook, entry, hooks_cmp);
+void            hooks_init(struct hooks *, struct hooks *);
+void            hooks_free(struct hooks *);
+void            hooks_add(struct hooks *, const char *, struct cmd_list *);
+void            hooks_copy(struct hooks *, struct hooks *);
+void            hooks_remove(struct hooks *, struct hook *);
+void            hooks_run(struct hook *, struct cmd_q *);
+struct hook    *hooks_find(struct hooks *, const char *);
+
 /* mode-key.c */
 extern const struct mode_key_table mode_key_tables[];
 extern struct mode_key_tree mode_key_tree_vi_edit;
@@ -1821,10 +1842,12 @@ extern const struct cmd_entry cmd_send_prefix_entry;
 extern const struct cmd_entry cmd_server_info_entry;
 extern const struct cmd_entry cmd_set_buffer_entry;
 extern const struct cmd_entry cmd_set_environment_entry;
+extern const struct cmd_entry cmd_set_hook_entry;
 extern const struct cmd_entry cmd_set_option_entry;
 extern const struct cmd_entry cmd_set_window_option_entry;
 extern const struct cmd_entry cmd_show_buffer_entry;
 extern const struct cmd_entry cmd_show_environment_entry;
+extern const struct cmd_entry cmd_show_hooks_entry;
 extern const struct cmd_entry cmd_show_messages_entry;
 extern const struct cmd_entry cmd_show_options_entry;
 extern const struct cmd_entry cmd_show_window_options_entry;
-- 
1.7.10.4


------------------------------------------------------------------------------
Minimize network downtime and maximize team effectiveness.
Reduce network management and security costs.Learn how to hire 
the most talented Cisco Certified professionals. Visit the 
Employer Resources Portal
http://www.cisco.com/web/learning/employer_resources/index.html
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to