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
c587ad027f
267
cmd-parse.y
267
cmd-parse.y
@ -42,13 +42,28 @@ struct cmd_parse_scope {
|
|||||||
TAILQ_ENTRY (cmd_parse_scope) entry;
|
TAILQ_ENTRY (cmd_parse_scope) entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum cmd_parse_argument_type {
|
||||||
|
CMD_PARSE_STRING,
|
||||||
|
CMD_PARSE_COMMANDS
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cmd_parse_argument {
|
||||||
|
enum cmd_parse_argument_type type;
|
||||||
|
char *string;
|
||||||
|
struct cmd_parse_commands *commands;
|
||||||
|
|
||||||
|
TAILQ_ENTRY(cmd_parse_argument) entry;
|
||||||
|
};
|
||||||
|
TAILQ_HEAD(cmd_parse_arguments, cmd_parse_argument);
|
||||||
|
|
||||||
struct cmd_parse_command {
|
struct cmd_parse_command {
|
||||||
u_int line;
|
u_int line;
|
||||||
|
struct cmd_parse_arguments arguments;
|
||||||
|
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
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);
|
||||||
|
|
||||||
@ -80,16 +95,15 @@ static void cmd_parse_free_commands(struct cmd_parse_commands *);
|
|||||||
static char *cmd_parse_commands_to_string(struct cmd_parse_commands *);
|
static char *cmd_parse_commands_to_string(struct cmd_parse_commands *);
|
||||||
static void cmd_parse_print_commands(struct cmd_parse_input *, u_int,
|
static void cmd_parse_print_commands(struct cmd_parse_input *, u_int,
|
||||||
struct cmd_list *);
|
struct cmd_list *);
|
||||||
|
static void cmd_parse_flatten_command(struct cmd_parse_command *);
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%union
|
%union
|
||||||
{
|
{
|
||||||
char *token;
|
char *token;
|
||||||
struct {
|
struct cmd_parse_arguments *arguments;
|
||||||
int argc;
|
struct cmd_parse_argument *argument;
|
||||||
char **argv;
|
|
||||||
} arguments;
|
|
||||||
int flag;
|
int flag;
|
||||||
struct {
|
struct {
|
||||||
int flag;
|
int flag;
|
||||||
@ -107,8 +121,9 @@ static void cmd_parse_print_commands(struct cmd_parse_input *, u_int,
|
|||||||
%token ENDIF
|
%token ENDIF
|
||||||
%token <token> FORMAT TOKEN EQUALS
|
%token <token> FORMAT TOKEN EQUALS
|
||||||
|
|
||||||
%type <token> argument expanded format
|
%type <token> expanded format
|
||||||
%type <arguments> arguments
|
%type <arguments> arguments
|
||||||
|
%type <argument> argument
|
||||||
%type <flag> if_open if_elif
|
%type <flag> if_open if_elif
|
||||||
%type <elif> elif elif1
|
%type <elif> elif elif1
|
||||||
%type <commands> argument_statements statements statement
|
%type <commands> argument_statements statements statement
|
||||||
@ -360,7 +375,7 @@ commands : command
|
|||||||
struct cmd_parse_state *ps = &parse_state;
|
struct cmd_parse_state *ps = &parse_state;
|
||||||
|
|
||||||
$$ = cmd_parse_new_commands();
|
$$ = cmd_parse_new_commands();
|
||||||
if ($1->argc != 0 &&
|
if (!TAILQ_EMPTY(&$1->arguments) &&
|
||||||
(ps->scope == NULL || ps->scope->flag))
|
(ps->scope == NULL || ps->scope->flag))
|
||||||
TAILQ_INSERT_TAIL($$, $1, entry);
|
TAILQ_INSERT_TAIL($$, $1, entry);
|
||||||
else
|
else
|
||||||
@ -380,7 +395,7 @@ commands : command
|
|||||||
{
|
{
|
||||||
struct cmd_parse_state *ps = &parse_state;
|
struct cmd_parse_state *ps = &parse_state;
|
||||||
|
|
||||||
if ($3->argc != 0 &&
|
if (!TAILQ_EMPTY(&$3->arguments) &&
|
||||||
(ps->scope == NULL || ps->scope->flag)) {
|
(ps->scope == NULL || ps->scope->flag)) {
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
TAILQ_INSERT_TAIL($$, $3, entry);
|
TAILQ_INSERT_TAIL($$, $3, entry);
|
||||||
@ -401,27 +416,38 @@ command : assignment
|
|||||||
|
|
||||||
$$ = xcalloc(1, sizeof *$$);
|
$$ = xcalloc(1, sizeof *$$);
|
||||||
$$->line = ps->input->line;
|
$$->line = ps->input->line;
|
||||||
|
TAILQ_INIT(&$$->arguments);
|
||||||
}
|
}
|
||||||
| optional_assignment TOKEN
|
| optional_assignment TOKEN
|
||||||
{
|
{
|
||||||
struct cmd_parse_state *ps = &parse_state;
|
struct cmd_parse_state *ps = &parse_state;
|
||||||
|
struct cmd_parse_argument *arg;
|
||||||
|
|
||||||
$$ = xcalloc(1, sizeof *$$);
|
$$ = xcalloc(1, sizeof *$$);
|
||||||
$$->line = ps->input->line;
|
$$->line = ps->input->line;
|
||||||
|
TAILQ_INIT(&$$->arguments);
|
||||||
|
|
||||||
cmd_prepend_argv(&$$->argc, &$$->argv, $2);
|
arg = xcalloc(1, sizeof *arg);
|
||||||
|
arg->type = CMD_PARSE_STRING;
|
||||||
|
arg->string = xstrdup($2);
|
||||||
|
TAILQ_INSERT_HEAD(&$$->arguments, arg, entry);
|
||||||
}
|
}
|
||||||
| optional_assignment TOKEN arguments
|
| optional_assignment TOKEN arguments
|
||||||
{
|
{
|
||||||
struct cmd_parse_state *ps = &parse_state;
|
struct cmd_parse_state *ps = &parse_state;
|
||||||
|
struct cmd_parse_argument *arg;
|
||||||
|
|
||||||
$$ = xcalloc(1, sizeof *$$);
|
$$ = xcalloc(1, sizeof *$$);
|
||||||
$$->line = ps->input->line;
|
$$->line = ps->input->line;
|
||||||
|
TAILQ_INIT(&$$->arguments);
|
||||||
|
|
||||||
$$->argc = $3.argc;
|
TAILQ_CONCAT(&$$->arguments, $3, entry);
|
||||||
$$->argv = $3.argv;
|
free($3);
|
||||||
cmd_prepend_argv(&$$->argc, &$$->argv, $2);
|
|
||||||
|
arg = xcalloc(1, sizeof *arg);
|
||||||
|
arg->type = CMD_PARSE_STRING;
|
||||||
|
arg->string = xstrdup($2);
|
||||||
|
TAILQ_INSERT_HEAD(&$$->arguments, arg, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
condition1 : if_open commands if_close
|
condition1 : if_open commands if_close
|
||||||
@ -505,30 +531,34 @@ elif1 : if_elif commands
|
|||||||
|
|
||||||
arguments : argument
|
arguments : argument
|
||||||
{
|
{
|
||||||
$$.argc = 1;
|
$$ = xcalloc(1, sizeof *$$);
|
||||||
$$.argv = xreallocarray(NULL, 1, sizeof *$$.argv);
|
TAILQ_INIT($$);
|
||||||
|
|
||||||
$$.argv[0] = $1;
|
TAILQ_INSERT_HEAD($$, $1, entry);
|
||||||
}
|
}
|
||||||
| argument arguments
|
| argument arguments
|
||||||
{
|
{
|
||||||
cmd_prepend_argv(&$2.argc, &$2.argv, $1);
|
TAILQ_INSERT_HEAD($2, $1, entry);
|
||||||
free($1);
|
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
argument : TOKEN
|
argument : TOKEN
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = xcalloc(1, sizeof *$$);
|
||||||
|
$$->type = CMD_PARSE_STRING;
|
||||||
|
$$->string = xstrdup($1);
|
||||||
}
|
}
|
||||||
| EQUALS
|
| EQUALS
|
||||||
{
|
{
|
||||||
$$ = $1;
|
$$ = xcalloc(1, sizeof *$$);
|
||||||
|
$$->type = CMD_PARSE_STRING;
|
||||||
|
$$->string = xstrdup($1);
|
||||||
}
|
}
|
||||||
| '{' argument_statements
|
| '{' argument_statements
|
||||||
{
|
{
|
||||||
$$ = cmd_parse_commands_to_string($2);
|
$$ = xcalloc(1, sizeof *$$);
|
||||||
cmd_parse_free_commands($2);
|
$$->type = CMD_PARSE_COMMANDS;
|
||||||
|
$$->commands = $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
argument_statements : statement '}'
|
argument_statements : statement '}'
|
||||||
@ -572,10 +602,30 @@ cmd_parse_print_commands(struct cmd_parse_input *pi, u_int line,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_parse_free_arguments(struct cmd_parse_arguments *args)
|
||||||
|
{
|
||||||
|
struct cmd_parse_argument *arg, *arg1;
|
||||||
|
|
||||||
|
TAILQ_FOREACH_SAFE(arg, args, entry, arg1) {
|
||||||
|
switch (arg->type) {
|
||||||
|
case CMD_PARSE_STRING:
|
||||||
|
free(arg->string);
|
||||||
|
break;
|
||||||
|
case CMD_PARSE_COMMANDS:
|
||||||
|
cmd_parse_free_commands(arg->commands);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
TAILQ_REMOVE(args, arg, entry);
|
||||||
|
free(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_free_argv(cmd->argc, cmd->argv);
|
||||||
|
cmd_parse_free_arguments(&cmd->arguments);
|
||||||
free(cmd);
|
free(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,7 +635,7 @@ cmd_parse_new_commands(void)
|
|||||||
struct cmd_parse_commands *cmds;
|
struct cmd_parse_commands *cmds;
|
||||||
|
|
||||||
cmds = xmalloc(sizeof *cmds);
|
cmds = xmalloc(sizeof *cmds);
|
||||||
TAILQ_INIT (cmds);
|
TAILQ_INIT(cmds);
|
||||||
return (cmds);
|
return (cmds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,30 +651,6 @@ cmd_parse_free_commands(struct cmd_parse_commands *cmds)
|
|||||||
free(cmds);
|
free(cmds);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
|
||||||
cmd_parse_commands_to_string(struct cmd_parse_commands *cmds)
|
|
||||||
{
|
|
||||||
struct cmd_parse_command *cmd;
|
|
||||||
char *string = NULL, *s, *line;
|
|
||||||
|
|
||||||
TAILQ_FOREACH(cmd, cmds, entry) {
|
|
||||||
line = cmd_stringify_argv(cmd->argc, cmd->argv);
|
|
||||||
if (string == NULL)
|
|
||||||
s = line;
|
|
||||||
else {
|
|
||||||
xasprintf(&s, "%s ; %s", s, line);
|
|
||||||
free(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(string);
|
|
||||||
string = s;
|
|
||||||
}
|
|
||||||
if (string == NULL)
|
|
||||||
string = xstrdup("");
|
|
||||||
log_debug("%s: %s", __func__, string);
|
|
||||||
return (string);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct cmd_parse_commands *
|
static struct cmd_parse_commands *
|
||||||
cmd_parse_run_parser(char **cause)
|
cmd_parse_run_parser(char **cause)
|
||||||
{
|
{
|
||||||
@ -674,6 +700,84 @@ cmd_parse_do_buffer(const char *buf, size_t len, struct cmd_parse_input *pi,
|
|||||||
return (cmd_parse_run_parser(cause));
|
return (cmd_parse_run_parser(cause));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_parse_log_commands(struct cmd_parse_commands *cmds, const char *prefix)
|
||||||
|
{
|
||||||
|
struct cmd_parse_command *cmd;
|
||||||
|
struct cmd_parse_argument *arg;
|
||||||
|
u_int i, j;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
TAILQ_FOREACH(cmd, cmds, entry) {
|
||||||
|
j = 0;
|
||||||
|
TAILQ_FOREACH(arg, &cmd->arguments, entry) {
|
||||||
|
switch (arg->type) {
|
||||||
|
case CMD_PARSE_STRING:
|
||||||
|
log_debug("%s %u:%u: %s", prefix, i, j,
|
||||||
|
arg->string);
|
||||||
|
break;
|
||||||
|
case CMD_PARSE_COMMANDS:
|
||||||
|
xasprintf(&s, "%s %u:%u", prefix, i, j);
|
||||||
|
cmd_parse_log_commands(arg->commands, s);
|
||||||
|
free(s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
cmd_parse_commands_to_string(struct cmd_parse_commands *cmds)
|
||||||
|
{
|
||||||
|
struct cmd_parse_command *cmd;
|
||||||
|
char *string = NULL, *s, *line;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(cmd, cmds, entry) {
|
||||||
|
cmd_parse_flatten_command(cmd);
|
||||||
|
|
||||||
|
line = cmd_stringify_argv(cmd->argc, cmd->argv);
|
||||||
|
if (string == NULL)
|
||||||
|
s = line;
|
||||||
|
else {
|
||||||
|
xasprintf(&s, "%s ; %s", s, line);
|
||||||
|
free(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(string);
|
||||||
|
string = s;
|
||||||
|
}
|
||||||
|
if (string == NULL)
|
||||||
|
string = xstrdup("");
|
||||||
|
log_debug("%s: %s", __func__, string);
|
||||||
|
return (string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_parse_flatten_command(struct cmd_parse_command *cmd)
|
||||||
|
{
|
||||||
|
struct cmd_parse_argument *arg;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
cmd->argc = 0;
|
||||||
|
cmd->argv = NULL;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(arg, &cmd->arguments, entry) {
|
||||||
|
switch (arg->type) {
|
||||||
|
case CMD_PARSE_STRING:
|
||||||
|
cmd_append_argv(&cmd->argc, &cmd->argv, arg->string);
|
||||||
|
break;
|
||||||
|
case CMD_PARSE_COMMANDS:
|
||||||
|
s = cmd_parse_commands_to_string(arg->commands);
|
||||||
|
cmd_append_argv(&cmd->argc, &cmd->argv, s);
|
||||||
|
free(s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct cmd_parse_result *
|
static struct cmd_parse_result *
|
||||||
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)
|
||||||
@ -694,6 +798,11 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
|
|||||||
return (&pr);
|
return (&pr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Flatten command arguments. */
|
||||||
|
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
|
* Walk the commands and expand any aliases. Each alias is parsed
|
||||||
* individually to a new command list, any trailing arguments appended
|
* individually to a new command list, any trailing arguments appended
|
||||||
@ -918,12 +1027,35 @@ cmd_parse_from_buffer(const void *buf, size_t len, struct cmd_parse_input *pi)
|
|||||||
return (cmd_parse_build_commands(cmds, pi));
|
return (cmd_parse_build_commands(cmds, pi));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_parse_add_command(struct cmd_parse_commands *cmds,
|
||||||
|
struct cmd_parse_input *pi, int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct cmd_parse_command *cmd;
|
||||||
|
struct cmd_parse_argument *arg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
cmd_log_argv(argc, argv, "%s", __func__);
|
||||||
|
|
||||||
|
cmd = xcalloc(1, sizeof *cmd);
|
||||||
|
cmd->line = pi->line;
|
||||||
|
|
||||||
|
TAILQ_INIT(&cmd->arguments);
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
arg = xcalloc(1, sizeof *arg);
|
||||||
|
arg->type = CMD_PARSE_STRING;
|
||||||
|
arg->string = xstrdup(argv[i]);
|
||||||
|
TAILQ_INSERT_TAIL(&cmd->arguments, arg, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
TAILQ_INSERT_TAIL(cmds, cmd, entry);
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
struct cmd_parse_input input;
|
struct cmd_parse_input input;
|
||||||
struct cmd_parse_commands *cmds;
|
struct cmd_parse_commands *cmds;
|
||||||
struct cmd_parse_command *cmd;
|
|
||||||
char **copy, **new_argv;
|
char **copy, **new_argv;
|
||||||
size_t size;
|
size_t size;
|
||||||
int i, last, new_argc;
|
int i, last, new_argc;
|
||||||
@ -958,37 +1090,16 @@ cmd_parse_from_arguments(int argc, char **argv, struct cmd_parse_input *pi)
|
|||||||
if (size != 0)
|
if (size != 0)
|
||||||
new_argc++;
|
new_argc++;
|
||||||
|
|
||||||
if (new_argc != 0) {
|
if (new_argc != 0)
|
||||||
cmd_log_argv(new_argc, new_argv, "%s: at %u", __func__,
|
cmd_parse_add_command(cmds, pi, new_argc, new_argv);
|
||||||
i);
|
|
||||||
|
|
||||||
cmd = xcalloc(1, sizeof *cmd);
|
|
||||||
cmd->line = pi->line;
|
|
||||||
|
|
||||||
cmd->argc = new_argc;
|
|
||||||
cmd->argv = cmd_copy_argv(new_argc, new_argv);
|
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(cmds, cmd, entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
last = i + 1;
|
last = i + 1;
|
||||||
}
|
}
|
||||||
if (last != argc) {
|
if (last != argc) {
|
||||||
new_argv = copy + last;
|
new_argv = copy + last;
|
||||||
new_argc = argc - last;
|
new_argc = argc - last;
|
||||||
|
|
||||||
if (new_argc != 0) {
|
if (new_argc != 0)
|
||||||
cmd_log_argv(new_argc, new_argv, "%s: at %u", __func__,
|
cmd_parse_add_command(cmds, pi, new_argc, new_argv);
|
||||||
last);
|
|
||||||
|
|
||||||
cmd = xcalloc(1, sizeof *cmd);
|
|
||||||
cmd->line = pi->line;
|
|
||||||
|
|
||||||
cmd->argc = new_argc;
|
|
||||||
cmd->argv = cmd_copy_argv(new_argc, new_argv);
|
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(cmds, cmd, entry);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_free_argv(argc, copy);
|
cmd_free_argv(argc, copy);
|
||||||
|
Loading…
Reference in New Issue
Block a user