Skip to content

Commit

Permalink
Key running commands for #() by the unexpanded command, and run them
Browse files Browse the repository at this point in the history
again if the expanded form changes (otherwise at most once per second as
usual). Fixes issues reported by Gregory Pakosz.
  • Loading branch information
nicm committed Nov 17, 2016
1 parent ddf7ac5 commit 3cf19d6
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 14 deletions.
34 changes: 20 additions & 14 deletions format.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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));
}

Expand All @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions xmalloc.c
Expand Up @@ -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, ...)
{
Expand Down
1 change: 1 addition & 0 deletions xmalloc.h
Expand Up @@ -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)));
Expand Down

0 comments on commit 3cf19d6

Please sign in to comment.