summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2017-01-09 21:03:26 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2017-01-09 21:03:26 +0000
commit6b544ed0aef6350d522dda46bce4c74d5877eb48 (patch)
tree4df258ec78d2103864623831f9e7b1e020dbf5dc /usr.bin
parent3095b0d9d204466e8d789384075b8b0ddf165676 (diff)
Add simple comparisons in formats: #{==:a,b} and #{!=:a,b} ("a" and "b"
are expanded so can compare formats). And expand the condition to #{?a,b,c} (the "a" part) if it doesn't work as a simple lookup. Also add FORMAT_NOJOBS flag to disable jobs in a format.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/tmux/format.c118
-rw-r--r--usr.bin/tmux/tmux.117
-rw-r--r--usr.bin/tmux/tmux.h3
3 files changed, 108 insertions, 30 deletions
diff --git a/usr.bin/tmux/format.c b/usr.bin/tmux/format.c
index 0b3ccd06259..a8b39ae3713 100644
--- a/usr.bin/tmux/format.c
+++ b/usr.bin/tmux/format.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: format.c,v 1.113 2016/11/17 10:06:08 nicm Exp $ */
+/* $OpenBSD: format.c,v 1.114 2017/01/09 21:03:25 nicm Exp $ */
/*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -707,6 +707,50 @@ found:
return (copy);
}
+/* Skip until comma. */
+static char *
+format_skip(char *s)
+{
+ int brackets = 0;
+
+ for (; *s != '\0'; s++) {
+ if (*s == '{')
+ brackets++;
+ if (*s == '}')
+ brackets--;
+ if (*s == ',' && brackets == 0)
+ break;
+ }
+ if (*s == '\0')
+ return (NULL);
+ return (s);
+}
+
+/* Return left and right alternatives separated by commas. */
+static int
+format_choose(char *s, char **left, char **right)
+{
+ char *cp;
+
+ cp = format_skip(s);
+ if (cp == NULL)
+ return (-1);
+ *cp = '\0';
+
+ *left = s;
+ *right = cp + 1;
+ return (0);
+}
+
+/* Is this true? */
+static int
+format_true(const char *s)
+{
+ if (s != NULL && *s != '\0' && (s[0] != '0' || s[1] != '\0'))
+ return (1);
+ return (0);
+}
+
/*
* Replace a key/value pair in buffer. #{blah} is expanded directly,
* #{?blah,a,b} is replace with a if blah exists and is nonzero else b.
@@ -716,10 +760,10 @@ 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, *found, *new, *value;
- char *from = NULL, *to = NULL;
+ char *from = NULL, *to = NULL, *left, *right;
size_t valuelen, newlen, fromlen, tolen, used;
long limit = 0;
- int modifiers = 0, brackets;
+ int modifiers = 0, compare = 0;
/* Make a copy of the key. */
copy0 = copy = xmalloc(keylen + 1);
@@ -728,7 +772,19 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
/* Is there a length limit or whatnot? */
switch (copy[0]) {
+ case '!':
+ if (copy[1] == '=' && copy[2] == ':') {
+ compare = -1;
+ copy += 3;
+ break;
+ }
+ break;
case '=':
+ if (copy[1] == '=' && copy[2] == ':') {
+ compare = 1;
+ copy += 3;
+ break;
+ }
errno = 0;
limit = strtol(copy + 1, &endptr, 10);
if (errno == ERANGE && (limit == LONG_MIN || limit == LONG_MAX))
@@ -780,39 +836,42 @@ format_replace(struct format_tree *ft, const char *key, size_t keylen,
break;
}
- /*
- * Is this a conditional? If so, check it exists and extract either the
- * first or second element. If not, look up the key directly.
- */
- if (*copy == '?') {
- ptr = strchr(copy, ',');
+ /* Is this a comparison or a conditional? */
+ if (compare != 0) {
+ /* Comparison: compare comma-separated left and right. */
+ if (format_choose(copy, &left, &right) != 0)
+ goto fail;
+ left = format_expand(ft, left);
+ right = format_expand(ft, right);
+ if (compare == 1 && strcmp(left, right) == 0)
+ value = xstrdup("1");
+ else if (compare == -1 && strcmp(left, right) != 0)
+ value = xstrdup("1");
+ else
+ value = xstrdup("0");
+ free(right);
+ free(left);
+ } else if (*copy == '?') {
+ /* Conditional: check first and choose second or third. */
+ ptr = format_skip(copy);
if (ptr == NULL)
goto fail;
*ptr = '\0';
- value = ptr + 1;
found = format_find(ft, copy + 1, modifiers);
-
- brackets = 0;
- for (ptr = ptr + 1; *ptr != '\0'; ptr++) {
- if (*ptr == '{')
- brackets++;
- if (*ptr == '}')
- brackets--;
- if (*ptr == ',' && brackets == 0)
- break;
- }
- if (*ptr == '\0')
+ if (found == NULL) {
+ log_debug("XXX %s", copy + 1);
+ found = format_expand(ft, copy + 1);}
+ if (format_choose(ptr + 1, &left, &right) != 0)
goto fail;
- if (found != NULL && *found != '\0' &&
- (found[0] != '0' || found[1] != '\0')) {
- *ptr = '\0';
- } else
- value = ptr + 1;
- value = format_expand(ft, value);
+ if (format_true(found))
+ value = format_expand(ft, left);
+ else
+ value = format_expand(ft, right);
free(found);
} else {
+ /* Neither: look up directly. */
value = format_find(ft, copy, modifiers);
if (value == NULL)
value = xstrdup("");
@@ -934,7 +993,10 @@ format_expand(struct format_tree *ft, const char *fmt)
break;
n = ptr - fmt;
- out = format_job_get(ft, xstrndup(fmt, n));
+ if (ft->flags & FORMAT_NOJOBS)
+ out = xstrdup("");
+ else
+ out = format_job_get(ft, xstrndup(fmt, n));
outlen = strlen(out);
while (len - off < outlen + 1) {
diff --git a/usr.bin/tmux/tmux.1 b/usr.bin/tmux/tmux.1
index 4b7b4b6d468..b319537efa4 100644
--- a/usr.bin/tmux/tmux.1
+++ b/usr.bin/tmux/tmux.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tmux.1,v 1.519 2017/01/09 19:27:00 nicm Exp $
+.\" $OpenBSD: tmux.1,v 1.520 2017/01/09 21:03:25 nicm Exp $
.\"
.\" Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
.\"
@@ -3397,6 +3397,21 @@ is enabled, or
.Ql no
if not.
.Pp
+Simple comparisons may be expressed by prefixing two comma-separated
+alternatives by
+.Ql ==
+or
+.Ql !=
+and a colon.
+For example
+.Ql #{==,#{host},myhost}
+will be replaced by
+.Ql 1
+if running on
+.Ql myhost ,
+otherwise by
+.Ql 0.
+.Pp
A limit may be placed on the length of the resultant string by prefixing it
by an
.Ql = ,
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index 816c049325a..e3064da4456 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.686 2017/01/09 19:27:00 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.687 2017/01/09 21:03:25 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -1568,6 +1568,7 @@ char *paste_make_sample(struct paste_buffer *);
/* format.c */
#define FORMAT_STATUS 0x1
#define FORMAT_FORCE 0x2
+#define FORMAT_NOJOBS 0x4
struct format_tree;
struct format_tree *format_create(struct cmdq_item *, int);
void format_free(struct format_tree *);