mirror of
https://github.com/tmux/tmux.git
synced 2026-07-03 10:12:31 +00:00
Fix various problems.
This commit is contained in:
2
client.c
2
client.c
@@ -78,7 +78,7 @@ client_command_has_flag(int argc, char **argv, int flag)
|
|||||||
int found;
|
int found;
|
||||||
|
|
||||||
values = args_from_vector(argc, argv);
|
values = args_from_vector(argc, argv);
|
||||||
tree = cmd_parse_from_arguments(values, argc);
|
tree = cmd_parse_from_arguments(values, argc, NULL);
|
||||||
found = cmd_parse_any_have(tree, flag);
|
found = cmd_parse_any_have(tree, flag);
|
||||||
|
|
||||||
cmd_parse_free(tree);
|
cmd_parse_free(tree);
|
||||||
|
|||||||
@@ -56,11 +56,12 @@ cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
{
|
{
|
||||||
struct args *args = cmd_get_args(self);
|
struct args *args = cmd_get_args(self);
|
||||||
key_code key;
|
key_code key;
|
||||||
const char *tablename, *note = args_get(args, 'N');
|
const char *tablename, *note = args_get(args, 'N'), *file;
|
||||||
int repeat;
|
int repeat;
|
||||||
struct args_value *value;
|
struct args_value *value;
|
||||||
u_int count = args_count(args);
|
u_int count = args_count(args);
|
||||||
struct cmd_parse_tree *cmd;
|
struct cmd_parse_tree *cmd;
|
||||||
|
struct cmd_parse_input pi;
|
||||||
|
|
||||||
key = key_string_lookup_string(args_string(args, 0));
|
key = key_string_lookup_string(args_string(args, 0));
|
||||||
if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
|
if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
|
||||||
@@ -88,7 +89,13 @@ cmd_bind_key_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = cmd_parse_from_arguments(args_values(args) + 1, count - 1);
|
memset(&pi, 0, sizeof pi);
|
||||||
|
cmd_get_source(self, &file, &pi.line);
|
||||||
|
if (file != NULL)
|
||||||
|
pi.file = file;
|
||||||
|
pi.flags = cmd_get_parse_flags(self);
|
||||||
|
|
||||||
|
cmd = cmd_parse_from_arguments(args_values(args) + 1, count - 1, &pi);
|
||||||
key_bindings_add(tablename, key, note, repeat, cmd);
|
key_bindings_add(tablename, key, note, repeat, cmd);
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -547,7 +547,10 @@ cmd_invoke_fire(struct cmdq_item *item, struct cmd_invoke_state *is)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
cmd_invoke_error(item, is, node, cause);
|
if (cmdq_get_client(item) != NULL)
|
||||||
|
cmdq_error(item, "%s", cause);
|
||||||
|
else
|
||||||
|
cfg_add_cause("%s", cause);
|
||||||
free(cause);
|
free(cause);
|
||||||
cmd_invoke_skip_sequence(is);
|
cmd_invoke_skip_sequence(is);
|
||||||
break;
|
break;
|
||||||
|
|||||||
74
cmd-parse.y
74
cmd-parse.y
@@ -103,6 +103,7 @@ static void cmd_parse_print_sequence(char **, struct cmd_parse_node *,
|
|||||||
u_int);
|
u_int);
|
||||||
static void cmd_parse_print_item(char **, struct cmd_parse_node *, u_int,
|
static void cmd_parse_print_item(char **, struct cmd_parse_node *, u_int,
|
||||||
int);
|
int);
|
||||||
|
static char *cmd_parse_make_string(struct cmd_parse_node *);
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@@ -716,16 +717,18 @@ cmd_parse_from_node(struct cmd_parse_tree *tree, struct cmd_parse_node *node)
|
|||||||
|
|
||||||
/* Find the last command node in tree order. */
|
/* Find the last command node in tree order. */
|
||||||
static struct cmd_parse_node *
|
static struct cmd_parse_node *
|
||||||
cmd_parse_last_command(struct cmd_parse_node *node)
|
cmd_parse_last_top_level_command(struct cmd_parse_tree *tree)
|
||||||
{
|
{
|
||||||
struct cmd_parse_node *child, *last = NULL, *found;
|
struct cmd_parse_node *root, *seq, *node, *last = NULL;
|
||||||
|
|
||||||
if (node->type == CMD_PARSE_COMMAND)
|
root = cmd_parse_root(tree);
|
||||||
last = node;
|
TAILQ_FOREACH(seq, &root->children, entry) {
|
||||||
TAILQ_FOREACH(child, &node->children, entry) {
|
if (seq->type == CMD_PARSE_SEQUENCE) {
|
||||||
found = cmd_parse_last_command(child);
|
TAILQ_FOREACH(node, &seq->children, entry) {
|
||||||
if (found != NULL)
|
if (node->type == CMD_PARSE_COMMAND)
|
||||||
last = found;
|
last = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (last);
|
return (last);
|
||||||
}
|
}
|
||||||
@@ -740,8 +743,8 @@ cmd_parse_expand_alias(struct cmd_parse_tree *src, struct cmd_parse_node *cmd,
|
|||||||
{
|
{
|
||||||
struct cmd_parse_input pi;
|
struct cmd_parse_input pi;
|
||||||
struct cmd_parse_tree *tree;
|
struct cmd_parse_tree *tree;
|
||||||
struct cmd_parse_node *first, *node, *last, *loop, *copy;
|
struct cmd_parse_node *first, *last, *loop, *copy;
|
||||||
char *alias;
|
char *alias, *name;
|
||||||
|
|
||||||
*out = NULL;
|
*out = NULL;
|
||||||
*cause = NULL;
|
*cause = NULL;
|
||||||
@@ -754,15 +757,12 @@ cmd_parse_expand_alias(struct cmd_parse_tree *src, struct cmd_parse_node *cmd,
|
|||||||
first = TAILQ_FIRST(&cmd->children);
|
first = TAILQ_FIRST(&cmd->children);
|
||||||
if (first == NULL)
|
if (first == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
if (first->type != CMD_PARSE_STRING)
|
name = cmd_parse_make_string(first);
|
||||||
return (0);
|
if (name == NULL)
|
||||||
node = TAILQ_FIRST(&first->children);
|
|
||||||
if (node == NULL || TAILQ_NEXT(node, entry) != NULL)
|
|
||||||
return (0);
|
|
||||||
if (node->type != CMD_PARSE_TEXT)
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
alias = cmd_get_alias(node->value);
|
alias = cmd_get_alias(name);
|
||||||
|
free(name);
|
||||||
if (alias == NULL)
|
if (alias == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
@@ -771,12 +771,12 @@ cmd_parse_expand_alias(struct cmd_parse_tree *src, struct cmd_parse_node *cmd,
|
|||||||
pi.line = cmd_parse_node_line(cmd);
|
pi.line = cmd_parse_node_line(cmd);
|
||||||
pi.flags = cmd_parse_flags(src) | CMD_PARSE_NOALIAS;
|
pi.flags = cmd_parse_flags(src) | CMD_PARSE_NOALIAS;
|
||||||
|
|
||||||
tree = cmd_parse_from_string(alias, &pi, cause);
|
tree = cmd_parse_from_buffer(alias, strlen(alias), &pi, cause);
|
||||||
free(alias);
|
free(alias);
|
||||||
if (tree == NULL)
|
if (tree == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
|
||||||
last = cmd_parse_last_command(cmd_parse_root(tree));
|
last = cmd_parse_last_top_level_command(tree);
|
||||||
if (last != NULL) {
|
if (last != NULL) {
|
||||||
loop = TAILQ_NEXT(first, entry);
|
loop = TAILQ_NEXT(first, entry);
|
||||||
while (loop != NULL) {
|
while (loop != NULL) {
|
||||||
@@ -824,10 +824,10 @@ cmd_parse_new_commands_node(struct cmd_parse_tree *tree, u_int line)
|
|||||||
/* Add one argument to the current command, creating it if needed. */
|
/* Add one argument to the current command, creating it if needed. */
|
||||||
static void
|
static void
|
||||||
cmd_parse_from_arguments_add(struct cmd_parse_node *seq,
|
cmd_parse_from_arguments_add(struct cmd_parse_node *seq,
|
||||||
struct cmd_parse_node **cmd, struct cmd_parse_node *child)
|
struct cmd_parse_node **cmd, struct cmd_parse_node *child, u_int line)
|
||||||
{
|
{
|
||||||
if (*cmd == NULL) {
|
if (*cmd == NULL) {
|
||||||
*cmd = cmd_parse_new_node(CMD_PARSE_COMMAND, 0);
|
*cmd = cmd_parse_new_node(CMD_PARSE_COMMAND, line);
|
||||||
TAILQ_INSERT_TAIL(&seq->children, *cmd, entry);
|
TAILQ_INSERT_TAIL(&seq->children, *cmd, entry);
|
||||||
}
|
}
|
||||||
TAILQ_INSERT_TAIL(&(*cmd)->children, child, entry);
|
TAILQ_INSERT_TAIL(&(*cmd)->children, child, entry);
|
||||||
@@ -835,17 +835,22 @@ cmd_parse_from_arguments_add(struct cmd_parse_node *seq,
|
|||||||
|
|
||||||
/* Build a parse tree directly from existing argument values. */
|
/* Build a parse tree directly from existing argument values. */
|
||||||
struct cmd_parse_tree *
|
struct cmd_parse_tree *
|
||||||
cmd_parse_from_arguments(struct args_value *values, u_int count)
|
cmd_parse_from_arguments(struct args_value *values, u_int count,
|
||||||
|
struct cmd_parse_input *pi)
|
||||||
{
|
{
|
||||||
struct cmd_parse_tree *new;
|
struct cmd_parse_tree *new, *new_cmd;
|
||||||
struct cmd_parse_node *root, *seq, *cmd = NULL, *child;
|
struct cmd_parse_node *root, *seq, *cmd = NULL, *child;
|
||||||
u_int i;
|
u_int i;
|
||||||
char *copy;
|
char *copy;
|
||||||
size_t size;
|
size_t size;
|
||||||
int end;
|
int end;
|
||||||
|
u_int line = 0;
|
||||||
|
|
||||||
root = cmd_parse_new_node(CMD_PARSE_ROOT, 0);
|
if (pi != NULL)
|
||||||
seq = cmd_parse_new_node(CMD_PARSE_SEQUENCE, 0);
|
line = pi->line;
|
||||||
|
|
||||||
|
root = cmd_parse_new_node(CMD_PARSE_ROOT, line);
|
||||||
|
seq = cmd_parse_new_node(CMD_PARSE_SEQUENCE, line);
|
||||||
TAILQ_INSERT_TAIL(&root->children, seq, entry);
|
TAILQ_INSERT_TAIL(&root->children, seq, entry);
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
@@ -865,16 +870,19 @@ cmd_parse_from_arguments(struct args_value *values, u_int count)
|
|||||||
else
|
else
|
||||||
end = 1;
|
end = 1;
|
||||||
}
|
}
|
||||||
|
if (end && size == 0) {
|
||||||
if (!end || size != 0) {
|
free(copy);
|
||||||
child = cmd_parse_new_string_node(copy, 0);
|
break;
|
||||||
cmd_parse_from_arguments_add(seq, &cmd, child);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
child = cmd_parse_new_string_node(copy, line);
|
||||||
|
cmd_parse_from_arguments_add(seq, &cmd, child, line);
|
||||||
free(copy);
|
free(copy);
|
||||||
break;
|
break;
|
||||||
case ARGS_COMMANDS:
|
case ARGS_COMMANDS:
|
||||||
child = cmd_parse_new_commands_node(values[i].cmd, 0);
|
new_cmd = values[i].cmd;
|
||||||
cmd_parse_from_arguments_add(seq, &cmd, child);
|
child = cmd_parse_new_commands_node(new_cmd, line);
|
||||||
|
cmd_parse_from_arguments_add(seq, &cmd, child, line);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fatalx("unknown argument type");
|
fatalx("unknown argument type");
|
||||||
@@ -886,6 +894,10 @@ cmd_parse_from_arguments(struct args_value *values, u_int count)
|
|||||||
|
|
||||||
new = xcalloc(1, sizeof *new);
|
new = xcalloc(1, sizeof *new);
|
||||||
new->references = 1;
|
new->references = 1;
|
||||||
|
if (pi != NULL) {
|
||||||
|
new->file = pi->file != NULL ? xstrdup(pi->file) : NULL;
|
||||||
|
new->flags = (pi->flags & ~CMD_PARSE_ONEGROUP);
|
||||||
|
}
|
||||||
new->root = root;
|
new->root = root;
|
||||||
return (new);
|
return (new);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2590,7 +2590,7 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
|
|||||||
item = cmdq_get_callback(server_client_default_command, NULL);
|
item = cmdq_get_callback(server_client_default_command, NULL);
|
||||||
else {
|
else {
|
||||||
values = args_from_vector(argc, argv);
|
values = args_from_vector(argc, argv);
|
||||||
tree = cmd_parse_from_arguments(values, argc);
|
tree = cmd_parse_from_arguments(values, argc, NULL);
|
||||||
args_free_values(values, argc);
|
args_free_values(values, argc);
|
||||||
free(values);
|
free(values);
|
||||||
cmd_free_argv(argc, argv);
|
cmd_free_argv(argc, argv);
|
||||||
|
|||||||
@@ -79,10 +79,11 @@ struct cmd_parse_tree *cmd_parse_from_string(const char *,
|
|||||||
struct cmd_parse_input *, char **);
|
struct cmd_parse_input *, char **);
|
||||||
struct cmd_parse_tree *cmd_parse_from_node(struct cmd_parse_tree *,
|
struct cmd_parse_tree *cmd_parse_from_node(struct cmd_parse_tree *,
|
||||||
struct cmd_parse_node *);
|
struct cmd_parse_node *);
|
||||||
|
struct cmd_parse_tree *cmd_parse_from_arguments(struct args_value *, u_int,
|
||||||
|
struct cmd_parse_input *);
|
||||||
int cmd_parse_expand_alias(struct cmd_parse_tree *,
|
int cmd_parse_expand_alias(struct cmd_parse_tree *,
|
||||||
struct cmd_parse_node *, struct cmd_parse_tree **,
|
struct cmd_parse_node *, struct cmd_parse_tree **,
|
||||||
char **);
|
char **);
|
||||||
struct cmd_parse_tree *cmd_parse_from_arguments(struct args_value *, u_int);
|
|
||||||
struct cmd_parse_tree *cmd_parse_add_ref(struct cmd_parse_tree *);
|
struct cmd_parse_tree *cmd_parse_add_ref(struct cmd_parse_tree *);
|
||||||
int cmd_parse_any_have(struct cmd_parse_tree *, int);
|
int cmd_parse_any_have(struct cmd_parse_tree *, int);
|
||||||
void cmd_parse_free(struct cmd_parse_tree *);
|
void cmd_parse_free(struct cmd_parse_tree *);
|
||||||
|
|||||||
Reference in New Issue
Block a user