mirror of
https://github.com/tmux/tmux.git
synced 2025-09-01 20:57:00 +00:00
Major tidy up and rework of options tree and set-option/show-options
commands this pushes more of the code into options.c and ties it more closely to the options table rather than having an unnecessary split. Also add support for array options (will be used later). Only (intentional) user visible change is that show-options output is now passed through vis(3) with VIS_DQ so quotes are escaped.
This commit is contained in:
@ -20,6 +20,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <vis.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
@ -30,9 +31,9 @@
|
||||
static enum cmd_retval cmd_show_options_exec(struct cmd *, struct cmdq_item *);
|
||||
|
||||
static enum cmd_retval cmd_show_options_one(struct cmd *, struct cmdq_item *,
|
||||
struct options *, int);
|
||||
struct options *);
|
||||
static enum cmd_retval cmd_show_options_all(struct cmd *, struct cmdq_item *,
|
||||
struct options *, enum options_table_scope);
|
||||
struct options *);
|
||||
|
||||
const struct cmd_entry cmd_show_options_entry = {
|
||||
.name = "show-options",
|
||||
@ -64,134 +65,106 @@ static enum cmd_retval
|
||||
cmd_show_options_exec(struct cmd *self, struct cmdq_item *item)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct session *s = item->state.tflag.s;
|
||||
struct winlink *wl = item->state.tflag.wl;
|
||||
struct cmd_find_state *fs = &item->state.tflag;
|
||||
struct options *oo;
|
||||
enum options_table_scope scope;
|
||||
int quiet;
|
||||
const char *target;
|
||||
char *cause;
|
||||
int window;
|
||||
|
||||
if (args_has(self->args, 's')) {
|
||||
oo = global_options;
|
||||
scope = OPTIONS_TABLE_SERVER;
|
||||
} else if (args_has(self->args, 'w') ||
|
||||
self->entry == &cmd_show_window_options_entry) {
|
||||
scope = OPTIONS_TABLE_WINDOW;
|
||||
if (args_has(self->args, 'g'))
|
||||
oo = global_w_options;
|
||||
else if (wl == NULL) {
|
||||
target = args_get(args, 't');
|
||||
if (target != NULL) {
|
||||
cmdq_error(item, "no such window: %s", target);
|
||||
} else
|
||||
cmdq_error(item, "no current window");
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else
|
||||
oo = wl->window->options;
|
||||
} else {
|
||||
scope = OPTIONS_TABLE_SESSION;
|
||||
if (args_has(self->args, 'g'))
|
||||
oo = global_s_options;
|
||||
else if (s == NULL) {
|
||||
target = args_get(args, 't');
|
||||
if (target != NULL) {
|
||||
cmdq_error(item, "no such session: %s", target);
|
||||
} else
|
||||
cmdq_error(item, "no current session");
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else
|
||||
oo = s->options;
|
||||
window = (self->entry == &cmd_show_window_options_entry);
|
||||
scope = options_scope_from_flags(args, window, fs, &oo, &cause);
|
||||
if (scope == OPTIONS_TABLE_NONE) {
|
||||
cmdq_error(item, "%s", cause);
|
||||
free(cause);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
quiet = args_has(self->args, 'q');
|
||||
if (args->argc == 0)
|
||||
return (cmd_show_options_all(self, item, oo, scope));
|
||||
return (cmd_show_options_all(self, item, oo));
|
||||
else
|
||||
return (cmd_show_options_one(self, item, oo, quiet));
|
||||
return (cmd_show_options_one(self, item, oo));
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_show_options_print(struct cmd *self, struct cmdq_item *item,
|
||||
struct option *o, int idx)
|
||||
{
|
||||
const char *name;
|
||||
const char *value;
|
||||
char *tmp, *escaped;
|
||||
|
||||
if (idx != -1) {
|
||||
xasprintf(&tmp, "%s[%d]", options_name(o), idx);
|
||||
name = tmp;
|
||||
} else {
|
||||
tmp = NULL;
|
||||
name = options_name(o);
|
||||
}
|
||||
|
||||
value = options_tostring(o, idx);
|
||||
if (args_has(self->args, 'v'))
|
||||
cmdq_print(item, "%s", value);
|
||||
else if (options_isstring(o)) {
|
||||
stravis(&escaped, value, VIS_OCTAL|VIS_TAB|VIS_NL|VIS_DQ);
|
||||
cmdq_print(item, "%s \"%s\"", name, escaped);
|
||||
free(escaped);
|
||||
} else
|
||||
cmdq_print(item, "%s %s", name, value);
|
||||
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
static enum cmd_retval
|
||||
cmd_show_options_one(struct cmd *self, struct cmdq_item *item,
|
||||
struct options *oo, int quiet)
|
||||
struct options *oo)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
const char *name = args->argv[0];
|
||||
const struct options_table_entry *oe;
|
||||
struct options_entry *o;
|
||||
const char *optval;
|
||||
struct args *args = self->args;
|
||||
struct option *o;
|
||||
int idx, ambiguous;
|
||||
const char *name = args->argv[0];
|
||||
|
||||
retry:
|
||||
if (*name == '@') {
|
||||
if ((o = options_find1(oo, name)) == NULL) {
|
||||
if (quiet)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
cmdq_error(item, "unknown option: %s", name);
|
||||
o = options_match_get(oo, name, &idx, 1, &ambiguous);
|
||||
if (o == NULL) {
|
||||
if (args_has(args, 'q'))
|
||||
return (CMD_RETURN_NORMAL);
|
||||
if (ambiguous) {
|
||||
cmdq_error(item, "ambiguous option: %s", name);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (args_has(self->args, 'v'))
|
||||
cmdq_print(item, "%s", o->str);
|
||||
else
|
||||
cmdq_print(item, "%s \"%s\"", o->name, o->str);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
oe = NULL;
|
||||
if (options_table_find(name, &oe) != 0) {
|
||||
cmdq_error(item, "ambiguous option: %s", name);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (oe == NULL) {
|
||||
if (quiet)
|
||||
if (options_match_get(oo, name, &idx, 0, &ambiguous) != NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
cmdq_error(item, "unknown option: %s", name);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (oe->style != NULL) {
|
||||
name = oe->style;
|
||||
goto retry;
|
||||
}
|
||||
if ((o = options_find1(oo, oe->name)) == NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
optval = options_table_print_entry(oe, o, args_has(self->args, 'v'));
|
||||
if (args_has(self->args, 'v'))
|
||||
cmdq_print(item, "%s", optval);
|
||||
else
|
||||
cmdq_print(item, "%s %s", oe->name, optval);
|
||||
cmd_show_options_print(self, item, o, idx);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
static enum cmd_retval
|
||||
cmd_show_options_all(struct cmd *self, struct cmdq_item *item,
|
||||
struct options *oo, enum options_table_scope scope)
|
||||
struct options *oo)
|
||||
{
|
||||
const struct options_table_entry *oe;
|
||||
struct options_entry *o;
|
||||
const char *optval;
|
||||
int vflag;
|
||||
struct option *o;
|
||||
const struct options_table_entry *oe;
|
||||
u_int size, idx;
|
||||
|
||||
o = options_first(oo);
|
||||
while (o != NULL) {
|
||||
if (*o->name == '@') {
|
||||
if (args_has(self->args, 'v'))
|
||||
cmdq_print(item, "%s", o->str);
|
||||
else
|
||||
cmdq_print(item, "%s \"%s\"", o->name, o->str);
|
||||
oe = options_table_entry(o);
|
||||
if (oe != NULL && oe->style != NULL) {
|
||||
o = options_next(o);
|
||||
continue;
|
||||
}
|
||||
if (options_array_size(o, &size) == -1)
|
||||
cmd_show_options_print(self, item, o, -1);
|
||||
else {
|
||||
for (idx = 0; idx < size; idx++) {
|
||||
if (options_array_get(o, idx) == NULL)
|
||||
continue;
|
||||
cmd_show_options_print(self, item, o, idx);
|
||||
}
|
||||
}
|
||||
o = options_next(o);
|
||||
}
|
||||
|
||||
vflag = args_has(self->args, 'v');
|
||||
for (oe = options_table; oe->name != NULL; oe++) {
|
||||
if (oe->style != NULL || oe->scope != scope)
|
||||
continue;
|
||||
if ((o = options_find1(oo, oe->name)) == NULL)
|
||||
continue;
|
||||
optval = options_table_print_entry(oe, o, vflag);
|
||||
if (vflag)
|
||||
cmdq_print(item, "%s", optval);
|
||||
else
|
||||
cmdq_print(item, "%s %s", oe->name, optval);
|
||||
}
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
Reference in New Issue
Block a user