Options and hooks updates.

This commit is contained in:
Nicholas Marriott
2026-06-30 17:57:38 +01:00
parent c92720e3b0
commit b3bb8bbd9f
8 changed files with 53 additions and 102 deletions

View File

@@ -100,8 +100,7 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
cdata->confirm_key = confirm_key[0];
else {
cmdq_error(item, "invalid confirm key");
cmd_parse_free(cdata->tree);
free(cdata);
cmd_confirm_before_free(cdata);
return (CMD_RETURN_ERROR);
}
}

View File

@@ -791,12 +791,10 @@ cmd_parse_add_ref(struct cmd_parse_tree *tree)
void
cmd_parse_free(struct cmd_parse_tree *tree)
{
if (tree == NULL)
return;
if (--tree->references != 0)
return;
if (tree != NULL && --tree->references == 0) {
cmd_parse_free_node(tree->root);
free(tree);
}
}
struct cmd_parse_node *

View File

@@ -369,7 +369,7 @@ cmdq_insert_hook(struct session *s, struct cmdq_item *item,
struct cmdq_state *new_state;
struct options_entry *o;
struct options_array_item *a;
struct cmd_list *cmdlist;
struct cmd_parse_tree *tree;
if (item->state->flags & CMDQ_STATE_NOHOOKS)
return;
@@ -429,9 +429,9 @@ cmdq_insert_hook(struct session *s, struct cmdq_item *item,
a = options_array_first(o);
while (a != NULL) {
cmdlist = options_array_item_value(a)->cmdlist;
if (cmdlist != NULL) {
new_item = cmdq_get_command(cmdlist, new_state);
tree = options_array_item_value(a)->cmd;
if (tree != NULL) {
new_item = cmd_invoke_get(tree, new_state, NULL);
if (item != NULL)
item = cmdq_insert_after(item, new_item);
else

View File

@@ -37,19 +37,19 @@ struct notify_entry {
static struct cmdq_item *
notify_insert_one_hook(struct cmdq_item *item, struct notify_entry *ne,
struct cmd_list *cmdlist, struct cmdq_state *state)
struct cmd_parse_tree *tree, struct cmdq_state *state)
{
struct cmdq_item *new_item;
char *s;
if (cmdlist == NULL)
if (tree == NULL)
return (item);
if (log_get_level() != 0) {
s = cmd_list_print(cmdlist, 0);
s = cmd_parse_print(tree);
log_debug("%s: hook %s is: %s", __func__, ne->name, s);
free(s);
}
new_item = cmdq_get_command(cmdlist, state);
new_item = cmd_invoke_get(tree, state, NULL);
return (cmdq_insert_after(item, new_item));
}
@@ -61,7 +61,7 @@ notify_insert_hook(struct cmdq_item *item, struct notify_entry *ne)
struct cmdq_state *state;
struct options_entry *o;
struct options_array_item *a;
struct cmd_list *cmdlist;
struct cmd_parse_tree *tree;
log_debug("%s: inserting hook %s", __func__, ne->name);
@@ -116,8 +116,8 @@ notify_insert_hook(struct cmdq_item *item, struct notify_entry *ne)
} else {
a = options_array_first(o);
while (a != NULL) {
cmdlist = options_array_item_value(a)->cmdlist;
item = notify_insert_one_hook(item, ne, cmdlist, state);
tree = options_array_item_value(a)->cmd;
item = notify_insert_one_hook(item, ne, tree, state);
a = options_array_next(a);
}
}

View File

@@ -125,8 +125,8 @@ options_value_free(struct options_entry *o, union options_value *ov)
{
if (OPTIONS_IS_STRING(o))
free(ov->string);
if (OPTIONS_IS_COMMAND(o) && ov->cmdlist != NULL)
cmd_list_free(ov->cmdlist);
if (OPTIONS_IS_COMMAND(o))
cmd_parse_free(ov->cmd);
}
static char *
@@ -136,7 +136,7 @@ options_value_to_string(struct options_entry *o, union options_value *ov,
char *s;
if (OPTIONS_IS_COMMAND(o))
return (cmd_list_print(ov->cmdlist, 0));
return (cmd_parse_print(ov->cmd));
if (OPTIONS_IS_NUMBER(o)) {
switch (o->tableentry->type) {
case OPTIONS_TABLE_NUMBER:
@@ -259,6 +259,7 @@ options_default(struct options *oo, const struct options_table_entry *oe)
{
struct options_entry *o;
union options_value *ov;
char *error = NULL;
u_int i;
o = options_empty(oo, oe);
@@ -279,22 +280,9 @@ options_default(struct options *oo, const struct options_table_entry *oe)
ov->string = xstrdup(oe->default_str);
break;
case OPTIONS_TABLE_COMMAND:
#if 0 /* XXX: command parser conversion */
struct cmd_parse_result *pr;
pr = cmd_parse_from_string(oe->default_str, NULL);
switch (pr->status) {
case CMD_PARSE_ERROR:
free(pr->error);
break;
case CMD_PARSE_SUCCESS:
ov->cmdlist = pr->cmdlist;
break;
}
#else
log_debug("XXX: command parser conversion not done for command option default %s",
oe->name);
#endif
ov->cmd = cmd_parse_from_string(oe->default_str, NULL, &error);
if (ov->cmd == NULL)
fatalx("bad default option %s", oe->name);
break;
default:
ov->number = oe->default_num;
@@ -443,6 +431,8 @@ options_array_set(struct options_entry *o, u_int idx, const char *value,
struct options_array_item *a;
char *new;
long long number;
struct cmd_parse_tree *tree;
char *error = NULL;
if (!OPTIONS_IS_ARRAY(o)) {
if (cause != NULL)
@@ -458,19 +448,13 @@ options_array_set(struct options_entry *o, u_int idx, const char *value,
}
if (OPTIONS_IS_COMMAND(o)) {
#if 0 /* XXX: command parser conversion */
struct cmd_parse_result *pr;
pr = cmd_parse_from_string(value, NULL);
switch (pr->status) {
case CMD_PARSE_ERROR:
tree = cmd_parse_from_string(value, NULL, &error);
if (tree == NULL) {
if (cause != NULL)
*cause = pr->error;
*cause = error;
else
free(pr->error);
free(error);
return (-1);
case CMD_PARSE_SUCCESS:
break;
}
a = options_array_item(o, idx);
@@ -478,15 +462,8 @@ options_array_set(struct options_entry *o, u_int idx, const char *value,
a = options_array_new(o, idx);
else
options_value_free(o, &a->value);
a->value.cmdlist = pr->cmdlist;
a->value.cmd = tree;
return (0);
#else
if (cause != NULL) {
xasprintf(cause,
"XXX: command parser conversion not done for command option array");
}
return (-1);
#endif
}
if (OPTIONS_IS_STRING(o)) {
@@ -776,7 +753,7 @@ options_get_number(struct options *oo, const char *name)
return (o->value.number);
}
struct cmd_list *
struct cmd_parse_tree *
options_get_command(struct options *oo, const char *name)
{
struct options_entry *o;
@@ -786,7 +763,7 @@ options_get_command(struct options *oo, const char *name)
fatalx("missing option %s", name);
if (!OPTIONS_IS_COMMAND(o))
fatalx("option %s is not a command", name);
return (o->value.cmdlist);
return (o->value.cmd);
}
struct options_entry *
@@ -852,7 +829,7 @@ options_set_number(struct options *oo, const char *name, long long value)
struct options_entry *
options_set_command(struct options *oo, const char *name,
struct cmd_list *value)
struct cmd_parse_tree *value)
{
struct options_entry *o;
@@ -868,9 +845,8 @@ options_set_command(struct options *oo, const char *name,
if (!OPTIONS_IS_COMMAND(o))
fatalx("option %s is not a command", name);
if (o->value.cmdlist != NULL)
cmd_list_free(o->value.cmdlist);
o->value.cmdlist = value;
cmd_parse_free(o->value.cmd);
o->value.cmd = cmd_parse_add_ref(value);
return (o);
}
@@ -1146,6 +1122,8 @@ options_from_string(struct options *oo, const struct options_table_entry *oe,
const char *errstr, *new;
char *old;
key_code key;
struct cmd_parse_tree *tree;
struct cmd_parse_input pi = { 0 };
if (oe != NULL) {
if (value == NULL &&
@@ -1203,25 +1181,14 @@ options_from_string(struct options *oo, const struct options_table_entry *oe,
return (options_from_string_flag(oo, name, value, cause));
case OPTIONS_TABLE_CHOICE:
return (options_from_string_choice(oe, oo, name, value, cause));
case OPTIONS_TABLE_COMMAND:
#if 0 /* XXX: command parser conversion */
struct cmd_parse_result *pr;
pr = cmd_parse_from_string(value, NULL);
switch (pr->status) {
case CMD_PARSE_ERROR:
*cause = pr->error;
case OPTIONS_TABLE_COMMAND: {
tree = cmd_parse_from_string(value, &pi, cause);
if (tree == NULL)
return (-1);
case CMD_PARSE_SUCCESS:
options_set_command(oo, name, pr->cmdlist);
options_set_command(oo, name, tree);
cmd_parse_free(tree);
return (0);
}
break;
#else
xasprintf(cause,
"XXX: command parser conversion not done for command option");
return (-1);
#endif
}
return (-1);
}

View File

@@ -2527,28 +2527,15 @@ bad:
proc_kill_peer(c->peer);
}
/* Callback when command is not allowed. */
static enum cmd_retval
server_client_read_only(struct cmdq_item *item, __unused void *data)
{
cmdq_error(item, "client is read-only");
return (CMD_RETURN_ERROR);
}
/* Callback for default command. */
static enum cmd_retval
server_client_default_command(struct cmdq_item *item, __unused void *data)
{
struct client *c = cmdq_get_client(item);
struct cmd_list *cmdlist;
struct cmd_parse_tree *tree;
struct cmdq_item *new_item;
cmdlist = options_get_command(global_options, "default-client-command");
if ((c->flags & CLIENT_READONLY) &&
!cmd_list_all_have(cmdlist, CMD_READONLY))
new_item = cmdq_get_callback(server_client_read_only, NULL);
else
new_item = cmdq_get_command(cmdlist, NULL);
tree = options_get_command(global_options, "default-client-command");
new_item = cmd_invoke_get(tree, NULL, NULL);
cmdq_insert_after(item, new_item);
return (CMD_RETURN_NORMAL);
}

View File

@@ -43,9 +43,9 @@ struct args_value;
struct cmd_parse_input {
int flags;
#define CMD_PARSE_QUIET 0x1
#define CMD_PARSE_PARSEONLY 0x2 /* XXX */
#define CMD_PARSE_NOALIAS 0x4 /* XXX */
#define CMD_PARSE_VERBOSE 0x8 /* XXX */
#define CMD_PARSE_PARSEONLY 0x2
#define CMD_PARSE_NOALIAS 0x4
#define CMD_PARSE_VERBOSE 0x8
#define CMD_PARSE_ONEGROUP 0x10
const char *file;

6
tmux.h
View File

@@ -2340,7 +2340,7 @@ union options_value {
long long number;
struct style style;
struct options_array array;
struct cmd_list *cmdlist;
struct cmd_parse_tree *cmd;
};
/* Option table entries. */
@@ -2673,13 +2673,13 @@ struct options_entry *options_match_get(struct options *, const char *, int *,
int, int *);
const char *options_get_string(struct options *, const char *);
long long options_get_number(struct options *, const char *);
struct cmd_list *options_get_command(struct options *, const char *);
struct cmd_parse_tree *options_get_command(struct options *, const char *);
struct options_entry * printflike(4, 5) options_set_string(struct options *,
const char *, int, const char *, ...);
struct options_entry *options_set_number(struct options *, const char *,
long long);
struct options_entry *options_set_command(struct options *, const char *,
struct cmd_list *);
struct cmd_parse_tree *);
int options_scope_from_name(struct args *, int,
const char *, struct cmd_find_state *, struct options **,
char **);