Merge branch 'obsd-master' into master

This commit is contained in:
Thomas Adam 2021-08-18 12:01:19 +01:00
commit c587ad027f

View File

@ -42,8 +42,23 @@ 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;
@ -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);