summaryrefslogtreecommitdiffstats
path: root/cmd-parse.y
diff options
context:
space:
mode:
authornicm <nicm>2019-06-02 07:10:15 +0000
committernicm <nicm>2019-06-02 07:10:15 +0000
commit900238a30657a477f3c62ba344fcc73fc0948ac7 (patch)
treeb0f3435acd101961c78bc636e523942c6166c919 /cmd-parse.y
parent2c6c3a1d27d3665a47d037965955d2bad1f81bcc (diff)
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@.
Diffstat (limited to 'cmd-parse.y')
-rw-r--r--cmd-parse.y263
1 files changed, 140 insertions, 123 deletions
diff --git a/cmd-parse.y b/cmd-parse.y
index 402ec806..e27cdcd8 100644
--- a/cmd-parse.y
+++ b/cmd-parse.y
@@ -65,7 +65,7 @@ struct cmd_parse_state {
u_int escapes;
char *error;
- struct cmd_parse_commands commands;
+ struct cmd_parse_commands *commands;
struct cmd_parse_scope *scope;
TAILQ_HEAD(, cmd_parse_scope) stack;
@@ -74,6 +74,7 @@ static struct cmd_parse_state parse_state;
static char *cmd_parse_get_error(const char *, u_int, const char *);
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 *);
%}
@@ -88,9 +89,9 @@ static void cmd_parse_free_commands(struct cmd_parse_commands *);
int flag;
struct {
int flag;
- struct cmd_parse_commands commands;
+ struct cmd_parse_commands *commands;
} elif;
- struct cmd_parse_commands commands;
+ struct cmd_parse_commands *commands;
struct cmd_parse_command *command;
}
@@ -115,45 +116,46 @@ lines : /* empty */
{
struct cmd_parse_state *ps = &parse_state;
- TAILQ_CONCAT(&ps->commands, &$1, entry);
+ ps->commands = $1;
}
statements : statement '\n'
{
- TAILQ_INIT(&$$);
- TAILQ_CONCAT(&$$, &$1, entry);
+ $$ = $1;
}
| statements statement '\n'
{
- TAILQ_INIT(&$$);
- TAILQ_CONCAT(&$$, &$1, entry);
- TAILQ_CONCAT(&$$, &$2, entry);
+ $$ = $1;
+ TAILQ_CONCAT($$, $2, entry);
+ free($2);
}
-
statement : condition
{
struct cmd_parse_state *ps = &parse_state;
- TAILQ_INIT(&$$);
if (ps->scope == NULL || ps->scope->flag)
- TAILQ_CONCAT(&$$, &$1, entry);
- else
- cmd_parse_free_commands(&$1);
+ $$ = $1;
+ else {
+ $$ = cmd_parse_new_commands();
+ cmd_parse_free_commands($1);
+ }
}
| assignment
{
- TAILQ_INIT(&$$);
+ $$ = xmalloc (sizeof *$$);
+ TAILQ_INIT($$);
}
| commands
{
struct cmd_parse_state *ps = &parse_state;
- TAILQ_INIT(&$$);
if (ps->scope == NULL || ps->scope->flag)
- TAILQ_CONCAT(&$$, &$1, entry);
- else
- cmd_parse_free_commands(&$1);
+ $$ = $1;
+ else {
+ $$ = cmd_parse_new_commands();
+ cmd_parse_free_commands($1);
+ }
}
expanded : FORMAT
@@ -243,117 +245,119 @@ if_close : ENDIF
condition : if_open '\n' statements if_close
{
- TAILQ_INIT(&$$);
if ($1)
- TAILQ_CONCAT(&$$, &$3, entry);
- else
- cmd_parse_free_commands(&$3);
+ $$ = $3;
+ else {
+ $$ = cmd_parse_new_commands();
+ cmd_parse_free_commands($3);
+ }
}
| if_open '\n' statements if_else '\n' statements if_close
{
- TAILQ_INIT(&$$);
if ($1) {
- TAILQ_CONCAT(&$$, &$3, entry);
- cmd_parse_free_commands(&$6);
+ $$ = $3;
+ cmd_parse_free_commands($6);
} else {
- TAILQ_CONCAT(&$$, &$6, entry);
- cmd_parse_free_commands(&$3);
+ $$ = $6;
+ cmd_parse_free_commands($3);
}
}
| if_open '\n' statements elif if_close
{
- TAILQ_INIT(&$$);
if ($1) {
- TAILQ_CONCAT(&$$, &$3, entry);
- cmd_parse_free_commands(&$4.commands);
+ $$ = $3;
+ cmd_parse_free_commands($4.commands);
} else if ($4.flag) {
- TAILQ_CONCAT(&$$, &$4.commands, entry);
- cmd_parse_free_commands(&$3);
+ $$ = $4.commands;
+ cmd_parse_free_commands($3);
} else {
- cmd_parse_free_commands(&$3);
- cmd_parse_free_commands(&$4.commands);
+ $$ = cmd_parse_new_commands();
+ cmd_parse_free_commands($3);
+ cmd_parse_free_commands($4.commands);
}
}
| if_open '\n' statements elif if_else '\n' statements if_close
{
- TAILQ_INIT(&$$);
if ($1) {
- TAILQ_CONCAT(&$$, &$3, entry);
- cmd_parse_free_commands(&$4.commands);
- cmd_parse_free_commands(&$7);
+ $$ = $3;
+ cmd_parse_free_commands($4.commands);
+ cmd_parse_free_commands($7);
} else if ($4.flag) {
- TAILQ_CONCAT(&$$, &$4.commands, entry);
- cmd_parse_free_commands(&$3);
- cmd_parse_free_commands(&$7);
+ $$ = $4.commands;
+ cmd_parse_free_commands($3);
+ cmd_parse_free_commands($7);
} else {
- TAILQ_CONCAT(&$$, &$7, entry);
- cmd_parse_free_commands(&$3);
- cmd_parse_free_commands(&$4.commands);
+ $$ = $7;
+ cmd_parse_free_commands($3);
+ cmd_parse_free_commands($4.commands);
}
}
elif : if_elif '\n' statements
{
- TAILQ_INIT(&$$.commands);
- if ($1)
- TAILQ_CONCAT(&$$.commands, &$3, entry);
- else
- cmd_parse_free_commands(&$3);
- $$.flag = $1;
+ if ($1) {
+ $$.flag = 1;
+ $$.commands = $3;
+ } else {
+ $$.flag = 0;
+ $$.commands = cmd_parse_new_commands();
+ cmd_parse_free_commands($3);
+ }
}
| if_elif '\n' statements elif
{
- TAILQ_INIT(&$$.commands);
if ($1) {
$$.flag = 1;
- TAILQ_CONCAT(&$$.commands, &$3, entry);
- cmd_parse_free_commands(&$4.commands);
+ $$.commands = $3;
+ cmd_parse_free_commands($4.commands);
+ } else if ($4.flag) {
+ $$.flag = 1;
+ $$.commands = $4.commands;
+ cmd_parse_free_commands($3);
} else {
- $$.flag = $4.flag;
- TAILQ_CONCAT(&$$.commands, &$4.commands, entry);
- cmd_parse_free_commands(&$3);
+ $$.flag = 0;
+ $$.commands = cmd_parse_new_commands();
+ cmd_parse_free_commands($3);
+ cmd_parse_free_commands($4.commands);
}
}
-
commands : command
{
struct cmd_parse_state *ps = &parse_state;
- TAILQ_INIT(&$$);
+ $$ = cmd_parse_new_commands();
if (ps->scope == NULL || ps->scope->flag)
- TAILQ_INSERT_TAIL(&$$, $1, entry);
+ TAILQ_INSERT_TAIL($$, $1, entry);
else
cmd_parse_free_command($1);
}
| commands ';'
{
- TAILQ_INIT(&$$);
- TAILQ_CONCAT(&$$, &$1, entry);
+ $$ = $1;
}
| commands ';' condition1
{
- TAILQ_INIT(&$$);
- TAILQ_CONCAT(&$$, &$1, entry);
- TAILQ_CONCAT(&$$, &$3, entry);
+ $$ = $1;
+ TAILQ_CONCAT($$, $3, entry);
+ free($3);
}
| commands ';' command
{
struct cmd_parse_state *ps = &parse_state;
- TAILQ_INIT(&$$);
if (ps->scope == NULL || ps->scope->flag) {
- TAILQ_CONCAT(&$$, &$1, entry);
- TAILQ_INSERT_TAIL(&$$, $3, entry);
+ $$ = $1;
+ TAILQ_INSERT_TAIL($$, $3, entry);
} else {
- cmd_parse_free_commands(&$1);
+ $$ = cmd_parse_new_commands();
+ cmd_parse_free_commands($1);
cmd_parse_free_command($3);
}
}
| condition1
{
- TAILQ_INIT(&$$);
- TAILQ_CONCAT(&$$, &$1, entry);
+ $$ = $1;
}
command : assignment TOKEN
@@ -379,76 +383,80 @@ command : assignment TOKEN
condition1 : if_open commands if_close
{
- TAILQ_INIT(&$$);
if ($1)
- TAILQ_CONCAT(&$$, &$2, entry);
- else
- cmd_parse_free_commands(&$2);
+ $$ = $2;
+ else {
+ $$ = cmd_parse_new_commands();
+ cmd_parse_free_commands($2);
+ }
}
| if_open commands if_else commands if_close
{
- TAILQ_INIT(&$$);
if ($1) {
- TAILQ_CONCAT(&$$, &$2, entry);
- cmd_parse_free_commands(&$4);
+ $$ = $2;
+ cmd_parse_free_commands($4);
} else {
- TAILQ_CONCAT(&$$, &$4, entry);
- cmd_parse_free_commands(&$2);
+ $$ = $4;
+ cmd_parse_free_commands($2);
}
}
| if_open commands elif1 if_close
{
- TAILQ_INIT(&$$);
if ($1) {
- TAILQ_CONCAT(&$$, &$2, entry);
- cmd_parse_free_commands(&$3.commands);
+ $$ = $2;
+ cmd_parse_free_commands($3.commands);
} else if ($3.flag) {
- TAILQ_CONCAT(&$$, &$3.commands, entry);
- cmd_parse_free_commands(&$2);
+ $$ = $3.commands;
+ cmd_parse_free_commands($2);
} else {
- cmd_parse_free_commands(&$2);
- cmd_parse_free_commands(&$3.commands);
+ $$ = cmd_parse_new_commands();
+ cmd_parse_free_commands($2);
+ cmd_parse_free_commands($3.commands);
}
}
| if_open commands elif1 if_else commands if_close
{
- TAILQ_INIT(&$$);
if ($1) {
- TAILQ_CONCAT(&$$, &$2, entry);
- cmd_parse_free_commands(&$3.commands);
- cmd_parse_free_commands(&$5);
+ $$ = $2;
+ cmd_parse_free_commands($3.commands);
+ cmd_parse_free_commands($5);
} else if ($3.flag) {
- TAILQ_CONCAT(&$$, &$3.commands, entry);
- cmd_parse_free_commands(&$2);
- cmd_parse_free_commands(&$5);
+ $$ = $3.commands;
+ cmd_parse_free_commands($2);
+ cmd_parse_free_commands($5);
} else {
- TAILQ_CONCAT(&$$, &$5, entry);
- cmd_parse_free_commands(&$2);
- cmd_parse_free_commands(&$3.commands);
+ $$ = $5;
+ cmd_parse_free_commands($2);
+ cmd_parse_free_commands($3.commands);
}
-
}
elif1 : if_elif commands
{
- TAILQ_INIT(&$$.commands);
- if ($1)
- TAILQ_CONCAT(&$$.commands, &$2, entry);
- else
- cmd_parse_free_commands(&$2);
- $$.flag = $1;
+ if ($1) {
+ $$.flag = 1;
+ $$.commands = $2;
+ } else {
+ $$.flag = 0;
+ $$.commands = cmd_parse_new_commands();
+ cmd_parse_free_commands($2);
+ }
}
| if_elif commands elif1
{
- TAILQ_INIT(&$$.commands);
if ($1) {
$$.flag = 1;
- TAILQ_CONCAT(&$$.commands, &$2, entry);
- cmd_parse_free_commands(&$3.commands);
+ $$.commands = $2;
+ cmd_parse_free_commands($3.commands);
+ } else if ($3.flag) {
+ $$.flag = 1;
+ $$.commands = $3.commands;
+ cmd_parse_free_commands($2);
} else {
- $$.flag = $3.flag;
- TAILQ_CONCAT(&$$.commands, &$3.commands, entry);
- cmd_parse_free_commands(&$2);
+ $$.flag = 0;
+ $$.commands = cmd_parse_new_commands();
+ cmd_parse_free_commands($2);
+ cmd_parse_free_commands($3.commands);
}
}
@@ -497,6 +505,16 @@ cmd_parse_free_command(struct cmd_parse_command *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
cmd_parse_free_commands(struct cmd_parse_commands *cmds)
{
@@ -506,17 +524,17 @@ cmd_parse_free_commands(struct cmd_parse_commands *cmds)
TAILQ_REMOVE(cmds, cmd, entry);
cmd_parse_free_command(cmd);
}
+ free(cmds);
}
static struct cmd_parse_commands *
cmd_parse_run_parser(char **cause)
{
- struct cmd_parse_state *ps = &parse_state;
- struct cmd_parse_commands *cmds;
- struct cmd_parse_scope *scope, *scope1;
- int retval;
+ struct cmd_parse_state *ps = &parse_state;
+ struct cmd_parse_scope *scope, *scope1;
+ int retval;
- TAILQ_INIT(&ps->commands);
+ ps->commands = NULL;
TAILQ_INIT(&ps->stack);
retval = yyparse();
@@ -529,10 +547,9 @@ cmd_parse_run_parser(char **cause)
return (NULL);
}
- cmds = xmalloc(sizeof *cmds);
- TAILQ_INIT(cmds);
- TAILQ_CONCAT(cmds, &ps->commands, entry);
- return (cmds);
+ if (ps->commands == NULL)
+ return (cmd_parse_new_commands());
+ return (ps->commands);
}
static struct cmd_parse_commands *
@@ -574,7 +591,7 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
/* Check for an empty list. */
if (TAILQ_EMPTY(cmds)) {
- free(cmds);
+ cmd_parse_free_commands(cmds);
pr.status = CMD_PARSE_EMPTY;
return (&pr);
}
@@ -668,7 +685,6 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
out:
cmd_parse_free_commands(cmds);
- free(cmds);
return (&pr);
}
@@ -747,8 +763,7 @@ cmd_parse_from_arguments(int argc, char **argv, struct cmd_parse_input *pi)
}
cmd_log_argv(argc, argv, "%s", __func__);
- cmds = xmalloc(sizeof *cmds);
- TAILQ_INIT(cmds);
+ cmds = cmd_parse_new_commands();
copy = cmd_copy_argv(argc, argv);
last = 0;
@@ -801,6 +816,8 @@ cmd_parse_from_arguments(int argc, char **argv, struct cmd_parse_input *pi)
TAILQ_INSERT_TAIL(cmds, cmd, entry);
}
}
+
+ cmd_free_argv(argc, copy);
return (cmd_parse_build_commands(cmds, pi));
}