version 1.112, 2016/10/16 19:36:37 |
version 1.113, 2016/11/17 10:06:08 |
|
|
/* Entry in format job tree. */ |
/* Entry in format job tree. */ |
struct format_job { |
struct format_job { |
const char *cmd; |
const char *cmd; |
|
const char *expanded; |
|
|
time_t last; |
time_t last; |
char *out; |
char *out; |
|
|
static char * |
static char * |
format_job_get(struct format_tree *ft, const char *cmd) |
format_job_get(struct format_tree *ft, const char *cmd) |
{ |
{ |
struct format_job fj0, *fj; |
struct format_job fj0, *fj; |
time_t t; |
time_t t; |
|
char *expanded; |
|
int force; |
|
|
fj0.cmd = cmd; |
fj0.cmd = cmd; |
if ((fj = RB_FIND(format_job_tree, &format_jobs, &fj0)) == NULL) { |
if ((fj = RB_FIND(format_job_tree, &format_jobs, &fj0)) == NULL) { |
fj = xcalloc(1, sizeof *fj); |
fj = xcalloc(1, sizeof *fj); |
fj->cmd = xstrdup(cmd); |
fj->cmd = xstrdup(cmd); |
|
fj->expanded = NULL; |
|
|
xasprintf(&fj->out, "<'%s' not ready>", fj->cmd); |
xasprintf(&fj->out, "<'%s' not ready>", fj->cmd); |
|
|
RB_INSERT(format_job_tree, &format_jobs, fj); |
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); |
t = time(NULL); |
if (fj->job == NULL && ((ft->flags & FORMAT_FORCE) || fj->last != t)) { |
if (fj->job == NULL && (force || fj->last != t)) { |
fj->job = job_run(fj->cmd, NULL, NULL, format_job_callback, |
fj->job = job_run(expanded, NULL, NULL, format_job_callback, |
NULL, fj); |
NULL, fj); |
if (fj->job == NULL) { |
if (fj->job == NULL) { |
free(fj->out); |
free(fj->out); |
|
|
if (ft->flags & FORMAT_STATUS) |
if (ft->flags & FORMAT_STATUS) |
fj->status = 1; |
fj->status = 1; |
|
|
|
free(expanded); |
return (format_expand(ft, fj->out)); |
return (format_expand(ft, fj->out)); |
} |
} |
|
|
|
|
if (fj->job != NULL) |
if (fj->job != NULL) |
job_free(fj->job); |
job_free(fj->job); |
|
|
|
free((void *)fj->expanded); |
free((void *)fj->cmd); |
free((void *)fj->cmd); |
free(fj->out); |
free(fj->out); |
|
|
|
|
char * |
char * |
format_expand(struct format_tree *ft, const char *fmt) |
format_expand(struct format_tree *ft, const char *fmt) |
{ |
{ |
char *buf, *tmp, *cmd, *out; |
char *buf, *out; |
const char *ptr, *s, *saved = fmt; |
const char *ptr, *s, *saved = fmt; |
size_t off, len, n, outlen; |
size_t off, len, n, outlen; |
int ch, brackets; |
int ch, brackets; |
|
|
break; |
break; |
n = ptr - fmt; |
n = ptr - fmt; |
|
|
tmp = xmalloc(n + 1); |
out = format_job_get(ft, xstrndup(fmt, n)); |
memcpy(tmp, fmt, n); |
|
tmp[n] = '\0'; |
|
cmd = format_expand(ft, tmp); |
|
|
|
out = format_job_get(ft, cmd); |
|
outlen = strlen(out); |
outlen = strlen(out); |
|
|
free(cmd); |
|
free(tmp); |
|
|
|
while (len - off < outlen + 1) { |
while (len - off < outlen + 1) { |
buf = xreallocarray(buf, 2, len); |
buf = xreallocarray(buf, 2, len); |