mirror of
https://github.com/tmux/tmux.git
synced 2024-12-14 10:58:48 +00:00
Merge branch 'obsd-master' into master
This commit is contained in:
commit
84955e3d62
251
cmd-parse.y
251
cmd-parse.y
@ -60,9 +60,6 @@ struct cmd_parse_command {
|
|||||||
u_int line;
|
u_int line;
|
||||||
struct cmd_parse_arguments arguments;
|
struct cmd_parse_arguments arguments;
|
||||||
|
|
||||||
int argc;
|
|
||||||
char **argv;
|
|
||||||
|
|
||||||
TAILQ_ENTRY(cmd_parse_command) entry;
|
TAILQ_ENTRY(cmd_parse_command) entry;
|
||||||
};
|
};
|
||||||
TAILQ_HEAD(cmd_parse_commands, cmd_parse_command);
|
TAILQ_HEAD(cmd_parse_commands, cmd_parse_command);
|
||||||
@ -92,10 +89,10 @@ static char *cmd_parse_get_error(const char *, u_int, const char *);
|
|||||||
static void cmd_parse_free_command(struct cmd_parse_command *);
|
static void cmd_parse_free_command(struct cmd_parse_command *);
|
||||||
static struct cmd_parse_commands *cmd_parse_new_commands(void);
|
static struct cmd_parse_commands *cmd_parse_new_commands(void);
|
||||||
static void cmd_parse_free_commands(struct cmd_parse_commands *);
|
static void cmd_parse_free_commands(struct cmd_parse_commands *);
|
||||||
static char *cmd_parse_commands_to_string(struct cmd_parse_commands *);
|
static void cmd_parse_build_commands(struct cmd_parse_commands *,
|
||||||
static void cmd_parse_print_commands(struct cmd_parse_input *, u_int,
|
struct cmd_parse_input *, struct cmd_parse_result *);
|
||||||
|
static void cmd_parse_print_commands(struct cmd_parse_input *,
|
||||||
struct cmd_list *);
|
struct cmd_list *);
|
||||||
static void cmd_parse_flatten_command(struct cmd_parse_command *);
|
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
@ -587,27 +584,23 @@ cmd_parse_get_error(const char *file, u_int line, const char *error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd_parse_print_commands(struct cmd_parse_input *pi, u_int line,
|
cmd_parse_print_commands(struct cmd_parse_input *pi, struct cmd_list *cmdlist)
|
||||||
struct cmd_list *cmdlist)
|
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
if (pi->item != NULL && (pi->flags & CMD_PARSE_VERBOSE)) {
|
if (pi->item == NULL || (~pi->flags & CMD_PARSE_VERBOSE))
|
||||||
|
return;
|
||||||
s = cmd_list_print(cmdlist, 0);
|
s = cmd_list_print(cmdlist, 0);
|
||||||
if (pi->file != NULL)
|
if (pi->file != NULL)
|
||||||
cmdq_print(pi->item, "%s:%u: %s", pi->file, line, s);
|
cmdq_print(pi->item, "%s:%u: %s", pi->file, pi->line, s);
|
||||||
else
|
else
|
||||||
cmdq_print(pi->item, "%u: %s", line, s);
|
cmdq_print(pi->item, "%u: %s", pi->line, s);
|
||||||
free(s);
|
free(s);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd_parse_free_arguments(struct cmd_parse_arguments *args)
|
cmd_parse_free_argument(struct cmd_parse_argument *arg)
|
||||||
{
|
{
|
||||||
struct cmd_parse_argument *arg, *arg1;
|
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(arg, args, entry, arg1) {
|
|
||||||
switch (arg->type) {
|
switch (arg->type) {
|
||||||
case CMD_PARSE_STRING:
|
case CMD_PARSE_STRING:
|
||||||
free(arg->string);
|
free(arg->string);
|
||||||
@ -616,15 +609,23 @@ cmd_parse_free_arguments(struct cmd_parse_arguments *args)
|
|||||||
cmd_parse_free_commands(arg->commands);
|
cmd_parse_free_commands(arg->commands);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
TAILQ_REMOVE(args, arg, entry);
|
|
||||||
free(arg);
|
free(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_parse_free_arguments(struct cmd_parse_arguments *args)
|
||||||
|
{
|
||||||
|
struct cmd_parse_argument *arg, *arg1;
|
||||||
|
|
||||||
|
TAILQ_FOREACH_SAFE(arg, args, entry, arg1) {
|
||||||
|
TAILQ_REMOVE(args, arg, entry);
|
||||||
|
cmd_parse_free_argument(arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmd_parse_free_command(struct cmd_parse_command *cmd)
|
cmd_parse_free_command(struct cmd_parse_command *cmd)
|
||||||
{
|
{
|
||||||
cmd_free_argv(cmd->argc, cmd->argv);
|
|
||||||
cmd_parse_free_arguments(&cmd->arguments);
|
cmd_parse_free_arguments(&cmd->arguments);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
}
|
}
|
||||||
@ -729,144 +730,120 @@ cmd_parse_log_commands(struct cmd_parse_commands *cmds, const char *prefix)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static int
|
||||||
cmd_parse_commands_to_string(struct cmd_parse_commands *cmds)
|
cmd_parse_expand_alias(struct cmd_parse_command *cmd,
|
||||||
|
struct cmd_parse_input *pi, struct cmd_parse_result *pr,
|
||||||
|
struct cmd_list **cmdlist)
|
||||||
{
|
{
|
||||||
struct cmd_parse_command *cmd;
|
struct cmd_parse_argument *arg, *arg1, *first, *after;
|
||||||
char *string = NULL, *s, *line;
|
struct cmd_parse_commands *cmds;
|
||||||
|
struct cmd_parse_command *last;
|
||||||
|
char *alias, *name, *cause;
|
||||||
|
|
||||||
TAILQ_FOREACH(cmd, cmds, entry) {
|
*cmdlist = NULL;
|
||||||
cmd_parse_flatten_command(cmd);
|
|
||||||
|
|
||||||
line = cmd_stringify_argv(cmd->argc, cmd->argv);
|
first = TAILQ_FIRST(&cmd->arguments);
|
||||||
if (string == NULL)
|
if (first == NULL || first->type != CMD_PARSE_STRING) {
|
||||||
s = line;
|
pr->status = CMD_PARSE_EMPTY;
|
||||||
else {
|
return (1);
|
||||||
xasprintf(&s, "%s ; %s", s, line);
|
}
|
||||||
free(line);
|
name = first->string;
|
||||||
|
|
||||||
|
alias = cmd_get_alias(name);
|
||||||
|
if (alias == NULL)
|
||||||
|
return (0);
|
||||||
|
log_debug("%s: %u alias %s = %s", __func__, pi->line, name, alias);
|
||||||
|
|
||||||
|
cmds = cmd_parse_do_buffer(alias, strlen(alias), pi, &cause);
|
||||||
|
free(alias);
|
||||||
|
if (cmds == NULL) {
|
||||||
|
pr->status = CMD_PARSE_ERROR;
|
||||||
|
pr->error = cause;
|
||||||
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(string);
|
last = TAILQ_LAST(cmds, cmd_parse_commands);
|
||||||
string = s;
|
if (last == NULL) {
|
||||||
|
*cmdlist = cmd_list_new();
|
||||||
|
return (1);
|
||||||
}
|
}
|
||||||
if (string == NULL)
|
|
||||||
string = xstrdup("");
|
TAILQ_REMOVE(&cmd->arguments, first, entry);
|
||||||
log_debug("%s: %s", __func__, string);
|
cmd_parse_free_argument(first);
|
||||||
return (string);
|
|
||||||
|
after = TAILQ_NEXT(TAILQ_FIRST(&last->arguments), entry);
|
||||||
|
TAILQ_FOREACH_SAFE(arg, &cmd->arguments, entry, arg1) {
|
||||||
|
TAILQ_REMOVE(&cmd->arguments, arg, entry);
|
||||||
|
if (after == NULL)
|
||||||
|
TAILQ_INSERT_TAIL(&last->arguments, arg, entry);
|
||||||
|
else
|
||||||
|
TAILQ_INSERT_AFTER(&last->arguments, after, arg, entry);
|
||||||
|
after = arg;
|
||||||
|
}
|
||||||
|
cmd_parse_log_commands(cmds, __func__);
|
||||||
|
|
||||||
|
cmd_parse_build_commands(cmds, pi, pr);
|
||||||
|
if (pr->status != CMD_PARSE_SUCCESS)
|
||||||
|
*cmdlist = pr->cmdlist;
|
||||||
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static struct cmd_list *
|
||||||
cmd_parse_flatten_command(struct cmd_parse_command *cmd)
|
cmd_parse_build_command(struct cmd_parse_command *cmd,
|
||||||
|
struct cmd_parse_input *pi, struct cmd_parse_result *pr)
|
||||||
{
|
{
|
||||||
struct cmd_parse_argument *arg;
|
struct cmd_parse_argument *arg;
|
||||||
char *s;
|
struct cmd_list *cmdlist;
|
||||||
|
struct cmd *add;
|
||||||
|
char *s, **argv = NULL, *cause;
|
||||||
|
int argc = 0;
|
||||||
|
|
||||||
cmd->argc = 0;
|
if (cmd_parse_expand_alias(cmd, pi, pr, &cmdlist))
|
||||||
cmd->argv = NULL;
|
return (cmdlist);
|
||||||
|
|
||||||
TAILQ_FOREACH(arg, &cmd->arguments, entry) {
|
TAILQ_FOREACH(arg, &cmd->arguments, entry) {
|
||||||
switch (arg->type) {
|
switch (arg->type) {
|
||||||
case CMD_PARSE_STRING:
|
case CMD_PARSE_STRING:
|
||||||
cmd_append_argv(&cmd->argc, &cmd->argv, arg->string);
|
cmd_append_argv(&argc, &argv, arg->string);
|
||||||
break;
|
break;
|
||||||
case CMD_PARSE_COMMANDS:
|
case CMD_PARSE_COMMANDS:
|
||||||
s = cmd_parse_commands_to_string(arg->commands);
|
cmd_parse_build_commands(arg->commands, pi, pr);
|
||||||
cmd_append_argv(&cmd->argc, &cmd->argv, s);
|
if (pr->status != CMD_PARSE_SUCCESS)
|
||||||
|
return (NULL);
|
||||||
|
s = cmd_list_print(pr->cmdlist, 0);
|
||||||
|
cmd_append_argv(&argc, &argv, s);
|
||||||
free(s);
|
free(s);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static struct cmd *
|
add = cmd_parse(argc, argv, pi->file, pi->line, &cause);
|
||||||
cmd_parse_build_command(struct cmd_parse_command *cmd,
|
|
||||||
struct cmd_parse_input *pi, u_int line, struct cmd_parse_result *pr)
|
|
||||||
{
|
|
||||||
struct cmd *add;
|
|
||||||
char *cause;
|
|
||||||
|
|
||||||
add = cmd_parse(cmd->argc, cmd->argv, pi->file, line, &cause);
|
|
||||||
if (add == NULL) {
|
if (add == NULL) {
|
||||||
pr->status = CMD_PARSE_ERROR;
|
pr->status = CMD_PARSE_ERROR;
|
||||||
pr->error = cmd_parse_get_error(pi->file, line, cause);
|
pr->error = cmd_parse_get_error(pi->file, pi->line, cause);
|
||||||
free(cause);
|
free(cause);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
return (add);
|
cmdlist = cmd_list_new();
|
||||||
|
cmd_list_append(cmdlist, add);
|
||||||
|
return (cmdlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct cmd_parse_result *
|
static void
|
||||||
cmd_parse_build_commands(struct cmd_parse_commands *cmds,
|
cmd_parse_build_commands(struct cmd_parse_commands *cmds,
|
||||||
struct cmd_parse_input *pi)
|
struct cmd_parse_input *pi, struct cmd_parse_result *pr)
|
||||||
{
|
{
|
||||||
static struct cmd_parse_result pr;
|
struct cmd_parse_command *cmd;
|
||||||
struct cmd_parse_commands *cmds2;
|
|
||||||
struct cmd_parse_command *cmd, *cmd2, *next, *next2, *after;
|
|
||||||
u_int line = UINT_MAX;
|
u_int line = UINT_MAX;
|
||||||
int i;
|
struct cmd_list *current = NULL, *result, *add;
|
||||||
struct cmd_list *current = NULL, *result;
|
char *s;
|
||||||
struct cmd *add;
|
|
||||||
char *name, *alias, *cause, *s;
|
|
||||||
|
|
||||||
/* Check for an empty list. */
|
/* Check for an empty list. */
|
||||||
if (TAILQ_EMPTY(cmds)) {
|
if (TAILQ_EMPTY(cmds)) {
|
||||||
cmd_parse_free_commands(cmds);
|
pr->status = CMD_PARSE_EMPTY;
|
||||||
pr.status = CMD_PARSE_EMPTY;
|
return;
|
||||||
return (&pr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Flatten command arguments. */
|
|
||||||
cmd_parse_log_commands(cmds, __func__);
|
cmd_parse_log_commands(cmds, __func__);
|
||||||
TAILQ_FOREACH(cmd, cmds, entry)
|
|
||||||
cmd_parse_flatten_command(cmd);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Walk the commands and expand any aliases. Each alias is parsed
|
|
||||||
* individually to a new command list, any trailing arguments appended
|
|
||||||
* to the last command, and all commands inserted into the original
|
|
||||||
* command list.
|
|
||||||
*/
|
|
||||||
TAILQ_FOREACH_SAFE(cmd, cmds, entry, next) {
|
|
||||||
name = cmd->argv[0];
|
|
||||||
|
|
||||||
alias = cmd_get_alias(name);
|
|
||||||
if (alias == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
line = cmd->line;
|
|
||||||
log_debug("%s: %u %s = %s", __func__, line, name, alias);
|
|
||||||
|
|
||||||
pi->line = line;
|
|
||||||
cmds2 = cmd_parse_do_buffer(alias, strlen(alias), pi, &cause);
|
|
||||||
free(alias);
|
|
||||||
if (cmds2 == NULL) {
|
|
||||||
pr.status = CMD_PARSE_ERROR;
|
|
||||||
pr.error = cause;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd2 = TAILQ_LAST(cmds2, cmd_parse_commands);
|
|
||||||
if (cmd2 == NULL) {
|
|
||||||
TAILQ_REMOVE(cmds, cmd, entry);
|
|
||||||
cmd_parse_free_command(cmd);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cmd_parse_flatten_command(cmd2);
|
|
||||||
for (i = 1; i < cmd->argc; i++)
|
|
||||||
cmd_append_argv(&cmd2->argc, &cmd2->argv, cmd->argv[i]);
|
|
||||||
|
|
||||||
after = cmd;
|
|
||||||
TAILQ_FOREACH_SAFE(cmd2, cmds2, entry, next2) {
|
|
||||||
cmd2->line = line;
|
|
||||||
TAILQ_REMOVE(cmds2, cmd2, entry);
|
|
||||||
TAILQ_INSERT_AFTER(cmds, after, cmd2, entry);
|
|
||||||
after = cmd2;
|
|
||||||
}
|
|
||||||
cmd_parse_free_commands(cmds2);
|
|
||||||
|
|
||||||
TAILQ_REMOVE(cmds, cmd, entry);
|
|
||||||
cmd_parse_free_command(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse each command into a command list. Create a new command list
|
* Parse each command into a command list. Create a new command list
|
||||||
@ -878,7 +855,7 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
|
|||||||
TAILQ_FOREACH(cmd, cmds, entry) {
|
TAILQ_FOREACH(cmd, cmds, entry) {
|
||||||
if (((~pi->flags & CMD_PARSE_ONEGROUP) && cmd->line != line)) {
|
if (((~pi->flags & CMD_PARSE_ONEGROUP) && cmd->line != line)) {
|
||||||
if (current != NULL) {
|
if (current != NULL) {
|
||||||
cmd_parse_print_commands(pi, line, current);
|
cmd_parse_print_commands(pi, current);
|
||||||
cmd_list_move(result, current);
|
cmd_list_move(result, current);
|
||||||
cmd_list_free(current);
|
cmd_list_free(current);
|
||||||
}
|
}
|
||||||
@ -886,18 +863,19 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
|
|||||||
}
|
}
|
||||||
if (current == NULL)
|
if (current == NULL)
|
||||||
current = cmd_list_new();
|
current = cmd_list_new();
|
||||||
line = cmd->line;
|
line = pi->line = cmd->line;
|
||||||
|
|
||||||
add = cmd_parse_build_command(cmd, pi, line, &pr);
|
add = cmd_parse_build_command(cmd, pi, pr);
|
||||||
if (add == NULL) {
|
if (add == NULL) {
|
||||||
cmd_list_free(result);
|
cmd_list_free(result);
|
||||||
cmd_list_free(current);
|
cmd_list_free(current);
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
cmd_list_append(current, add);
|
cmd_list_move(current, add);
|
||||||
|
cmd_list_free(add);
|
||||||
}
|
}
|
||||||
if (current != NULL) {
|
if (current != NULL) {
|
||||||
cmd_parse_print_commands(pi, line, current);
|
cmd_parse_print_commands(pi, current);
|
||||||
cmd_list_move(result, current);
|
cmd_list_move(result, current);
|
||||||
cmd_list_free(current);
|
cmd_list_free(current);
|
||||||
}
|
}
|
||||||
@ -906,13 +884,8 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
|
|||||||
log_debug("%s: %s", __func__, s);
|
log_debug("%s: %s", __func__, s);
|
||||||
free(s);
|
free(s);
|
||||||
|
|
||||||
pr.status = CMD_PARSE_SUCCESS;
|
pr->status = CMD_PARSE_SUCCESS;
|
||||||
pr.cmdlist = result;
|
pr->cmdlist = result;
|
||||||
|
|
||||||
out:
|
|
||||||
cmd_parse_free_commands(cmds);
|
|
||||||
|
|
||||||
return (&pr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cmd_parse_result *
|
struct cmd_parse_result *
|
||||||
@ -935,7 +908,10 @@ cmd_parse_from_file(FILE *f, struct cmd_parse_input *pi)
|
|||||||
pr.error = cause;
|
pr.error = cause;
|
||||||
return (&pr);
|
return (&pr);
|
||||||
}
|
}
|
||||||
return (cmd_parse_build_commands(cmds, pi));
|
cmd_parse_build_commands(cmds, pi, &pr);
|
||||||
|
cmd_parse_free_commands(cmds);
|
||||||
|
return (&pr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cmd_parse_result *
|
struct cmd_parse_result *
|
||||||
@ -1036,7 +1012,9 @@ cmd_parse_from_buffer(const void *buf, size_t len, struct cmd_parse_input *pi)
|
|||||||
pr.error = cause;
|
pr.error = cause;
|
||||||
return (&pr);
|
return (&pr);
|
||||||
}
|
}
|
||||||
return (cmd_parse_build_commands(cmds, pi));
|
cmd_parse_build_commands(cmds, pi, &pr);
|
||||||
|
cmd_parse_free_commands(cmds);
|
||||||
|
return (&pr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1066,6 +1044,7 @@ cmd_parse_add_command(struct cmd_parse_commands *cmds,
|
|||||||
struct cmd_parse_result *
|
struct cmd_parse_result *
|
||||||
cmd_parse_from_arguments(int argc, char **argv, struct cmd_parse_input *pi)
|
cmd_parse_from_arguments(int argc, char **argv, struct cmd_parse_input *pi)
|
||||||
{
|
{
|
||||||
|
static struct cmd_parse_result pr;
|
||||||
struct cmd_parse_input input;
|
struct cmd_parse_input input;
|
||||||
struct cmd_parse_commands *cmds;
|
struct cmd_parse_commands *cmds;
|
||||||
char **copy, **new_argv;
|
char **copy, **new_argv;
|
||||||
@ -1115,7 +1094,9 @@ cmd_parse_from_arguments(int argc, char **argv, struct cmd_parse_input *pi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmd_free_argv(argc, copy);
|
cmd_free_argv(argc, copy);
|
||||||
return (cmd_parse_build_commands(cmds, pi));
|
cmd_parse_build_commands(cmds, pi, &pr);
|
||||||
|
cmd_parse_free_commands(cmds);
|
||||||
|
return (&pr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int printflike(1, 2)
|
static int printflike(1, 2)
|
||||||
|
Loading…
Reference in New Issue
Block a user