The branch, master has been updated
       via  293e331d69def60110bdc49b6453af905e0509b3 (commit)
      from  2a91025581ddaa934ffa471f5b27a33d19e4ea2d (commit)

- Log -----------------------------------------------------------------
commit 293e331d69def60110bdc49b6453af905e0509b3
Author: Nicholas Marriott <nicholas.marri...@gmail.com>
Commit: Nicholas Marriott <nicholas.marri...@gmail.com>

    Add functions to allocate and free command contexts rather than doing it 
all on
    the stack.
---
 cfg.c                |   35 +++++++++++++++++++----------------
 cmd-command-prompt.c |   19 ++++++++++---------
 cmd-confirm-before.c |   19 ++++++++++---------
 cmd-if-shell.c       |   20 +++++++-------------
 cmd-list.c           |    5 +++--
 cmd-run-shell.c      |   22 ++++++++--------------
 cmd.c                |   46 +++++++++++++++++++++++++++++++++-------------
 control.c            |   18 ++++++++++--------
 key-bindings.c       |   21 +++++++++++----------
 server-client.c      |   25 ++++++++++++++-----------
 tmux.h               |   11 +++++++----
 window-choose.c      |   19 ++++++++++---------
 12 files changed, 142 insertions(+), 118 deletions(-)

diff --git a/cfg.c b/cfg.c
index c5c8c65..5592229 100644
--- a/cfg.c
+++ b/cfg.c
@@ -80,7 +80,7 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct 
causelist *causes)
        char            *buf, *copy, *line, *cause;
        size_t           len, oldlen;
        struct cmd_list *cmdlist;
-       struct cmd_ctx   ctx;
+       struct cmd_ctx  *ctx;
        enum cmd_retval  retval;
 
        if ((f = fopen(path, "rb")) == NULL) {
@@ -90,6 +90,21 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct 
causelist *causes)
 
        cfg_references++;
 
+       ctx = cmd_get_ctx();
+       if (ctxin == NULL) {
+               ctx->msgdata = NULL;
+               ctx->curclient = NULL;
+               ctx->cmdclient = NULL;
+       } else {
+               ctx->msgdata = ctxin->msgdata;
+               ctx->curclient = ctxin->curclient;
+               ctx->cmdclient = ctxin->cmdclient;
+       }
+
+       ctx->error = cfg_error;
+       ctx->print = cfg_print;
+       ctx->info = cfg_print;
+
        n = 0;
        line = NULL;
        retval = CMD_RETURN_NORMAL;
@@ -146,22 +161,8 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct 
causelist *causes)
                if (cmdlist == NULL)
                        continue;
 
-               if (ctxin == NULL) {
-                       ctx.msgdata = NULL;
-                       ctx.curclient = NULL;
-                       ctx.cmdclient = NULL;
-               } else {
-                       ctx.msgdata = ctxin->msgdata;
-                       ctx.curclient = ctxin->curclient;
-                       ctx.cmdclient = ctxin->cmdclient;
-               }
-
-               ctx.error = cfg_error;
-               ctx.print = cfg_print;
-               ctx.info = cfg_print;
-
                cfg_cause = NULL;
-               switch (cmd_list_exec(cmdlist, &ctx)) {
+               switch (cmd_list_exec(cmdlist, ctx)) {
                case CMD_RETURN_YIELD:
                        if (retval != CMD_RETURN_ATTACH)
                                retval = CMD_RETURN_YIELD;
@@ -186,6 +187,8 @@ load_cfg(const char *path, struct cmd_ctx *ctxin, struct 
causelist *causes)
        }
        fclose(f);
 
+       cmd_free_ctx(ctx);
+
        cfg_references--;
 
        return (retval);
diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c
index ea38035..2a0e1aa 100644
--- a/cmd-command-prompt.c
+++ b/cmd-command-prompt.c
@@ -150,7 +150,7 @@ cmd_command_prompt_callback(void *data, const char *s)
        struct cmd_command_prompt_cdata *cdata = data;
        struct client                   *c = cdata->c;
        struct cmd_list                 *cmdlist;
-       struct cmd_ctx                   ctx;
+       struct cmd_ctx                  *ctx;
        char                            *cause, *new_template, *prompt, *ptr;
        char                            *input = NULL;
 
@@ -184,17 +184,18 @@ cmd_command_prompt_callback(void *data, const char *s)
                return (0);
        }
 
-       ctx.msgdata = NULL;
-       ctx.curclient = c;
+       ctx = cmd_get_ctx();
+       ctx->msgdata = NULL;
+       ctx->curclient = c;
+       ctx->cmdclient = NULL;
 
-       ctx.error = key_bindings_error;
-       ctx.print = key_bindings_print;
-       ctx.info = key_bindings_info;
+       ctx->error = key_bindings_error;
+       ctx->print = key_bindings_print;
+       ctx->info = key_bindings_info;
 
-       ctx.cmdclient = NULL;
-
-       cmd_list_exec(cmdlist, &ctx);
+       cmd_list_exec(cmdlist, ctx);
        cmd_list_free(cmdlist);
+       cmd_free_ctx(ctx);
 
        if (c->prompt_callbackfn != (void *) &cmd_command_prompt_callback)
                return (1);
diff --git a/cmd-confirm-before.c b/cmd-confirm-before.c
index 329027c..33733c3 100644
--- a/cmd-confirm-before.c
+++ b/cmd-confirm-before.c
@@ -108,7 +108,7 @@ cmd_confirm_before_callback(void *data, const char *s)
        struct cmd_confirm_before_data  *cdata = data;
        struct client                   *c = cdata->c;
        struct cmd_list                 *cmdlist;
-       struct cmd_ctx                   ctx;
+       struct cmd_ctx                  *ctx;
        char                            *cause;
 
        if (s == NULL || *s == '\0')
@@ -125,17 +125,18 @@ cmd_confirm_before_callback(void *data, const char *s)
                return (0);
        }
 
-       ctx.msgdata = NULL;
-       ctx.curclient = c;
+       ctx = cmd_get_ctx();
+       ctx->msgdata = NULL;
+       ctx->curclient = c;
+       ctx->cmdclient = NULL;
 
-       ctx.error = key_bindings_error;
-       ctx.print = key_bindings_print;
-       ctx.info = key_bindings_info;
+       ctx->error = key_bindings_error;
+       ctx->print = key_bindings_print;
+       ctx->info = key_bindings_info;
 
-       ctx.cmdclient = NULL;
-
-       cmd_list_exec(cmdlist, &ctx);
+       cmd_list_exec(cmdlist, ctx);
        cmd_list_free(cmdlist);
+       cmd_free_ctx(ctx);
 
        return (0);
 }
diff --git a/cmd-if-shell.c b/cmd-if-shell.c
index 636cf80..6f0b151 100644
--- a/cmd-if-shell.c
+++ b/cmd-if-shell.c
@@ -47,7 +47,7 @@ const struct cmd_entry cmd_if_shell_entry = {
 struct cmd_if_shell_data {
        char            *cmd_if;
        char            *cmd_else;
-       struct cmd_ctx   ctx;
+       struct cmd_ctx  *ctx;
 };
 
 enum cmd_retval
@@ -63,12 +63,9 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
                cdata->cmd_else = xstrdup(args->argv[2]);
        else
                cdata->cmd_else = NULL;
-       memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
 
-       if (ctx->cmdclient != NULL)
-               ctx->cmdclient->references++;
-       if (ctx->curclient != NULL)
-               ctx->curclient->references++;
+       cdata->ctx = ctx;
+       cmd_ref_ctx(ctx);
 
        job_run(shellcmd, cmd_if_shell_callback, cmd_if_shell_free, cdata);
 
@@ -79,7 +76,7 @@ void
 cmd_if_shell_callback(struct job *job)
 {
        struct cmd_if_shell_data        *cdata = job->data;
-       struct cmd_ctx                  *ctx = &cdata->ctx;
+       struct cmd_ctx                  *ctx = cdata->ctx;
        struct cmd_list                 *cmdlist;
        char                            *cause, *cmd;
 
@@ -105,14 +102,11 @@ void
 cmd_if_shell_free(void *data)
 {
        struct cmd_if_shell_data        *cdata = data;
-       struct cmd_ctx                  *ctx = &cdata->ctx;
+       struct cmd_ctx                  *ctx = cdata->ctx;
 
-       if (ctx->cmdclient != NULL) {
-               ctx->cmdclient->references--;
+       if (ctx->cmdclient != NULL)
                ctx->cmdclient->flags |= CLIENT_EXIT;
-       }
-       if (ctx->curclient != NULL)
-               ctx->curclient->references--;
+       cmd_free_ctx(ctx);
 
        free(cdata->cmd_else);
        free(cdata->cmd_if);
diff --git a/cmd-list.c b/cmd-list.c
index 1717ec3..6820d00 100644
--- a/cmd-list.c
+++ b/cmd-list.c
@@ -97,7 +97,7 @@ cmd_list_exec(struct cmd_list *cmdlist, struct cmd_ctx *ctx)
        TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
                if (guards)
                        ctx->print(ctx, "%%begin");
-               n = cmd_exec(cmd, ctx);
+               n = cmd->entry->exec(cmd, ctx);
                if (guards)
                        ctx->print(ctx, "%%end");
 
@@ -146,7 +146,8 @@ cmd_list_free(struct cmd_list *cmdlist)
        while (!TAILQ_EMPTY(&cmdlist->list)) {
                cmd = TAILQ_FIRST(&cmdlist->list);
                TAILQ_REMOVE(&cmdlist->list, cmd, qentry);
-               cmd_free(cmd);
+               args_free(cmd->args);
+               free(cmd);
        }
        free(cmdlist);
 }
diff --git a/cmd-run-shell.c b/cmd-run-shell.c
index 44e796d..03cbc29 100644
--- a/cmd-run-shell.c
+++ b/cmd-run-shell.c
@@ -47,7 +47,7 @@ const struct cmd_entry cmd_run_shell_entry = {
 
 struct cmd_run_shell_data {
        char            *cmd;
-       struct cmd_ctx   ctx;
+       struct cmd_ctx  *ctx;
        u_int            wp_id;
 };
 
@@ -55,7 +55,7 @@ void
 cmd_run_shell_print(struct job *job, const char *msg)
 {
        struct cmd_run_shell_data       *cdata = job->data;
-       struct cmd_ctx                  *ctx = &cdata->ctx;
+       struct cmd_ctx                  *ctx = cdata->ctx;
        struct window_pane              *wp;
 
        wp = window_pane_find_by_id(cdata->wp_id);
@@ -84,12 +84,9 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
        cdata = xmalloc(sizeof *cdata);
        cdata->cmd = xstrdup(args->argv[0]);
        cdata->wp_id = wp->id;
-       memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
 
-       if (ctx->cmdclient != NULL)
-               ctx->cmdclient->references++;
-       if (ctx->curclient != NULL)
-               ctx->curclient->references++;
+       cdata->ctx = ctx;
+       cmd_ref_ctx(ctx);
 
        job_run(shellcmd, cmd_run_shell_callback, cmd_run_shell_free, cdata);
 
@@ -100,7 +97,7 @@ void
 cmd_run_shell_callback(struct job *job)
 {
        struct cmd_run_shell_data       *cdata = job->data;
-       struct cmd_ctx                  *ctx = &cdata->ctx;
+       struct cmd_ctx                  *ctx = cdata->ctx;
        char                            *cmd, *msg, *line;
        size_t                           size;
        int                              retcode;
@@ -154,14 +151,11 @@ void
 cmd_run_shell_free(void *data)
 {
        struct cmd_run_shell_data       *cdata = data;
-       struct cmd_ctx                  *ctx = &cdata->ctx;
+       struct cmd_ctx                  *ctx = cdata->ctx;
 
-       if (ctx->cmdclient != NULL) {
-               ctx->cmdclient->references--;
+       if (ctx->cmdclient != NULL)
                ctx->cmdclient->flags |= CLIENT_EXIT;
-       }
-       if (ctx->curclient != NULL)
-               ctx->curclient->references--;
+       cmd_free_ctx(ctx);
 
        free(cdata->cmd);
        free(cdata);
diff --git a/cmd.c b/cmd.c
index 52c1a30..23e86cf 100644
--- a/cmd.c
+++ b/cmd.c
@@ -132,6 +132,39 @@ struct winlink     *cmd_find_window_offset(const char *, 
struct session *, int *);
 int             cmd_find_index_offset(const char *, struct session *, int *);
 struct window_pane *cmd_find_pane_offset(const char *, struct winlink *);
 
+struct cmd_ctx *
+cmd_get_ctx(void)
+{
+       struct cmd_ctx  *ctx;
+
+       ctx = xcalloc(1, sizeof *ctx);
+       ctx->references = 0;
+
+       cmd_ref_ctx(ctx);
+       return (ctx);
+}
+
+void
+cmd_free_ctx(struct cmd_ctx *ctx)
+{
+       if (ctx->cmdclient != NULL)
+               ctx->cmdclient->references--;
+       if (ctx->curclient != NULL)
+               ctx->curclient->references--;
+       if (--ctx->references == 0)
+               free(ctx);
+}
+
+void
+cmd_ref_ctx(struct cmd_ctx *ctx)
+{
+       ctx->references++;
+       if (ctx->cmdclient != NULL)
+               ctx->cmdclient->references++;
+       if (ctx->curclient != NULL)
+               ctx->curclient->references++;
+}
+
 int
 cmd_pack_argv(int argc, char **argv, char *buf, size_t len)
 {
@@ -281,19 +314,6 @@ usage:
        return (NULL);
 }
 
-enum cmd_retval
-cmd_exec(struct cmd *cmd, struct cmd_ctx *ctx)
-{
-       return (cmd->entry->exec(cmd, ctx));
-}
-
-void
-cmd_free(struct cmd *cmd)
-{
-       args_free(cmd->args);
-       free(cmd);
-}
-
 size_t
 cmd_print(struct cmd *cmd, char *buf, size_t len)
 {
diff --git a/control.c b/control.c
index b5ec6bd..f00f57f 100644
--- a/control.c
+++ b/control.c
@@ -93,7 +93,7 @@ void
 control_callback(struct client *c, int closed, unused void *data)
 {
        char            *line, *cause;
-       struct cmd_ctx   ctx;
+       struct cmd_ctx  *ctx;
        struct cmd_list *cmdlist;
 
        if (closed)
@@ -108,22 +108,24 @@ control_callback(struct client *c, int closed, unused 
void *data)
                        break;
                }
 
-               ctx.msgdata = NULL;
-               ctx.cmdclient = NULL;
-               ctx.curclient = c;
+               ctx = cmd_get_ctx();
+               ctx->msgdata = NULL;
+               ctx->cmdclient = NULL;
+               ctx->curclient = c;
 
-               ctx.error = control_msg_error;
-               ctx.print = control_msg_print;
-               ctx.info = control_msg_info;
+               ctx->error = control_msg_error;
+               ctx->print = control_msg_print;
+               ctx->info = control_msg_info;
 
                if (cmd_string_parse(line, &cmdlist, &cause) != 0) {
                        control_write(c, "%%error in line \"%s\": %s", line,
                            cause);
                        free(cause);
                } else {
-                       cmd_list_exec(cmdlist, &ctx);
+                       cmd_list_exec(cmdlist, ctx);
                        cmd_list_free(cmdlist);
                }
+               cmd_free_ctx(ctx);
 
                free(line);
        }
diff --git a/key-bindings.c b/key-bindings.c
index cf5237d..a25d370 100644
--- a/key-bindings.c
+++ b/key-bindings.c
@@ -262,18 +262,18 @@ key_bindings_info(struct cmd_ctx *ctx, const char *fmt, 
...)
 void
 key_bindings_dispatch(struct key_binding *bd, struct client *c)
 {
-       struct cmd_ctx   ctx;
+       struct cmd_ctx  *ctx;
        struct cmd      *cmd;
        int              readonly;
 
-       ctx.msgdata = NULL;
-       ctx.curclient = c;
+       ctx = cmd_get_ctx();
+       ctx->msgdata = NULL;
+       ctx->cmdclient = NULL;
+       ctx->curclient = c;
 
-       ctx.error = key_bindings_error;
-       ctx.print = key_bindings_print;
-       ctx.info = key_bindings_info;
-
-       ctx.cmdclient = NULL;
+       ctx->error = key_bindings_error;
+       ctx->print = key_bindings_print;
+       ctx->info = key_bindings_info;
 
        readonly = 1;
        TAILQ_FOREACH(cmd, &bd->cmdlist->list, qentry) {
@@ -281,9 +281,10 @@ key_bindings_dispatch(struct key_binding *bd, struct 
client *c)
                        readonly = 0;
        }
        if (!readonly && c->flags & CLIENT_READONLY) {
-               key_bindings_info(&ctx, "Client is read-only");
+               key_bindings_info(ctx, "client is read-only");
                return;
        }
 
-       cmd_list_exec(bd->cmdlist, &ctx);
+       cmd_list_exec(bd->cmdlist, ctx);
+       cmd_free_ctx(ctx);
 }
diff --git a/server-client.c b/server-client.c
index d4449a5..1500419 100644
--- a/server-client.c
+++ b/server-client.c
@@ -864,24 +864,24 @@ server_client_msg_info(struct cmd_ctx *ctx, const char 
*fmt, ...)
 void
 server_client_msg_command(struct client *c, struct msg_command_data *data)
 {
-       struct cmd_ctx   ctx;
+       struct cmd_ctx  *ctx;
        struct cmd_list *cmdlist = NULL;
        int              argc;
        char           **argv, *cause;
 
-       ctx.error = server_client_msg_error;
-       ctx.print = server_client_msg_print;
-       ctx.info = server_client_msg_info;
+       ctx = cmd_get_ctx();
+       ctx->msgdata = data;
+       ctx->curclient = NULL;
+       ctx->cmdclient = c;
 
-       ctx.msgdata = data;
-       ctx.curclient = NULL;
-
-       ctx.cmdclient = c;
+       ctx->error = server_client_msg_error;
+       ctx->print = server_client_msg_print;
+       ctx->info = server_client_msg_info;
 
        argc = data->argc;
        data->argv[(sizeof data->argv) - 1] = '\0';
        if (cmd_unpack_argv(data->argv, sizeof data->argv, argc, &argv) != 0) {
-               server_client_msg_error(&ctx, "command too long");
+               server_client_msg_error(ctx, "command too long");
                goto error;
        }
 
@@ -892,13 +892,13 @@ server_client_msg_command(struct client *c, struct 
msg_command_data *data)
        }
 
        if ((cmdlist = cmd_list_parse(argc, argv, &cause)) == NULL) {
-               server_client_msg_error(&ctx, "%s", cause);
+               server_client_msg_error(ctx, "%s", cause);
                cmd_free_argv(argc, argv);
                goto error;
        }
        cmd_free_argv(argc, argv);
 
-       switch (cmd_list_exec(cmdlist, &ctx))
+       switch (cmd_list_exec(cmdlist, ctx))
        {
        case CMD_RETURN_ERROR:
        case CMD_RETURN_NORMAL:
@@ -909,11 +909,14 @@ server_client_msg_command(struct client *c, struct 
msg_command_data *data)
                break;
        }
        cmd_list_free(cmdlist);
+       cmd_free_ctx(ctx);
        return;
 
 error:
        if (cmdlist != NULL)
                cmd_list_free(cmdlist);
+       cmd_free_ctx(ctx);
+
        c->flags |= CLIENT_EXIT;
 }
 
diff --git a/tmux.h b/tmux.h
index d602b14..df47cdb 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1362,8 +1362,10 @@ struct cmd_ctx {
         * cmdclient and curclient may both be NULL if the command is in the
         * configuration file.
         */
-       struct client  *curclient;
-       struct client  *cmdclient;
+       struct client           *curclient;
+       struct client           *cmdclient;
+
+       int                      references;
 
        struct msg_command_data *msgdata;
 
@@ -1710,13 +1712,14 @@ long long        args_strtonum(
                    struct args *, u_char, long long, long long, char **);
 
 /* cmd.c */
+struct cmd_ctx *cmd_get_ctx(void);
+void            cmd_free_ctx(struct cmd_ctx *);
+void            cmd_ref_ctx(struct cmd_ctx *);
 int             cmd_pack_argv(int, char **, char *, size_t);
 int             cmd_unpack_argv(char *, size_t, int, char ***);
 char          **cmd_copy_argv(int, char *const *);
 void            cmd_free_argv(int, char **);
 struct cmd     *cmd_parse(int, char **, char **);
-enum cmd_retval         cmd_exec(struct cmd *, struct cmd_ctx *);
-void            cmd_free(struct cmd *);
 size_t          cmd_print(struct cmd *, char *, size_t);
 struct session *cmd_current_session(struct cmd_ctx *, int);
 struct client  *cmd_current_client(struct cmd_ctx *);
diff --git a/window-choose.c b/window-choose.c
index d37527d..e48db7e 100644
--- a/window-choose.c
+++ b/window-choose.c
@@ -200,7 +200,7 @@ window_choose_data_free(struct window_choose_data *wcd)
 void
 window_choose_data_run(struct window_choose_data *cdata)
 {
-       struct cmd_ctx           ctx;
+       struct cmd_ctx          *ctx;
        struct cmd_list         *cmdlist;
        char                    *cause;
 
@@ -220,17 +220,18 @@ window_choose_data_run(struct window_choose_data *cdata)
                return;
        }
 
-       ctx.msgdata = NULL;
-       ctx.curclient = cdata->start_client;
+       ctx = cmd_get_ctx();
+       ctx->msgdata = NULL;
+       ctx->curclient = cdata->start_client;
+       ctx->cmdclient = NULL;
 
-       ctx.error = key_bindings_error;
-       ctx.print = key_bindings_print;
-       ctx.info = key_bindings_info;
+       ctx->error = key_bindings_error;
+       ctx->print = key_bindings_print;
+       ctx->info = key_bindings_info;
 
-       ctx.cmdclient = NULL;
-
-       cmd_list_exec(cmdlist, &ctx);
+       cmd_list_exec(cmdlist, ctx);
        cmd_list_free(cmdlist);
+       cmd_free_ctx(ctx);
 }
 
 void


-----------------------------------------------------------------------

Summary of changes:
 cfg.c                |   35 +++++++++++++++++++----------------
 cmd-command-prompt.c |   19 ++++++++++---------
 cmd-confirm-before.c |   19 ++++++++++---------
 cmd-if-shell.c       |   20 +++++++-------------
 cmd-list.c           |    5 +++--
 cmd-run-shell.c      |   22 ++++++++--------------
 cmd.c                |   46 +++++++++++++++++++++++++++++++++-------------
 control.c            |   18 ++++++++++--------
 key-bindings.c       |   21 +++++++++++----------
 server-client.c      |   25 ++++++++++++++-----------
 tmux.h               |   11 +++++++----
 window-choose.c      |   19 ++++++++++---------
 12 files changed, 142 insertions(+), 118 deletions(-)


hooks/post-receive
-- 
tmux

------------------------------------------------------------------------------
The Go Parallel Website, sponsored by Intel - in partnership with Geeknet, 
is your hub for all things parallel software development, from weekly thought 
leadership blogs to news, videos, case studies, tutorials, tech docs, 
whitepapers, evaluation guides, and opinion stories. Check out the most 
recent posts - join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
tmux-cvs mailing list
tmux-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-cvs

Reply via email to