Coverage Report

Created: 2025-08-26 06:15

/src/tmux/cmd-show-options.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD$ */
2
3
/*
4
 * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
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 <stdlib.h>
22
#include <string.h>
23
24
#include "tmux.h"
25
26
/*
27
 * Show options.
28
 */
29
30
static enum cmd_retval  cmd_show_options_exec(struct cmd *, struct cmdq_item *);
31
32
static void   cmd_show_options_print(struct cmd *, struct cmdq_item *,
33
          struct options_entry *, int, int);
34
static enum cmd_retval  cmd_show_options_all(struct cmd *, struct cmdq_item *,
35
          int, struct options *);
36
37
const struct cmd_entry cmd_show_options_entry = {
38
  .name = "show-options",
39
  .alias = "show",
40
41
  .args = { "AgHpqst:vw", 0, 1, NULL },
42
  .usage = "[-AgHpqsvw] " CMD_TARGET_PANE_USAGE " [option]",
43
44
  .target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL },
45
46
  .flags = CMD_AFTERHOOK,
47
  .exec = cmd_show_options_exec
48
};
49
50
const struct cmd_entry cmd_show_window_options_entry = {
51
  .name = "show-window-options",
52
  .alias = "showw",
53
54
  .args = { "gvt:", 0, 1, NULL },
55
  .usage = "[-gv] " CMD_TARGET_WINDOW_USAGE " [option]",
56
57
  .target = { 't', CMD_FIND_WINDOW, CMD_FIND_CANFAIL },
58
59
  .flags = CMD_AFTERHOOK,
60
  .exec = cmd_show_options_exec
61
};
62
63
const struct cmd_entry cmd_show_hooks_entry = {
64
  .name = "show-hooks",
65
  .alias = NULL,
66
67
  .args = { "gpt:w", 0, 1, NULL },
68
  .usage = "[-gpw] " CMD_TARGET_PANE_USAGE " [hook]",
69
70
  .target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL },
71
72
  .flags = CMD_AFTERHOOK,
73
  .exec = cmd_show_options_exec
74
};
75
76
static enum cmd_retval
77
cmd_show_options_exec(struct cmd *self, struct cmdq_item *item)
78
0
{
79
0
  struct args     *args = cmd_get_args(self);
80
0
  struct cmd_find_state   *target = cmdq_get_target(item);
81
0
  struct options      *oo;
82
0
  char        *argument, *name = NULL, *cause;
83
0
  int        window, idx, ambiguous, parent, scope;
84
0
  struct options_entry    *o;
85
86
0
  window = (cmd_get_entry(self) == &cmd_show_window_options_entry);
87
88
0
  if (args_count(args) == 0) {
89
0
    scope = options_scope_from_flags(args, window, target, &oo,
90
0
        &cause);
91
0
    if (scope == OPTIONS_TABLE_NONE) {
92
0
      if (args_has(args, 'q'))
93
0
        return (CMD_RETURN_NORMAL);
94
0
      cmdq_error(item, "%s", cause);
95
0
      free(cause);
96
0
      return (CMD_RETURN_ERROR);
97
0
    }
98
0
    return (cmd_show_options_all(self, item, scope, oo));
99
0
  }
100
0
  argument = format_single_from_target(item, args_string(args, 0));
101
102
0
  name = options_match(argument, &idx, &ambiguous);
103
0
  if (name == NULL) {
104
0
    if (args_has(args, 'q'))
105
0
      goto out;
106
0
    if (ambiguous)
107
0
      cmdq_error(item, "ambiguous option: %s", argument);
108
0
    else
109
0
      cmdq_error(item, "invalid option: %s", argument);
110
0
    goto fail;
111
0
  }
112
0
  scope = options_scope_from_name(args, window, name, target, &oo,
113
0
      &cause);
114
0
  if (scope == OPTIONS_TABLE_NONE) {
115
0
    if (args_has(args, 'q'))
116
0
      goto out;
117
0
    cmdq_error(item, "%s", cause);
118
0
    free(cause);
119
0
    goto fail;
120
0
  }
121
0
  o = options_get_only(oo, name);
122
0
  if (args_has(args, 'A') && o == NULL) {
123
0
    o = options_get(oo, name);
124
0
    parent = 1;
125
0
  } else
126
0
    parent = 0;
127
0
  if (o != NULL)
128
0
    cmd_show_options_print(self, item, o, idx, parent);
129
0
  else if (*name == '@') {
130
0
    if (args_has(args, 'q'))
131
0
      goto out;
132
0
    cmdq_error(item, "invalid option: %s", argument);
133
0
    goto fail;
134
0
  }
135
136
0
out:
137
0
  free(name);
138
0
  free(argument);
139
0
  return (CMD_RETURN_NORMAL);
140
141
0
fail:
142
0
  free(name);
143
0
  free(argument);
144
0
  return (CMD_RETURN_ERROR);
145
0
}
146
147
static void
148
cmd_show_options_print(struct cmd *self, struct cmdq_item *item,
149
    struct options_entry *o, int idx, int parent)
150
0
{
151
0
  struct args     *args = cmd_get_args(self);
152
0
  struct options_array_item *a;
153
0
  const char      *name = options_name(o);
154
0
  char        *value, *tmp = NULL, *escaped;
155
156
0
  if (idx != -1) {
157
0
    xasprintf(&tmp, "%s[%d]", name, idx);
158
0
    name = tmp;
159
0
  } else {
160
0
    if (options_is_array(o)) {
161
0
      a = options_array_first(o);
162
0
      if (a == NULL) {
163
0
        if (!args_has(args, 'v'))
164
0
          cmdq_print(item, "%s", name);
165
0
        return;
166
0
      }
167
0
      while (a != NULL) {
168
0
        idx = options_array_item_index(a);
169
0
        cmd_show_options_print(self, item, o, idx,
170
0
            parent);
171
0
        a = options_array_next(a);
172
0
      }
173
0
      return;
174
0
    }
175
0
  }
176
177
0
  value = options_to_string(o, idx, 0);
178
0
  if (args_has(args, 'v'))
179
0
    cmdq_print(item, "%s", value);
180
0
  else if (options_is_string(o)) {
181
0
    escaped = args_escape(value);
182
0
    if (parent)
183
0
      cmdq_print(item, "%s* %s", name, escaped);
184
0
    else
185
0
      cmdq_print(item, "%s %s", name, escaped);
186
0
    free(escaped);
187
0
  } else {
188
0
    if (parent)
189
0
      cmdq_print(item, "%s* %s", name, value);
190
0
    else
191
0
      cmdq_print(item, "%s %s", name, value);
192
0
  }
193
0
  free(value);
194
195
0
  free(tmp);
196
0
}
197
198
static enum cmd_retval
199
cmd_show_options_all(struct cmd *self, struct cmdq_item *item, int scope,
200
    struct options *oo)
201
0
{
202
0
  struct args       *args = cmd_get_args(self);
203
0
  const struct options_table_entry  *oe;
204
0
  struct options_entry      *o;
205
0
  struct options_array_item   *a;
206
0
  const char        *name;
207
0
  u_int          idx;
208
0
  int          parent;
209
210
0
  if (cmd_get_entry(self) != &cmd_show_hooks_entry) {
211
0
    o = options_first(oo);
212
0
    while (o != NULL) {
213
0
      if (options_table_entry(o) == NULL)
214
0
        cmd_show_options_print(self, item, o, -1, 0);
215
0
      o = options_next(o);
216
0
    }
217
0
  }
218
0
  for (oe = options_table; oe->name != NULL; oe++) {
219
0
    if (~oe->scope & scope)
220
0
      continue;
221
222
0
    if ((cmd_get_entry(self) != &cmd_show_hooks_entry &&
223
0
        !args_has(args, 'H') &&
224
0
        (oe->flags & OPTIONS_TABLE_IS_HOOK)) ||
225
0
        (cmd_get_entry(self) == &cmd_show_hooks_entry &&
226
0
        (~oe->flags & OPTIONS_TABLE_IS_HOOK)))
227
0
      continue;
228
229
0
    o = options_get_only(oo, oe->name);
230
0
    if (o == NULL) {
231
0
      if (!args_has(args, 'A'))
232
0
        continue;
233
0
      o = options_get(oo, oe->name);
234
0
      if (o == NULL)
235
0
        continue;
236
0
      parent = 1;
237
0
    } else
238
0
      parent = 0;
239
240
0
    if (!options_is_array(o))
241
0
      cmd_show_options_print(self, item, o, -1, parent);
242
0
    else if ((a = options_array_first(o)) == NULL) {
243
0
      if (!args_has(args, 'v')) {
244
0
        name = options_name(o);
245
0
        if (parent)
246
0
          cmdq_print(item, "%s*", name);
247
0
        else
248
0
          cmdq_print(item, "%s", name);
249
0
      }
250
0
    } else {
251
0
      while (a != NULL) {
252
0
        idx = options_array_item_index(a);
253
0
        cmd_show_options_print(self, item, o, idx,
254
0
            parent);
255
0
        a = options_array_next(a);
256
0
      }
257
0
    }
258
0
  }
259
0
  return (CMD_RETURN_NORMAL);
260
0
}