Let nitpicking commence!

Apart from nitpicks this looks good, will look at the other diffs a bit
later.

On Sun, Apr 14, 2013 at 05:01:36PM +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.
> ---
>  Makefile.am      |   3 ++
>  cmd-set-hook.c   | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  cmd-show-hooks.c |  71 +++++++++++++++++++++++++++++++++++
>  hooks.c          | 110 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  session.c        |   2 +
>  tmux.c           |   2 +
>  tmux.h           |  27 ++++++++++++++
>  7 files changed, 315 insertions(+)
>  create mode 100644 cmd-set-hook.c
>  create mode 100644 cmd-show-hooks.c
>  create mode 100644 hooks.c
> 
> diff --git a/Makefile.am b/Makefile.am
> index 2ce54b1..4a0bb2d 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -121,8 +121,10 @@ dist_tmux_SOURCES = \
>       cmd-server-info.c \
>       cmd-set-buffer.c \
>       cmd-set-environment.c \
> +     cmd-set-hook.c \
>       cmd-set-option.c \
>       cmd-show-environment.c \
> +     cmd-show-hooks.c \
>       cmd-show-messages.c \
>       cmd-show-options.c \
>       cmd-source-file.c \
> @@ -145,6 +147,7 @@ dist_tmux_SOURCES = \
>       grid-cell.c \
>       grid-view.c \
>       grid.c \
> +     hooks.c \
>       input-keys.c \
>       input.c \
>       job.c \
> diff --git a/cmd-set-hook.c b/cmd-set-hook.c
> new file mode 100644
> index 0000000..c732856
> --- /dev/null
> +++ b/cmd-set-hook.c
> @@ -0,0 +1,100 @@
> +/* $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>

Do we need ctype.h? Also a stray blank line above <string.h>.

> +
> +#include "tmux.h"
> +
> +enum cmd_retval cmd_set_hook_exec(struct cmd *, struct cmd_q *);
> +void         cmd_set_hook_prepare(struct cmd *, struct cmd_q *);
> +
> +const struct cmd_entry cmd_set_hook_entry = {
> +     "set-hook", NULL,
> +     "gn:t:u", 0, 1,
> +     "[-n hook-name] [-g]" CMD_TARGET_SESSION_USAGE " [-u hook-name] 
> [command]",
> +     0,
> +     NULL,
> +     NULL,
> +     cmd_set_hook_exec,
> +     cmd_set_hook_prepare
> +};
> +
> +void
> +cmd_set_hook_prepare(struct cmd *self, struct cmd_q *cmdq)
> +{
> +     struct args             *args = self->args;

Looks like too many tabs here.

> +
> +     cmdq->cmd_ctx.s = cmd_find_session(cmdq, args_get(args, 't'), 0);
> +}
> +
> +enum cmd_retval
> +cmd_set_hook_exec(struct cmd *self, struct cmd_q *cmdq)
> +{
> +     struct args     *args = self->args;
> +     struct session  *s;
> +     struct cmd_list *cmdlist;
> +     struct hooks    *hooks;
> +     struct hook     *hook;
> +     char            *cause;
> +     const char      *hook_name, *hook_cmd;
> +
> +     s = cmdq->cmd_ctx.s;
> +
> +     if (args_has(args, 't') && s == NULL)
> +             return (CMD_RETURN_ERROR);
> +
> +     if (s == NULL && cmdq->client != NULL)
> +             s = cmdq->client->session;
> +
> +     if ((hook_name = args_get(args, 'n')) == NULL) {
> +             cmdq_error(cmdq, "No hook name given.");

No capital letter and no period please.

> +             return (CMD_RETURN_ERROR);
> +     }
> +
> +     hooks = args_has(args, 'g') ? &global_hooks : &s->hooks;
> +
> +     if (s != NULL && args_has(args, 'u')) {
> +             if ((hook = hooks_find(hooks, (char *)hook_name)) != NULL)
> +                     hooks_remove(hooks, hook);
> +             return (CMD_RETURN_NORMAL);
> +     }
> +
> +     if (args->argc == 0) {
> +             cmdq_error(cmdq, "No command for hook '%s' given.", hook_name);

And here.

> +             return (CMD_RETURN_ERROR);
> +     }
> +     hook_cmd = args->argv[0];
> +
> +     if (cmd_string_parse(hook_cmd, &cmdlist, NULL, 0, &cause) != 0) {
> +             if (cmdlist == NULL || cause != NULL) {
> +                     cmdq_error(cmdq, "Hook error: (%s)", cause);
> +                     return (CMD_RETURN_ERROR);
> +             }
> +     }
> +
> +     if (cmdlist == NULL)
> +             return (CMD_RETURN_ERROR);
> +
> +     hooks_add(hooks, hook_name, cmdlist);
> +     return (CMD_RETURN_NORMAL);
> +}
> diff --git a/cmd-show-hooks.c b/cmd-show-hooks.c
> new file mode 100644
> index 0000000..b98dbe5
> --- /dev/null
> +++ b/cmd-show-hooks.c
> @@ -0,0 +1,71 @@
> +/* $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>

Same.

> +
> +#include "tmux.h"
> +
> +enum cmd_retval cmd_show_hooks_exec(struct cmd *, struct cmd_q *);
> +void         cmd_show_hooks_prepare(struct cmd *, struct cmd_q *);
> +
> +const struct cmd_entry cmd_show_hooks_entry = {
> +     "show-hooks", NULL,
> +     "gt:", 0, 1,
> +     "[-g] " CMD_TARGET_SESSION_USAGE,
> +     0,
> +     NULL,
> +     NULL,
> +     cmd_show_hooks_exec,
> +     cmd_show_hooks_prepare
> +};
> +
> +void
> +cmd_show_hooks_prepare(struct cmd *self, struct cmd_q *cmdq)
> +{
> +     struct args             *args = self->args;

Same :-).

> +
> +     cmdq->cmd_ctx.s = cmd_find_session(cmdq, args_get(args, 't'), 0);
> +}
> +
> +enum cmd_retval
> +cmd_show_hooks_exec(struct cmd *self, struct cmd_q *cmdq)
> +{
> +     struct args     *args = self->args;
> +     struct session  *s;
> +     struct hooks    *hooks;
> +     struct hook     *hook;
> +     char             tmp[BUFSIZ];
> +     size_t           used;
> +
> +     if ((s = cmdq->cmd_ctx.s) == NULL)
> +             return (CMD_RETURN_ERROR);
> +
> +     hooks = args_has(args, 'g') ? &global_hooks : &s->hooks;
> +
> +     RB_FOREACH(hook, hooks_tree, &hooks->tree) {
> +             used = xsnprintf(tmp, sizeof tmp, "%s -> ", hook->name);
> +             cmd_list_print(hook->cmdlist, tmp + used, (sizeof tmp) - used);
> +             cmdq_print(cmdq, "%s", tmp);
> +     }
> +     return (CMD_RETURN_NORMAL);
> +}
> diff --git a/hooks.c b/hooks.c
> new file mode 100644
> index 0000000..8fdcf00
> --- /dev/null
> +++ b/hooks.c
> @@ -0,0 +1,110 @@
> +/* $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 <stdlib.h>
> +
> +#include <string.h>

No blank line between these two.

> +
> +#include "tmux.h"
> +
> +RB_GENERATE(hooks_tree, hook, entry, hooks_cmp);
> +
> +struct hook  *hooks_find1(struct hooks *, const char *);
> +
> +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->tree);
> +     hooks->parent = copy;
> +}
> +
> +void
> +hooks_free(struct hooks *hooks)
> +{
> +     struct hook     *h, *h2;
> +
> +     RB_FOREACH_SAFE(h, hooks_tree, &hooks->tree, h2)
> +             hooks_remove(hooks, h);
> +}
> +
> +void
> +hooks_add(struct hooks *hooks, const char *name, struct cmd_list *cmdlist)
> +{
> +     struct hook     *h;
> +
> +     if ((h = hooks_find1(hooks, name)) != NULL)
> +             hooks_remove(hooks, h);
> +
> +     h = xcalloc(1, sizeof *h);
> +     h->name = xstrdup(name);
> +     h->cmdlist = cmdlist;
> +     h->cmdlist->references++;
> +
> +     RB_INSERT(hooks_tree, &hooks->tree, h);
> +}
> +
> +void
> +hooks_remove(struct hooks *hooks, struct hook *h)
> +{
> +     RB_REMOVE(hooks_tree, &hooks->tree, h);
> +     cmd_list_free(h->cmdlist);
> +     free(h->name);
> +     free(h);
> +}
> +
> +struct hook *
> +hooks_find1(struct hooks *hooks, const char *name)
> +{
> +     struct hook     h;
> +
> +     h.name = (char *) name;
> +     return (RB_FIND(hooks_tree, &hooks->tree, &h));
> +}
> +
> +struct hook *
> +hooks_find(struct hooks *hooks, const char *name)
> +{
> +     struct hook      h, *he;
> +
> +     h.name = (char *) name;
> +     he = RB_FIND(hooks_tree, &hooks->tree, &h);
> +     while (he == NULL) {
> +             hooks = hooks->parent;
> +             if (hooks == NULL)
> +                     break;
> +             he = RB_FIND(hooks_tree, &hooks->tree, &h);
> +     }
> +     return (he);
> +}
> +
> +void
> +hooks_run(struct hook *hook, struct cmd_q *cmdq)
> +{
> +     struct cmd      *cmd;
> +
> +     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 e8fd98b..8aa6089 100644
> --- a/tmux.c
> +++ b/tmux.c
> @@ -39,6 +39,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;
>  
> @@ -322,6 +323,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 f0b9edf..22d0964 100644
> --- a/tmux.h
> +++ b/tmux.h
> @@ -1075,6 +1075,18 @@ struct environ_entry {
>  };
>  RB_HEAD(environ, environ_entry);
>  
> +/* Hooks. */
> +struct hook {
> +     char            *name;
> +     struct cmd_list *cmdlist;
> +     RB_ENTRY(hook)   entry;
> +};
> +
> +struct hooks {
> +     RB_HEAD(hooks_tree, hook) tree;
> +     struct hooks    *parent;
> +};
> +
>  /* Client session. */
>  struct session_group {
>       TAILQ_HEAD(, session) sessions;
> @@ -1100,6 +1112,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 */
> @@ -1500,6 +1513,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;
> @@ -1547,6 +1561,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_tree, 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;
> @@ -1820,10 +1845,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.11.4
> 
> 
> ------------------------------------------------------------------------------
> 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
> tmux-users@lists.sourceforge.net
> 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
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to