xref: /openbsd/usr.bin/tmux/options.c (revision 4cfece93)
1 /* $OpenBSD: options.c,v 1.59 2020/06/16 08:18:34 nicm Exp $ */
2 
3 /*
4  * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 
21 #include <ctype.h>
22 #include <fnmatch.h>
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "tmux.h"
28 
29 /*
30  * Option handling; each option has a name, type and value and is stored in
31  * a red-black tree.
32  */
33 
34 struct options_array_item {
35 	u_int				 index;
36 	union options_value		 value;
37 	RB_ENTRY(options_array_item)	 entry;
38 };
39 static int
40 options_array_cmp(struct options_array_item *a1, struct options_array_item *a2)
41 {
42 	if (a1->index < a2->index)
43 		return (-1);
44 	if (a1->index > a2->index)
45 		return (1);
46 	return (0);
47 }
48 RB_GENERATE_STATIC(options_array, options_array_item, entry, options_array_cmp);
49 
50 struct options_entry {
51 	struct options				*owner;
52 
53 	const char				*name;
54 	const struct options_table_entry	*tableentry;
55 	union options_value			 value;
56 
57 	int					 cached;
58 	struct style				 style;
59 
60 	RB_ENTRY(options_entry)			 entry;
61 };
62 
63 struct options {
64 	RB_HEAD(options_tree, options_entry)	 tree;
65 	struct options				*parent;
66 };
67 
68 static struct options_entry	*options_add(struct options *, const char *);
69 static void			 options_remove(struct options_entry *);
70 
71 #define OPTIONS_IS_STRING(o)						\
72 	((o)->tableentry == NULL ||					\
73 	    (o)->tableentry->type == OPTIONS_TABLE_STRING)
74 #define OPTIONS_IS_NUMBER(o) \
75 	((o)->tableentry != NULL &&					\
76 	    ((o)->tableentry->type == OPTIONS_TABLE_NUMBER ||		\
77 	    (o)->tableentry->type == OPTIONS_TABLE_KEY ||		\
78 	    (o)->tableentry->type == OPTIONS_TABLE_COLOUR ||		\
79 	    (o)->tableentry->type == OPTIONS_TABLE_FLAG ||		\
80 	    (o)->tableentry->type == OPTIONS_TABLE_CHOICE))
81 #define OPTIONS_IS_COMMAND(o) \
82 	((o)->tableentry != NULL &&					\
83 	    (o)->tableentry->type == OPTIONS_TABLE_COMMAND)
84 
85 #define OPTIONS_IS_ARRAY(o)						\
86 	((o)->tableentry != NULL &&					\
87 	    ((o)->tableentry->flags & OPTIONS_TABLE_IS_ARRAY))
88 
89 static int	options_cmp(struct options_entry *, struct options_entry *);
90 RB_GENERATE_STATIC(options_tree, options_entry, entry, options_cmp);
91 
92 static int
93 options_cmp(struct options_entry *lhs, struct options_entry *rhs)
94 {
95 	return (strcmp(lhs->name, rhs->name));
96 }
97 
98 static const struct options_table_entry *
99 options_parent_table_entry(struct options *oo, const char *s)
100 {
101 	struct options_entry	*o;
102 
103 	if (oo->parent == NULL)
104 		fatalx("no parent options for %s", s);
105 	o = options_get(oo->parent, s);
106 	if (o == NULL)
107 		fatalx("%s not in parent options", s);
108 	return (o->tableentry);
109 }
110 
111 static void
112 options_value_free(struct options_entry *o, union options_value *ov)
113 {
114 	if (OPTIONS_IS_STRING(o))
115 		free(ov->string);
116 	if (OPTIONS_IS_COMMAND(o) && ov->cmdlist != NULL)
117 		cmd_list_free(ov->cmdlist);
118 }
119 
120 static char *
121 options_value_to_string(struct options_entry *o, union options_value *ov,
122     int numeric)
123 {
124 	char	*s;
125 
126 	if (OPTIONS_IS_COMMAND(o))
127 		return (cmd_list_print(ov->cmdlist, 0));
128 	if (OPTIONS_IS_NUMBER(o)) {
129 		switch (o->tableentry->type) {
130 		case OPTIONS_TABLE_NUMBER:
131 			xasprintf(&s, "%lld", ov->number);
132 			break;
133 		case OPTIONS_TABLE_KEY:
134 			s = xstrdup(key_string_lookup_key(ov->number, 0));
135 			break;
136 		case OPTIONS_TABLE_COLOUR:
137 			s = xstrdup(colour_tostring(ov->number));
138 			break;
139 		case OPTIONS_TABLE_FLAG:
140 			if (numeric)
141 				xasprintf(&s, "%lld", ov->number);
142 			else
143 				s = xstrdup(ov->number ? "on" : "off");
144 			break;
145 		case OPTIONS_TABLE_CHOICE:
146 			s = xstrdup(o->tableentry->choices[ov->number]);
147 			break;
148 		case OPTIONS_TABLE_STRING:
149 		case OPTIONS_TABLE_COMMAND:
150 			fatalx("not a number option type");
151 		}
152 		return (s);
153 	}
154 	if (OPTIONS_IS_STRING(o))
155 		return (xstrdup(ov->string));
156 	return (xstrdup(""));
157 }
158 
159 struct options *
160 options_create(struct options *parent)
161 {
162 	struct options	*oo;
163 
164 	oo = xcalloc(1, sizeof *oo);
165 	RB_INIT(&oo->tree);
166 	oo->parent = parent;
167 	return (oo);
168 }
169 
170 void
171 options_free(struct options *oo)
172 {
173 	struct options_entry	*o, *tmp;
174 
175 	RB_FOREACH_SAFE(o, options_tree, &oo->tree, tmp)
176 		options_remove(o);
177 	free(oo);
178 }
179 
180 struct options *
181 options_get_parent(struct options *oo)
182 {
183 	return (oo->parent);
184 }
185 
186 void
187 options_set_parent(struct options *oo, struct options *parent)
188 {
189 	oo->parent = parent;
190 }
191 
192 struct options_entry *
193 options_first(struct options *oo)
194 {
195 	return (RB_MIN(options_tree, &oo->tree));
196 }
197 
198 struct options_entry *
199 options_next(struct options_entry *o)
200 {
201 	return (RB_NEXT(options_tree, &oo->tree, o));
202 }
203 
204 struct options_entry *
205 options_get_only(struct options *oo, const char *name)
206 {
207 	struct options_entry	o;
208 
209 	o.name = name;
210 	return (RB_FIND(options_tree, &oo->tree, &o));
211 }
212 
213 struct options_entry *
214 options_get(struct options *oo, const char *name)
215 {
216 	struct options_entry	*o;
217 
218 	o = options_get_only(oo, name);
219 	while (o == NULL) {
220 		oo = oo->parent;
221 		if (oo == NULL)
222 			break;
223 		o = options_get_only(oo, name);
224 	}
225 	return (o);
226 }
227 
228 struct options_entry *
229 options_empty(struct options *oo, const struct options_table_entry *oe)
230 {
231 	struct options_entry	*o;
232 
233 	o = options_add(oo, oe->name);
234 	o->tableentry = oe;
235 
236 	if (oe->flags & OPTIONS_TABLE_IS_ARRAY)
237 		RB_INIT(&o->value.array);
238 
239 	return (o);
240 }
241 
242 struct options_entry *
243 options_default(struct options *oo, const struct options_table_entry *oe)
244 {
245 	struct options_entry	*o;
246 	union options_value	*ov;
247 	u_int			 i;
248 
249 	o = options_empty(oo, oe);
250 	ov = &o->value;
251 
252 	if (oe->flags & OPTIONS_TABLE_IS_ARRAY) {
253 		if (oe->default_arr == NULL) {
254 			options_array_assign(o, oe->default_str, NULL);
255 			return (o);
256 		}
257 		for (i = 0; oe->default_arr[i] != NULL; i++)
258 			options_array_set(o, i, oe->default_arr[i], 0, NULL);
259 		return (o);
260 	}
261 
262 	switch (oe->type) {
263 	case OPTIONS_TABLE_STRING:
264 		ov->string = xstrdup(oe->default_str);
265 		break;
266 	default:
267 		ov->number = oe->default_num;
268 		break;
269 	}
270 	return (o);
271 }
272 
273 char *
274 options_default_to_string(const struct options_table_entry *oe)
275 {
276 	char	*s;
277 
278 	switch (oe->type) {
279 	case OPTIONS_TABLE_STRING:
280 	case OPTIONS_TABLE_COMMAND:
281 		s = xstrdup(oe->default_str);
282 		break;
283 	case OPTIONS_TABLE_NUMBER:
284 		xasprintf(&s, "%lld", oe->default_num);
285 		break;
286 	case OPTIONS_TABLE_KEY:
287 		s = xstrdup(key_string_lookup_key(oe->default_num, 0));
288 		break;
289 	case OPTIONS_TABLE_COLOUR:
290 		s = xstrdup(colour_tostring(oe->default_num));
291 		break;
292 	case OPTIONS_TABLE_FLAG:
293 		s = xstrdup(oe->default_num ? "on" : "off");
294 		break;
295 	case OPTIONS_TABLE_CHOICE:
296 		s = xstrdup(oe->choices[oe->default_num]);
297 		break;
298 	}
299 	return (s);
300 }
301 
302 static struct options_entry *
303 options_add(struct options *oo, const char *name)
304 {
305 	struct options_entry	*o;
306 
307 	o = options_get_only(oo, name);
308 	if (o != NULL)
309 		options_remove(o);
310 
311 	o = xcalloc(1, sizeof *o);
312 	o->owner = oo;
313 	o->name = xstrdup(name);
314 
315 	RB_INSERT(options_tree, &oo->tree, o);
316 	return (o);
317 }
318 
319 static void
320 options_remove(struct options_entry *o)
321 {
322 	struct options	*oo = o->owner;
323 
324 	if (OPTIONS_IS_ARRAY(o))
325 		options_array_clear(o);
326 	else
327 		options_value_free(o, &o->value);
328 	RB_REMOVE(options_tree, &oo->tree, o);
329 	free((void *)o->name);
330 	free(o);
331 }
332 
333 const char *
334 options_name(struct options_entry *o)
335 {
336 	return (o->name);
337 }
338 
339 struct options *
340 options_owner(struct options_entry *o)
341 {
342 	return (o->owner);
343 }
344 
345 const struct options_table_entry *
346 options_table_entry(struct options_entry *o)
347 {
348 	return (o->tableentry);
349 }
350 
351 static struct options_array_item *
352 options_array_item(struct options_entry *o, u_int idx)
353 {
354 	struct options_array_item	a;
355 
356 	a.index = idx;
357 	return (RB_FIND(options_array, &o->value.array, &a));
358 }
359 
360 static struct options_array_item *
361 options_array_new(struct options_entry *o, u_int idx)
362 {
363 	struct options_array_item	*a;
364 
365 	a = xcalloc(1, sizeof *a);
366 	a->index = idx;
367 	RB_INSERT(options_array, &o->value.array, a);
368 	return (a);
369 }
370 
371 static void
372 options_array_free(struct options_entry *o, struct options_array_item *a)
373 {
374 	options_value_free(o, &a->value);
375 	RB_REMOVE(options_array, &o->value.array, a);
376 	free(a);
377 }
378 
379 void
380 options_array_clear(struct options_entry *o)
381 {
382 	struct options_array_item	*a, *a1;
383 
384 	if (!OPTIONS_IS_ARRAY(o))
385 		return;
386 
387 	RB_FOREACH_SAFE(a, options_array, &o->value.array, a1)
388 	    options_array_free(o, a);
389 }
390 
391 union options_value *
392 options_array_get(struct options_entry *o, u_int idx)
393 {
394 	struct options_array_item	*a;
395 
396 	if (!OPTIONS_IS_ARRAY(o))
397 		return (NULL);
398 	a = options_array_item(o, idx);
399 	if (a == NULL)
400 		return (NULL);
401 	return (&a->value);
402 }
403 
404 int
405 options_array_set(struct options_entry *o, u_int idx, const char *value,
406     int append, char **cause)
407 {
408 	struct options_array_item	*a;
409 	char				*new;
410 	struct cmd_parse_result		*pr;
411 
412 	if (!OPTIONS_IS_ARRAY(o)) {
413 		if (cause != NULL)
414 			*cause = xstrdup("not an array");
415 		return (-1);
416 	}
417 
418 	if (value == NULL) {
419 		a = options_array_item(o, idx);
420 		if (a != NULL)
421 			options_array_free(o, a);
422 		return (0);
423 	}
424 
425 	if (OPTIONS_IS_COMMAND(o)) {
426 		pr = cmd_parse_from_string(value, NULL);
427 		switch (pr->status) {
428 		case CMD_PARSE_EMPTY:
429 			if (cause != NULL)
430 				*cause = xstrdup("empty command");
431 			return (-1);
432 		case CMD_PARSE_ERROR:
433 			if (cause != NULL)
434 				*cause = pr->error;
435 			else
436 				free(pr->error);
437 			return (-1);
438 		case CMD_PARSE_SUCCESS:
439 			break;
440 		}
441 
442 		a = options_array_item(o, idx);
443 		if (a == NULL)
444 			a = options_array_new(o, idx);
445 		else
446 			options_value_free(o, &a->value);
447 		a->value.cmdlist = pr->cmdlist;
448 		return (0);
449 	}
450 
451 	if (OPTIONS_IS_STRING(o)) {
452 		a = options_array_item(o, idx);
453 		if (a != NULL && append)
454 			xasprintf(&new, "%s%s", a->value.string, value);
455 		else
456 			new = xstrdup(value);
457 		if (a == NULL)
458 			a = options_array_new(o, idx);
459 		else
460 			options_value_free(o, &a->value);
461 		a->value.string = new;
462 		return (0);
463 	}
464 
465 	if (cause != NULL)
466 		*cause = xstrdup("wrong array type");
467 	return (-1);
468 }
469 
470 int
471 options_array_assign(struct options_entry *o, const char *s, char **cause)
472 {
473 	const char	*separator;
474 	char		*copy, *next, *string;
475 	u_int		 i;
476 
477 	separator = o->tableentry->separator;
478 	if (separator == NULL)
479 		separator = " ,";
480 	if (*separator == '\0') {
481 		if (*s == '\0')
482 			return (0);
483 		for (i = 0; i < UINT_MAX; i++) {
484 			if (options_array_item(o, i) == NULL)
485 				break;
486 		}
487 		return (options_array_set(o, i, s, 0, cause));
488 	}
489 
490 	if (*s == '\0')
491 		return (0);
492 	copy = string = xstrdup(s);
493 	while ((next = strsep(&string, separator)) != NULL) {
494 		if (*next == '\0')
495 			continue;
496 		for (i = 0; i < UINT_MAX; i++) {
497 			if (options_array_item(o, i) == NULL)
498 				break;
499 		}
500 		if (i == UINT_MAX)
501 			break;
502 		if (options_array_set(o, i, next, 0, cause) != 0) {
503 			free(copy);
504 			return (-1);
505 		}
506 	}
507 	free(copy);
508 	return (0);
509 }
510 
511 struct options_array_item *
512 options_array_first(struct options_entry *o)
513 {
514 	if (!OPTIONS_IS_ARRAY(o))
515 		return (NULL);
516 	return (RB_MIN(options_array, &o->value.array));
517 }
518 
519 struct options_array_item *
520 options_array_next(struct options_array_item *a)
521 {
522 	return (RB_NEXT(options_array, &o->value.array, a));
523 }
524 
525 u_int
526 options_array_item_index(struct options_array_item *a)
527 {
528 	return (a->index);
529 }
530 
531 union options_value *
532 options_array_item_value(struct options_array_item *a)
533 {
534 	return (&a->value);
535 }
536 
537 int
538 options_is_array(struct options_entry *o)
539 {
540 	return (OPTIONS_IS_ARRAY(o));
541 }
542 
543 int
544 options_is_string(struct options_entry *o)
545 {
546 	return (OPTIONS_IS_STRING(o));
547 }
548 
549 char *
550 options_to_string(struct options_entry *o, int idx, int numeric)
551 {
552 	struct options_array_item	*a;
553 
554 	if (OPTIONS_IS_ARRAY(o)) {
555 		if (idx == -1)
556 			return (xstrdup(""));
557 		a = options_array_item(o, idx);
558 		if (a == NULL)
559 			return (xstrdup(""));
560 		return (options_value_to_string(o, &a->value, numeric));
561 	}
562 	return (options_value_to_string(o, &o->value, numeric));
563 }
564 
565 char *
566 options_parse(const char *name, int *idx)
567 {
568 	char	*copy, *cp, *end;
569 
570 	if (*name == '\0')
571 		return (NULL);
572 	copy = xstrdup(name);
573 	if ((cp = strchr(copy, '[')) == NULL) {
574 		*idx = -1;
575 		return (copy);
576 	}
577 	end = strchr(cp + 1, ']');
578 	if (end == NULL || end[1] != '\0' || !isdigit((u_char)end[-1])) {
579 		free(copy);
580 		return (NULL);
581 	}
582 	if (sscanf(cp, "[%d]", idx) != 1 || *idx < 0) {
583 		free(copy);
584 		return (NULL);
585 	}
586 	*cp = '\0';
587 	return (copy);
588 }
589 
590 struct options_entry *
591 options_parse_get(struct options *oo, const char *s, int *idx, int only)
592 {
593 	struct options_entry	*o;
594 	char			*name;
595 
596 	name = options_parse(s, idx);
597 	if (name == NULL)
598 		return (NULL);
599 	if (only)
600 		o = options_get_only(oo, name);
601 	else
602 		o = options_get(oo, name);
603 	free(name);
604 	return (o);
605 }
606 
607 char *
608 options_match(const char *s, int *idx, int *ambiguous)
609 {
610 	const struct options_table_entry	*oe, *found;
611 	char					*name;
612 	size_t					 namelen;
613 
614 	name = options_parse(s, idx);
615 	if (name == NULL)
616 		return (NULL);
617 	namelen = strlen(name);
618 
619 	if (*name == '@') {
620 		*ambiguous = 0;
621 		return (name);
622 	}
623 
624 	found = NULL;
625 	for (oe = options_table; oe->name != NULL; oe++) {
626 		if (strcmp(oe->name, name) == 0) {
627 			found = oe;
628 			break;
629 		}
630 		if (strncmp(oe->name, name, namelen) == 0) {
631 			if (found != NULL) {
632 				*ambiguous = 1;
633 				free(name);
634 				return (NULL);
635 			}
636 			found = oe;
637 		}
638 	}
639 	free(name);
640 	if (found == NULL) {
641 		*ambiguous = 0;
642 		return (NULL);
643 	}
644 	return (xstrdup(found->name));
645 }
646 
647 struct options_entry *
648 options_match_get(struct options *oo, const char *s, int *idx, int only,
649     int *ambiguous)
650 {
651 	char			*name;
652 	struct options_entry	*o;
653 
654 	name = options_match(s, idx, ambiguous);
655 	if (name == NULL)
656 		return (NULL);
657 	*ambiguous = 0;
658 	if (only)
659 		o = options_get_only(oo, name);
660 	else
661 		o = options_get(oo, name);
662 	free(name);
663 	return (o);
664 }
665 
666 const char *
667 options_get_string(struct options *oo, const char *name)
668 {
669 	struct options_entry	*o;
670 
671 	o = options_get(oo, name);
672 	if (o == NULL)
673 		fatalx("missing option %s", name);
674 	if (!OPTIONS_IS_STRING(o))
675 		fatalx("option %s is not a string", name);
676 	return (o->value.string);
677 }
678 
679 long long
680 options_get_number(struct options *oo, const char *name)
681 {
682 	struct options_entry	*o;
683 
684 	o = options_get(oo, name);
685 	if (o == NULL)
686 		fatalx("missing option %s", name);
687 	if (!OPTIONS_IS_NUMBER(o))
688 	    fatalx("option %s is not a number", name);
689 	return (o->value.number);
690 }
691 
692 struct options_entry *
693 options_set_string(struct options *oo, const char *name, int append,
694     const char *fmt, ...)
695 {
696 	struct options_entry	*o;
697 	va_list			 ap;
698 	const char		*separator = "";
699 	char			*s, *value;
700 
701 	va_start(ap, fmt);
702 	xvasprintf(&s, fmt, ap);
703 	va_end(ap);
704 
705 	o = options_get_only(oo, name);
706 	if (o != NULL && append && OPTIONS_IS_STRING(o)) {
707 		if (*name != '@') {
708 			separator = o->tableentry->separator;
709 			if (separator == NULL)
710 				separator = "";
711 		}
712 		xasprintf(&value, "%s%s%s", o->value.string, separator, s);
713 		free(s);
714 	} else
715 		value = s;
716 	if (o == NULL && *name == '@')
717 		o = options_add(oo, name);
718 	else if (o == NULL) {
719 		o = options_default(oo, options_parent_table_entry(oo, name));
720 		if (o == NULL)
721 			return (NULL);
722 	}
723 
724 	if (!OPTIONS_IS_STRING(o))
725 		fatalx("option %s is not a string", name);
726 	free(o->value.string);
727 	o->value.string = value;
728 	o->cached = 0;
729 	return (o);
730 }
731 
732 struct options_entry *
733 options_set_number(struct options *oo, const char *name, long long value)
734 {
735 	struct options_entry	*o;
736 
737 	if (*name == '@')
738 		fatalx("user option %s must be a string", name);
739 
740 	o = options_get_only(oo, name);
741 	if (o == NULL) {
742 		o = options_default(oo, options_parent_table_entry(oo, name));
743 		if (o == NULL)
744 			return (NULL);
745 	}
746 
747 	if (!OPTIONS_IS_NUMBER(o))
748 		fatalx("option %s is not a number", name);
749 	o->value.number = value;
750 	return (o);
751 }
752 
753 int
754 options_scope_from_name(struct args *args, int window,
755     const char *name, struct cmd_find_state *fs, struct options **oo,
756     char **cause)
757 {
758 	struct session				*s = fs->s;
759 	struct winlink				*wl = fs->wl;
760 	struct window_pane			*wp = fs->wp;
761 	const char				*target = args_get(args, 't');
762 	const struct options_table_entry	*oe;
763 	int					 scope = OPTIONS_TABLE_NONE;
764 
765 	if (*name == '@')
766 		return (options_scope_from_flags(args, window, fs, oo, cause));
767 
768 	for (oe = options_table; oe->name != NULL; oe++) {
769 		if (strcmp(oe->name, name) == 0)
770 			break;
771 	}
772 	if (oe->name == NULL) {
773 		xasprintf(cause, "unknown option: %s", name);
774 		return (OPTIONS_TABLE_NONE);
775 	}
776 	switch (oe->scope) {
777 	case OPTIONS_TABLE_SERVER:
778 		*oo = global_options;
779 		scope = OPTIONS_TABLE_SERVER;
780 		break;
781 	case OPTIONS_TABLE_SESSION:
782 		if (args_has(args, 'g')) {
783 			*oo = global_s_options;
784 			scope = OPTIONS_TABLE_SESSION;
785 		} else if (s == NULL && target != NULL)
786 			xasprintf(cause, "no such session: %s", target);
787 		else if (s == NULL)
788 			xasprintf(cause, "no current session");
789 		else {
790 			*oo = s->options;
791 			scope = OPTIONS_TABLE_SESSION;
792 		}
793 		break;
794 	case OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE:
795 		if (args_has(args, 'p')) {
796 			if (wp == NULL && target != NULL)
797 				xasprintf(cause, "no such pane: %s", target);
798 			else if (wp == NULL)
799 				xasprintf(cause, "no current pane");
800 			else {
801 				*oo = wp->options;
802 				scope = OPTIONS_TABLE_PANE;
803 			}
804 			break;
805 		}
806 		/* FALLTHROUGH */
807 	case OPTIONS_TABLE_WINDOW:
808 		if (args_has(args, 'g')) {
809 			*oo = global_w_options;
810 			scope = OPTIONS_TABLE_WINDOW;
811 		} else if (wl == NULL && target != NULL)
812 			xasprintf(cause, "no such window: %s", target);
813 		else if (wl == NULL)
814 			xasprintf(cause, "no current window");
815 		else {
816 			*oo = wl->window->options;
817 			scope = OPTIONS_TABLE_WINDOW;
818 		}
819 		break;
820 	}
821 	return (scope);
822 }
823 
824 int
825 options_scope_from_flags(struct args *args, int window,
826     struct cmd_find_state *fs, struct options **oo, char **cause)
827 {
828 	struct session		*s = fs->s;
829 	struct winlink		*wl = fs->wl;
830 	struct window_pane	*wp = fs->wp;
831 	const char		*target = args_get(args, 't');
832 
833 	if (args_has(args, 's')) {
834 		*oo = global_options;
835 		return (OPTIONS_TABLE_SERVER);
836 	}
837 
838 	if (args_has(args, 'p')) {
839 		if (wp == NULL) {
840 			if (target != NULL)
841 				xasprintf(cause, "no such pane: %s", target);
842 			else
843 				xasprintf(cause, "no current pane");
844 			return (OPTIONS_TABLE_NONE);
845 		}
846 		*oo = wp->options;
847 		return (OPTIONS_TABLE_PANE);
848 	} else if (window || args_has(args, 'w')) {
849 		if (args_has(args, 'g')) {
850 			*oo = global_w_options;
851 			return (OPTIONS_TABLE_WINDOW);
852 		}
853 		if (wl == NULL) {
854 			if (target != NULL)
855 				xasprintf(cause, "no such window: %s", target);
856 			else
857 				xasprintf(cause, "no current window");
858 			return (OPTIONS_TABLE_NONE);
859 		}
860 		*oo = wl->window->options;
861 		return (OPTIONS_TABLE_WINDOW);
862 	} else {
863 		if (args_has(args, 'g')) {
864 			*oo = global_s_options;
865 			return (OPTIONS_TABLE_SESSION);
866 		}
867 		if (s == NULL) {
868 			if (target != NULL)
869 				xasprintf(cause, "no such session: %s", target);
870 			else
871 				xasprintf(cause, "no current session");
872 			return (OPTIONS_TABLE_NONE);
873 		}
874 		*oo = s->options;
875 		return (OPTIONS_TABLE_SESSION);
876 	}
877 }
878 
879 struct style *
880 options_string_to_style(struct options *oo, const char *name,
881     struct format_tree *ft)
882 {
883 	struct options_entry	*o;
884 	const char		*s;
885 	char			*expanded;
886 
887 	o = options_get(oo, name);
888 	if (o == NULL || !OPTIONS_IS_STRING(o))
889 		return (NULL);
890 
891 	if (o->cached)
892 		return (&o->style);
893 	s = o->value.string;
894 	log_debug("%s: %s is '%s'", __func__, name, s);
895 
896 	style_set(&o->style, &grid_default_cell);
897 	o->cached = (strstr(s, "#{") == NULL);
898 
899 	if (ft != NULL && !o->cached) {
900 		expanded = format_expand(ft, s);
901 		if (style_parse(&o->style, &grid_default_cell, expanded) != 0) {
902 			free(expanded);
903 			return (NULL);
904 		}
905 		free(expanded);
906 	} else {
907 		if (style_parse(&o->style, &grid_default_cell, s) != 0)
908 			return (NULL);
909 	}
910 	return (&o->style);
911 }
912 
913 static int
914 options_from_string_check(const struct options_table_entry *oe,
915     const char *value, char **cause)
916 {
917 	struct style	sy;
918 
919 	if (oe == NULL)
920 		return (0);
921 	if (strcmp(oe->name, "default-shell") == 0 && !checkshell(value)) {
922 		xasprintf(cause, "not a suitable shell: %s", value);
923 		return (-1);
924 	}
925 	if (oe->pattern != NULL && fnmatch(oe->pattern, value, 0) != 0) {
926 		xasprintf(cause, "value is invalid: %s", value);
927 		return (-1);
928 	}
929 	if ((oe->flags & OPTIONS_TABLE_IS_STYLE) &&
930 	    strstr(value, "#{") == NULL &&
931 	    style_parse(&sy, &grid_default_cell, value) != 0) {
932 		xasprintf(cause, "invalid style: %s", value);
933 		return (-1);
934 	}
935 	return (0);
936 }
937 
938 static int
939 options_from_string_flag(struct options *oo, const char *name,
940     const char *value, char **cause)
941 {
942 	int	flag;
943 
944 	if (value == NULL || *value == '\0')
945 		flag = !options_get_number(oo, name);
946 	else if (strcmp(value, "1") == 0 ||
947 	    strcasecmp(value, "on") == 0 ||
948 	    strcasecmp(value, "yes") == 0)
949 		flag = 1;
950 	else if (strcmp(value, "0") == 0 ||
951 	    strcasecmp(value, "off") == 0 ||
952 	    strcasecmp(value, "no") == 0)
953 		flag = 0;
954 	else {
955 		xasprintf(cause, "bad value: %s", value);
956 		return (-1);
957 	}
958 	options_set_number(oo, name, flag);
959 	return (0);
960 }
961 
962 static int
963 options_from_string_choice(const struct options_table_entry *oe,
964     struct options *oo, const char *name, const char *value, char **cause)
965 {
966 	const char	**cp;
967 	int		  n, choice = -1;
968 
969 	if (value == NULL) {
970 		choice = options_get_number(oo, name);
971 		if (choice < 2)
972 			choice = !choice;
973 	} else {
974 		n = 0;
975 		for (cp = oe->choices; *cp != NULL; cp++) {
976 			if (strcmp(*cp, value) == 0)
977 				choice = n;
978 			n++;
979 		}
980 		if (choice == -1) {
981 			xasprintf(cause, "unknown value: %s", value);
982 			return (-1);
983 		}
984 	}
985 	options_set_number(oo, name, choice);
986 	return (0);
987 }
988 
989 int
990 options_from_string(struct options *oo, const struct options_table_entry *oe,
991     const char *name, const char *value, int append, char **cause)
992 {
993 	enum options_table_type	 type;
994 	long long		 number;
995 	const char		*errstr, *new;
996 	char			*old;
997 	key_code		 key;
998 
999 	if (oe != NULL) {
1000 		if (value == NULL &&
1001 		    oe->type != OPTIONS_TABLE_FLAG &&
1002 		    oe->type != OPTIONS_TABLE_CHOICE) {
1003 			xasprintf(cause, "empty value");
1004 			return (-1);
1005 		}
1006 		type = oe->type;
1007 	} else {
1008 		if (*name != '@') {
1009 			xasprintf(cause, "bad option name");
1010 			return (-1);
1011 		}
1012 		type = OPTIONS_TABLE_STRING;
1013 	}
1014 
1015 	switch (type) {
1016 	case OPTIONS_TABLE_STRING:
1017 		old = xstrdup(options_get_string(oo, name));
1018 		options_set_string(oo, name, append, "%s", value);
1019 
1020 		new = options_get_string(oo, name);
1021 		if (options_from_string_check(oe, new, cause) != 0) {
1022 			options_set_string(oo, name, 0, "%s", old);
1023 			free(old);
1024 			return (-1);
1025 		}
1026 		free(old);
1027 		return (0);
1028 	case OPTIONS_TABLE_NUMBER:
1029 		number = strtonum(value, oe->minimum, oe->maximum, &errstr);
1030 		if (errstr != NULL) {
1031 			xasprintf(cause, "value is %s: %s", errstr, value);
1032 			return (-1);
1033 		}
1034 		options_set_number(oo, name, number);
1035 		return (0);
1036 	case OPTIONS_TABLE_KEY:
1037 		key = key_string_lookup_string(value);
1038 		if (key == KEYC_UNKNOWN) {
1039 			xasprintf(cause, "bad key: %s", value);
1040 			return (-1);
1041 		}
1042 		options_set_number(oo, name, key);
1043 		return (0);
1044 	case OPTIONS_TABLE_COLOUR:
1045 		if ((number = colour_fromstring(value)) == -1) {
1046 			xasprintf(cause, "bad colour: %s", value);
1047 			return (-1);
1048 		}
1049 		options_set_number(oo, name, number);
1050 		return (0);
1051 	case OPTIONS_TABLE_FLAG:
1052 		return (options_from_string_flag(oo, name, value, cause));
1053 	case OPTIONS_TABLE_CHOICE:
1054 		return (options_from_string_choice(oe, oo, name, value, cause));
1055 	case OPTIONS_TABLE_COMMAND:
1056 		break;
1057 	}
1058 	return (-1);
1059 }
1060 
1061 void
1062 options_push_changes(const char *name)
1063 {
1064 	struct client		*loop;
1065 	struct session		*s;
1066 	struct window		*w;
1067 	struct window_pane	*wp;
1068 
1069 	if (strcmp(name, "automatic-rename") == 0) {
1070 		RB_FOREACH(w, windows, &windows) {
1071 			if (w->active == NULL)
1072 				continue;
1073 			if (options_get_number(w->options, "automatic-rename"))
1074 				w->active->flags |= PANE_CHANGED;
1075 		}
1076 	}
1077 	if (strcmp(name, "key-table") == 0) {
1078 		TAILQ_FOREACH(loop, &clients, entry)
1079 			server_client_set_key_table(loop, NULL);
1080 	}
1081 	if (strcmp(name, "user-keys") == 0) {
1082 		TAILQ_FOREACH(loop, &clients, entry) {
1083 			if (loop->tty.flags & TTY_OPENED)
1084 				tty_keys_build(&loop->tty);
1085 		}
1086 	}
1087 	if (strcmp(name, "status") == 0 ||
1088 	    strcmp(name, "status-interval") == 0)
1089 		status_timer_start_all();
1090 	if (strcmp(name, "monitor-silence") == 0)
1091 		alerts_reset_all();
1092 	if (strcmp(name, "window-style") == 0 ||
1093 	    strcmp(name, "window-active-style") == 0) {
1094 		RB_FOREACH(wp, window_pane_tree, &all_window_panes)
1095 			wp->flags |= PANE_STYLECHANGED;
1096 	}
1097 	if (strcmp(name, "pane-border-status") == 0) {
1098 		RB_FOREACH(w, windows, &windows)
1099 			layout_fix_panes(w);
1100 	}
1101 	RB_FOREACH(s, sessions, &sessions)
1102 		status_update_cache(s);
1103 
1104 	recalculate_sizes();
1105 	TAILQ_FOREACH(loop, &clients, entry) {
1106 		if (loop->session != NULL)
1107 			server_redraw_client(loop);
1108 	}
1109 }
1110 
1111 int
1112 options_remove_or_default(struct options_entry *o, int idx, char **cause)
1113 {
1114 	struct options	*oo = o->owner;
1115 
1116 	if (idx == -1) {
1117 		if (o->tableentry != NULL &&
1118 		    (oo == global_options ||
1119 		    oo == global_s_options ||
1120 		    oo == global_w_options))
1121 			options_default(oo, o->tableentry);
1122 		else
1123 			options_remove(o);
1124 	} else if (options_array_set(o, idx, NULL, 0, cause) != 0)
1125 		return (-1);
1126 	return (0);
1127 }
1128