Home | History | Annotate | Line # | Download | only in dist
      1 /* $OpenBSD$ */
      2 
      3 /*
      4  * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott (at) 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 char *
     99 options_map_name(const char *name)
    100 {
    101 	const struct options_name_map	*map;
    102 
    103 	for (map = options_other_names; map->from != NULL; map++) {
    104 		if (strcmp(map->from, name) == 0)
    105 			return (map->to);
    106 	}
    107 	return (name);
    108 }
    109 
    110 static const struct options_table_entry *
    111 options_parent_table_entry(struct options *oo, const char *s)
    112 {
    113 	struct options_entry	*o;
    114 
    115 	if (oo->parent == NULL)
    116 		fatalx("no parent options for %s", s);
    117 	o = options_get(oo->parent, s);
    118 	if (o == NULL)
    119 		fatalx("%s not in parent options", s);
    120 	return (o->tableentry);
    121 }
    122 
    123 static void
    124 options_value_free(struct options_entry *o, union options_value *ov)
    125 {
    126 	if (OPTIONS_IS_STRING(o))
    127 		free(ov->string);
    128 	if (OPTIONS_IS_COMMAND(o) && ov->cmdlist != NULL)
    129 		cmd_list_free(ov->cmdlist);
    130 }
    131 
    132 static char *
    133 options_value_to_string(struct options_entry *o, union options_value *ov,
    134     int numeric)
    135 {
    136 	char	*s;
    137 
    138 	if (OPTIONS_IS_COMMAND(o))
    139 		return (cmd_list_print(ov->cmdlist, 0));
    140 	if (OPTIONS_IS_NUMBER(o)) {
    141 		switch (o->tableentry->type) {
    142 		case OPTIONS_TABLE_NUMBER:
    143 			xasprintf(&s, "%lld", ov->number);
    144 			break;
    145 		case OPTIONS_TABLE_KEY:
    146 			s = xstrdup(key_string_lookup_key(ov->number, 0));
    147 			break;
    148 		case OPTIONS_TABLE_COLOUR:
    149 			s = xstrdup(colour_tostring(ov->number));
    150 			break;
    151 		case OPTIONS_TABLE_FLAG:
    152 			if (numeric)
    153 				xasprintf(&s, "%lld", ov->number);
    154 			else
    155 				s = xstrdup(ov->number ? "on" : "off");
    156 			break;
    157 		case OPTIONS_TABLE_CHOICE:
    158 			s = xstrdup(o->tableentry->choices[ov->number]);
    159 			break;
    160 		default:
    161 			fatalx("not a number option type");
    162 		}
    163 		return (s);
    164 	}
    165 	if (OPTIONS_IS_STRING(o))
    166 		return (xstrdup(ov->string));
    167 	return (xstrdup(""));
    168 }
    169 
    170 struct options *
    171 options_create(struct options *parent)
    172 {
    173 	struct options	*oo;
    174 
    175 	oo = xcalloc(1, sizeof *oo);
    176 	RB_INIT(&oo->tree);
    177 	oo->parent = parent;
    178 	return (oo);
    179 }
    180 
    181 void
    182 options_free(struct options *oo)
    183 {
    184 	struct options_entry	*o, *tmp;
    185 
    186 	RB_FOREACH_SAFE(o, options_tree, &oo->tree, tmp)
    187 		options_remove(o);
    188 	free(oo);
    189 }
    190 
    191 struct options *
    192 options_get_parent(struct options *oo)
    193 {
    194 	return (oo->parent);
    195 }
    196 
    197 void
    198 options_set_parent(struct options *oo, struct options *parent)
    199 {
    200 	oo->parent = parent;
    201 }
    202 
    203 struct options_entry *
    204 options_first(struct options *oo)
    205 {
    206 	return (RB_MIN(options_tree, &oo->tree));
    207 }
    208 
    209 struct options_entry *
    210 options_next(struct options_entry *o)
    211 {
    212 	return (RB_NEXT(options_tree, &oo->tree, o));
    213 }
    214 
    215 struct options_entry *
    216 options_get_only(struct options *oo, const char *name)
    217 {
    218 	struct options_entry	o = { .name = name }, *found;
    219 
    220 	found = RB_FIND(options_tree, &oo->tree, &o);
    221 	if (found == NULL) {
    222 		o.name = options_map_name(name);
    223 		return (RB_FIND(options_tree, &oo->tree, &o));
    224 	}
    225 	return (found);
    226 }
    227 
    228 struct options_entry *
    229 options_get(struct options *oo, const char *name)
    230 {
    231 	struct options_entry	*o;
    232 
    233 	o = options_get_only(oo, name);
    234 	while (o == NULL) {
    235 		oo = oo->parent;
    236 		if (oo == NULL)
    237 			break;
    238 		o = options_get_only(oo, name);
    239 	}
    240 	return (o);
    241 }
    242 
    243 struct options_entry *
    244 options_empty(struct options *oo, const struct options_table_entry *oe)
    245 {
    246 	struct options_entry	*o;
    247 
    248 	o = options_add(oo, oe->name);
    249 	o->tableentry = oe;
    250 
    251 	if (oe->flags & OPTIONS_TABLE_IS_ARRAY)
    252 		RB_INIT(&o->value.array);
    253 
    254 	return (o);
    255 }
    256 
    257 struct options_entry *
    258 options_default(struct options *oo, const struct options_table_entry *oe)
    259 {
    260 	struct options_entry	*o;
    261 	union options_value	*ov;
    262 	u_int			 i;
    263 	struct cmd_parse_result	*pr;
    264 
    265 	o = options_empty(oo, oe);
    266 	ov = &o->value;
    267 
    268 	if (oe->flags & OPTIONS_TABLE_IS_ARRAY) {
    269 		if (oe->default_arr == NULL) {
    270 			options_array_assign(o, oe->default_str, NULL);
    271 			return (o);
    272 		}
    273 		for (i = 0; oe->default_arr[i] != NULL; i++)
    274 			options_array_set(o, i, oe->default_arr[i], 0, NULL);
    275 		return (o);
    276 	}
    277 
    278 	switch (oe->type) {
    279 	case OPTIONS_TABLE_STRING:
    280 		ov->string = xstrdup(oe->default_str);
    281 		break;
    282 	case OPTIONS_TABLE_COMMAND:
    283 		pr = cmd_parse_from_string(oe->default_str, NULL);
    284 		switch (pr->status) {
    285 		case CMD_PARSE_ERROR:
    286 			free(pr->error);
    287 			break;
    288 		case CMD_PARSE_SUCCESS:
    289 			ov->cmdlist = pr->cmdlist;
    290 			break;
    291 		}
    292 		break;
    293 	default:
    294 		ov->number = oe->default_num;
    295 		break;
    296 	}
    297 	return (o);
    298 }
    299 
    300 char *
    301 options_default_to_string(const struct options_table_entry *oe)
    302 {
    303 	char	*s;
    304 
    305 	switch (oe->type) {
    306 	case OPTIONS_TABLE_STRING:
    307 	case OPTIONS_TABLE_COMMAND:
    308 		s = xstrdup(oe->default_str);
    309 		break;
    310 	case OPTIONS_TABLE_NUMBER:
    311 		xasprintf(&s, "%lld", oe->default_num);
    312 		break;
    313 	case OPTIONS_TABLE_KEY:
    314 		s = xstrdup(key_string_lookup_key(oe->default_num, 0));
    315 		break;
    316 	case OPTIONS_TABLE_COLOUR:
    317 		s = xstrdup(colour_tostring(oe->default_num));
    318 		break;
    319 	case OPTIONS_TABLE_FLAG:
    320 		s = xstrdup(oe->default_num ? "on" : "off");
    321 		break;
    322 	case OPTIONS_TABLE_CHOICE:
    323 		s = xstrdup(oe->choices[oe->default_num]);
    324 		break;
    325 	default:
    326 		fatalx("unknown option type");
    327 	}
    328 	return (s);
    329 }
    330 
    331 static struct options_entry *
    332 options_add(struct options *oo, const char *name)
    333 {
    334 	struct options_entry	*o;
    335 
    336 	o = options_get_only(oo, name);
    337 	if (o != NULL)
    338 		options_remove(o);
    339 
    340 	o = xcalloc(1, sizeof *o);
    341 	o->owner = oo;
    342 	o->name = xstrdup(name);
    343 
    344 	RB_INSERT(options_tree, &oo->tree, o);
    345 	return (o);
    346 }
    347 
    348 static void
    349 options_remove(struct options_entry *o)
    350 {
    351 	struct options	*oo = o->owner;
    352 
    353 	if (OPTIONS_IS_ARRAY(o))
    354 		options_array_clear(o);
    355 	else
    356 		options_value_free(o, &o->value);
    357 	RB_REMOVE(options_tree, &oo->tree, o);
    358 	free(__UNCONST(o->name));
    359 	free(o);
    360 }
    361 
    362 const char *
    363 options_name(struct options_entry *o)
    364 {
    365 	return (o->name);
    366 }
    367 
    368 struct options *
    369 options_owner(struct options_entry *o)
    370 {
    371 	return (o->owner);
    372 }
    373 
    374 const struct options_table_entry *
    375 options_table_entry(struct options_entry *o)
    376 {
    377 	return (o->tableentry);
    378 }
    379 
    380 static struct options_array_item *
    381 options_array_item(struct options_entry *o, u_int idx)
    382 {
    383 	struct options_array_item	a;
    384 
    385 	a.index = idx;
    386 	return (RB_FIND(options_array, &o->value.array, &a));
    387 }
    388 
    389 static struct options_array_item *
    390 options_array_new(struct options_entry *o, u_int idx)
    391 {
    392 	struct options_array_item	*a;
    393 
    394 	a = xcalloc(1, sizeof *a);
    395 	a->index = idx;
    396 	RB_INSERT(options_array, &o->value.array, a);
    397 	return (a);
    398 }
    399 
    400 static void
    401 options_array_free(struct options_entry *o, struct options_array_item *a)
    402 {
    403 	options_value_free(o, &a->value);
    404 	RB_REMOVE(options_array, &o->value.array, a);
    405 	free(a);
    406 }
    407 
    408 void
    409 options_array_clear(struct options_entry *o)
    410 {
    411 	struct options_array_item	*a, *a1;
    412 
    413 	if (!OPTIONS_IS_ARRAY(o))
    414 		return;
    415 
    416 	RB_FOREACH_SAFE(a, options_array, &o->value.array, a1)
    417 		options_array_free(o, a);
    418 }
    419 
    420 union options_value *
    421 options_array_get(struct options_entry *o, u_int idx)
    422 {
    423 	struct options_array_item	*a;
    424 
    425 	if (!OPTIONS_IS_ARRAY(o))
    426 		return (NULL);
    427 	a = options_array_item(o, idx);
    428 	if (a == NULL)
    429 		return (NULL);
    430 	return (&a->value);
    431 }
    432 
    433 int
    434 options_array_set(struct options_entry *o, u_int idx, const char *value,
    435     int append, char **cause)
    436 {
    437 	struct options_array_item	*a;
    438 	char				*new;
    439 	struct cmd_parse_result		*pr;
    440 	long long		 	 number;
    441 
    442 	if (!OPTIONS_IS_ARRAY(o)) {
    443 		if (cause != NULL)
    444 			*cause = xstrdup("not an array");
    445 		return (-1);
    446 	}
    447 
    448 	if (value == NULL) {
    449 		a = options_array_item(o, idx);
    450 		if (a != NULL)
    451 			options_array_free(o, a);
    452 		return (0);
    453 	}
    454 
    455 	if (OPTIONS_IS_COMMAND(o)) {
    456 		pr = cmd_parse_from_string(value, NULL);
    457 		switch (pr->status) {
    458 		case CMD_PARSE_ERROR:
    459 			if (cause != NULL)
    460 				*cause = pr->error;
    461 			else
    462 				free(pr->error);
    463 			return (-1);
    464 		case CMD_PARSE_SUCCESS:
    465 			break;
    466 		}
    467 
    468 		a = options_array_item(o, idx);
    469 		if (a == NULL)
    470 			a = options_array_new(o, idx);
    471 		else
    472 			options_value_free(o, &a->value);
    473 		a->value.cmdlist = pr->cmdlist;
    474 		return (0);
    475 	}
    476 
    477 	if (OPTIONS_IS_STRING(o)) {
    478 		a = options_array_item(o, idx);
    479 		if (a != NULL && append)
    480 			xasprintf(&new, "%s%s", a->value.string, value);
    481 		else
    482 			new = xstrdup(value);
    483 		if (a == NULL)
    484 			a = options_array_new(o, idx);
    485 		else
    486 			options_value_free(o, &a->value);
    487 		a->value.string = new;
    488 		return (0);
    489 	}
    490 
    491 	if (o->tableentry->type == OPTIONS_TABLE_COLOUR) {
    492 		if ((number = colour_fromstring(value)) == -1) {
    493 			xasprintf(cause, "bad colour: %s", value);
    494 			return (-1);
    495 		}
    496 		a = options_array_item(o, idx);
    497 		if (a == NULL)
    498 			a = options_array_new(o, idx);
    499 		else
    500 			options_value_free(o, &a->value);
    501 		a->value.number = number;
    502 		return (0);
    503 	}
    504 
    505 	if (cause != NULL)
    506 		*cause = xstrdup("wrong array type");
    507 	return (-1);
    508 }
    509 
    510 int
    511 options_array_assign(struct options_entry *o, const char *s, char **cause)
    512 {
    513 	const char	*separator;
    514 	char		*copy, *next, *string;
    515 	u_int		 i;
    516 
    517 	separator = o->tableentry->separator;
    518 	if (separator == NULL)
    519 		separator = " ,";
    520 	if (*separator == '\0') {
    521 		if (*s == '\0')
    522 			return (0);
    523 		for (i = 0; i < UINT_MAX; i++) {
    524 			if (options_array_item(o, i) == NULL)
    525 				break;
    526 		}
    527 		return (options_array_set(o, i, s, 0, cause));
    528 	}
    529 
    530 	if (*s == '\0')
    531 		return (0);
    532 	copy = string = xstrdup(s);
    533 	while ((next = strsep(&string, separator)) != NULL) {
    534 		if (*next == '\0')
    535 			continue;
    536 		for (i = 0; i < UINT_MAX; i++) {
    537 			if (options_array_item(o, i) == NULL)
    538 				break;
    539 		}
    540 		if (i == UINT_MAX)
    541 			break;
    542 		if (options_array_set(o, i, next, 0, cause) != 0) {
    543 			free(copy);
    544 			return (-1);
    545 		}
    546 	}
    547 	free(copy);
    548 	return (0);
    549 }
    550 
    551 struct options_array_item *
    552 options_array_first(struct options_entry *o)
    553 {
    554 	if (!OPTIONS_IS_ARRAY(o))
    555 		return (NULL);
    556 	return (RB_MIN(options_array, &o->value.array));
    557 }
    558 
    559 struct options_array_item *
    560 options_array_next(struct options_array_item *a)
    561 {
    562 	return (RB_NEXT(options_array, &o->value.array, a));
    563 }
    564 
    565 u_int
    566 options_array_item_index(struct options_array_item *a)
    567 {
    568 	return (a->index);
    569 }
    570 
    571 union options_value *
    572 options_array_item_value(struct options_array_item *a)
    573 {
    574 	return (&a->value);
    575 }
    576 
    577 int
    578 options_is_array(struct options_entry *o)
    579 {
    580 	return (OPTIONS_IS_ARRAY(o));
    581 }
    582 
    583 int
    584 options_is_string(struct options_entry *o)
    585 {
    586 	return (OPTIONS_IS_STRING(o));
    587 }
    588 
    589 char *
    590 options_to_string(struct options_entry *o, int idx, int numeric)
    591 {
    592 	struct options_array_item	*a;
    593 	char				*result = NULL;
    594 	char				*last = NULL;
    595 	char				*next;
    596 
    597 	if (OPTIONS_IS_ARRAY(o)) {
    598 		if (idx == -1) {
    599 			RB_FOREACH(a, options_array, &o->value.array) {
    600 				next = options_value_to_string(o, &a->value,
    601 				    numeric);
    602 				if (last == NULL)
    603 					result = next;
    604 				else {
    605 					xasprintf(&result, "%s %s", last, next);
    606 					free(last);
    607 					free(next);
    608 				}
    609 				last = result;
    610 			}
    611 			if (result == NULL)
    612 				return (xstrdup(""));
    613 			return (result);
    614 		}
    615 		a = options_array_item(o, idx);
    616 		if (a == NULL)
    617 			return (xstrdup(""));
    618 		return (options_value_to_string(o, &a->value, numeric));
    619 	}
    620 	return (options_value_to_string(o, &o->value, numeric));
    621 }
    622 
    623 char *
    624 options_parse(const char *name, int *idx)
    625 {
    626 	char	*copy, *cp, *end;
    627 
    628 	if (*name == '\0')
    629 		return (NULL);
    630 	copy = xstrdup(name);
    631 	if ((cp = strchr(copy, '[')) == NULL) {
    632 		*idx = -1;
    633 		return (copy);
    634 	}
    635 	end = strchr(cp + 1, ']');
    636 	if (end == NULL || end[1] != '\0' || !isdigit((u_char)end[-1])) {
    637 		free(copy);
    638 		return (NULL);
    639 	}
    640 	if (sscanf(cp, "[%d]", idx) != 1 || *idx < 0) {
    641 		free(copy);
    642 		return (NULL);
    643 	}
    644 	*cp = '\0';
    645 	return (copy);
    646 }
    647 
    648 struct options_entry *
    649 options_parse_get(struct options *oo, const char *s, int *idx, int only)
    650 {
    651 	struct options_entry	*o;
    652 	char			*name;
    653 
    654 	name = options_parse(s, idx);
    655 	if (name == NULL)
    656 		return (NULL);
    657 	if (only)
    658 		o = options_get_only(oo, name);
    659 	else
    660 		o = options_get(oo, name);
    661 	free(name);
    662 	return (o);
    663 }
    664 
    665 char *
    666 options_match(const char *s, int *idx, int *ambiguous)
    667 {
    668 	const struct options_table_entry	*oe, *found;
    669 	char					*parsed;
    670 	const char				*name;
    671 	size_t					 namelen;
    672 
    673 	parsed = options_parse(s, idx);
    674 	if (parsed == NULL)
    675 		return (NULL);
    676 	if (*parsed == '@') {
    677 		*ambiguous = 0;
    678 		return (parsed);
    679 	}
    680 
    681 	name = options_map_name(parsed);
    682 	namelen = strlen(name);
    683 
    684 	found = NULL;
    685 	for (oe = options_table; oe->name != NULL; oe++) {
    686 		if (strcmp(oe->name, name) == 0) {
    687 			found = oe;
    688 			break;
    689 		}
    690 		if (strncmp(oe->name, name, namelen) == 0) {
    691 			if (found != NULL) {
    692 				*ambiguous = 1;
    693 				free(parsed);
    694 				return (NULL);
    695 			}
    696 			found = oe;
    697 		}
    698 	}
    699 	free(parsed);
    700 	if (found == NULL) {
    701 		*ambiguous = 0;
    702 		return (NULL);
    703 	}
    704 	return (xstrdup(found->name));
    705 }
    706 
    707 struct options_entry *
    708 options_match_get(struct options *oo, const char *s, int *idx, int only,
    709     int *ambiguous)
    710 {
    711 	char			*name;
    712 	struct options_entry	*o;
    713 
    714 	name = options_match(s, idx, ambiguous);
    715 	if (name == NULL)
    716 		return (NULL);
    717 	*ambiguous = 0;
    718 	if (only)
    719 		o = options_get_only(oo, name);
    720 	else
    721 		o = options_get(oo, name);
    722 	free(name);
    723 	return (o);
    724 }
    725 
    726 const char *
    727 options_get_string(struct options *oo, const char *name)
    728 {
    729 	struct options_entry	*o;
    730 
    731 	o = options_get(oo, name);
    732 	if (o == NULL)
    733 		fatalx("missing option %s", name);
    734 	if (!OPTIONS_IS_STRING(o))
    735 		fatalx("option %s is not a string", name);
    736 	return (o->value.string);
    737 }
    738 
    739 long long
    740 options_get_number(struct options *oo, const char *name)
    741 {
    742 	struct options_entry	*o;
    743 
    744 	o = options_get(oo, name);
    745 	if (o == NULL)
    746 		fatalx("missing option %s", name);
    747 	if (!OPTIONS_IS_NUMBER(o))
    748 		fatalx("option %s is not a number", name);
    749 	return (o->value.number);
    750 }
    751 
    752 const struct cmd_list *
    753 options_get_command(struct options *oo, const char *name)
    754 {
    755 	struct options_entry	*o;
    756 
    757 	o = options_get(oo, name);
    758 	if (o == NULL)
    759 		fatalx("missing option %s", name);
    760 	if (!OPTIONS_IS_COMMAND(o))
    761 		fatalx("option %s is not a command", name);
    762 	return (o->value.cmdlist);
    763 }
    764 
    765 struct options_entry *
    766 options_set_string(struct options *oo, const char *name, int append,
    767     const char *fmt, ...)
    768 {
    769 	struct options_entry	*o;
    770 	va_list			 ap;
    771 	const char		*separator = "";
    772 	char			*s, *value;
    773 
    774 	va_start(ap, fmt);
    775 	xvasprintf(&s, fmt, ap);
    776 	va_end(ap);
    777 
    778 	o = options_get_only(oo, name);
    779 	if (o != NULL && append && OPTIONS_IS_STRING(o)) {
    780 		if (*name != '@') {
    781 			separator = o->tableentry->separator;
    782 			if (separator == NULL)
    783 				separator = "";
    784 		}
    785 		xasprintf(&value, "%s%s%s", o->value.string, separator, s);
    786 		free(s);
    787 	} else
    788 		value = s;
    789 	if (o == NULL && *name == '@')
    790 		o = options_add(oo, name);
    791 	else if (o == NULL) {
    792 		o = options_default(oo, options_parent_table_entry(oo, name));
    793 		if (o == NULL)
    794 			return (NULL);
    795 	}
    796 
    797 	if (!OPTIONS_IS_STRING(o))
    798 		fatalx("option %s is not a string", name);
    799 	free(o->value.string);
    800 	o->value.string = value;
    801 	o->cached = 0;
    802 	return (o);
    803 }
    804 
    805 struct options_entry *
    806 options_set_number(struct options *oo, const char *name, long long value)
    807 {
    808 	struct options_entry	*o;
    809 
    810 	if (*name == '@')
    811 		fatalx("user option %s must be a string", name);
    812 
    813 	o = options_get_only(oo, name);
    814 	if (o == NULL) {
    815 		o = options_default(oo, options_parent_table_entry(oo, name));
    816 		if (o == NULL)
    817 			return (NULL);
    818 	}
    819 
    820 	if (!OPTIONS_IS_NUMBER(o))
    821 		fatalx("option %s is not a number", name);
    822 	o->value.number = value;
    823 	return (o);
    824 }
    825 
    826 struct options_entry *
    827 options_set_command(struct options *oo, const char *name,
    828     struct cmd_list *value)
    829 {
    830 	struct options_entry	*o;
    831 
    832 	if (*name == '@')
    833 		fatalx("user option %s must be a string", name);
    834 
    835 	o = options_get_only(oo, name);
    836 	if (o == NULL) {
    837 		o = options_default(oo, options_parent_table_entry(oo, name));
    838 		if (o == NULL)
    839 			return (NULL);
    840 	}
    841 
    842 	if (!OPTIONS_IS_COMMAND(o))
    843 		fatalx("option %s is not a command", name);
    844 	if (o->value.cmdlist != NULL)
    845 		cmd_list_free(o->value.cmdlist);
    846 	o->value.cmdlist = value;
    847 	return (o);
    848 }
    849 
    850 int
    851 options_scope_from_name(struct args *args, int window,
    852     const char *name, struct cmd_find_state *fs, struct options **oo,
    853     char **cause)
    854 {
    855 	struct session				*s = fs->s;
    856 	struct winlink				*wl = fs->wl;
    857 	struct window_pane			*wp = fs->wp;
    858 	const char				*target = args_get(args, 't');
    859 	const struct options_table_entry	*oe;
    860 	int					 scope = OPTIONS_TABLE_NONE;
    861 
    862 	if (*name == '@')
    863 		return (options_scope_from_flags(args, window, fs, oo, cause));
    864 
    865 	for (oe = options_table; oe->name != NULL; oe++) {
    866 		if (strcmp(oe->name, name) == 0)
    867 			break;
    868 	}
    869 	if (oe->name == NULL) {
    870 		xasprintf(cause, "unknown option: %s", name);
    871 		return (OPTIONS_TABLE_NONE);
    872 	}
    873 	switch (oe->scope) {
    874 	case OPTIONS_TABLE_SERVER:
    875 		*oo = global_options;
    876 		scope = OPTIONS_TABLE_SERVER;
    877 		break;
    878 	case OPTIONS_TABLE_SESSION:
    879 		if (args_has(args, 'g')) {
    880 			*oo = global_s_options;
    881 			scope = OPTIONS_TABLE_SESSION;
    882 		} else if (s == NULL && target != NULL)
    883 			xasprintf(cause, "no such session: %s", target);
    884 		else if (s == NULL)
    885 			xasprintf(cause, "no current session");
    886 		else {
    887 			*oo = s->options;
    888 			scope = OPTIONS_TABLE_SESSION;
    889 		}
    890 		break;
    891 	case OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE:
    892 		if (args_has(args, 'p')) {
    893 			if (wp == NULL && target != NULL)
    894 				xasprintf(cause, "no such pane: %s", target);
    895 			else if (wp == NULL)
    896 				xasprintf(cause, "no current pane");
    897 			else {
    898 				*oo = wp->options;
    899 				scope = OPTIONS_TABLE_PANE;
    900 			}
    901 			break;
    902 		}
    903 		/* FALLTHROUGH */
    904 	case OPTIONS_TABLE_WINDOW:
    905 		if (args_has(args, 'g')) {
    906 			*oo = global_w_options;
    907 			scope = OPTIONS_TABLE_WINDOW;
    908 		} else if (wl == NULL && target != NULL)
    909 			xasprintf(cause, "no such window: %s", target);
    910 		else if (wl == NULL)
    911 			xasprintf(cause, "no current window");
    912 		else {
    913 			*oo = wl->window->options;
    914 			scope = OPTIONS_TABLE_WINDOW;
    915 		}
    916 		break;
    917 	}
    918 	return (scope);
    919 }
    920 
    921 int
    922 options_scope_from_flags(struct args *args, int window,
    923     struct cmd_find_state *fs, struct options **oo, char **cause)
    924 {
    925 	struct session		*s = fs->s;
    926 	struct winlink		*wl = fs->wl;
    927 	struct window_pane	*wp = fs->wp;
    928 	const char		*target = args_get(args, 't');
    929 
    930 	if (args_has(args, 's')) {
    931 		*oo = global_options;
    932 		return (OPTIONS_TABLE_SERVER);
    933 	}
    934 
    935 	if (args_has(args, 'p')) {
    936 		if (wp == NULL) {
    937 			if (target != NULL)
    938 				xasprintf(cause, "no such pane: %s", target);
    939 			else
    940 				xasprintf(cause, "no current pane");
    941 			return (OPTIONS_TABLE_NONE);
    942 		}
    943 		*oo = wp->options;
    944 		return (OPTIONS_TABLE_PANE);
    945 	} else if (window || args_has(args, 'w')) {
    946 		if (args_has(args, 'g')) {
    947 			*oo = global_w_options;
    948 			return (OPTIONS_TABLE_WINDOW);
    949 		}
    950 		if (wl == NULL) {
    951 			if (target != NULL)
    952 				xasprintf(cause, "no such window: %s", target);
    953 			else
    954 				xasprintf(cause, "no current window");
    955 			return (OPTIONS_TABLE_NONE);
    956 		}
    957 		*oo = wl->window->options;
    958 		return (OPTIONS_TABLE_WINDOW);
    959 	} else {
    960 		if (args_has(args, 'g')) {
    961 			*oo = global_s_options;
    962 			return (OPTIONS_TABLE_SESSION);
    963 		}
    964 		if (s == NULL) {
    965 			if (target != NULL)
    966 				xasprintf(cause, "no such session: %s", target);
    967 			else
    968 				xasprintf(cause, "no current session");
    969 			return (OPTIONS_TABLE_NONE);
    970 		}
    971 		*oo = s->options;
    972 		return (OPTIONS_TABLE_SESSION);
    973 	}
    974 }
    975 
    976 struct style *
    977 options_string_to_style(struct options *oo, const char *name,
    978     struct format_tree *ft)
    979 {
    980 	struct options_entry	*o;
    981 	const char		*s;
    982 	char			*expanded;
    983 
    984 	o = options_get(oo, name);
    985 	if (o == NULL || !OPTIONS_IS_STRING(o))
    986 		return (NULL);
    987 
    988 	if (o->cached)
    989 		return (&o->style);
    990 	s = o->value.string;
    991 	log_debug("%s: %s is '%s'", __func__, name, s);
    992 
    993 	style_set(&o->style, &grid_default_cell);
    994 	o->cached = (strstr(s, "#{") == NULL);
    995 
    996 	if (ft != NULL && !o->cached) {
    997 		expanded = format_expand(ft, s);
    998 		if (style_parse(&o->style, &grid_default_cell, expanded) != 0) {
    999 			free(expanded);
   1000 			return (NULL);
   1001 		}
   1002 		free(expanded);
   1003 	} else {
   1004 		if (style_parse(&o->style, &grid_default_cell, s) != 0)
   1005 			return (NULL);
   1006 	}
   1007 	return (&o->style);
   1008 }
   1009 
   1010 static int
   1011 options_from_string_check(const struct options_table_entry *oe,
   1012     const char *value, char **cause)
   1013 {
   1014 	struct style	sy;
   1015 
   1016 	if (oe == NULL)
   1017 		return (0);
   1018 	if (strcmp(oe->name, "default-shell") == 0 && !checkshell(value)) {
   1019 		xasprintf(cause, "not a suitable shell: %s", value);
   1020 		return (-1);
   1021 	}
   1022 	if (oe->pattern != NULL && fnmatch(oe->pattern, value, 0) != 0) {
   1023 		xasprintf(cause, "value is invalid: %s", value);
   1024 		return (-1);
   1025 	}
   1026 	if ((oe->flags & OPTIONS_TABLE_IS_STYLE) &&
   1027 	    strstr(value, "#{") == NULL &&
   1028 	    style_parse(&sy, &grid_default_cell, value) != 0) {
   1029 		xasprintf(cause, "invalid style: %s", value);
   1030 		return (-1);
   1031 	}
   1032 	return (0);
   1033 }
   1034 
   1035 static int
   1036 options_from_string_flag(struct options *oo, const char *name,
   1037     const char *value, char **cause)
   1038 {
   1039 	int	flag;
   1040 
   1041 	if (value == NULL || *value == '\0')
   1042 		flag = !options_get_number(oo, name);
   1043 	else if (strcmp(value, "1") == 0 ||
   1044 	    strcasecmp(value, "on") == 0 ||
   1045 	    strcasecmp(value, "yes") == 0)
   1046 		flag = 1;
   1047 	else if (strcmp(value, "0") == 0 ||
   1048 	    strcasecmp(value, "off") == 0 ||
   1049 	    strcasecmp(value, "no") == 0)
   1050 		flag = 0;
   1051 	else {
   1052 		xasprintf(cause, "bad value: %s", value);
   1053 		return (-1);
   1054 	}
   1055 	options_set_number(oo, name, flag);
   1056 	return (0);
   1057 }
   1058 
   1059 int
   1060 options_find_choice(const struct options_table_entry *oe, const char *value,
   1061     char **cause)
   1062 {
   1063 	const char	**cp;
   1064 	int		  n = 0, choice = -1;
   1065 
   1066 	for (cp = oe->choices; *cp != NULL; cp++) {
   1067 		if (strcmp(*cp, value) == 0)
   1068 			choice = n;
   1069 		n++;
   1070 	}
   1071 	if (choice == -1) {
   1072 		xasprintf(cause, "unknown value: %s", value);
   1073 		return (-1);
   1074 	}
   1075 	return (choice);
   1076 }
   1077 
   1078 static int
   1079 options_from_string_choice(const struct options_table_entry *oe,
   1080     struct options *oo, const char *name, const char *value, char **cause)
   1081 {
   1082 	int	choice = -1;
   1083 
   1084 	if (value == NULL) {
   1085 		choice = options_get_number(oo, name);
   1086 		if (choice < 2)
   1087 			choice = !choice;
   1088 	} else {
   1089 		choice = options_find_choice(oe, value, cause);
   1090 		if (choice < 0)
   1091 			return (-1);
   1092 	}
   1093 	options_set_number(oo, name, choice);
   1094 	return (0);
   1095 }
   1096 
   1097 int
   1098 options_from_string(struct options *oo, const struct options_table_entry *oe,
   1099     const char *name, const char *value, int append, char **cause)
   1100 {
   1101 	enum options_table_type	 type;
   1102 	long long		 number;
   1103 	const char		*errstr, *new;
   1104 	char			*old;
   1105 	key_code		 key;
   1106 	struct cmd_parse_result	*pr;
   1107 
   1108 	if (oe != NULL) {
   1109 		if (value == NULL &&
   1110 		    oe->type != OPTIONS_TABLE_FLAG &&
   1111 		    oe->type != OPTIONS_TABLE_CHOICE) {
   1112 			xasprintf(cause, "empty value");
   1113 			return (-1);
   1114 		}
   1115 		type = oe->type;
   1116 	} else {
   1117 		if (*name != '@') {
   1118 			xasprintf(cause, "bad option name");
   1119 			return (-1);
   1120 		}
   1121 		type = OPTIONS_TABLE_STRING;
   1122 	}
   1123 
   1124 	switch (type) {
   1125 	case OPTIONS_TABLE_STRING:
   1126 		old = xstrdup(options_get_string(oo, name));
   1127 		options_set_string(oo, name, append, "%s", value);
   1128 
   1129 		new = options_get_string(oo, name);
   1130 		if (options_from_string_check(oe, new, cause) != 0) {
   1131 			options_set_string(oo, name, 0, "%s", old);
   1132 			free(old);
   1133 			return (-1);
   1134 		}
   1135 		free(old);
   1136 		return (0);
   1137 	case OPTIONS_TABLE_NUMBER:
   1138 		number = strtonum(value, oe->minimum, oe->maximum, &errstr);
   1139 		if (errstr != NULL) {
   1140 			xasprintf(cause, "value is %s: %s", errstr, value);
   1141 			return (-1);
   1142 		}
   1143 		options_set_number(oo, name, number);
   1144 		return (0);
   1145 	case OPTIONS_TABLE_KEY:
   1146 		key = key_string_lookup_string(value);
   1147 		if (key == KEYC_UNKNOWN) {
   1148 			xasprintf(cause, "bad key: %s", value);
   1149 			return (-1);
   1150 		}
   1151 		options_set_number(oo, name, key);
   1152 		return (0);
   1153 	case OPTIONS_TABLE_COLOUR:
   1154 		if ((number = colour_fromstring(value)) == -1) {
   1155 			xasprintf(cause, "bad colour: %s", value);
   1156 			return (-1);
   1157 		}
   1158 		options_set_number(oo, name, number);
   1159 		return (0);
   1160 	case OPTIONS_TABLE_FLAG:
   1161 		return (options_from_string_flag(oo, name, value, cause));
   1162 	case OPTIONS_TABLE_CHOICE:
   1163 		return (options_from_string_choice(oe, oo, name, value, cause));
   1164 	case OPTIONS_TABLE_COMMAND:
   1165 		pr = cmd_parse_from_string(value, NULL);
   1166 		switch (pr->status) {
   1167 		case CMD_PARSE_ERROR:
   1168 			*cause = pr->error;
   1169 			return (-1);
   1170 		case CMD_PARSE_SUCCESS:
   1171 			options_set_command(oo, name, pr->cmdlist);
   1172 			return (0);
   1173 		}
   1174 		break;
   1175 	}
   1176 	return (-1);
   1177 }
   1178 
   1179 void
   1180 options_push_changes(const char *name)
   1181 {
   1182 	struct client		*loop;
   1183 	struct session		*s;
   1184 	struct window		*w;
   1185 	struct window_pane	*wp;
   1186 
   1187 	log_debug("%s: %s", __func__, name);
   1188 
   1189 	if (strcmp(name, "automatic-rename") == 0) {
   1190 		RB_FOREACH(w, windows, &windows) {
   1191 			if (w->active == NULL)
   1192 				continue;
   1193 			if (options_get_number(w->options, name))
   1194 				w->active->flags |= PANE_CHANGED;
   1195 		}
   1196 	}
   1197 	if (strcmp(name, "cursor-colour") == 0) {
   1198 		RB_FOREACH(wp, window_pane_tree, &all_window_panes)
   1199 			window_pane_default_cursor(wp);
   1200 	}
   1201 	if (strcmp(name, "cursor-style") == 0) {
   1202 		RB_FOREACH(wp, window_pane_tree, &all_window_panes)
   1203 			window_pane_default_cursor(wp);
   1204 	}
   1205 	if (strcmp(name, "fill-character") == 0) {
   1206 		RB_FOREACH(w, windows, &windows)
   1207 			window_set_fill_character(w);
   1208 	}
   1209 	if (strcmp(name, "key-table") == 0) {
   1210 		TAILQ_FOREACH(loop, &clients, entry)
   1211 			server_client_set_key_table(loop, NULL);
   1212 	}
   1213 	if (strcmp(name, "user-keys") == 0) {
   1214 		TAILQ_FOREACH(loop, &clients, entry) {
   1215 			if (loop->tty.flags & TTY_OPENED)
   1216 				tty_keys_build(&loop->tty);
   1217 		}
   1218 	}
   1219 	if (strcmp(name, "status") == 0 ||
   1220 	    strcmp(name, "status-interval") == 0)
   1221 		status_timer_start_all();
   1222 	if (strcmp(name, "monitor-silence") == 0)
   1223 		alerts_reset_all();
   1224 	if (strcmp(name, "window-style") == 0 ||
   1225 	    strcmp(name, "window-active-style") == 0) {
   1226 		RB_FOREACH(wp, window_pane_tree, &all_window_panes)
   1227 			wp->flags |= (PANE_STYLECHANGED|PANE_THEMECHANGED);
   1228 	}
   1229 	if (strcmp(name, "pane-colours") == 0) {
   1230 		RB_FOREACH(wp, window_pane_tree, &all_window_panes)
   1231 			colour_palette_from_option(&wp->palette, wp->options);
   1232 	}
   1233 	if (strcmp(name, "pane-border-status") == 0 ||
   1234 	    strcmp(name, "pane-scrollbars") == 0 ||
   1235 	    strcmp(name, "pane-scrollbars-position") == 0) {
   1236 		RB_FOREACH(w, windows, &windows)
   1237 			layout_fix_panes(w, NULL);
   1238 	}
   1239 	if (strcmp(name, "pane-scrollbars-style") == 0) {
   1240 		RB_FOREACH(wp, window_pane_tree, &all_window_panes) {
   1241 			style_set_scrollbar_style_from_option(
   1242 			    &wp->scrollbar_style, wp->options);
   1243 		}
   1244 		RB_FOREACH(w, windows, &windows)
   1245 			layout_fix_panes(w, NULL);
   1246 	}
   1247 	if (strcmp(name, "codepoint-widths") == 0)
   1248 		utf8_update_width_cache();
   1249 	if (strcmp(name, "input-buffer-size") == 0)
   1250 		input_set_buffer_size(options_get_number(global_options, name));
   1251 	RB_FOREACH(s, sessions, &sessions)
   1252 		status_update_cache(s);
   1253 
   1254 	recalculate_sizes();
   1255 	TAILQ_FOREACH(loop, &clients, entry) {
   1256 		if (loop->session != NULL)
   1257 			server_redraw_client(loop);
   1258 	}
   1259 }
   1260 
   1261 int
   1262 options_remove_or_default(struct options_entry *o, int idx, char **cause)
   1263 {
   1264 	struct options	*oo = o->owner;
   1265 
   1266 	if (idx == -1) {
   1267 		if (o->tableentry != NULL &&
   1268 		    (oo == global_options ||
   1269 		    oo == global_s_options ||
   1270 		    oo == global_w_options))
   1271 			options_default(oo, o->tableentry);
   1272 		else
   1273 			options_remove(o);
   1274 	} else if (options_array_set(o, idx, NULL, 0, cause) != 0)
   1275 		return (-1);
   1276 	return (0);
   1277 }
   1278