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