Coverage Report

Created: 2026-07-16 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tmux/cmd-show-options.c
Line
Count
Source
1
/* $OpenBSD: cmd-show-options.c,v 1.73 2026/07/10 13:38:45 nicm Exp $ */
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 *, const char *, int);
34
static void   cmd_show_hooks_print_monitor(struct cmdq_item *,
35
          struct options_entry *);
36
static enum cmd_retval  cmd_show_hooks_monitor(struct cmd *, struct cmdq_item *,
37
          int, struct options *);
38
static enum cmd_retval  cmd_show_options_all(struct cmd *, struct cmdq_item *,
39
          int, struct options *);
40
41
const struct cmd_entry cmd_show_options_entry = {
42
  .name = "show-options",
43
  .alias = "show",
44
45
  .args = { "AgHpqst:vw", 0, 1, NULL },
46
  .usage = "[-AgHpqsvw] " CMD_TARGET_PANE_USAGE " [option]",
47
48
  .target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL },
49
50
  .flags = CMD_AFTERHOOK,
51
  .exec = cmd_show_options_exec
52
};
53
54
const struct cmd_entry cmd_show_window_options_entry = {
55
  .name = "show-window-options",
56
  .alias = "showw",
57
58
  .args = { "gvt:", 0, 1, NULL },
59
  .usage = "[-gv] " CMD_TARGET_WINDOW_USAGE " [option]",
60
61
  .target = { 't', CMD_FIND_WINDOW, CMD_FIND_CANFAIL },
62
63
  .flags = CMD_AFTERHOOK,
64
  .exec = cmd_show_options_exec
65
};
66
67
const struct cmd_entry cmd_show_hooks_entry = {
68
  .name = "show-hooks",
69
  .alias = NULL,
70
71
  .args = { "Bgpt:w", 0, 1, NULL },
72
  .usage = "[-Bgpw] " CMD_TARGET_PANE_USAGE " [hook]",
73
74
  .target = { 't', CMD_FIND_PANE, CMD_FIND_CANFAIL },
75
76
  .flags = CMD_AFTERHOOK,
77
  .exec = cmd_show_options_exec
78
};
79
80
static enum cmd_retval
81
cmd_show_options_exec(struct cmd *self, struct cmdq_item *item)
82
0
{
83
0
  struct args     *args = cmd_get_args(self);
84
0
  struct cmd_find_state   *target = cmdq_get_target(item);
85
0
  struct options      *oo;
86
0
  char        *argument, *name = NULL, *cause;
87
0
  char        *array_key = NULL;
88
0
  int        window, ambiguous, parent, scope;
89
0
  struct options_entry    *o;
90
91
0
  window = (cmd_get_entry(self) == &cmd_show_window_options_entry);
92
93
0
  if (args_count(args) == 0) {
94
0
    scope = options_scope_from_flags(args, window, target, &oo,
95
0
        &cause);
96
0
    if (scope == OPTIONS_TABLE_NONE) {
97
0
      if (args_has(args, 'q'))
98
0
        return (CMD_RETURN_NORMAL);
99
0
      cmdq_error(item, "%s", cause);
100
0
      free(cause);
101
0
      return (CMD_RETURN_ERROR);
102
0
    }
103
0
    if (cmd_get_entry(self) == &cmd_show_hooks_entry &&
104
0
        args_has(args, 'B'))
105
0
      return (cmd_show_hooks_monitor(self, item, scope, oo));
106
0
    return (cmd_show_options_all(self, item, scope, oo));
107
0
  }
108
0
  argument = format_single_from_target(item, args_string(args, 0));
109
110
0
  name = options_match(argument, &array_key, &ambiguous);
111
0
  if (name == NULL) {
112
0
    if (args_has(args, 'q'))
113
0
      goto out;
114
0
    if (ambiguous)
115
0
      cmdq_error(item, "ambiguous option: %s", argument);
116
0
    else
117
0
      cmdq_error(item, "invalid option: %s", argument);
118
0
    goto fail;
119
0
  }
120
0
  scope = options_scope_from_name(args, window, name, target, &oo,
121
0
      &cause);
122
0
  if (scope == OPTIONS_TABLE_NONE) {
123
0
    if (args_has(args, 'q'))
124
0
      goto out;
125
0
    cmdq_error(item, "%s", cause);
126
0
    free(cause);
127
0
    goto fail;
128
0
  }
129
0
  o = options_get_only(oo, name);
130
0
  if (args_has(args, 'A') && o == NULL) {
131
0
    o = options_get(oo, name);
132
0
    parent = 1;
133
0
  } else
134
0
    parent = 0;
135
0
  if (o != NULL) {
136
0
    if (cmd_get_entry(self) == &cmd_show_hooks_entry &&
137
0
        args_has(args, 'B'))
138
0
      cmd_show_hooks_print_monitor(item, o);
139
0
    else
140
0
      cmd_show_options_print(self, item, o, array_key, parent);
141
0
  }
142
0
  else if (*name == '@') {
143
0
    if (args_has(args, 'q'))
144
0
      goto out;
145
0
    cmdq_error(item, "invalid option: %s", argument);
146
0
    goto fail;
147
0
  }
148
149
0
out:
150
0
  free(name);
151
0
  free(array_key);
152
0
  free(argument);
153
0
  return (CMD_RETURN_NORMAL);
154
155
0
fail:
156
0
  free(name);
157
0
  free(array_key);
158
0
  free(argument);
159
0
  return (CMD_RETURN_ERROR);
160
0
}
161
162
static void
163
cmd_show_options_print(struct cmd *self, struct cmdq_item *item,
164
    struct options_entry *o, const char *array_key, int parent)
165
0
{
166
0
  struct args     *args = cmd_get_args(self);
167
0
  struct options_array_item *a;
168
0
  const char      *name = options_name(o);
169
0
  char        *value, *tmp = NULL, *escaped;
170
171
0
  if (array_key != NULL) {
172
0
    xasprintf(&tmp, "%s[%s]", name, array_key);
173
0
    name = tmp;
174
0
  } else {
175
0
    if (options_is_array(o)) {
176
0
      a = options_array_first(o);
177
0
      if (a == NULL) {
178
0
        if (!args_has(args, 'v'))
179
0
          cmdq_print(item, "%s", name);
180
0
        return;
181
0
      }
182
0
      while (a != NULL) {
183
0
        array_key = options_array_item_key(a);
184
0
        cmd_show_options_print(self, item, o, array_key,
185
0
            parent);
186
0
        a = options_array_next(a);
187
0
      }
188
0
      return;
189
0
    }
190
0
  }
191
192
0
  value = options_to_string(o, array_key, 0);
193
0
  if (args_has(args, 'v'))
194
0
    cmdq_print(item, "%s", value);
195
0
  else if (options_is_string(o)) {
196
0
    escaped = args_escape(value);
197
0
    if (parent)
198
0
      cmdq_print(item, "%s* %s", name, escaped);
199
0
    else
200
0
      cmdq_print(item, "%s %s", name, escaped);
201
0
    free(escaped);
202
0
  } else {
203
0
    if (parent)
204
0
      cmdq_print(item, "%s* %s", name, value);
205
0
    else
206
0
      cmdq_print(item, "%s %s", name, value);
207
0
  }
208
0
  free(value);
209
210
0
  free(tmp);
211
0
}
212
213
static void
214
cmd_show_hooks_print_monitor(struct cmdq_item *item, struct options_entry *o)
215
0
{
216
0
  char  *value;
217
218
0
  value = hooks_monitor_to_string(o);
219
0
  if (value == NULL)
220
0
    return;
221
0
  cmdq_print(item, "%s", value);
222
0
  free(value);
223
0
}
224
225
/* Show all hook monitors. */
226
static enum cmd_retval
227
cmd_show_hooks_monitor(__unused struct cmd *self, struct cmdq_item *item,
228
    __unused int scope, struct options *oo)
229
0
{
230
0
  struct options_entry  *o;
231
232
0
  o = options_first(oo);
233
0
  while (o != NULL) {
234
0
    cmd_show_hooks_print_monitor(item, o);
235
0
    o = options_next(o);
236
0
  }
237
0
  return (CMD_RETURN_NORMAL);
238
0
}
239
240
static enum cmd_retval
241
cmd_show_options_all(struct cmd *self, struct cmdq_item *item, int scope,
242
    struct options *oo)
243
0
{
244
0
  struct args       *args = cmd_get_args(self);
245
0
  const struct options_table_entry  *oe;
246
0
  struct options_entry      *o;
247
0
  struct options_array_item   *a;
248
0
  const char        *name, *array_key;
249
0
  int          parent;
250
251
0
  if (cmd_get_entry(self) != &cmd_show_hooks_entry) {
252
0
    o = options_first(oo);
253
0
    while (o != NULL) {
254
0
      if (options_table_entry(o) == NULL)
255
0
        cmd_show_options_print(self, item, o, NULL, 0);
256
0
      o = options_next(o);
257
0
    }
258
0
  }
259
0
  for (oe = options_table; oe->name != NULL; oe++) {
260
0
    if (~oe->scope & scope)
261
0
      continue;
262
263
0
    if ((cmd_get_entry(self) != &cmd_show_hooks_entry &&
264
0
        !args_has(args, 'H') &&
265
0
        (oe->flags & OPTIONS_TABLE_IS_HOOK)) ||
266
0
        (cmd_get_entry(self) == &cmd_show_hooks_entry &&
267
0
        (~oe->flags & OPTIONS_TABLE_IS_HOOK)))
268
0
      continue;
269
270
0
    o = options_get_only(oo, oe->name);
271
0
    if (o == NULL) {
272
0
      if (!args_has(args, 'A'))
273
0
        continue;
274
0
      o = options_get(oo, oe->name);
275
0
      if (o == NULL)
276
0
        continue;
277
0
      parent = 1;
278
0
    } else
279
0
      parent = 0;
280
281
0
    if (!options_is_array(o))
282
0
      cmd_show_options_print(self, item, o, NULL, parent);
283
0
    else if ((a = options_array_first(o)) == NULL) {
284
0
      if (!args_has(args, 'v')) {
285
0
        name = options_name(o);
286
0
        if (parent)
287
0
          cmdq_print(item, "%s*", name);
288
0
        else
289
0
          cmdq_print(item, "%s", name);
290
0
      }
291
0
    } else {
292
0
      while (a != NULL) {
293
0
        array_key = options_array_item_key(a);
294
0
        cmd_show_options_print(self, item, o, array_key,
295
0
            parent);
296
0
        a = options_array_next(a);
297
0
      }
298
0
    }
299
0
  }
300
0
  return (CMD_RETURN_NORMAL);
301
0
}