4 * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
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.
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.
19 #include <sys/types.h>
30 * Option handling; each option has a name, type and value and is stored in
34 struct options_array_item
{
36 union options_value value
;
37 RB_ENTRY(options_array_item
) entry
;
40 options_array_cmp(struct options_array_item
*a1
, struct options_array_item
*a2
)
42 if (a1
->index
< a2
->index
)
44 if (a1
->index
> a2
->index
)
48 RB_GENERATE_STATIC(options_array
, options_array_item
, entry
, options_array_cmp
);
50 struct options_entry
{
51 struct options
*owner
;
54 const struct options_table_entry
*tableentry
;
55 union options_value value
;
60 RB_ENTRY(options_entry
) entry
;
64 RB_HEAD(options_tree
, options_entry
) tree
;
65 struct options
*parent
;
68 static struct options_entry
*options_add(struct options
*, const char *);
69 static void options_remove(struct options_entry
*);
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)
85 #define OPTIONS_IS_ARRAY(o) \
86 ((o)->tableentry != NULL && \
87 ((o)->tableentry->flags & OPTIONS_TABLE_IS_ARRAY))
89 static int options_cmp(struct options_entry
*, struct options_entry
*);
90 RB_GENERATE_STATIC(options_tree
, options_entry
, entry
, options_cmp
);
93 options_cmp(struct options_entry
*lhs
, struct options_entry
*rhs
)
95 return (strcmp(lhs
->name
, rhs
->name
));
99 options_map_name(const char *name
)
101 const struct options_name_map
*map
;
103 for (map
= options_other_names
; map
->from
!= NULL
; map
++) {
104 if (strcmp(map
->from
, name
) == 0)
110 static const struct options_table_entry
*
111 options_parent_table_entry(struct options
*oo
, const char *s
)
113 struct options_entry
*o
;
115 if (oo
->parent
== NULL
)
116 fatalx("no parent options for %s", s
);
117 o
= options_get(oo
->parent
, s
);
119 fatalx("%s not in parent options", s
);
120 return (o
->tableentry
);
124 options_value_free(struct options_entry
*o
, union options_value
*ov
)
126 if (OPTIONS_IS_STRING(o
))
128 if (OPTIONS_IS_COMMAND(o
) && ov
->cmdlist
!= NULL
)
129 cmd_list_free(ov
->cmdlist
);
133 options_value_to_string(struct options_entry
*o
, union options_value
*ov
,
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
);
145 case OPTIONS_TABLE_KEY
:
146 s
= xstrdup(key_string_lookup_key(ov
->number
, 0));
148 case OPTIONS_TABLE_COLOUR
:
149 s
= xstrdup(colour_tostring(ov
->number
));
151 case OPTIONS_TABLE_FLAG
:
153 xasprintf(&s
, "%lld", ov
->number
);
155 s
= xstrdup(ov
->number
? "on" : "off");
157 case OPTIONS_TABLE_CHOICE
:
158 s
= xstrdup(o
->tableentry
->choices
[ov
->number
]);
161 fatalx("not a number option type");
165 if (OPTIONS_IS_STRING(o
))
166 return (xstrdup(ov
->string
));
167 return (xstrdup(""));
171 options_create(struct options
*parent
)
175 oo
= xcalloc(1, sizeof *oo
);
182 options_free(struct options
*oo
)
184 struct options_entry
*o
, *tmp
;
186 RB_FOREACH_SAFE(o
, options_tree
, &oo
->tree
, tmp
)
192 options_get_parent(struct options
*oo
)
198 options_set_parent(struct options
*oo
, struct options
*parent
)
203 struct options_entry
*
204 options_first(struct options
*oo
)
206 return (RB_MIN(options_tree
, &oo
->tree
));
209 struct options_entry
*
210 options_next(struct options_entry
*o
)
212 return (RB_NEXT(options_tree
, &oo
->tree
, o
));
215 struct options_entry
*
216 options_get_only(struct options
*oo
, const char *name
)
218 struct options_entry o
= { .name
= name
}, *found
;
220 found
= RB_FIND(options_tree
, &oo
->tree
, &o
);
222 o
.name
= options_map_name(name
);
223 return (RB_FIND(options_tree
, &oo
->tree
, &o
));
228 struct options_entry
*
229 options_get(struct options
*oo
, const char *name
)
231 struct options_entry
*o
;
233 o
= options_get_only(oo
, name
);
238 o
= options_get_only(oo
, name
);
243 struct options_entry
*
244 options_empty(struct options
*oo
, const struct options_table_entry
*oe
)
246 struct options_entry
*o
;
248 o
= options_add(oo
, oe
->name
);
251 if (oe
->flags
& OPTIONS_TABLE_IS_ARRAY
)
252 RB_INIT(&o
->value
.array
);
257 struct options_entry
*
258 options_default(struct options
*oo
, const struct options_table_entry
*oe
)
260 struct options_entry
*o
;
261 union options_value
*ov
;
264 o
= options_empty(oo
, oe
);
267 if (oe
->flags
& OPTIONS_TABLE_IS_ARRAY
) {
268 if (oe
->default_arr
== NULL
) {
269 options_array_assign(o
, oe
->default_str
, NULL
);
272 for (i
= 0; oe
->default_arr
[i
] != NULL
; i
++)
273 options_array_set(o
, i
, oe
->default_arr
[i
], 0, NULL
);
278 case OPTIONS_TABLE_STRING
:
279 ov
->string
= xstrdup(oe
->default_str
);
282 ov
->number
= oe
->default_num
;
289 options_default_to_string(const struct options_table_entry
*oe
)
294 case OPTIONS_TABLE_STRING
:
295 case OPTIONS_TABLE_COMMAND
:
296 s
= xstrdup(oe
->default_str
);
298 case OPTIONS_TABLE_NUMBER
:
299 xasprintf(&s
, "%lld", oe
->default_num
);
301 case OPTIONS_TABLE_KEY
:
302 s
= xstrdup(key_string_lookup_key(oe
->default_num
, 0));
304 case OPTIONS_TABLE_COLOUR
:
305 s
= xstrdup(colour_tostring(oe
->default_num
));
307 case OPTIONS_TABLE_FLAG
:
308 s
= xstrdup(oe
->default_num
? "on" : "off");
310 case OPTIONS_TABLE_CHOICE
:
311 s
= xstrdup(oe
->choices
[oe
->default_num
]);
314 fatalx("unknown option type");
319 static struct options_entry
*
320 options_add(struct options
*oo
, const char *name
)
322 struct options_entry
*o
;
324 o
= options_get_only(oo
, name
);
328 o
= xcalloc(1, sizeof *o
);
330 o
->name
= xstrdup(name
);
332 RB_INSERT(options_tree
, &oo
->tree
, o
);
337 options_remove(struct options_entry
*o
)
339 struct options
*oo
= o
->owner
;
341 if (OPTIONS_IS_ARRAY(o
))
342 options_array_clear(o
);
344 options_value_free(o
, &o
->value
);
345 RB_REMOVE(options_tree
, &oo
->tree
, o
);
346 free((void *)o
->name
);
351 options_name(struct options_entry
*o
)
357 options_owner(struct options_entry
*o
)
362 const struct options_table_entry
*
363 options_table_entry(struct options_entry
*o
)
365 return (o
->tableentry
);
368 static struct options_array_item
*
369 options_array_item(struct options_entry
*o
, u_int idx
)
371 struct options_array_item a
;
374 return (RB_FIND(options_array
, &o
->value
.array
, &a
));
377 static struct options_array_item
*
378 options_array_new(struct options_entry
*o
, u_int idx
)
380 struct options_array_item
*a
;
382 a
= xcalloc(1, sizeof *a
);
384 RB_INSERT(options_array
, &o
->value
.array
, a
);
389 options_array_free(struct options_entry
*o
, struct options_array_item
*a
)
391 options_value_free(o
, &a
->value
);
392 RB_REMOVE(options_array
, &o
->value
.array
, a
);
397 options_array_clear(struct options_entry
*o
)
399 struct options_array_item
*a
, *a1
;
401 if (!OPTIONS_IS_ARRAY(o
))
404 RB_FOREACH_SAFE(a
, options_array
, &o
->value
.array
, a1
)
405 options_array_free(o
, a
);
408 union options_value
*
409 options_array_get(struct options_entry
*o
, u_int idx
)
411 struct options_array_item
*a
;
413 if (!OPTIONS_IS_ARRAY(o
))
415 a
= options_array_item(o
, idx
);
422 options_array_set(struct options_entry
*o
, u_int idx
, const char *value
,
423 int append
, char **cause
)
425 struct options_array_item
*a
;
427 struct cmd_parse_result
*pr
;
430 if (!OPTIONS_IS_ARRAY(o
)) {
432 *cause
= xstrdup("not an array");
437 a
= options_array_item(o
, idx
);
439 options_array_free(o
, a
);
443 if (OPTIONS_IS_COMMAND(o
)) {
444 pr
= cmd_parse_from_string(value
, NULL
);
445 switch (pr
->status
) {
446 case CMD_PARSE_ERROR
:
452 case CMD_PARSE_SUCCESS
:
456 a
= options_array_item(o
, idx
);
458 a
= options_array_new(o
, idx
);
460 options_value_free(o
, &a
->value
);
461 a
->value
.cmdlist
= pr
->cmdlist
;
465 if (OPTIONS_IS_STRING(o
)) {
466 a
= options_array_item(o
, idx
);
467 if (a
!= NULL
&& append
)
468 xasprintf(&new, "%s%s", a
->value
.string
, value
);
470 new = xstrdup(value
);
472 a
= options_array_new(o
, idx
);
474 options_value_free(o
, &a
->value
);
475 a
->value
.string
= new;
479 if (o
->tableentry
->type
== OPTIONS_TABLE_COLOUR
) {
480 if ((number
= colour_fromstring(value
)) == -1) {
481 xasprintf(cause
, "bad colour: %s", value
);
484 a
= options_array_item(o
, idx
);
486 a
= options_array_new(o
, idx
);
488 options_value_free(o
, &a
->value
);
489 a
->value
.number
= number
;
494 *cause
= xstrdup("wrong array type");
499 options_array_assign(struct options_entry
*o
, const char *s
, char **cause
)
501 const char *separator
;
502 char *copy
, *next
, *string
;
505 separator
= o
->tableentry
->separator
;
506 if (separator
== NULL
)
508 if (*separator
== '\0') {
511 for (i
= 0; i
< UINT_MAX
; i
++) {
512 if (options_array_item(o
, i
) == NULL
)
515 return (options_array_set(o
, i
, s
, 0, cause
));
520 copy
= string
= xstrdup(s
);
521 while ((next
= strsep(&string
, separator
)) != NULL
) {
524 for (i
= 0; i
< UINT_MAX
; i
++) {
525 if (options_array_item(o
, i
) == NULL
)
530 if (options_array_set(o
, i
, next
, 0, cause
) != 0) {
539 struct options_array_item
*
540 options_array_first(struct options_entry
*o
)
542 if (!OPTIONS_IS_ARRAY(o
))
544 return (RB_MIN(options_array
, &o
->value
.array
));
547 struct options_array_item
*
548 options_array_next(struct options_array_item
*a
)
550 return (RB_NEXT(options_array
, &o
->value
.array
, a
));
554 options_array_item_index(struct options_array_item
*a
)
559 union options_value
*
560 options_array_item_value(struct options_array_item
*a
)
566 options_is_array(struct options_entry
*o
)
568 return (OPTIONS_IS_ARRAY(o
));
572 options_is_string(struct options_entry
*o
)
574 return (OPTIONS_IS_STRING(o
));
578 options_to_string(struct options_entry
*o
, int idx
, int numeric
)
580 struct options_array_item
*a
;
585 if (OPTIONS_IS_ARRAY(o
)) {
587 RB_FOREACH(a
, options_array
, &o
->value
.array
) {
588 next
= options_value_to_string(o
, &a
->value
,
593 xasprintf(&result
, "%s %s", last
, next
);
600 return (xstrdup(""));
603 a
= options_array_item(o
, idx
);
605 return (xstrdup(""));
606 return (options_value_to_string(o
, &a
->value
, numeric
));
608 return (options_value_to_string(o
, &o
->value
, numeric
));
612 options_parse(const char *name
, int *idx
)
614 char *copy
, *cp
, *end
;
618 copy
= xstrdup(name
);
619 if ((cp
= strchr(copy
, '[')) == NULL
) {
623 end
= strchr(cp
+ 1, ']');
624 if (end
== NULL
|| end
[1] != '\0' || !isdigit((u_char
)end
[-1])) {
628 if (sscanf(cp
, "[%d]", idx
) != 1 || *idx
< 0) {
636 struct options_entry
*
637 options_parse_get(struct options
*oo
, const char *s
, int *idx
, int only
)
639 struct options_entry
*o
;
642 name
= options_parse(s
, idx
);
646 o
= options_get_only(oo
, name
);
648 o
= options_get(oo
, name
);
654 options_match(const char *s
, int *idx
, int *ambiguous
)
656 const struct options_table_entry
*oe
, *found
;
661 parsed
= options_parse(s
, idx
);
664 if (*parsed
== '@') {
669 name
= options_map_name(parsed
);
670 namelen
= strlen(name
);
673 for (oe
= options_table
; oe
->name
!= NULL
; oe
++) {
674 if (strcmp(oe
->name
, name
) == 0) {
678 if (strncmp(oe
->name
, name
, namelen
) == 0) {
692 return (xstrdup(found
->name
));
695 struct options_entry
*
696 options_match_get(struct options
*oo
, const char *s
, int *idx
, int only
,
700 struct options_entry
*o
;
702 name
= options_match(s
, idx
, ambiguous
);
707 o
= options_get_only(oo
, name
);
709 o
= options_get(oo
, name
);
715 options_get_string(struct options
*oo
, const char *name
)
717 struct options_entry
*o
;
719 o
= options_get(oo
, name
);
721 fatalx("missing option %s", name
);
722 if (!OPTIONS_IS_STRING(o
))
723 fatalx("option %s is not a string", name
);
724 return (o
->value
.string
);
728 options_get_number(struct options
*oo
, const char *name
)
730 struct options_entry
*o
;
732 o
= options_get(oo
, name
);
734 fatalx("missing option %s", name
);
735 if (!OPTIONS_IS_NUMBER(o
))
736 fatalx("option %s is not a number", name
);
737 return (o
->value
.number
);
740 struct options_entry
*
741 options_set_string(struct options
*oo
, const char *name
, int append
,
742 const char *fmt
, ...)
744 struct options_entry
*o
;
746 const char *separator
= "";
750 xvasprintf(&s
, fmt
, ap
);
753 o
= options_get_only(oo
, name
);
754 if (o
!= NULL
&& append
&& OPTIONS_IS_STRING(o
)) {
756 separator
= o
->tableentry
->separator
;
757 if (separator
== NULL
)
760 xasprintf(&value
, "%s%s%s", o
->value
.string
, separator
, s
);
764 if (o
== NULL
&& *name
== '@')
765 o
= options_add(oo
, name
);
766 else if (o
== NULL
) {
767 o
= options_default(oo
, options_parent_table_entry(oo
, name
));
772 if (!OPTIONS_IS_STRING(o
))
773 fatalx("option %s is not a string", name
);
774 free(o
->value
.string
);
775 o
->value
.string
= value
;
780 struct options_entry
*
781 options_set_number(struct options
*oo
, const char *name
, long long value
)
783 struct options_entry
*o
;
786 fatalx("user option %s must be a string", name
);
788 o
= options_get_only(oo
, name
);
790 o
= options_default(oo
, options_parent_table_entry(oo
, name
));
795 if (!OPTIONS_IS_NUMBER(o
))
796 fatalx("option %s is not a number", name
);
797 o
->value
.number
= value
;
802 options_scope_from_name(struct args
*args
, int window
,
803 const char *name
, struct cmd_find_state
*fs
, struct options
**oo
,
806 struct session
*s
= fs
->s
;
807 struct winlink
*wl
= fs
->wl
;
808 struct window_pane
*wp
= fs
->wp
;
809 const char *target
= args_get(args
, 't');
810 const struct options_table_entry
*oe
;
811 int scope
= OPTIONS_TABLE_NONE
;
814 return (options_scope_from_flags(args
, window
, fs
, oo
, cause
));
816 for (oe
= options_table
; oe
->name
!= NULL
; oe
++) {
817 if (strcmp(oe
->name
, name
) == 0)
820 if (oe
->name
== NULL
) {
821 xasprintf(cause
, "unknown option: %s", name
);
822 return (OPTIONS_TABLE_NONE
);
825 case OPTIONS_TABLE_SERVER
:
826 *oo
= global_options
;
827 scope
= OPTIONS_TABLE_SERVER
;
829 case OPTIONS_TABLE_SESSION
:
830 if (args_has(args
, 'g')) {
831 *oo
= global_s_options
;
832 scope
= OPTIONS_TABLE_SESSION
;
833 } else if (s
== NULL
&& target
!= NULL
)
834 xasprintf(cause
, "no such session: %s", target
);
836 xasprintf(cause
, "no current session");
839 scope
= OPTIONS_TABLE_SESSION
;
842 case OPTIONS_TABLE_WINDOW
|OPTIONS_TABLE_PANE
:
843 if (args_has(args
, 'p')) {
844 if (wp
== NULL
&& target
!= NULL
)
845 xasprintf(cause
, "no such pane: %s", target
);
847 xasprintf(cause
, "no current pane");
850 scope
= OPTIONS_TABLE_PANE
;
855 case OPTIONS_TABLE_WINDOW
:
856 if (args_has(args
, 'g')) {
857 *oo
= global_w_options
;
858 scope
= OPTIONS_TABLE_WINDOW
;
859 } else if (wl
== NULL
&& target
!= NULL
)
860 xasprintf(cause
, "no such window: %s", target
);
862 xasprintf(cause
, "no current window");
864 *oo
= wl
->window
->options
;
865 scope
= OPTIONS_TABLE_WINDOW
;
873 options_scope_from_flags(struct args
*args
, int window
,
874 struct cmd_find_state
*fs
, struct options
**oo
, char **cause
)
876 struct session
*s
= fs
->s
;
877 struct winlink
*wl
= fs
->wl
;
878 struct window_pane
*wp
= fs
->wp
;
879 const char *target
= args_get(args
, 't');
881 if (args_has(args
, 's')) {
882 *oo
= global_options
;
883 return (OPTIONS_TABLE_SERVER
);
886 if (args_has(args
, 'p')) {
889 xasprintf(cause
, "no such pane: %s", target
);
891 xasprintf(cause
, "no current pane");
892 return (OPTIONS_TABLE_NONE
);
895 return (OPTIONS_TABLE_PANE
);
896 } else if (window
|| args_has(args
, 'w')) {
897 if (args_has(args
, 'g')) {
898 *oo
= global_w_options
;
899 return (OPTIONS_TABLE_WINDOW
);
903 xasprintf(cause
, "no such window: %s", target
);
905 xasprintf(cause
, "no current window");
906 return (OPTIONS_TABLE_NONE
);
908 *oo
= wl
->window
->options
;
909 return (OPTIONS_TABLE_WINDOW
);
911 if (args_has(args
, 'g')) {
912 *oo
= global_s_options
;
913 return (OPTIONS_TABLE_SESSION
);
917 xasprintf(cause
, "no such session: %s", target
);
919 xasprintf(cause
, "no current session");
920 return (OPTIONS_TABLE_NONE
);
923 return (OPTIONS_TABLE_SESSION
);
928 options_string_to_style(struct options
*oo
, const char *name
,
929 struct format_tree
*ft
)
931 struct options_entry
*o
;
935 o
= options_get(oo
, name
);
936 if (o
== NULL
|| !OPTIONS_IS_STRING(o
))
942 log_debug("%s: %s is '%s'", __func__
, name
, s
);
944 style_set(&o
->style
, &grid_default_cell
);
945 o
->cached
= (strstr(s
, "#{") == NULL
);
947 if (ft
!= NULL
&& !o
->cached
) {
948 expanded
= format_expand(ft
, s
);
949 if (style_parse(&o
->style
, &grid_default_cell
, expanded
) != 0) {
955 if (style_parse(&o
->style
, &grid_default_cell
, s
) != 0)
962 options_from_string_check(const struct options_table_entry
*oe
,
963 const char *value
, char **cause
)
969 if (strcmp(oe
->name
, "default-shell") == 0 && !checkshell(value
)) {
970 xasprintf(cause
, "not a suitable shell: %s", value
);
973 if (oe
->pattern
!= NULL
&& fnmatch(oe
->pattern
, value
, 0) != 0) {
974 xasprintf(cause
, "value is invalid: %s", value
);
977 if ((oe
->flags
& OPTIONS_TABLE_IS_STYLE
) &&
978 strstr(value
, "#{") == NULL
&&
979 style_parse(&sy
, &grid_default_cell
, value
) != 0) {
980 xasprintf(cause
, "invalid style: %s", value
);
987 options_from_string_flag(struct options
*oo
, const char *name
,
988 const char *value
, char **cause
)
992 if (value
== NULL
|| *value
== '\0')
993 flag
= !options_get_number(oo
, name
);
994 else if (strcmp(value
, "1") == 0 ||
995 strcasecmp(value
, "on") == 0 ||
996 strcasecmp(value
, "yes") == 0)
998 else if (strcmp(value
, "0") == 0 ||
999 strcasecmp(value
, "off") == 0 ||
1000 strcasecmp(value
, "no") == 0)
1003 xasprintf(cause
, "bad value: %s", value
);
1006 options_set_number(oo
, name
, flag
);
1011 options_find_choice(const struct options_table_entry
*oe
, const char *value
,
1015 int n
= 0, choice
= -1;
1017 for (cp
= oe
->choices
; *cp
!= NULL
; cp
++) {
1018 if (strcmp(*cp
, value
) == 0)
1023 xasprintf(cause
, "unknown value: %s", value
);
1030 options_from_string_choice(const struct options_table_entry
*oe
,
1031 struct options
*oo
, const char *name
, const char *value
, char **cause
)
1035 if (value
== NULL
) {
1036 choice
= options_get_number(oo
, name
);
1040 choice
= options_find_choice(oe
, value
, cause
);
1044 options_set_number(oo
, name
, choice
);
1049 options_from_string(struct options
*oo
, const struct options_table_entry
*oe
,
1050 const char *name
, const char *value
, int append
, char **cause
)
1052 enum options_table_type type
;
1054 const char *errstr
, *new;
1059 if (value
== NULL
&&
1060 oe
->type
!= OPTIONS_TABLE_FLAG
&&
1061 oe
->type
!= OPTIONS_TABLE_CHOICE
) {
1062 xasprintf(cause
, "empty value");
1068 xasprintf(cause
, "bad option name");
1071 type
= OPTIONS_TABLE_STRING
;
1075 case OPTIONS_TABLE_STRING
:
1076 old
= xstrdup(options_get_string(oo
, name
));
1077 options_set_string(oo
, name
, append
, "%s", value
);
1079 new = options_get_string(oo
, name
);
1080 if (options_from_string_check(oe
, new, cause
) != 0) {
1081 options_set_string(oo
, name
, 0, "%s", old
);
1087 case OPTIONS_TABLE_NUMBER
:
1088 number
= strtonum(value
, oe
->minimum
, oe
->maximum
, &errstr
);
1089 if (errstr
!= NULL
) {
1090 xasprintf(cause
, "value is %s: %s", errstr
, value
);
1093 options_set_number(oo
, name
, number
);
1095 case OPTIONS_TABLE_KEY
:
1096 key
= key_string_lookup_string(value
);
1097 if (key
== KEYC_UNKNOWN
) {
1098 xasprintf(cause
, "bad key: %s", value
);
1101 options_set_number(oo
, name
, key
);
1103 case OPTIONS_TABLE_COLOUR
:
1104 if ((number
= colour_fromstring(value
)) == -1) {
1105 xasprintf(cause
, "bad colour: %s", value
);
1108 options_set_number(oo
, name
, number
);
1110 case OPTIONS_TABLE_FLAG
:
1111 return (options_from_string_flag(oo
, name
, value
, cause
));
1112 case OPTIONS_TABLE_CHOICE
:
1113 return (options_from_string_choice(oe
, oo
, name
, value
, cause
));
1114 case OPTIONS_TABLE_COMMAND
:
1121 options_push_changes(const char *name
)
1123 struct client
*loop
;
1126 struct window_pane
*wp
;
1128 log_debug("%s: %s", __func__
, name
);
1130 if (strcmp(name
, "automatic-rename") == 0) {
1131 RB_FOREACH(w
, windows
, &windows
) {
1132 if (w
->active
== NULL
)
1134 if (options_get_number(w
->options
, name
))
1135 w
->active
->flags
|= PANE_CHANGED
;
1138 if (strcmp(name
, "cursor-colour") == 0) {
1139 RB_FOREACH(wp
, window_pane_tree
, &all_window_panes
)
1140 window_pane_default_cursor(wp
);
1142 if (strcmp(name
, "cursor-style") == 0) {
1143 RB_FOREACH(wp
, window_pane_tree
, &all_window_panes
)
1144 window_pane_default_cursor(wp
);
1146 if (strcmp(name
, "fill-character") == 0) {
1147 RB_FOREACH(w
, windows
, &windows
)
1148 window_set_fill_character(w
);
1150 if (strcmp(name
, "key-table") == 0) {
1151 TAILQ_FOREACH(loop
, &clients
, entry
)
1152 server_client_set_key_table(loop
, NULL
);
1154 if (strcmp(name
, "user-keys") == 0) {
1155 TAILQ_FOREACH(loop
, &clients
, entry
) {
1156 if (loop
->tty
.flags
& TTY_OPENED
)
1157 tty_keys_build(&loop
->tty
);
1160 if (strcmp(name
, "status") == 0 ||
1161 strcmp(name
, "status-interval") == 0)
1162 status_timer_start_all();
1163 if (strcmp(name
, "monitor-silence") == 0)
1165 if (strcmp(name
, "window-style") == 0 ||
1166 strcmp(name
, "window-active-style") == 0) {
1167 RB_FOREACH(wp
, window_pane_tree
, &all_window_panes
)
1168 wp
->flags
|= PANE_STYLECHANGED
;
1170 if (strcmp(name
, "pane-colours") == 0) {
1171 RB_FOREACH(wp
, window_pane_tree
, &all_window_panes
)
1172 colour_palette_from_option(&wp
->palette
, wp
->options
);
1174 if (strcmp(name
, "pane-border-status") == 0) {
1175 RB_FOREACH(w
, windows
, &windows
)
1176 layout_fix_panes(w
, NULL
);
1178 RB_FOREACH(s
, sessions
, &sessions
)
1179 status_update_cache(s
);
1181 recalculate_sizes();
1182 TAILQ_FOREACH(loop
, &clients
, entry
) {
1183 if (loop
->session
!= NULL
)
1184 server_redraw_client(loop
);
1189 options_remove_or_default(struct options_entry
*o
, int idx
, char **cause
)
1191 struct options
*oo
= o
->owner
;
1194 if (o
->tableentry
!= NULL
&&
1195 (oo
== global_options
||
1196 oo
== global_s_options
||
1197 oo
== global_w_options
))
1198 options_default(oo
, o
->tableentry
);
1201 } else if (options_array_set(o
, idx
, NULL
, 0, cause
) != 0)