From 7e9a8899f550ff0eb982e12e65e70acbc1391660 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 18 Nov 2015 14:13:56 +0000 Subject: Add s/foo/bar/: prefix for formats to substitute bar for foo. --- usr.bin/tmux/format.c | 82 +++++++++++++++++++++++++++++++++++++++++---------- usr.bin/tmux/tmux.1 | 11 +++++-- 2 files changed, 76 insertions(+), 17 deletions(-) diff --git a/usr.bin/tmux/format.c b/usr.bin/tmux/format.c index 1571636cfef..56ef9694ec4 100644 --- a/usr.bin/tmux/format.c +++ b/usr.bin/tmux/format.c @@ -1,4 +1,4 @@ -/* $OpenBSD: format.c,v 1.97 2015/11/13 12:18:52 nicm Exp $ */ +/* $OpenBSD: format.c,v 1.98 2015/11/18 14:13:55 nicm Exp $ */ /* * Copyright (c) 2011 Nicholas Marriott @@ -99,6 +99,7 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2) #define FORMAT_TIMESTRING 0x1 #define FORMAT_BASENAME 0x2 #define FORMAT_DIRNAME 0x4 +#define FORMAT_SUBSTITUTE 0x8 /* Entry in format tree. */ struct format_entry { @@ -682,8 +683,9 @@ int format_replace(struct format_tree *ft, const char *key, size_t keylen, char **buf, size_t *len, size_t *off) { - char *copy, *copy0, *endptr, *ptr, *saved, *trimmed, *value; - size_t valuelen; + char *copy, *copy0, *endptr, *ptr, *found, *new, *value; + char *from = NULL, *to = NULL; + size_t valuelen, newlen, fromlen, tolen, used; u_long limit = 0; int modifiers = 0, brackets; @@ -721,6 +723,29 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, modifiers |= FORMAT_TIMESTRING; copy += 2; break; + case 's': + if (copy[1] != '/') + break; + from = copy + 2; + for (copy = from; *copy != '\0' && *copy != '/'; copy++) + /* nothing */; + if (copy[0] != '/' || copy == from) { + copy = copy0; + break; + } + copy[0] = '\0'; + to = copy + 1; + for (copy = to; *copy != '\0' && *copy != '/'; copy++) + /* nothing */; + if (copy[0] != '/' || copy[1] != ':') { + copy = copy0; + break; + } + copy[0] = '\0'; + + modifiers |= FORMAT_SUBSTITUTE; + copy += 2; + break; } /* @@ -734,7 +759,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, *ptr = '\0'; value = ptr + 1; - saved = format_find(ft, copy + 1, modifiers); + found = format_find(ft, copy + 1, modifiers); brackets = 0; for (ptr = ptr + 1; *ptr != '\0'; ptr++) { @@ -748,29 +773,56 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, if (*ptr == '\0') goto fail; - if (saved != NULL && *saved != '\0' && - (saved[0] != '0' || saved[1] != '\0')) { + if (found != NULL && *found != '\0' && + (found[0] != '0' || found[1] != '\0')) { *ptr = '\0'; } else value = ptr + 1; value = format_expand(ft, value); - free(saved); - saved = value; + free(found); } else { - saved = value = format_find(ft, copy, modifiers); + value = format_find(ft, copy, modifiers); if (value == NULL) - saved = value = xstrdup(""); + value = xstrdup(""); + } + + /* Perform substitution if any. */ + if (modifiers & FORMAT_SUBSTITUTE) { + fromlen = strlen(from); + tolen = strlen(to); + + newlen = strlen(value) + 1; + copy = new = xmalloc(newlen); + for (ptr = value; *ptr != '\0'; /* nothing */) { + if (strncmp(ptr, from, fromlen) != 0) { + *new++ = *ptr++; + continue; + } + used = new - copy; + + newlen += tolen; + copy = xrealloc(copy, newlen); + + new = copy + used; + memcpy(new, to, tolen); + + new += tolen; + ptr += fromlen; + } + *new = '\0'; + free(value); + value = copy; } /* Truncate the value if needed. */ if (limit != 0) { - value = trimmed = utf8_trimcstr(value, limit); - free(saved); - saved = trimmed; + new = utf8_trimcstr(value, limit); + free(value); + value = new; } - valuelen = strlen(value); /* Expand the buffer and copy in the value. */ + valuelen = strlen(value); while (*len - *off < valuelen + 1) { *buf = xreallocarray(*buf, 2, *len); *len *= 2; @@ -778,7 +830,7 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen, memcpy(*buf + *off, value, valuelen); *off += valuelen; - free(saved); + free(value); free(copy0); return (0); diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1 index 3fd2f2170c2..af40d3e0137 100644 --- a/usr.bin/tmux/tmux.1 +++ b/usr.bin/tmux/tmux.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tmux.1,v 1.460 2015/11/13 10:00:26 nicm Exp $ +.\" $OpenBSD: tmux.1,v 1.461 2015/11/18 14:13:55 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -14,7 +14,7 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: November 13 2015 $ +.Dd $Mdocdate: November 18 2015 $ .Dt TMUX 1 .Os .Sh NAME @@ -3311,6 +3311,13 @@ prefixes are and .Xr dirname 3 of the variable respectively. +A prefix of the form +.Ql s/foo/bar/: +will substitute +.Ql foo +with +.Ql bar +throughout. .Pp In addition, the first line of a shell command's output may be inserted using .Ql #() . -- cgit v1.2.3