diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2018-05-22 08:49:13 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2018-05-22 08:49:13 +0000 |
commit | dbc00665addacfb4fe58f83ac39d31508389b024 (patch) | |
tree | 222e0b93839eff80c8f3cd960a4835402c50c55a /usr.bin/tmux/format.c | |
parent | 5e9862c12ac9542c5e346abf53a9111d1cef696d (diff) |
Allow escaping , and } with # in #{}; GitHub issue 1332.
Diffstat (limited to 'usr.bin/tmux/format.c')
-rw-r--r-- | usr.bin/tmux/format.c | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/usr.bin/tmux/format.c b/usr.bin/tmux/format.c index 6310e218e65..2d8a2bf69c6 100644 --- a/usr.bin/tmux/format.c +++ b/usr.bin/tmux/format.c @@ -1,4 +1,4 @@ -/* $OpenBSD: format.c,v 1.154 2018/04/18 14:35:37 nicm Exp $ */ +/* $OpenBSD: format.c,v 1.155 2018/05/22 08:49:12 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -837,18 +837,22 @@ found: return (copy); } -/* Skip until comma. */ -static char * -format_skip(char *s) +/* Skip until end. */ +static const char * +format_skip(const char *s, char end) { int brackets = 0; for (; *s != '\0'; s++) { - if (*s == '{') + if (*s == '#' && s[1] == '{') brackets++; + if (*s == '#' && strchr(",#{}", s[1]) != NULL) { + s++; + continue; + } if (*s == '}') brackets--; - if (*s == ',' && brackets == 0) + if (*s == end && brackets == 0) break; } if (*s == '\0') @@ -862,7 +866,7 @@ format_choose(char *s, char **left, char **right) { char *cp; - cp = format_skip(s); + cp = (char *)format_skip(s, ','); if (cp == NULL) return (-1); *cp = '\0'; @@ -892,6 +896,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, size_t valuelen, newlen, fromlen, tolen, used; long limit = 0; int modifiers = 0, compare = 0, search = 0; + int literal = 0; /* Make a copy of the key. */ copy0 = copy = xmalloc(keylen + 1); @@ -900,6 +905,12 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, /* Is there a length limit or whatnot? */ switch (copy[0]) { + case 'l': + if (copy[1] != ':') + break; + literal = 1; + copy += 2; + break; case 'm': if (copy[1] != ':') break; @@ -988,6 +999,12 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, break; } + /* Is this a literal string? */ + if (literal) { + value = xstrdup(copy); + goto done; + } + /* Is this a comparison or a conditional? */ if (search) { /* Search in pane. */ @@ -1019,7 +1036,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, free(left); } else if (*copy == '?') { /* Conditional: check first and choose second or third. */ - ptr = format_skip(copy); + ptr = (char *)format_skip(copy, ','); if (ptr == NULL) goto fail; *ptr = '\0'; @@ -1082,6 +1099,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, } /* Expand the buffer and copy in the value. */ +done: valuelen = strlen(value); while (*len - *off < valuelen + 1) { *buf = xreallocarray(*buf, 2, *len); @@ -1179,14 +1197,8 @@ format_expand(struct format_tree *ft, const char *fmt) fmt += n + 1; continue; case '{': - brackets = 1; - for (ptr = fmt; *ptr != '\0'; ptr++) { - if (*ptr == '{') - brackets++; - if (*ptr == '}' && --brackets == 0) - break; - } - if (*ptr != '}' || brackets != 0) + ptr = format_skip(fmt - 2, '}'); + if (ptr == NULL) break; n = ptr - fmt; @@ -1194,12 +1206,14 @@ format_expand(struct format_tree *ft, const char *fmt) break; fmt += n + 1; continue; + case '}': case '#': + case ',': while (len - off < 2) { buf = xreallocarray(buf, 2, len); len *= 2; } - buf[off++] = '#'; + buf[off++] = ch; continue; default: s = NULL; |