From 03758a50dc21b7c77b75f689d06f81292266c20a Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 6 Feb 2015 17:11:39 +0000 Subject: [PATCH] Add format_expand_time and use it instead of status_replace where command execution is not needed. --- cmd-pipe-pane.c | 21 +++++++++++++++++---- format.c | 30 ++++++++++++++++++++++++++++++ status.c | 27 ++++++++++++++++++++++----- tmux.h | 1 + 4 files changed, 70 insertions(+), 9 deletions(-) diff --git a/cmd-pipe-pane.c b/cmd-pipe-pane.c index fde6baaa..df706432 100644 --- a/cmd-pipe-pane.c +++ b/cmd-pipe-pane.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -49,11 +50,14 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; + struct session *s; + struct winlink *wl; struct window_pane *wp; - char *command; + char *cmd; int old_fd, pipe_fd[2], null_fd; + struct format_tree *ft; - if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL) + if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL) return (CMD_RETURN_ERROR); c = cmd_find_client(cmdq, NULL, 1); @@ -84,10 +88,18 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq) return (CMD_RETURN_ERROR); } + /* Expand the command. */ + ft = format_create(); + format_defaults(ft, c, s, wl, wp); + cmd = format_expand_time(ft, args->argv[0], time(NULL)); + format_free(ft); + /* Fork the child. */ switch (fork()) { case -1: cmdq_error(cmdq, "fork error: %s", strerror(errno)); + + free(cmd); return (CMD_RETURN_ERROR); case 0: /* Child process. */ @@ -109,8 +121,7 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq) closefrom(STDERR_FILENO + 1); - command = status_replace(c, NULL, args->argv[0], time(NULL), 0); - execl(_PATH_BSHELL, "sh", "-c", command, (char *) NULL); + execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL); _exit(1); default: /* Parent process. */ @@ -124,6 +135,8 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq) bufferevent_enable(wp->pipe_event, EV_WRITE); setblocking(wp->pipe_fd, 0); + + free(cmd); return (CMD_RETURN_NORMAL); } } diff --git a/format.c b/format.c index f7cd3596..01fa3ade 100644 --- a/format.c +++ b/format.c @@ -326,6 +326,33 @@ fail: return (-1); } +/* Expand keys in a template, passing through strftime first. */ +char * +format_expand_time(struct format_tree *ft, const char *fmt, time_t t) +{ + char *tmp, *expanded; + size_t tmplen; + struct tm *tm; + + if (fmt == NULL) + return (xstrdup("")); + + tm = localtime(&t); + + tmp = NULL; + tmplen = strlen(fmt); + + do { + tmp = xreallocarray(tmp, 2, tmplen); + tmplen *= 2; + } while (strftime(tmp, tmplen, fmt, tm) == 0); + + expanded = format_expand(ft, tmp); + free(tmp); + + return (expanded); +} + /* Expand keys in a template. */ char * format_expand(struct format_tree *ft, const char *fmt) @@ -335,6 +362,9 @@ format_expand(struct format_tree *ft, const char *fmt) size_t off, len, n; int ch, brackets; + if (fmt == NULL) + return (xstrdup("")); + len = 64; buf = xmalloc(len); off = 0; diff --git a/status.c b/status.c index 93dc0217..27556651 100644 --- a/status.c +++ b/status.c @@ -760,14 +760,20 @@ status_prompt_set(struct client *c, const char *msg, const char *input, int (*callbackfn)(void *, const char *), void (*freefn)(void *), void *data, int flags) { - int keys; + struct format_tree *ft; + int keys; + time_t t; + + ft = format_create(); + format_defaults(ft, c, NULL, NULL, NULL); + t = time(NULL); status_message_clear(c); status_prompt_clear(c); - c->prompt_string = status_replace(c, NULL, msg, time(NULL), 0); + c->prompt_string = format_expand_time(ft, msg, time(NULL)); - c->prompt_buffer = status_replace(c, NULL, input, time(NULL), 0); + c->prompt_buffer = format_expand_time(ft, input, time(NULL)); c->prompt_index = strlen(c->prompt_buffer); c->prompt_callbackfn = callbackfn; @@ -786,6 +792,8 @@ status_prompt_set(struct client *c, const char *msg, const char *input, c->tty.flags |= (TTY_NOCURSOR|TTY_FREEZE); c->flags |= CLIENT_STATUS; + + format_free(ft); } /* Remove status line prompt. */ @@ -814,16 +822,25 @@ status_prompt_clear(struct client *c) void status_prompt_update(struct client *c, const char *msg, const char *input) { + struct format_tree *ft; + time_t t; + + ft = format_create(); + format_defaults(ft, c, NULL, NULL, NULL); + t = time(NULL); + free(c->prompt_string); - c->prompt_string = status_replace(c, NULL, msg, time(NULL), 0); + c->prompt_string = format_expand_time(ft, msg, time(NULL)); free(c->prompt_buffer); - c->prompt_buffer = status_replace(c, NULL, input, time(NULL), 0); + c->prompt_buffer = format_expand_time(ft, input, time(NULL)); c->prompt_index = strlen(c->prompt_buffer); c->prompt_hindex = 0; c->flags |= CLIENT_STATUS; + + format_free(ft); } /* Draw client prompt on status line of present else on last line. */ diff --git a/tmux.h b/tmux.h index c9be497a..72e417f9 100644 --- a/tmux.h +++ b/tmux.h @@ -1512,6 +1512,7 @@ void format_free(struct format_tree *); void printflike(3, 4) format_add(struct format_tree *, const char *, const char *, ...); const char *format_find(struct format_tree *, const char *); +char *format_expand_time(struct format_tree *, const char *, time_t); char *format_expand(struct format_tree *, const char *); void format_defaults(struct format_tree *, struct client *, struct session *, struct winlink *, struct window_pane *);