diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2019-06-02 07:10:16 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2019-06-02 07:10:16 +0000 |
commit | f05aac487e17edc6860ce2f447de9eb34ccafaad (patch) | |
tree | b44da346055956e148afdf627f873c01420933bd /usr.bin/tmux | |
parent | 802f885d01f6c3254766c03b08a59cf170ddfe8e (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 'usr.bin/tmux')
-rw-r--r-- | usr.bin/tmux/cmd-parse.y | 265 |
1 files changed, 141 insertions, 124 deletions
diff --git a/usr.bin/tmux/cmd-parse.y b/usr.bin/tmux/cmd-parse.y index 4f0e2ca4bec..cfb09d24b1f 100644 --- a/usr.bin/tmux/cmd-parse.y +++ b/usr.bin/tmux/cmd-parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-parse.y,v 1.12 2019/06/01 06:20:22 nicm Exp $ */ +/* $OpenBSD: cmd-parse.y,v 1.13 2019/06/02 07:10:15 nicm Exp $ */ /* * Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com> @@ -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)); } |