yacc(1) copies its union so it is not a good place to store

TAILQ_HEADs. Allocate them instead. Found from a problem reported by
sthen@.
This commit is contained in:
nicm 2019-06-02 07:10:15 +00:00 committed by Nicholas Marriott
parent 1a3a973bd0
commit 17bc11bd15

View File

@ -64,7 +64,7 @@ struct cmd_parse_state {
u_int escapes; u_int escapes;
char *error; char *error;
struct cmd_parse_commands commands; struct cmd_parse_commands *commands;
struct cmd_parse_scope *scope; struct cmd_parse_scope *scope;
TAILQ_HEAD(, cmd_parse_scope) stack; TAILQ_HEAD(, cmd_parse_scope) stack;
@ -73,6 +73,7 @@ static struct cmd_parse_state parse_state;
static char *cmd_parse_get_error(const char *, u_int, const char *); 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 void cmd_parse_free_commands(struct cmd_parse_commands *); static void cmd_parse_free_commands(struct cmd_parse_commands *);
%} %}
@ -87,9 +88,9 @@ static void cmd_parse_free_commands(struct cmd_parse_commands *);
int flag; int flag;
struct { struct {
int flag; int flag;
struct cmd_parse_commands commands; struct cmd_parse_commands *commands;
} elif; } elif;
struct cmd_parse_commands commands; struct cmd_parse_commands *commands;
struct cmd_parse_command *command; struct cmd_parse_command *command;
} }
@ -114,45 +115,46 @@ lines : /* empty */
{ {
struct cmd_parse_state *ps = &parse_state; struct cmd_parse_state *ps = &parse_state;
TAILQ_CONCAT(&ps->commands, &$1, entry); ps->commands = $1;
} }
statements : statement '\n' statements : statement '\n'
{ {
TAILQ_INIT(&$$); $$ = $1;
TAILQ_CONCAT(&$$, &$1, entry);
} }
| statements statement '\n' | statements statement '\n'
{ {
TAILQ_INIT(&$$); $$ = $1;
TAILQ_CONCAT(&$$, &$1, entry); TAILQ_CONCAT($$, $2, entry);
TAILQ_CONCAT(&$$, &$2, entry); free($2);
} }
statement : condition statement : condition
{ {
struct cmd_parse_state *ps = &parse_state; struct cmd_parse_state *ps = &parse_state;
TAILQ_INIT(&$$);
if (ps->scope == NULL || ps->scope->flag) if (ps->scope == NULL || ps->scope->flag)
TAILQ_CONCAT(&$$, &$1, entry); $$ = $1;
else else {
cmd_parse_free_commands(&$1); $$ = cmd_parse_new_commands();
cmd_parse_free_commands($1);
}
} }
| assignment | assignment
{ {
TAILQ_INIT(&$$); $$ = xmalloc (sizeof *$$);
TAILQ_INIT($$);
} }
| commands | commands
{ {
struct cmd_parse_state *ps = &parse_state; struct cmd_parse_state *ps = &parse_state;
TAILQ_INIT(&$$);
if (ps->scope == NULL || ps->scope->flag) if (ps->scope == NULL || ps->scope->flag)
TAILQ_CONCAT(&$$, &$1, entry); $$ = $1;
else else {
cmd_parse_free_commands(&$1); $$ = cmd_parse_new_commands();
cmd_parse_free_commands($1);
}
} }
expanded : FORMAT expanded : FORMAT
@ -242,117 +244,119 @@ if_close : ENDIF
condition : if_open '\n' statements if_close condition : if_open '\n' statements if_close
{ {
TAILQ_INIT(&$$);
if ($1) if ($1)
TAILQ_CONCAT(&$$, &$3, entry); $$ = $3;
else else {
cmd_parse_free_commands(&$3); $$ = cmd_parse_new_commands();
cmd_parse_free_commands($3);
}
} }
| if_open '\n' statements if_else '\n' statements if_close | if_open '\n' statements if_else '\n' statements if_close
{ {
TAILQ_INIT(&$$);
if ($1) { if ($1) {
TAILQ_CONCAT(&$$, &$3, entry); $$ = $3;
cmd_parse_free_commands(&$6); cmd_parse_free_commands($6);
} else { } else {
TAILQ_CONCAT(&$$, &$6, entry); $$ = $6;
cmd_parse_free_commands(&$3); cmd_parse_free_commands($3);
} }
} }
| if_open '\n' statements elif if_close | if_open '\n' statements elif if_close
{ {
TAILQ_INIT(&$$);
if ($1) { if ($1) {
TAILQ_CONCAT(&$$, &$3, entry); $$ = $3;
cmd_parse_free_commands(&$4.commands); cmd_parse_free_commands($4.commands);
} else if ($4.flag) { } else if ($4.flag) {
TAILQ_CONCAT(&$$, &$4.commands, entry); $$ = $4.commands;
cmd_parse_free_commands(&$3); cmd_parse_free_commands($3);
} else { } else {
cmd_parse_free_commands(&$3); $$ = cmd_parse_new_commands();
cmd_parse_free_commands(&$4.commands); cmd_parse_free_commands($3);
cmd_parse_free_commands($4.commands);
} }
} }
| if_open '\n' statements elif if_else '\n' statements if_close | if_open '\n' statements elif if_else '\n' statements if_close
{ {
TAILQ_INIT(&$$);
if ($1) { if ($1) {
TAILQ_CONCAT(&$$, &$3, entry); $$ = $3;
cmd_parse_free_commands(&$4.commands); cmd_parse_free_commands($4.commands);
cmd_parse_free_commands(&$7); cmd_parse_free_commands($7);
} else if ($4.flag) { } else if ($4.flag) {
TAILQ_CONCAT(&$$, &$4.commands, entry); $$ = $4.commands;
cmd_parse_free_commands(&$3); cmd_parse_free_commands($3);
cmd_parse_free_commands(&$7); cmd_parse_free_commands($7);
} else { } else {
TAILQ_CONCAT(&$$, &$7, entry); $$ = $7;
cmd_parse_free_commands(&$3); cmd_parse_free_commands($3);
cmd_parse_free_commands(&$4.commands); cmd_parse_free_commands($4.commands);
} }
} }
elif : if_elif '\n' statements elif : if_elif '\n' statements
{ {
TAILQ_INIT(&$$.commands); if ($1) {
if ($1) $$.flag = 1;
TAILQ_CONCAT(&$$.commands, &$3, entry); $$.commands = $3;
else } else {
cmd_parse_free_commands(&$3); $$.flag = 0;
$$.flag = $1; $$.commands = cmd_parse_new_commands();
cmd_parse_free_commands($3);
}
} }
| if_elif '\n' statements elif | if_elif '\n' statements elif
{ {
TAILQ_INIT(&$$.commands);
if ($1) { if ($1) {
$$.flag = 1; $$.flag = 1;
TAILQ_CONCAT(&$$.commands, &$3, entry); $$.commands = $3;
cmd_parse_free_commands(&$4.commands); cmd_parse_free_commands($4.commands);
} else if ($4.flag) {
$$.flag = 1;
$$.commands = $4.commands;
cmd_parse_free_commands($3);
} else { } else {
$$.flag = $4.flag; $$.flag = 0;
TAILQ_CONCAT(&$$.commands, &$4.commands, entry); $$.commands = cmd_parse_new_commands();
cmd_parse_free_commands(&$3); cmd_parse_free_commands($3);
cmd_parse_free_commands($4.commands);
} }
} }
commands : command commands : command
{ {
struct cmd_parse_state *ps = &parse_state; struct cmd_parse_state *ps = &parse_state;
TAILQ_INIT(&$$); $$ = cmd_parse_new_commands();
if (ps->scope == NULL || ps->scope->flag) if (ps->scope == NULL || ps->scope->flag)
TAILQ_INSERT_TAIL(&$$, $1, entry); TAILQ_INSERT_TAIL($$, $1, entry);
else else
cmd_parse_free_command($1); cmd_parse_free_command($1);
} }
| commands ';' | commands ';'
{ {
TAILQ_INIT(&$$); $$ = $1;
TAILQ_CONCAT(&$$, &$1, entry);
} }
| commands ';' condition1 | commands ';' condition1
{ {
TAILQ_INIT(&$$); $$ = $1;
TAILQ_CONCAT(&$$, &$1, entry); TAILQ_CONCAT($$, $3, entry);
TAILQ_CONCAT(&$$, &$3, entry); free($3);
} }
| commands ';' command | commands ';' command
{ {
struct cmd_parse_state *ps = &parse_state; struct cmd_parse_state *ps = &parse_state;
TAILQ_INIT(&$$);
if (ps->scope == NULL || ps->scope->flag) { if (ps->scope == NULL || ps->scope->flag) {
TAILQ_CONCAT(&$$, &$1, entry); $$ = $1;
TAILQ_INSERT_TAIL(&$$, $3, entry); TAILQ_INSERT_TAIL($$, $3, entry);
} else { } else {
cmd_parse_free_commands(&$1); $$ = cmd_parse_new_commands();
cmd_parse_free_commands($1);
cmd_parse_free_command($3); cmd_parse_free_command($3);
} }
} }
| condition1 | condition1
{ {
TAILQ_INIT(&$$); $$ = $1;
TAILQ_CONCAT(&$$, &$1, entry);
} }
command : assignment TOKEN command : assignment TOKEN
@ -378,76 +382,80 @@ command : assignment TOKEN
condition1 : if_open commands if_close condition1 : if_open commands if_close
{ {
TAILQ_INIT(&$$);
if ($1) if ($1)
TAILQ_CONCAT(&$$, &$2, entry); $$ = $2;
else else {
cmd_parse_free_commands(&$2); $$ = cmd_parse_new_commands();
cmd_parse_free_commands($2);
}
} }
| if_open commands if_else commands if_close | if_open commands if_else commands if_close
{ {
TAILQ_INIT(&$$);
if ($1) { if ($1) {
TAILQ_CONCAT(&$$, &$2, entry); $$ = $2;
cmd_parse_free_commands(&$4); cmd_parse_free_commands($4);
} else { } else {
TAILQ_CONCAT(&$$, &$4, entry); $$ = $4;
cmd_parse_free_commands(&$2); cmd_parse_free_commands($2);
} }
} }
| if_open commands elif1 if_close | if_open commands elif1 if_close
{ {
TAILQ_INIT(&$$);
if ($1) { if ($1) {
TAILQ_CONCAT(&$$, &$2, entry); $$ = $2;
cmd_parse_free_commands(&$3.commands); cmd_parse_free_commands($3.commands);
} else if ($3.flag) { } else if ($3.flag) {
TAILQ_CONCAT(&$$, &$3.commands, entry); $$ = $3.commands;
cmd_parse_free_commands(&$2); cmd_parse_free_commands($2);
} else { } else {
cmd_parse_free_commands(&$2); $$ = cmd_parse_new_commands();
cmd_parse_free_commands(&$3.commands); cmd_parse_free_commands($2);
cmd_parse_free_commands($3.commands);
} }
} }
| if_open commands elif1 if_else commands if_close | if_open commands elif1 if_else commands if_close
{ {
TAILQ_INIT(&$$);
if ($1) { if ($1) {
TAILQ_CONCAT(&$$, &$2, entry); $$ = $2;
cmd_parse_free_commands(&$3.commands); cmd_parse_free_commands($3.commands);
cmd_parse_free_commands(&$5); cmd_parse_free_commands($5);
} else if ($3.flag) { } else if ($3.flag) {
TAILQ_CONCAT(&$$, &$3.commands, entry); $$ = $3.commands;
cmd_parse_free_commands(&$2); cmd_parse_free_commands($2);
cmd_parse_free_commands(&$5); cmd_parse_free_commands($5);
} else { } else {
TAILQ_CONCAT(&$$, &$5, entry); $$ = $5;
cmd_parse_free_commands(&$2); cmd_parse_free_commands($2);
cmd_parse_free_commands(&$3.commands); cmd_parse_free_commands($3.commands);
} }
} }
elif1 : if_elif commands elif1 : if_elif commands
{ {
TAILQ_INIT(&$$.commands); if ($1) {
if ($1) $$.flag = 1;
TAILQ_CONCAT(&$$.commands, &$2, entry); $$.commands = $2;
else } else {
cmd_parse_free_commands(&$2); $$.flag = 0;
$$.flag = $1; $$.commands = cmd_parse_new_commands();
cmd_parse_free_commands($2);
}
} }
| if_elif commands elif1 | if_elif commands elif1
{ {
TAILQ_INIT(&$$.commands);
if ($1) { if ($1) {
$$.flag = 1; $$.flag = 1;
TAILQ_CONCAT(&$$.commands, &$2, entry); $$.commands = $2;
cmd_parse_free_commands(&$3.commands); cmd_parse_free_commands($3.commands);
} else if ($3.flag) {
$$.flag = 1;
$$.commands = $3.commands;
cmd_parse_free_commands($2);
} else { } else {
$$.flag = $3.flag; $$.flag = 0;
TAILQ_CONCAT(&$$.commands, &$3.commands, entry); $$.commands = cmd_parse_new_commands();
cmd_parse_free_commands(&$2); cmd_parse_free_commands($2);
cmd_parse_free_commands($3.commands);
} }
} }
@ -496,6 +504,16 @@ cmd_parse_free_command(struct cmd_parse_command *cmd)
free(cmd); free(cmd);
} }
static struct cmd_parse_commands *
cmd_parse_new_commands(void)
{
struct cmd_parse_commands *cmds;
cmds = xmalloc(sizeof *cmds);
TAILQ_INIT (cmds);
return (cmds);
}
static void static void
cmd_parse_free_commands(struct cmd_parse_commands *cmds) cmd_parse_free_commands(struct cmd_parse_commands *cmds)
{ {
@ -505,17 +523,17 @@ cmd_parse_free_commands(struct cmd_parse_commands *cmds)
TAILQ_REMOVE(cmds, cmd, entry); TAILQ_REMOVE(cmds, cmd, entry);
cmd_parse_free_command(cmd); cmd_parse_free_command(cmd);
} }
free(cmds);
} }
static struct cmd_parse_commands * static struct cmd_parse_commands *
cmd_parse_run_parser(char **cause) cmd_parse_run_parser(char **cause)
{ {
struct cmd_parse_state *ps = &parse_state; struct cmd_parse_state *ps = &parse_state;
struct cmd_parse_commands *cmds; struct cmd_parse_scope *scope, *scope1;
struct cmd_parse_scope *scope, *scope1; int retval;
int retval;
TAILQ_INIT(&ps->commands); ps->commands = NULL;
TAILQ_INIT(&ps->stack); TAILQ_INIT(&ps->stack);
retval = yyparse(); retval = yyparse();
@ -528,10 +546,9 @@ cmd_parse_run_parser(char **cause)
return (NULL); return (NULL);
} }
cmds = xmalloc(sizeof *cmds); if (ps->commands == NULL)
TAILQ_INIT(cmds); return (cmd_parse_new_commands());
TAILQ_CONCAT(cmds, &ps->commands, entry); return (ps->commands);
return (cmds);
} }
static struct cmd_parse_commands * static struct cmd_parse_commands *
@ -573,7 +590,7 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
/* Check for an empty list. */ /* Check for an empty list. */
if (TAILQ_EMPTY(cmds)) { if (TAILQ_EMPTY(cmds)) {
free(cmds); cmd_parse_free_commands(cmds);
pr.status = CMD_PARSE_EMPTY; pr.status = CMD_PARSE_EMPTY;
return (&pr); return (&pr);
} }
@ -667,7 +684,6 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
out: out:
cmd_parse_free_commands(cmds); cmd_parse_free_commands(cmds);
free(cmds);
return (&pr); return (&pr);
} }
@ -746,8 +762,7 @@ cmd_parse_from_arguments(int argc, char **argv, struct cmd_parse_input *pi)
} }
cmd_log_argv(argc, argv, "%s", __func__); cmd_log_argv(argc, argv, "%s", __func__);
cmds = xmalloc(sizeof *cmds); cmds = cmd_parse_new_commands();
TAILQ_INIT(cmds);
copy = cmd_copy_argv(argc, argv); copy = cmd_copy_argv(argc, argv);
last = 0; last = 0;
@ -800,6 +815,8 @@ cmd_parse_from_arguments(int argc, char **argv, struct cmd_parse_input *pi)
TAILQ_INSERT_TAIL(cmds, cmd, entry); TAILQ_INSERT_TAIL(cmds, cmd, entry);
} }
} }
cmd_free_argv(argc, copy);
return (cmd_parse_build_commands(cmds, pi)); return (cmd_parse_build_commands(cmds, pi));
} }