summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2015-11-18 14:13:56 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2015-11-18 14:13:56 +0000
commit7e9a8899f550ff0eb982e12e65e70acbc1391660 (patch)
tree0cb7f578e78a375f0b747b1f85a947b83a5d4d96
parent144caf06f010a87ee375f0b23001338868287495 (diff)
Add s/foo/bar/: prefix for formats to substitute bar for foo.
-rw-r--r--usr.bin/tmux/format.c82
-rw-r--r--usr.bin/tmux/tmux.111
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 <nicm@users.sourceforge.net>
@@ -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 <nicm@users.sourceforge.net>
.\"
@@ -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 #() .