Annotation of src/usr.bin/tmux/options.c, Revision 1.42
1.42 ! nicm 1: /* $OpenBSD: options.c,v 1.41 2019/04/23 20:36:55 nicm Exp $ */
1.1 nicm 2:
3: /*
1.18 nicm 4: * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
1.1 nicm 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:
1.26 nicm 21: #include <ctype.h>
1.1 nicm 22: #include <stdarg.h>
1.8 nicm 23: #include <stdlib.h>
1.1 nicm 24: #include <string.h>
25:
26: #include "tmux.h"
27:
28: /*
29: * Option handling; each option has a name, type and value and is stored in
1.9 nicm 30: * a red-black tree.
1.1 nicm 31: */
32:
1.39 nicm 33: struct options_array_item {
34: u_int index;
1.41 nicm 35: union options_value value;
1.39 nicm 36: RB_ENTRY(options_array_item) entry;
37: };
38: static int
39: options_array_cmp(struct options_array_item *a1, struct options_array_item *a2)
40: {
41: if (a1->index < a2->index)
42: return (-1);
43: if (a1->index > a2->index)
44: return (1);
45: return (0);
46: }
47: RB_GENERATE_STATIC(options_array, options_array_item, entry, options_array_cmp);
48:
1.27 nicm 49: struct options_entry {
1.41 nicm 50: struct options *owner;
1.26 nicm 51:
1.41 nicm 52: const char *name;
53: const struct options_table_entry *tableentry;
54: union options_value value;
1.26 nicm 55:
1.41 nicm 56: RB_ENTRY(options_entry) entry;
1.26 nicm 57: };
58:
1.13 nicm 59: struct options {
1.27 nicm 60: RB_HEAD(options_tree, options_entry) tree;
1.26 nicm 61: struct options *parent;
1.13 nicm 62: };
63:
1.27 nicm 64: static struct options_entry *options_add(struct options *, const char *);
1.26 nicm 65:
66: #define OPTIONS_IS_STRING(o) \
67: ((o)->tableentry == NULL || \
68: (o)->tableentry->type == OPTIONS_TABLE_STRING)
69: #define OPTIONS_IS_NUMBER(o) \
70: ((o)->tableentry != NULL && \
71: ((o)->tableentry->type == OPTIONS_TABLE_NUMBER || \
72: (o)->tableentry->type == OPTIONS_TABLE_KEY || \
73: (o)->tableentry->type == OPTIONS_TABLE_COLOUR || \
74: (o)->tableentry->type == OPTIONS_TABLE_FLAG || \
75: (o)->tableentry->type == OPTIONS_TABLE_CHOICE))
76: #define OPTIONS_IS_STYLE(o) \
77: ((o)->tableentry != NULL && \
78: (o)->tableentry->type == OPTIONS_TABLE_STYLE)
1.41 nicm 79:
80: #define OPTIONS_IS_ARRAY(o) \
1.26 nicm 81: ((o)->tableentry != NULL && \
1.41 nicm 82: ((o)->tableentry->flags & OPTIONS_TABLE_IS_ARRAY))
1.26 nicm 83:
1.27 nicm 84: static int options_cmp(struct options_entry *, struct options_entry *);
85: RB_GENERATE_STATIC(options_tree, options_entry, entry, options_cmp);
1.1 nicm 86:
1.17 nicm 87: static int
1.27 nicm 88: options_cmp(struct options_entry *lhs, struct options_entry *rhs)
1.26 nicm 89: {
90: return (strcmp(lhs->name, rhs->name));
91: }
92:
93: static const struct options_table_entry *
94: options_parent_table_entry(struct options *oo, const char *s)
1.1 nicm 95: {
1.27 nicm 96: struct options_entry *o;
1.26 nicm 97:
98: if (oo->parent == NULL)
99: fatalx("no parent options for %s", s);
100: o = options_get_only(oo->parent, s);
101: if (o == NULL)
102: fatalx("%s not in parent options", s);
103: return (o->tableentry);
1.1 nicm 104: }
105:
1.41 nicm 106: static void
107: options_value_free(struct options_entry *o, union options_value *ov)
108: {
109: if (OPTIONS_IS_STRING(o))
110: free(ov->string);
111: }
112:
1.42 ! nicm 113: static char *
1.41 nicm 114: options_value_tostring(struct options_entry *o, union options_value *ov,
115: int numeric)
116: {
1.42 ! nicm 117: char *s;
1.41 nicm 118:
119: if (OPTIONS_IS_STYLE(o))
1.42 ! nicm 120: return (xstrdup(style_tostring(&ov->style)));
1.41 nicm 121: if (OPTIONS_IS_NUMBER(o)) {
122: switch (o->tableentry->type) {
123: case OPTIONS_TABLE_NUMBER:
1.42 ! nicm 124: xasprintf(&s, "%lld", ov->number);
1.41 nicm 125: break;
126: case OPTIONS_TABLE_KEY:
1.42 ! nicm 127: s = xstrdup(key_string_lookup_key(ov->number));
1.41 nicm 128: break;
129: case OPTIONS_TABLE_COLOUR:
1.42 ! nicm 130: s = xstrdup(colour_tostring(ov->number));
1.41 nicm 131: break;
132: case OPTIONS_TABLE_FLAG:
133: if (numeric)
1.42 ! nicm 134: xasprintf(&s, "%lld", ov->number);
1.41 nicm 135: else
1.42 ! nicm 136: s = xstrdup(ov->number ? "on" : "off");
1.41 nicm 137: break;
138: case OPTIONS_TABLE_CHOICE:
1.42 ! nicm 139: s = xstrdup(o->tableentry->choices[ov->number]);
1.41 nicm 140: break;
141: case OPTIONS_TABLE_STRING:
142: case OPTIONS_TABLE_STYLE:
1.42 ! nicm 143: fatalx("not a number option type");
1.41 nicm 144: }
145: return (s);
146: }
147: if (OPTIONS_IS_STRING(o))
1.42 ! nicm 148: return (xstrdup(ov->string));
! 149: return (xstrdup(""));
1.41 nicm 150: }
151:
1.13 nicm 152: struct options *
153: options_create(struct options *parent)
1.1 nicm 154: {
1.16 nicm 155: struct options *oo;
1.13 nicm 156:
157: oo = xcalloc(1, sizeof *oo);
1.7 nicm 158: RB_INIT(&oo->tree);
1.1 nicm 159: oo->parent = parent;
1.13 nicm 160: return (oo);
1.1 nicm 161: }
162:
163: void
164: options_free(struct options *oo)
165: {
1.27 nicm 166: struct options_entry *o, *tmp;
1.1 nicm 167:
1.35 nicm 168: RB_FOREACH_SAFE(o, options_tree, &oo->tree, tmp)
1.26 nicm 169: options_remove(o);
1.13 nicm 170: free(oo);
171: }
172:
1.27 nicm 173: struct options_entry *
1.13 nicm 174: options_first(struct options *oo)
175: {
176: return (RB_MIN(options_tree, &oo->tree));
177: }
178:
1.27 nicm 179: struct options_entry *
180: options_next(struct options_entry *o)
1.13 nicm 181: {
182: return (RB_NEXT(options_tree, &oo->tree, o));
1.1 nicm 183: }
184:
1.27 nicm 185: struct options_entry *
1.26 nicm 186: options_get_only(struct options *oo, const char *name)
1.1 nicm 187: {
1.27 nicm 188: struct options_entry o;
1.1 nicm 189:
1.26 nicm 190: o.name = name;
191: return (RB_FIND(options_tree, &oo->tree, &o));
1.1 nicm 192: }
193:
1.27 nicm 194: struct options_entry *
1.26 nicm 195: options_get(struct options *oo, const char *name)
1.1 nicm 196: {
1.27 nicm 197: struct options_entry *o;
1.1 nicm 198:
1.26 nicm 199: o = options_get_only(oo, name);
1.1 nicm 200: while (o == NULL) {
201: oo = oo->parent;
202: if (oo == NULL)
203: break;
1.26 nicm 204: o = options_get_only(oo, name);
205: }
206: return (o);
207: }
208:
1.27 nicm 209: struct options_entry *
1.26 nicm 210: options_empty(struct options *oo, const struct options_table_entry *oe)
211: {
1.27 nicm 212: struct options_entry *o;
1.26 nicm 213:
214: o = options_add(oo, oe->name);
215: o->tableentry = oe;
216:
1.42 ! nicm 217: if (oe->flags & OPTIONS_TABLE_IS_ARRAY)
1.41 nicm 218: RB_INIT(&o->value.array);
1.39 nicm 219:
1.26 nicm 220: return (o);
221: }
222:
1.27 nicm 223: struct options_entry *
1.26 nicm 224: options_default(struct options *oo, const struct options_table_entry *oe)
225: {
1.41 nicm 226: struct options_entry *o;
227: union options_value *ov;
228: u_int i;
1.26 nicm 229:
230: o = options_empty(oo, oe);
1.41 nicm 231: ov = &o->value;
232:
233: if (oe->flags & OPTIONS_TABLE_IS_ARRAY) {
1.38 nicm 234: if (oe->default_arr != NULL) {
235: for (i = 0; oe->default_arr[i] != NULL; i++)
236: options_array_set(o, i, oe->default_arr[i], 0);
237: } else
238: options_array_assign(o, oe->default_str);
1.41 nicm 239: return (o);
240: }
241:
242: switch (oe->type) {
243: case OPTIONS_TABLE_STRING:
244: ov->string = xstrdup(oe->default_str);
245: break;
246: case OPTIONS_TABLE_STYLE:
247: style_set(&ov->style, &grid_default_cell);
248: style_parse(&ov->style, &grid_default_cell, oe->default_str);
249: break;
250: default:
251: ov->number = oe->default_num;
252: break;
253: }
1.26 nicm 254: return (o);
255: }
256:
1.27 nicm 257: static struct options_entry *
1.26 nicm 258: options_add(struct options *oo, const char *name)
259: {
1.27 nicm 260: struct options_entry *o;
1.26 nicm 261:
262: o = options_get_only(oo, name);
263: if (o != NULL)
264: options_remove(o);
265:
266: o = xcalloc(1, sizeof *o);
267: o->owner = oo;
268: o->name = xstrdup(name);
269:
270: RB_INSERT(options_tree, &oo->tree, o);
1.1 nicm 271: return (o);
272: }
273:
1.2 nicm 274: void
1.27 nicm 275: options_remove(struct options_entry *o)
1.26 nicm 276: {
277: struct options *oo = o->owner;
278:
1.41 nicm 279: if (OPTIONS_IS_ARRAY(o))
1.39 nicm 280: options_array_clear(o);
1.41 nicm 281: else
282: options_value_free(o, &o->value);
1.26 nicm 283: RB_REMOVE(options_tree, &oo->tree, o);
284: free(o);
285: }
286:
287: const char *
1.27 nicm 288: options_name(struct options_entry *o)
1.26 nicm 289: {
290: return (o->name);
291: }
292:
293: const struct options_table_entry *
1.27 nicm 294: options_table_entry(struct options_entry *o)
1.26 nicm 295: {
296: return (o->tableentry);
297: }
298:
1.39 nicm 299: static struct options_array_item *
300: options_array_item(struct options_entry *o, u_int idx)
301: {
302: struct options_array_item a;
303:
304: a.index = idx;
1.41 nicm 305: return (RB_FIND(options_array, &o->value.array, &a));
1.39 nicm 306: }
307:
308: static void
309: options_array_free(struct options_entry *o, struct options_array_item *a)
310: {
1.41 nicm 311: options_value_free(o, &a->value);
312: RB_REMOVE(options_array, &o->value.array, a);
1.39 nicm 313: free(a);
314: }
315:
1.31 nicm 316: void
317: options_array_clear(struct options_entry *o)
318: {
1.39 nicm 319: struct options_array_item *a, *a1;
320:
321: if (!OPTIONS_IS_ARRAY(o))
322: return;
323:
1.41 nicm 324: RB_FOREACH_SAFE(a, options_array, &o->value.array, a1)
1.39 nicm 325: options_array_free(o, a);
1.31 nicm 326: }
327:
1.41 nicm 328: union options_value *
1.27 nicm 329: options_array_get(struct options_entry *o, u_int idx)
1.26 nicm 330: {
1.39 nicm 331: struct options_array_item *a;
332:
1.26 nicm 333: if (!OPTIONS_IS_ARRAY(o))
334: return (NULL);
1.39 nicm 335: a = options_array_item(o, idx);
336: if (a == NULL)
1.26 nicm 337: return (NULL);
1.41 nicm 338: return (&a->value);
1.26 nicm 339: }
340:
341: int
1.31 nicm 342: options_array_set(struct options_entry *o, u_int idx, const char *value,
343: int append)
1.26 nicm 344: {
1.39 nicm 345: struct options_array_item *a;
346: char *new;
1.26 nicm 347:
348: if (!OPTIONS_IS_ARRAY(o))
349: return (-1);
350:
1.39 nicm 351: a = options_array_item(o, idx);
352: if (value == NULL) {
353: if (a != NULL)
354: options_array_free(o, a);
355: return (0);
1.26 nicm 356: }
1.31 nicm 357:
1.39 nicm 358: if (a == NULL) {
359: a = xcalloc(1, sizeof *a);
360: a->index = idx;
1.41 nicm 361: a->value.string = xstrdup(value);
362: RB_INSERT(options_array, &o->value.array, a);
1.39 nicm 363: } else {
1.41 nicm 364: options_value_free(o, &a->value);
1.39 nicm 365: if (a != NULL && append)
1.41 nicm 366: xasprintf(&new, "%s%s", a->value.string, value);
1.31 nicm 367: else
368: new = xstrdup(value);
1.41 nicm 369: a->value.string = new;
1.31 nicm 370: }
371:
1.26 nicm 372: return (0);
373: }
374:
1.31 nicm 375: void
376: options_array_assign(struct options_entry *o, const char *s)
377: {
378: const char *separator;
379: char *copy, *next, *string;
380: u_int i;
381:
382: separator = o->tableentry->separator;
383: if (separator == NULL)
384: separator = " ,";
385:
386: copy = string = xstrdup(s);
387: while ((next = strsep(&string, separator)) != NULL) {
388: if (*next == '\0')
389: continue;
1.39 nicm 390: for (i = 0; i < UINT_MAX; i++) {
391: if (options_array_item(o, i) == NULL)
1.31 nicm 392: break;
393: }
1.39 nicm 394: if (i == UINT_MAX)
1.31 nicm 395: break;
396: options_array_set(o, i, next, 0);
397: }
398: free(copy);
399: }
400:
1.39 nicm 401: struct options_array_item *
402: options_array_first(struct options_entry *o)
403: {
404: if (!OPTIONS_IS_ARRAY(o))
405: return (NULL);
1.41 nicm 406: return (RB_MIN(options_array, &o->value.array));
1.39 nicm 407: }
408:
409: struct options_array_item *
410: options_array_next(struct options_array_item *a)
411: {
1.41 nicm 412: return (RB_NEXT(options_array, &o->value.array, a));
1.39 nicm 413: }
414:
415: u_int
416: options_array_item_index(struct options_array_item *a)
417: {
418: return (a->index);
419: }
420:
1.41 nicm 421: union options_value *
1.39 nicm 422: options_array_item_value(struct options_array_item *a)
423: {
1.41 nicm 424: return (&a->value);
1.39 nicm 425: }
426:
427: int
428: options_isarray(struct options_entry *o)
429: {
430: return (OPTIONS_IS_ARRAY(o));
431: }
432:
1.26 nicm 433: int
1.27 nicm 434: options_isstring(struct options_entry *o)
1.26 nicm 435: {
1.41 nicm 436: return (OPTIONS_IS_STRING(o));
1.26 nicm 437: }
438:
1.42 ! nicm 439: char *
1.32 nicm 440: options_tostring(struct options_entry *o, int idx, int numeric)
1.26 nicm 441: {
1.39 nicm 442: struct options_array_item *a;
1.26 nicm 443:
444: if (OPTIONS_IS_ARRAY(o)) {
445: if (idx == -1)
1.42 ! nicm 446: return (xstrdup(""));
1.39 nicm 447: a = options_array_item(o, idx);
448: if (a == NULL)
1.42 ! nicm 449: return (xstrdup(""));
1.41 nicm 450: return (options_value_tostring(o, &a->value, numeric));
1.26 nicm 451: }
1.41 nicm 452: return (options_value_tostring(o, &o->value, numeric));
1.26 nicm 453: }
454:
455: char *
456: options_parse(const char *name, int *idx)
1.1 nicm 457: {
1.26 nicm 458: char *copy, *cp, *end;
1.1 nicm 459:
1.26 nicm 460: if (*name == '\0')
461: return (NULL);
462: copy = xstrdup(name);
463: if ((cp = strchr(copy, '[')) == NULL) {
464: *idx = -1;
465: return (copy);
466: }
467: end = strchr(cp + 1, ']');
468: if (end == NULL || end[1] != '\0' || !isdigit((u_char)end[-1])) {
469: free(copy);
470: return (NULL);
471: }
472: if (sscanf(cp, "[%d]", idx) != 1 || *idx < 0) {
473: free(copy);
474: return (NULL);
475: }
476: *cp = '\0';
477: return (copy);
1.1 nicm 478: }
479:
1.27 nicm 480: struct options_entry *
1.26 nicm 481: options_parse_get(struct options *oo, const char *s, int *idx, int only)
1.1 nicm 482: {
1.27 nicm 483: struct options_entry *o;
484: char *name;
1.1 nicm 485:
1.26 nicm 486: name = options_parse(s, idx);
487: if (name == NULL)
488: return (NULL);
489: if (only)
490: o = options_get_only(oo, name);
491: else
492: o = options_get(oo, name);
493: free(name);
494: return (o);
495: }
1.1 nicm 496:
1.26 nicm 497: char *
498: options_match(const char *s, int *idx, int* ambiguous)
499: {
500: const struct options_table_entry *oe, *found;
501: char *name;
502: size_t namelen;
503:
504: name = options_parse(s, idx);
1.33 nicm 505: if (name == NULL)
506: return (NULL);
1.26 nicm 507: namelen = strlen(name);
1.29 nicm 508:
509: if (*name == '@') {
510: *ambiguous = 0;
1.34 nicm 511: return (name);
1.29 nicm 512: }
1.26 nicm 513:
514: found = NULL;
515: for (oe = options_table; oe->name != NULL; oe++) {
516: if (strcmp(oe->name, name) == 0) {
517: found = oe;
518: break;
519: }
520: if (strncmp(oe->name, name, namelen) == 0) {
521: if (found != NULL) {
522: *ambiguous = 1;
523: free(name);
524: return (NULL);
525: }
526: found = oe;
527: }
528: }
529: free(name);
530: if (found == NULL) {
531: *ambiguous = 0;
532: return (NULL);
1.22 nicm 533: }
1.26 nicm 534: return (xstrdup(found->name));
535: }
1.22 nicm 536:
1.27 nicm 537: struct options_entry *
1.26 nicm 538: options_match_get(struct options *oo, const char *s, int *idx, int only,
539: int* ambiguous)
540: {
1.27 nicm 541: char *name;
542: struct options_entry *o;
1.21 nicm 543:
1.26 nicm 544: name = options_match(s, idx, ambiguous);
545: if (name == NULL)
546: return (NULL);
547: *ambiguous = 0;
548: if (only)
549: o = options_get_only(oo, name);
550: else
551: o = options_get(oo, name);
552: free(name);
1.4 nicm 553: return (o);
1.1 nicm 554: }
1.26 nicm 555:
1.23 nicm 556: const char *
1.1 nicm 557: options_get_string(struct options *oo, const char *name)
558: {
1.27 nicm 559: struct options_entry *o;
1.26 nicm 560:
561: o = options_get(oo, name);
562: if (o == NULL)
563: fatalx("missing option %s", name);
564: if (!OPTIONS_IS_STRING(o))
565: fatalx("option %s is not a string", name);
1.41 nicm 566: return (o->value.string);
1.26 nicm 567: }
568:
569: long long
570: options_get_number(struct options *oo, const char *name)
571: {
1.27 nicm 572: struct options_entry *o;
1.1 nicm 573:
1.26 nicm 574: o = options_get(oo, name);
575: if (o == NULL)
1.15 nicm 576: fatalx("missing option %s", name);
1.26 nicm 577: if (!OPTIONS_IS_NUMBER(o))
578: fatalx("option %s is not a number", name);
1.41 nicm 579: return (o->value.number);
1.1 nicm 580: }
581:
1.37 nicm 582: struct style *
1.26 nicm 583: options_get_style(struct options *oo, const char *name)
584: {
1.27 nicm 585: struct options_entry *o;
1.26 nicm 586:
587: o = options_get(oo, name);
588: if (o == NULL)
589: fatalx("missing option %s", name);
590: if (!OPTIONS_IS_STYLE(o))
591: fatalx("option %s is not a style", name);
1.41 nicm 592: return (&o->value.style);
1.26 nicm 593: }
594:
1.27 nicm 595: struct options_entry *
1.26 nicm 596: options_set_string(struct options *oo, const char *name, int append,
597: const char *fmt, ...)
1.1 nicm 598: {
1.27 nicm 599: struct options_entry *o;
600: va_list ap;
601: char *s, *value;
1.1 nicm 602:
1.26 nicm 603: va_start(ap, fmt);
604: xvasprintf(&s, fmt, ap);
605: va_end(ap);
606:
607: o = options_get_only(oo, name);
608: if (o != NULL && append && OPTIONS_IS_STRING(o)) {
1.41 nicm 609: xasprintf(&value, "%s%s", o->value.string, s);
1.26 nicm 610: free(s);
611: } else
612: value = s;
613: if (o == NULL && *name == '@')
614: o = options_add(oo, name);
615: else if (o == NULL) {
616: o = options_default(oo, options_parent_table_entry(oo, name));
617: if (o == NULL)
618: return (NULL);
619: }
1.21 nicm 620:
1.26 nicm 621: if (!OPTIONS_IS_STRING(o))
622: fatalx("option %s is not a string", name);
1.41 nicm 623: free(o->value.string);
624: o->value.string = value;
1.4 nicm 625: return (o);
1.1 nicm 626: }
627:
1.27 nicm 628: struct options_entry *
1.26 nicm 629: options_set_number(struct options *oo, const char *name, long long value)
1.1 nicm 630: {
1.27 nicm 631: struct options_entry *o;
1.26 nicm 632:
633: if (*name == '@')
634: fatalx("user option %s must be a string", name);
1.1 nicm 635:
1.26 nicm 636: o = options_get_only(oo, name);
637: if (o == NULL) {
638: o = options_default(oo, options_parent_table_entry(oo, name));
639: if (o == NULL)
640: return (NULL);
641: }
642:
643: if (!OPTIONS_IS_NUMBER(o))
644: fatalx("option %s is not a number", name);
1.41 nicm 645: o->value.number = value;
1.26 nicm 646: return (o);
1.10 nicm 647: }
648:
1.27 nicm 649: struct options_entry *
1.22 nicm 650: options_set_style(struct options *oo, const char *name, int append,
651: const char *value)
1.10 nicm 652: {
1.27 nicm 653: struct options_entry *o;
1.37 nicm 654: struct style sy;
1.26 nicm 655:
656: if (*name == '@')
657: fatalx("user option %s must be a string", name);
1.10 nicm 658:
1.26 nicm 659: o = options_get_only(oo, name);
660: if (o != NULL && append && OPTIONS_IS_STYLE(o))
1.41 nicm 661: style_copy(&sy, &o->value.style);
1.12 nicm 662: else
1.37 nicm 663: style_set(&sy, &grid_default_cell);
664: if (style_parse(&sy, &grid_default_cell, value) == -1)
1.26 nicm 665: return (NULL);
666: if (o == NULL) {
667: o = options_default(oo, options_parent_table_entry(oo, name));
668: if (o == NULL)
669: return (NULL);
670: }
671:
672: if (!OPTIONS_IS_STYLE(o))
673: fatalx("option %s is not a style", name);
1.41 nicm 674: style_copy(&o->value.style, &sy);
1.26 nicm 675: return (o);
676: }
1.12 nicm 677:
1.26 nicm 678: enum options_table_scope
679: options_scope_from_flags(struct args *args, int window,
680: struct cmd_find_state *fs, struct options **oo, char **cause)
681: {
682: struct session *s = fs->s;
683: struct winlink *wl = fs->wl;
684: const char *target= args_get(args, 't');
685:
686: if (args_has(args, 's')) {
687: *oo = global_options;
688: return (OPTIONS_TABLE_SERVER);
689: }
1.12 nicm 690:
1.26 nicm 691: if (window || args_has(args, 'w')) {
692: if (args_has(args, 'g')) {
693: *oo = global_w_options;
694: return (OPTIONS_TABLE_WINDOW);
695: }
696: if (wl == NULL) {
697: if (target != NULL)
698: xasprintf(cause, "no such window: %s", target);
699: else
700: xasprintf(cause, "no current window");
701: return (OPTIONS_TABLE_NONE);
702: }
703: *oo = wl->window->options;
704: return (OPTIONS_TABLE_WINDOW);
705: } else {
706: if (args_has(args, 'g')) {
707: *oo = global_s_options;
708: return (OPTIONS_TABLE_SESSION);
709: }
710: if (s == NULL) {
711: if (target != NULL)
712: xasprintf(cause, "no such session: %s", target);
713: else
714: xasprintf(cause, "no current session");
715: return (OPTIONS_TABLE_NONE);
716: }
717: *oo = s->options;
718: return (OPTIONS_TABLE_SESSION);
719: }
1.1 nicm 720: }