Allow nested format expansion.

This commit is contained in:
Nicholas Marriott 2013-08-19 22:14:55 +01:00
parent 84c22d053b
commit 04288fcd4c

View File

@ -193,7 +193,7 @@ int
format_replace(struct format_tree *ft, const char *key, size_t keylen, format_replace(struct format_tree *ft, const char *key, size_t keylen,
char **buf, size_t *len, size_t *off) char **buf, size_t *len, size_t *off)
{ {
char *copy, *copy0, *endptr, *ptr; char *copy, *copy0, *endptr, *ptr, *saved;
const char *value; const char *value;
size_t valuelen; size_t valuelen;
u_long limit = ULONG_MAX; u_long limit = ULONG_MAX;
@ -247,10 +247,13 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
goto fail; goto fail;
value = ptr + 1; value = ptr + 1;
} }
saved = format_expand(ft, value);
value = saved;
} else { } else {
value = format_find(ft, copy); value = format_find(ft, copy);
if (value == NULL) if (value == NULL)
value = ""; value = "";
saved = NULL;
} }
valuelen = strlen(value); valuelen = strlen(value);
@ -266,6 +269,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
memcpy(*buf + *off, value, valuelen); memcpy(*buf + *off, value, valuelen);
*off += valuelen; *off += valuelen;
free(saved);
free(copy0); free(copy0);
return (0); return (0);
@ -278,10 +282,10 @@ fail:
char * char *
format_expand(struct format_tree *ft, const char *fmt) format_expand(struct format_tree *ft, const char *fmt)
{ {
char *buf, *ptr; char *buf;
const char *s; const char *ptr, *s;
size_t off, len, n; size_t off, len, n;
int ch; int ch, brackets;
len = 64; len = 64;
buf = xmalloc(len); buf = xmalloc(len);
@ -299,11 +303,16 @@ format_expand(struct format_tree *ft, const char *fmt)
fmt++; fmt++;
ch = (u_char) *fmt++; ch = (u_char) *fmt++;
switch (ch) { switch (ch) {
case '{': case '{':
ptr = strchr(fmt, '}'); brackets = 1;
if (ptr == NULL) for (ptr = fmt; *ptr != '\0'; ptr++) {
if (*ptr == '{')
brackets++;
if (*ptr == '}' && --brackets == 0)
break;
}
if (*ptr != '}' || brackets != 0)
break; break;
n = ptr - fmt; n = ptr - fmt;