mirror of
https://github.com/tmux/tmux.git
synced 2025-09-01 12:37:02 +00:00
Merge branch 'obsd-master'
This commit is contained in:
94
format.c
94
format.c
@ -104,6 +104,8 @@ format_job_cmp(struct format_job *fj1, struct format_job *fj2)
|
||||
#define FORMAT_CHARACTER 0x10000
|
||||
#define FORMAT_COLOUR 0x20000
|
||||
#define FORMAT_CLIENTS 0x40000
|
||||
#define FORMAT_NOT 0x80000
|
||||
#define FORMAT_NOT_NOT 0x100000
|
||||
|
||||
/* Limit on recursion. */
|
||||
#define FORMAT_LOOP_LIMIT 100
|
||||
@ -4007,7 +4009,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
|
||||
cp++;
|
||||
|
||||
/* Check single character modifiers with no arguments. */
|
||||
if (strchr("labcdnwETSWPL<>", cp[0]) != NULL &&
|
||||
if (strchr("labcdnwETSWPL!<>", cp[0]) != NULL &&
|
||||
format_is_end(cp[1])) {
|
||||
format_add_modifier(&list, count, cp, 1, NULL, 0);
|
||||
cp++;
|
||||
@ -4017,6 +4019,7 @@ format_build_modifiers(struct format_expand_state *es, const char **s,
|
||||
/* Then try double character with no arguments. */
|
||||
if ((memcmp("||", cp, 2) == 0 ||
|
||||
memcmp("&&", cp, 2) == 0 ||
|
||||
memcmp("!!", cp, 2) == 0 ||
|
||||
memcmp("!=", cp, 2) == 0 ||
|
||||
memcmp("==", cp, 2) == 0 ||
|
||||
memcmp("<=", cp, 2) == 0 ||
|
||||
@ -4152,6 +4155,60 @@ format_search(struct format_modifier *fm, struct window_pane *wp, const char *s)
|
||||
return (value);
|
||||
}
|
||||
|
||||
/* Handle unary boolean operators, "!" and "!!". */
|
||||
static char *
|
||||
format_bool_op_1(struct format_expand_state *es, const char *fmt, int not)
|
||||
{
|
||||
int result;
|
||||
char *expanded;
|
||||
|
||||
expanded = format_expand1(es, fmt);
|
||||
result = format_true(expanded);
|
||||
if (not)
|
||||
result = !result;
|
||||
free(expanded);
|
||||
|
||||
return (xstrdup(result ? "1" : "0"));
|
||||
}
|
||||
|
||||
/* Handle n-ary boolean operators, "&&" and "||". */
|
||||
static char *
|
||||
format_bool_op_n(struct format_expand_state *es, const char *fmt, int and)
|
||||
{
|
||||
int result;
|
||||
const char *cp1, *cp2;
|
||||
char *raw, *expanded;
|
||||
|
||||
result = and ? 1 : 0;
|
||||
cp1 = fmt;
|
||||
|
||||
while (and ? result : !result) {
|
||||
cp2 = format_skip(cp1, ",");
|
||||
|
||||
if (cp2 == NULL)
|
||||
raw = xstrdup(cp1);
|
||||
else
|
||||
raw = xstrndup(cp1, cp2 - cp1);
|
||||
expanded = format_expand1(es, raw);
|
||||
free(raw);
|
||||
format_log(es, "operator %s has operand: %s",
|
||||
and ? "&&" : "||", expanded);
|
||||
|
||||
if (and)
|
||||
result = result && format_true(expanded);
|
||||
else
|
||||
result = result || format_true(expanded);
|
||||
free(expanded);
|
||||
|
||||
if (cp2 == NULL)
|
||||
break;
|
||||
else
|
||||
cp1 = cp2 + 1;
|
||||
}
|
||||
|
||||
return (xstrdup(result ? "1" : "0"));
|
||||
}
|
||||
|
||||
/* Does session name exist? */
|
||||
static char *
|
||||
format_session_name(struct format_expand_state *es, const char *fmt)
|
||||
@ -4528,6 +4585,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
||||
int j, c;
|
||||
struct format_modifier *list, *cmp = NULL, *search = NULL;
|
||||
struct format_modifier **sub = NULL, *mexp = NULL, *fm;
|
||||
struct format_modifier *bool_op_n = NULL;
|
||||
u_int i, count, nsub = 0;
|
||||
struct format_expand_state next;
|
||||
|
||||
@ -4552,6 +4610,9 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
||||
case '>':
|
||||
cmp = fm;
|
||||
break;
|
||||
case '!':
|
||||
modifiers |= FORMAT_NOT;
|
||||
break;
|
||||
case 'C':
|
||||
search = fm;
|
||||
break;
|
||||
@ -4650,8 +4711,11 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
||||
}
|
||||
} else if (fm->size == 2) {
|
||||
if (strcmp(fm->modifier, "||") == 0 ||
|
||||
strcmp(fm->modifier, "&&") == 0 ||
|
||||
strcmp(fm->modifier, "==") == 0 ||
|
||||
strcmp(fm->modifier, "&&") == 0)
|
||||
bool_op_n = fm;
|
||||
else if (strcmp(fm->modifier, "!!") == 0)
|
||||
modifiers |= FORMAT_NOT_NOT;
|
||||
else if (strcmp(fm->modifier, "==") == 0 ||
|
||||
strcmp(fm->modifier, "!=") == 0 ||
|
||||
strcmp(fm->modifier, ">=") == 0 ||
|
||||
strcmp(fm->modifier, "<=") == 0)
|
||||
@ -4690,7 +4754,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Is this a loop, comparison or condition? */
|
||||
/* Is this a loop, operator, comparison or condition? */
|
||||
if (modifiers & FORMAT_SESSIONS) {
|
||||
value = format_loop_sessions(es, copy);
|
||||
if (value == NULL)
|
||||
@ -4726,6 +4790,16 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
||||
value = format_search(search, wp, new);
|
||||
}
|
||||
free(new);
|
||||
} else if (modifiers & FORMAT_NOT) {
|
||||
value = format_bool_op_1(es, copy, 1);
|
||||
} else if (modifiers & FORMAT_NOT_NOT) {
|
||||
value = format_bool_op_1(es, copy, 0);
|
||||
} else if (bool_op_n != NULL) {
|
||||
/* n-ary boolean operator. */
|
||||
if (strcmp(bool_op_n->modifier, "||") == 0)
|
||||
value = format_bool_op_n(es, copy, 0);
|
||||
else if (strcmp(bool_op_n->modifier, "&&") == 0)
|
||||
value = format_bool_op_n(es, copy, 1);
|
||||
} else if (cmp != NULL) {
|
||||
/* Comparison of left and right. */
|
||||
if (format_choose(es, copy, &left, &right, 1) != 0) {
|
||||
@ -4736,17 +4810,7 @@ format_replace(struct format_expand_state *es, const char *key, size_t keylen,
|
||||
format_log(es, "compare %s left is: %s", cmp->modifier, left);
|
||||
format_log(es, "compare %s right is: %s", cmp->modifier, right);
|
||||
|
||||
if (strcmp(cmp->modifier, "||") == 0) {
|
||||
if (format_true(left) || format_true(right))
|
||||
value = xstrdup("1");
|
||||
else
|
||||
value = xstrdup("0");
|
||||
} else if (strcmp(cmp->modifier, "&&") == 0) {
|
||||
if (format_true(left) && format_true(right))
|
||||
value = xstrdup("1");
|
||||
else
|
||||
value = xstrdup("0");
|
||||
} else if (strcmp(cmp->modifier, "==") == 0) {
|
||||
if (strcmp(cmp->modifier, "==") == 0) {
|
||||
if (strcmp(left, right) == 0)
|
||||
value = xstrdup("1");
|
||||
else
|
||||
|
10
tmux.1
10
tmux.1
@ -5706,9 +5706,17 @@ otherwise by
|
||||
.Ql ||
|
||||
and
|
||||
.Ql &&
|
||||
evaluate to true if either or both of two comma-separated alternatives are
|
||||
evaluate to true if any or all of the comma-separated alternatives are
|
||||
true, for example
|
||||
.Ql #{||:#{pane_in_mode},#{alternate_on}} .
|
||||
.Ql \&!
|
||||
evaluates to true if the value is false and vice versa, for example
|
||||
.Ql #{!:#{pane_in_mode}} .
|
||||
.Ql !!
|
||||
converts a value to a canonical boolean form, 1 for true and 0 for false, for
|
||||
example
|
||||
.Ql #{!!:non-empty string}
|
||||
evaluates to 1.
|
||||
.Pp
|
||||
An
|
||||
.Ql m
|
||||
|
Reference in New Issue
Block a user