Key running commands for #() by the unexpanded command, and run them

again if the expanded form changes (otherwise at most once per second as
usual). Fixes issues reported by Gregory Pakosz.
This commit is contained in:
nicm 2016-11-17 10:06:08 +00:00
parent ddf7ac5ae4
commit 3cf19d6dd0
3 changed files with 31 additions and 14 deletions

View File

@ -78,6 +78,7 @@ static void format_defaults_winlink(struct format_tree *, struct session *,
/* Entry in format job tree. */
struct format_job {
const char *cmd;
const char *expanded;
time_t last;
char *out;
@ -232,22 +233,33 @@ format_job_callback(struct job *job)
static char *
format_job_get(struct format_tree *ft, const char *cmd)
{
struct format_job fj0, *fj;
time_t t;
struct format_job fj0, *fj;
time_t t;
char *expanded;
int force;
fj0.cmd = cmd;
if ((fj = RB_FIND(format_job_tree, &format_jobs, &fj0)) == NULL) {
fj = xcalloc(1, sizeof *fj);
fj->cmd = xstrdup(cmd);
fj->expanded = NULL;
xasprintf(&fj->out, "<'%s' not ready>", fj->cmd);
RB_INSERT(format_job_tree, &format_jobs, fj);
}
expanded = format_expand(ft, cmd);
if (fj->expanded == NULL || strcmp(expanded, fj->expanded) != 0) {
free((void *)fj->expanded);
fj->expanded = xstrdup(expanded);
force = 1;
} else
force = (ft->flags & FORMAT_FORCE);
t = time(NULL);
if (fj->job == NULL && ((ft->flags & FORMAT_FORCE) || fj->last != t)) {
fj->job = job_run(fj->cmd, NULL, NULL, format_job_callback,
if (fj->job == NULL && (force || fj->last != t)) {
fj->job = job_run(expanded, NULL, NULL, format_job_callback,
NULL, fj);
if (fj->job == NULL) {
free(fj->out);
@ -259,6 +271,7 @@ format_job_get(struct format_tree *ft, const char *cmd)
if (ft->flags & FORMAT_STATUS)
fj->status = 1;
free(expanded);
return (format_expand(ft, fj->out));
}
@ -281,6 +294,7 @@ format_job_timer(__unused int fd, __unused short events, __unused void *arg)
if (fj->job != NULL)
job_free(fj->job);
free((void *)fj->expanded);
free((void *)fj->cmd);
free(fj->out);
@ -883,7 +897,7 @@ format_expand_time(struct format_tree *ft, const char *fmt, time_t t)
char *
format_expand(struct format_tree *ft, const char *fmt)
{
char *buf, *tmp, *cmd, *out;
char *buf, *out;
const char *ptr, *s, *saved = fmt;
size_t off, len, n, outlen;
int ch, brackets;
@ -920,17 +934,9 @@ format_expand(struct format_tree *ft, const char *fmt)
break;
n = ptr - fmt;
tmp = xmalloc(n + 1);
memcpy(tmp, fmt, n);
tmp[n] = '\0';
cmd = format_expand(ft, tmp);
out = format_job_get(ft, cmd);
out = format_job_get(ft, xstrndup(fmt, n));
outlen = strlen(out);
free(cmd);
free(tmp);
while (len - off < outlen + 1) {
buf = xreallocarray(buf, 2, len);
len *= 2;

View File

@ -81,6 +81,16 @@ xstrdup(const char *str)
return cp;
}
char *
xstrndup(const char *str, size_t maxlen)
{
char *cp;
if ((cp = strndup(str, maxlen)) == NULL)
fatalx("xstrndup: %s", strerror(errno));
return cp;
}
int
xasprintf(char **ret, const char *fmt, ...)
{

View File

@ -24,6 +24,7 @@ void *xcalloc(size_t, size_t);
void *xrealloc(void *, size_t);
void *xreallocarray(void *, size_t, size_t);
char *xstrdup(const char *);
char *xstrndup(const char *, size_t);
int xasprintf(char **, const char *, ...)
__attribute__((__format__ (printf, 2, 3)))
__attribute__((__nonnull__ (2)));