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