On Mon, Apr 08, 2013 at 09:48:04AM +0100, Thomas Adam wrote:
> 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 <[email protected]>
> + *
> + * 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>
I don't think we need ctype.h in this file?
> +#include <stdlib.h>
> +
Stray blank line here.
> +#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);
I don't think this should copy - it should work like options and keep a
reference to the parent struct hooks and search both (child first). This
means changes to the global hooks are reflected in all sessions not just
new ones.
> +}
> +
> +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;
Is this guard necessary?
> +
> + 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);
And this?
> +
> + 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;
Likewise. I tend to think this kind of guard is better outside in the
places the hook could be NULL.
> +
> + 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
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/tmux-users
------------------------------------------------------------------------------
Precog is a next-generation analytics platform capable of advanced
analytics on semi-structured data. The platform includes APIs for building
apps and a phenomenal toolset for data science. Developers can use
our toolset for easy data analysis & visualization. Get a free account!
http://www2.precog.com/precogplatform/slashdotnewsletter
_______________________________________________
tmux-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tmux-users