1 /* $OpenBSD$ */ 2 3 /* 4 * Copyright (c) 2011 Nicholas Marriott <nicm@users.sourceforge.net> 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 <string.h> 22 23 #include "tmux.h" 24 25 /* 26 * This file has a tables with all the server, session and window 27 * options. These tables are the master copy of the options with their real 28 * (user-visible) types, range limits and default values. At start these are 29 * copied into the runtime global options trees (which only has number and 30 * string types). These tables are then used to look up the real type when the 31 * user sets an option or its value needs to be shown. 32 */ 33 34 /* Choice option type lists. */ 35 const char *options_table_mode_keys_list[] = { 36 "emacs", "vi", NULL 37 }; 38 const char *options_table_clock_mode_style_list[] = { 39 "12", "24", NULL 40 }; 41 const char *options_table_status_keys_list[] = { 42 "emacs", "vi", NULL 43 }; 44 const char *options_table_status_justify_list[] = { 45 "left", "centre", "right", NULL 46 }; 47 const char *options_table_status_position_list[] = { 48 "top", "bottom", NULL 49 }; 50 const char *options_table_bell_action_list[] = { 51 "none", "any", "current", "other", NULL 52 }; 53 54 /* Server options. */ 55 const struct options_table_entry server_options_table[] = { 56 { .name = "buffer-limit", 57 .type = OPTIONS_TABLE_NUMBER, 58 .minimum = 1, 59 .maximum = INT_MAX, 60 .default_num = 20 61 }, 62 63 { .name = "default-terminal", 64 .type = OPTIONS_TABLE_STRING, 65 .default_str = "screen" 66 }, 67 68 { .name = "escape-time", 69 .type = OPTIONS_TABLE_NUMBER, 70 .minimum = 0, 71 .maximum = INT_MAX, 72 .default_num = 500 73 }, 74 75 { .name = "exit-unattached", 76 .type = OPTIONS_TABLE_FLAG, 77 .default_num = 0 78 }, 79 80 { .name = "focus-events", 81 .type = OPTIONS_TABLE_FLAG, 82 .default_num = 0 83 }, 84 85 { .name = "history-file", 86 .type = OPTIONS_TABLE_STRING, 87 .default_str = NULL 88 }, 89 90 { .name = "message-limit", 91 .type = OPTIONS_TABLE_NUMBER, 92 .minimum = 0, 93 .maximum = INT_MAX, 94 .default_num = 100 95 }, 96 97 { .name = "quiet", 98 .type = OPTIONS_TABLE_FLAG, 99 .default_num = 0 100 }, 101 102 { .name = "set-clipboard", 103 .type = OPTIONS_TABLE_FLAG, 104 .default_num = 1 105 }, 106 107 { .name = "terminal-overrides", 108 .type = OPTIONS_TABLE_STRING, 109 .default_str = "xterm*:XT:Ms=\\E]52;%p1%s;%p2%s\\007" 110 ":Cs=\\E]12;%p1%s\\007:Cr=\\E]112\\007" 111 ":Ss=\\E[%p1%d q:Se=\\E[2 q,screen*:XT" 112 }, 113 114 { .name = NULL } 115 }; 116 117 /* Session options. */ 118 const struct options_table_entry session_options_table[] = { 119 { .name = "assume-paste-time", 120 .type = OPTIONS_TABLE_NUMBER, 121 .minimum = 0, 122 .maximum = INT_MAX, 123 .default_num = 1, 124 }, 125 126 { .name = "base-index", 127 .type = OPTIONS_TABLE_NUMBER, 128 .minimum = 0, 129 .maximum = INT_MAX, 130 .default_num = 0 131 }, 132 133 { .name = "bell-action", 134 .type = OPTIONS_TABLE_CHOICE, 135 .choices = options_table_bell_action_list, 136 .default_num = BELL_ANY 137 }, 138 139 { .name = "bell-on-alert", 140 .type = OPTIONS_TABLE_FLAG, 141 .default_num = 0 142 }, 143 144 { .name = "default-command", 145 .type = OPTIONS_TABLE_STRING, 146 .default_str = "" 147 }, 148 149 { .name = "default-shell", 150 .type = OPTIONS_TABLE_STRING, 151 .default_str = _PATH_BSHELL 152 }, 153 154 { .name = "destroy-unattached", 155 .type = OPTIONS_TABLE_FLAG, 156 .default_num = 0 157 }, 158 159 { .name = "detach-on-destroy", 160 .type = OPTIONS_TABLE_FLAG, 161 .default_num = 1 162 }, 163 164 { .name = "display-panes-active-colour", 165 .type = OPTIONS_TABLE_COLOUR, 166 .default_num = 1 167 }, 168 169 { .name = "display-panes-colour", 170 .type = OPTIONS_TABLE_COLOUR, 171 .default_num = 4 172 }, 173 174 { .name = "display-panes-time", 175 .type = OPTIONS_TABLE_NUMBER, 176 .minimum = 1, 177 .maximum = INT_MAX, 178 .default_num = 1000 179 }, 180 181 { .name = "display-time", 182 .type = OPTIONS_TABLE_NUMBER, 183 .minimum = 1, 184 .maximum = INT_MAX, 185 .default_num = 750 186 }, 187 188 { .name = "history-limit", 189 .type = OPTIONS_TABLE_NUMBER, 190 .minimum = 0, 191 .maximum = INT_MAX, 192 .default_num = 2000 193 }, 194 195 { .name = "lock-after-time", 196 .type = OPTIONS_TABLE_NUMBER, 197 .minimum = 0, 198 .maximum = INT_MAX, 199 .default_num = 0 200 }, 201 202 { .name = "lock-command", 203 .type = OPTIONS_TABLE_STRING, 204 .default_str = "lock -np" 205 }, 206 207 { .name = "message-attr", 208 .type = OPTIONS_TABLE_ATTRIBUTES, 209 .default_num = 0, 210 .style = "message-style" 211 }, 212 213 { .name = "message-bg", 214 .type = OPTIONS_TABLE_COLOUR, 215 .default_num = 3, 216 .style = "message-style" 217 }, 218 219 { .name = "message-command-attr", 220 .type = OPTIONS_TABLE_ATTRIBUTES, 221 .default_num = 0, 222 .style = "message-command-style" 223 }, 224 225 { .name = "message-command-bg", 226 .type = OPTIONS_TABLE_COLOUR, 227 .default_num = 0, 228 .style = "message-command-style" 229 }, 230 231 { .name = "message-command-fg", 232 .type = OPTIONS_TABLE_COLOUR, 233 .default_num = 3, 234 .style = "message-command-style" 235 }, 236 237 { .name = "message-command-style", 238 .type = OPTIONS_TABLE_STYLE, 239 .default_str = "bg=black,fg=yellow" 240 }, 241 242 { .name = "message-fg", 243 .type = OPTIONS_TABLE_COLOUR, 244 .default_num = 0, 245 .style = "message-style" 246 }, 247 248 { .name = "message-style", 249 .type = OPTIONS_TABLE_STYLE, 250 .default_str = "bg=yellow,fg=black" 251 }, 252 253 { .name = "mouse", 254 .type = OPTIONS_TABLE_FLAG, 255 .default_num = 0 256 }, 257 258 { .name = "mouse-utf8", 259 .type = OPTIONS_TABLE_FLAG, 260 .default_num = 0 261 }, 262 263 { .name = "prefix", 264 .type = OPTIONS_TABLE_KEY, 265 .default_num = '\002', 266 }, 267 268 { .name = "prefix2", 269 .type = OPTIONS_TABLE_KEY, 270 .default_num = KEYC_NONE, 271 }, 272 273 { .name = "renumber-windows", 274 .type = OPTIONS_TABLE_FLAG, 275 .default_num = 0 276 }, 277 278 { .name = "repeat-time", 279 .type = OPTIONS_TABLE_NUMBER, 280 .minimum = 0, 281 .maximum = SHRT_MAX, 282 .default_num = 500 283 }, 284 285 { .name = "set-remain-on-exit", 286 .type = OPTIONS_TABLE_FLAG, 287 .default_num = 0 288 }, 289 290 { .name = "set-titles", 291 .type = OPTIONS_TABLE_FLAG, 292 .default_num = 0 293 }, 294 295 { .name = "set-titles-string", 296 .type = OPTIONS_TABLE_STRING, 297 .default_str = "#S:#I:#W - \"#T\" #{session_alerts}" 298 }, 299 300 { .name = "status", 301 .type = OPTIONS_TABLE_FLAG, 302 .default_num = 1 303 }, 304 305 { .name = "status-attr", 306 .type = OPTIONS_TABLE_ATTRIBUTES, 307 .default_num = 0, 308 .style = "status-style" 309 }, 310 311 { .name = "status-bg", 312 .type = OPTIONS_TABLE_COLOUR, 313 .default_num = 2, 314 .style = "status-style" 315 }, 316 317 { .name = "status-fg", 318 .type = OPTIONS_TABLE_COLOUR, 319 .default_num = 0, 320 .style = "status-style" 321 }, 322 323 { .name = "status-interval", 324 .type = OPTIONS_TABLE_NUMBER, 325 .minimum = 0, 326 .maximum = INT_MAX, 327 .default_num = 15 328 }, 329 330 { .name = "status-justify", 331 .type = OPTIONS_TABLE_CHOICE, 332 .choices = options_table_status_justify_list, 333 .default_num = 0 334 }, 335 336 { .name = "status-keys", 337 .type = OPTIONS_TABLE_CHOICE, 338 .choices = options_table_status_keys_list, 339 .default_num = MODEKEY_EMACS 340 }, 341 342 { .name = "status-left", 343 .type = OPTIONS_TABLE_STRING, 344 .default_str = "[#S] " 345 }, 346 347 { .name = "status-left-attr", 348 .type = OPTIONS_TABLE_ATTRIBUTES, 349 .default_num = 0, 350 .style = "status-left-style" 351 }, 352 353 { .name = "status-left-bg", 354 .type = OPTIONS_TABLE_COLOUR, 355 .default_num = 8, 356 .style = "status-left-style" 357 }, 358 359 { .name = "status-left-fg", 360 .type = OPTIONS_TABLE_COLOUR, 361 .default_num = 8, 362 .style = "status-left-style" 363 }, 364 365 { .name = "status-left-length", 366 .type = OPTIONS_TABLE_NUMBER, 367 .minimum = 0, 368 .maximum = SHRT_MAX, 369 .default_num = 10 370 }, 371 372 { .name = "status-left-style", 373 .type = OPTIONS_TABLE_STYLE, 374 .default_str = "default" 375 }, 376 377 { .name = "status-position", 378 .type = OPTIONS_TABLE_CHOICE, 379 .choices = options_table_status_position_list, 380 .default_num = 1 381 }, 382 383 { .name = "status-right", 384 .type = OPTIONS_TABLE_STRING, 385 .default_str = " \"#{=21:pane_title}\" %H:%M %d-%b-%y" 386 }, 387 388 { .name = "status-right-attr", 389 .type = OPTIONS_TABLE_ATTRIBUTES, 390 .default_num = 0, 391 .style = "status-right-style" 392 }, 393 394 { .name = "status-right-bg", 395 .type = OPTIONS_TABLE_COLOUR, 396 .default_num = 8, 397 .style = "status-right-style" 398 }, 399 400 { .name = "status-right-fg", 401 .type = OPTIONS_TABLE_COLOUR, 402 .default_num = 8, 403 .style = "status-right-style" 404 }, 405 406 { .name = "status-right-length", 407 .type = OPTIONS_TABLE_NUMBER, 408 .minimum = 0, 409 .maximum = SHRT_MAX, 410 .default_num = 40 411 }, 412 413 { .name = "status-right-style", 414 .type = OPTIONS_TABLE_STYLE, 415 .default_str = "default" 416 }, 417 418 { .name = "status-style", 419 .type = OPTIONS_TABLE_STYLE, 420 .default_str = "bg=green,fg=black" 421 }, 422 423 { .name = "status-utf8", 424 .type = OPTIONS_TABLE_FLAG, 425 .default_num = 0 /* overridden in main() */ 426 }, 427 428 { .name = "update-environment", 429 .type = OPTIONS_TABLE_STRING, 430 .default_str = "DISPLAY SSH_ASKPASS SSH_AUTH_SOCK SSH_AGENT_PID " 431 "SSH_CONNECTION WINDOWID XAUTHORITY" 432 433 }, 434 435 { .name = "visual-activity", 436 .type = OPTIONS_TABLE_FLAG, 437 .default_num = 0 438 }, 439 440 { .name = "visual-bell", 441 .type = OPTIONS_TABLE_FLAG, 442 .default_num = 0 443 }, 444 445 { .name = "visual-silence", 446 .type = OPTIONS_TABLE_FLAG, 447 .default_num = 0 448 }, 449 450 { .name = "word-separators", 451 .type = OPTIONS_TABLE_STRING, 452 .default_str = " -_@" 453 }, 454 455 { .name = NULL } 456 }; 457 458 /* Window options. */ 459 const struct options_table_entry window_options_table[] = { 460 { .name = "aggressive-resize", 461 .type = OPTIONS_TABLE_FLAG, 462 .default_num = 0 463 }, 464 465 { .name = "allow-rename", 466 .type = OPTIONS_TABLE_FLAG, 467 .default_num = 1 468 }, 469 470 { .name = "alternate-screen", 471 .type = OPTIONS_TABLE_FLAG, 472 .default_num = 1 473 }, 474 475 { .name = "automatic-rename", 476 .type = OPTIONS_TABLE_FLAG, 477 .default_num = 1 478 }, 479 480 { .name = "automatic-rename-format", 481 .type = OPTIONS_TABLE_STRING, 482 .default_str = "#{?pane_in_mode,[tmux],#{pane_current_command}}" 483 "#{?pane_dead,[dead],}" 484 }, 485 486 { .name = "clock-mode-colour", 487 .type = OPTIONS_TABLE_COLOUR, 488 .default_num = 4 489 }, 490 491 { .name = "clock-mode-style", 492 .type = OPTIONS_TABLE_CHOICE, 493 .choices = options_table_clock_mode_style_list, 494 .default_num = 1 495 }, 496 497 { .name = "force-height", 498 .type = OPTIONS_TABLE_NUMBER, 499 .minimum = 0, 500 .maximum = INT_MAX, 501 .default_num = 0 502 }, 503 504 { .name = "force-width", 505 .type = OPTIONS_TABLE_NUMBER, 506 .minimum = 0, 507 .maximum = INT_MAX, 508 .default_num = 0 509 }, 510 511 { .name = "main-pane-height", 512 .type = OPTIONS_TABLE_NUMBER, 513 .minimum = 1, 514 .maximum = INT_MAX, 515 .default_num = 24 516 }, 517 518 { .name = "main-pane-width", 519 .type = OPTIONS_TABLE_NUMBER, 520 .minimum = 1, 521 .maximum = INT_MAX, 522 .default_num = 80 523 }, 524 525 { .name = "mode-attr", 526 .type = OPTIONS_TABLE_ATTRIBUTES, 527 .default_num = 0, 528 .style = "mode-style" 529 }, 530 531 { .name = "mode-bg", 532 .type = OPTIONS_TABLE_COLOUR, 533 .default_num = 3, 534 .style = "mode-style" 535 }, 536 537 { .name = "mode-fg", 538 .type = OPTIONS_TABLE_COLOUR, 539 .default_num = 0, 540 .style = "mode-style" 541 }, 542 543 { .name = "mode-keys", 544 .type = OPTIONS_TABLE_CHOICE, 545 .choices = options_table_mode_keys_list, 546 .default_num = MODEKEY_EMACS 547 }, 548 549 { .name = "mode-style", 550 .type = OPTIONS_TABLE_STYLE, 551 .default_str = "bg=yellow,fg=black" 552 }, 553 554 { .name = "monitor-activity", 555 .type = OPTIONS_TABLE_FLAG, 556 .default_num = 0 557 }, 558 559 { .name = "monitor-silence", 560 .type = OPTIONS_TABLE_NUMBER, 561 .minimum = 0, 562 .maximum = INT_MAX, 563 .default_num = 0 564 }, 565 566 { .name = "other-pane-height", 567 .type = OPTIONS_TABLE_NUMBER, 568 .minimum = 0, 569 .maximum = INT_MAX, 570 .default_num = 0 571 }, 572 573 { .name = "other-pane-width", 574 .type = OPTIONS_TABLE_NUMBER, 575 .minimum = 0, 576 .maximum = INT_MAX, 577 .default_num = 0 578 }, 579 580 { .name = "pane-active-border-bg", 581 .type = OPTIONS_TABLE_COLOUR, 582 .default_num = 8, 583 .style = "pane-active-border-style" 584 }, 585 586 { .name = "pane-active-border-fg", 587 .type = OPTIONS_TABLE_COLOUR, 588 .default_num = 2, 589 .style = "pane-active-border-style" 590 }, 591 592 { .name = "pane-active-border-style", 593 .type = OPTIONS_TABLE_STYLE, 594 .default_str = "fg=green" 595 }, 596 597 { .name = "pane-base-index", 598 .type = OPTIONS_TABLE_NUMBER, 599 .minimum = 0, 600 .maximum = USHRT_MAX, 601 .default_num = 0 602 }, 603 604 { .name = "pane-border-bg", 605 .type = OPTIONS_TABLE_COLOUR, 606 .default_num = 8, 607 .style = "pane-border-style" 608 }, 609 610 { .name = "pane-border-fg", 611 .type = OPTIONS_TABLE_COLOUR, 612 .default_num = 8, 613 .style = "pane-border-style" 614 }, 615 616 { .name = "pane-border-style", 617 .type = OPTIONS_TABLE_STYLE, 618 .default_str = "default" 619 }, 620 621 { .name = "remain-on-exit", 622 .type = OPTIONS_TABLE_FLAG, 623 .default_num = 0 624 }, 625 626 { .name = "synchronize-panes", 627 .type = OPTIONS_TABLE_FLAG, 628 .default_num = 0 629 }, 630 631 { .name = "utf8", 632 .type = OPTIONS_TABLE_FLAG, 633 .default_num = 0 /* overridden in main() */ 634 }, 635 636 { .name = "window-active-style", 637 .type = OPTIONS_TABLE_STYLE, 638 .default_str = "default" 639 }, 640 641 { .name = "window-style", 642 .type = OPTIONS_TABLE_STYLE, 643 .default_str = "default" 644 }, 645 646 { .name = "window-status-activity-attr", 647 .type = OPTIONS_TABLE_ATTRIBUTES, 648 .default_num = GRID_ATTR_REVERSE, 649 .style = "window-status-activity-style" 650 }, 651 652 { .name = "window-status-activity-bg", 653 .type = OPTIONS_TABLE_COLOUR, 654 .default_num = 8, 655 .style = "window-status-activity-style" 656 }, 657 658 { .name = "window-status-activity-fg", 659 .type = OPTIONS_TABLE_COLOUR, 660 .default_num = 8, 661 .style = "window-status-activity-style" 662 }, 663 664 { .name = "window-status-activity-style", 665 .type = OPTIONS_TABLE_STYLE, 666 .default_str = "reverse" 667 }, 668 669 { .name = "window-status-attr", 670 .type = OPTIONS_TABLE_ATTRIBUTES, 671 .default_num = 0, 672 .style = "window-status-style" 673 }, 674 675 { .name = "window-status-bell-attr", 676 .type = OPTIONS_TABLE_ATTRIBUTES, 677 .default_num = GRID_ATTR_REVERSE, 678 .style = "window-status-bell-style" 679 }, 680 681 { .name = "window-status-bell-bg", 682 .type = OPTIONS_TABLE_COLOUR, 683 .default_num = 8, 684 .style = "window-status-bell-style" 685 }, 686 687 { .name = "window-status-bell-fg", 688 .type = OPTIONS_TABLE_COLOUR, 689 .default_num = 8, 690 .style = "window-status-bell-style" 691 }, 692 693 { .name = "window-status-bell-style", 694 .type = OPTIONS_TABLE_STYLE, 695 .default_str = "reverse" 696 }, 697 698 { .name = "window-status-bg", 699 .type = OPTIONS_TABLE_COLOUR, 700 .default_num = 8, 701 .style = "window-status-style" 702 }, 703 704 { .name = "window-status-current-attr", 705 .type = OPTIONS_TABLE_ATTRIBUTES, 706 .default_num = 0, 707 .style = "window-status-current-style" 708 }, 709 710 { .name = "window-status-current-bg", 711 .type = OPTIONS_TABLE_COLOUR, 712 .default_num = 8, 713 .style = "window-status-current-style" 714 }, 715 716 { .name = "window-status-current-fg", 717 .type = OPTIONS_TABLE_COLOUR, 718 .default_num = 8, 719 .style = "window-status-current-style" 720 }, 721 722 { .name = "window-status-current-format", 723 .type = OPTIONS_TABLE_STRING, 724 .default_str = "#I:#W#{?window_flags,#{window_flags}, }" 725 }, 726 727 { .name = "window-status-current-style", 728 .type = OPTIONS_TABLE_STYLE, 729 .default_str = "default" 730 }, 731 732 { .name = "window-status-fg", 733 .type = OPTIONS_TABLE_COLOUR, 734 .default_num = 8, 735 .style = "window-status-style" 736 }, 737 738 { .name = "window-status-format", 739 .type = OPTIONS_TABLE_STRING, 740 .default_str = "#I:#W#{?window_flags,#{window_flags}, }" 741 }, 742 743 { .name = "window-status-last-attr", 744 .type = OPTIONS_TABLE_ATTRIBUTES, 745 .default_num = 0, 746 .style = "window-status-last-style" 747 }, 748 749 { .name = "window-status-last-bg", 750 .type = OPTIONS_TABLE_COLOUR, 751 .default_num = 8, 752 .style = "window-status-last-style" 753 }, 754 755 { .name = "window-status-last-fg", 756 .type = OPTIONS_TABLE_COLOUR, 757 .default_num = 8, 758 .style = "window-status-last-style" 759 }, 760 761 { .name = "window-status-last-style", 762 .type = OPTIONS_TABLE_STYLE, 763 .default_str = "default" 764 }, 765 766 { .name = "window-status-separator", 767 .type = OPTIONS_TABLE_STRING, 768 .default_str = " " 769 }, 770 771 { .name = "window-status-style", 772 .type = OPTIONS_TABLE_STYLE, 773 .default_str = "default" 774 }, 775 776 { .name = "wrap-search", 777 .type = OPTIONS_TABLE_FLAG, 778 .default_num = 1 779 }, 780 781 { .name = "xterm-keys", 782 .type = OPTIONS_TABLE_FLAG, 783 .default_num = 0 784 }, 785 786 { .name = NULL } 787 }; 788 789 /* Populate an options tree from a table. */ 790 void 791 options_table_populate_tree( 792 const struct options_table_entry *table, struct options *oo) 793 { 794 const struct options_table_entry *oe; 795 796 for (oe = table; oe->name != NULL; oe++) { 797 switch (oe->type) { 798 case OPTIONS_TABLE_STRING: 799 options_set_string(oo, oe->name, "%s", oe->default_str); 800 break; 801 case OPTIONS_TABLE_STYLE: 802 options_set_style(oo, oe->name, oe->default_str, 0); 803 break; 804 default: 805 options_set_number(oo, oe->name, oe->default_num); 806 break; 807 } 808 } 809 } 810 811 /* Print an option using its type from the table. */ 812 const char * 813 options_table_print_entry(const struct options_table_entry *oe, 814 struct options_entry *o, int no_quotes) 815 { 816 static char out[BUFSIZ]; 817 const char *s; 818 819 *out = '\0'; 820 switch (oe->type) { 821 case OPTIONS_TABLE_STRING: 822 if (no_quotes) 823 xsnprintf(out, sizeof out, "%s", o->str); 824 else 825 xsnprintf(out, sizeof out, "\"%s\"", o->str); 826 break; 827 case OPTIONS_TABLE_NUMBER: 828 xsnprintf(out, sizeof out, "%lld", o->num); 829 break; 830 case OPTIONS_TABLE_KEY: 831 xsnprintf(out, sizeof out, "%s", 832 key_string_lookup_key(o->num)); 833 break; 834 case OPTIONS_TABLE_COLOUR: 835 s = colour_tostring(o->num); 836 xsnprintf(out, sizeof out, "%s", s); 837 break; 838 case OPTIONS_TABLE_ATTRIBUTES: 839 s = attributes_tostring(o->num); 840 xsnprintf(out, sizeof out, "%s", s); 841 break; 842 case OPTIONS_TABLE_FLAG: 843 if (o->num) 844 strlcpy(out, "on", sizeof out); 845 else 846 strlcpy(out, "off", sizeof out); 847 break; 848 case OPTIONS_TABLE_CHOICE: 849 s = oe->choices[o->num]; 850 xsnprintf(out, sizeof out, "%s", s); 851 break; 852 case OPTIONS_TABLE_STYLE: 853 s = style_tostring(&o->style); 854 xsnprintf(out, sizeof out, "%s", s); 855 break; 856 } 857 return (out); 858 } 859 860 /* Find an option. */ 861 int 862 options_table_find( 863 const char *optstr, const struct options_table_entry **table, 864 const struct options_table_entry **oe) 865 { 866 static const struct options_table_entry *tables[] = { 867 server_options_table, 868 window_options_table, 869 session_options_table 870 }; 871 const struct options_table_entry *oe_loop; 872 u_int i; 873 874 for (i = 0; i < nitems(tables); i++) { 875 for (oe_loop = tables[i]; oe_loop->name != NULL; oe_loop++) { 876 if (strncmp(oe_loop->name, optstr, strlen(optstr)) != 0) 877 continue; 878 879 /* If already found, ambiguous. */ 880 if (*oe != NULL) 881 return (-1); 882 *oe = oe_loop; 883 *table = tables[i]; 884 885 /* Bail now if an exact match. */ 886 if (strcmp((*oe)->name, optstr) == 0) 887 break; 888 } 889 } 890 return (0); 891 } 892