mirror of
https://github.com/tmux/tmux.git
synced 2026-10-09 11:44:23 +00:00
Track allocations in yacc to avoid leaking when parsing commands, GitHub
issue 5632 from Jeong, Heon.
This commit is contained in:
318
cmd-parse.y
318
cmd-parse.y
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cmd-parse.y,v 1.62 2026/10/08 06:29:32 nicm Exp $ */
|
||||
/* $OpenBSD: cmd-parse.y,v 1.63 2026/10/08 06:44:16 nicm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
@@ -69,6 +69,22 @@ struct cmd_parse_command {
|
||||
};
|
||||
TAILQ_HEAD(cmd_parse_commands, cmd_parse_command);
|
||||
|
||||
enum cmd_parse_value_type {
|
||||
CMD_PARSE_VALUE_STRING,
|
||||
CMD_PARSE_VALUE_ARGUMENT,
|
||||
CMD_PARSE_VALUE_ARGUMENTS,
|
||||
CMD_PARSE_VALUE_COMMAND,
|
||||
CMD_PARSE_VALUE_COMMANDS
|
||||
};
|
||||
|
||||
struct cmd_parse_owned_value {
|
||||
enum cmd_parse_value_type type;
|
||||
void *value;
|
||||
|
||||
TAILQ_ENTRY(cmd_parse_owned_value) entry;
|
||||
};
|
||||
TAILQ_HEAD(cmd_parse_owned_values, cmd_parse_owned_value);
|
||||
|
||||
struct cmd_parse_state {
|
||||
FILE *f;
|
||||
|
||||
@@ -87,10 +103,16 @@ struct cmd_parse_state {
|
||||
|
||||
struct cmd_parse_scope *scope;
|
||||
TAILQ_HEAD(, cmd_parse_scope) stack;
|
||||
|
||||
struct cmd_parse_owned_values values;
|
||||
};
|
||||
static struct cmd_parse_state parse_state;
|
||||
|
||||
static char *cmd_parse_get_error(const char *, u_int, const char *);
|
||||
static void *cmd_parse_own(enum cmd_parse_value_type, void *);
|
||||
static struct cmd_parse_commands *cmd_parse_own_commands(void);
|
||||
static void *cmd_parse_take(void *);
|
||||
static void cmd_parse_drop(void *);
|
||||
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 *);
|
||||
@@ -139,7 +161,7 @@ lines : /* empty */
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
|
||||
ps->commands = $1;
|
||||
ps->commands = cmd_parse_take($1);
|
||||
}
|
||||
|
||||
statements : statement '\n'
|
||||
@@ -150,18 +172,16 @@ statements : statement '\n'
|
||||
{
|
||||
$$ = $1;
|
||||
TAILQ_CONCAT($$, $2, entry);
|
||||
free($2);
|
||||
cmd_parse_drop($2);
|
||||
}
|
||||
|
||||
statement : /* empty */
|
||||
{
|
||||
$$ = xmalloc (sizeof *$$);
|
||||
TAILQ_INIT($$);
|
||||
$$ = cmd_parse_own_commands();
|
||||
}
|
||||
| hidden_assignment
|
||||
{
|
||||
$$ = xmalloc (sizeof *$$);
|
||||
TAILQ_INIT($$);
|
||||
$$ = cmd_parse_own_commands();
|
||||
}
|
||||
| condition
|
||||
{
|
||||
@@ -170,8 +190,8 @@ statement : /* empty */
|
||||
if (ps->scope == NULL || ps->scope->flag)
|
||||
$$ = $1;
|
||||
else {
|
||||
$$ = cmd_parse_new_commands();
|
||||
cmd_parse_free_commands($1);
|
||||
$$ = cmd_parse_own_commands();
|
||||
cmd_parse_drop($1);
|
||||
}
|
||||
}
|
||||
| commands
|
||||
@@ -181,8 +201,8 @@ statement : /* empty */
|
||||
if (ps->scope == NULL || ps->scope->flag)
|
||||
$$ = $1;
|
||||
else {
|
||||
$$ = cmd_parse_new_commands();
|
||||
cmd_parse_free_commands($1);
|
||||
$$ = cmd_parse_own_commands();
|
||||
cmd_parse_drop($1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +224,7 @@ expanded : format
|
||||
struct cmd_find_state *fsp;
|
||||
struct cmd_find_state fs;
|
||||
int flags = FORMAT_NOJOBS;
|
||||
char *expanded;
|
||||
|
||||
if (cmd_find_valid_state(&pi->fs))
|
||||
fsp = &pi->fs;
|
||||
@@ -214,9 +235,10 @@ expanded : format
|
||||
ft = format_create(c, pi->item, FORMAT_NONE, flags);
|
||||
format_defaults(ft, c, fsp->s, fsp->wl, fsp->wp);
|
||||
|
||||
$$ = format_expand(ft, $1);
|
||||
expanded = format_expand(ft, $1);
|
||||
$$ = cmd_parse_own(CMD_PARSE_VALUE_STRING, expanded);
|
||||
format_free(ft);
|
||||
free($1);
|
||||
cmd_parse_drop($1);
|
||||
}
|
||||
|
||||
optional_assignment : /* empty */
|
||||
@@ -241,7 +263,7 @@ assignment : EQUALS
|
||||
}
|
||||
if ((~flags & CMD_PARSE_PARSEONLY) && flag)
|
||||
environ_put(global_environ, $1, 0);
|
||||
free($1);
|
||||
cmd_parse_drop($1);
|
||||
}
|
||||
|
||||
hidden_assignment : HIDDEN EQUALS
|
||||
@@ -263,7 +285,7 @@ hidden_assignment : HIDDEN EQUALS
|
||||
}
|
||||
if ((~flags & CMD_PARSE_PARSEONLY) && flag)
|
||||
environ_put(global_environ, $2, ENVIRON_HIDDEN);
|
||||
free($2);
|
||||
cmd_parse_drop($2);
|
||||
}
|
||||
|
||||
if_open : IF expanded
|
||||
@@ -274,7 +296,7 @@ if_open : IF expanded
|
||||
scope = xmalloc(sizeof *scope);
|
||||
$$ = scope->flag = format_true($2);
|
||||
scope->taken = scope->flag;
|
||||
free($2);
|
||||
cmd_parse_drop($2);
|
||||
|
||||
if (ps->scope != NULL)
|
||||
TAILQ_INSERT_HEAD(&ps->stack, ps->scope, entry);
|
||||
@@ -303,7 +325,7 @@ if_elif : ELIF expanded
|
||||
scope->flag = !ps->scope->taken && format_true($2);
|
||||
scope->taken = ps->scope->taken || scope->flag;
|
||||
$$ = scope->flag;
|
||||
free($2);
|
||||
cmd_parse_drop($2);
|
||||
|
||||
free(ps->scope);
|
||||
ps->scope = scope;
|
||||
@@ -324,48 +346,48 @@ condition : if_open '\n' statements if_close
|
||||
if ($1)
|
||||
$$ = $3;
|
||||
else {
|
||||
$$ = cmd_parse_new_commands();
|
||||
cmd_parse_free_commands($3);
|
||||
$$ = cmd_parse_own_commands();
|
||||
cmd_parse_drop($3);
|
||||
}
|
||||
}
|
||||
| if_open '\n' statements if_else '\n' statements if_close
|
||||
{
|
||||
if ($1) {
|
||||
$$ = $3;
|
||||
cmd_parse_free_commands($6);
|
||||
cmd_parse_drop($6);
|
||||
} else {
|
||||
$$ = $6;
|
||||
cmd_parse_free_commands($3);
|
||||
cmd_parse_drop($3);
|
||||
}
|
||||
}
|
||||
| if_open '\n' statements elif if_close
|
||||
{
|
||||
if ($1) {
|
||||
$$ = $3;
|
||||
cmd_parse_free_commands($4.commands);
|
||||
cmd_parse_drop($4.commands);
|
||||
} else if ($4.flag) {
|
||||
$$ = $4.commands;
|
||||
cmd_parse_free_commands($3);
|
||||
cmd_parse_drop($3);
|
||||
} else {
|
||||
$$ = cmd_parse_new_commands();
|
||||
cmd_parse_free_commands($3);
|
||||
cmd_parse_free_commands($4.commands);
|
||||
$$ = cmd_parse_own_commands();
|
||||
cmd_parse_drop($3);
|
||||
cmd_parse_drop($4.commands);
|
||||
}
|
||||
}
|
||||
| if_open '\n' statements elif if_else '\n' statements if_close
|
||||
{
|
||||
if ($1) {
|
||||
$$ = $3;
|
||||
cmd_parse_free_commands($4.commands);
|
||||
cmd_parse_free_commands($7);
|
||||
cmd_parse_drop($4.commands);
|
||||
cmd_parse_drop($7);
|
||||
} else if ($4.flag) {
|
||||
$$ = $4.commands;
|
||||
cmd_parse_free_commands($3);
|
||||
cmd_parse_free_commands($7);
|
||||
cmd_parse_drop($3);
|
||||
cmd_parse_drop($7);
|
||||
} else {
|
||||
$$ = $7;
|
||||
cmd_parse_free_commands($3);
|
||||
cmd_parse_free_commands($4.commands);
|
||||
cmd_parse_drop($3);
|
||||
cmd_parse_drop($4.commands);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,8 +398,8 @@ elif : if_elif '\n' statements
|
||||
$$.commands = $3;
|
||||
} else {
|
||||
$$.flag = 0;
|
||||
$$.commands = cmd_parse_new_commands();
|
||||
cmd_parse_free_commands($3);
|
||||
$$.commands = cmd_parse_own_commands();
|
||||
cmd_parse_drop($3);
|
||||
}
|
||||
}
|
||||
| if_elif '\n' statements elif
|
||||
@@ -385,16 +407,16 @@ elif : if_elif '\n' statements
|
||||
if ($1) {
|
||||
$$.flag = 1;
|
||||
$$.commands = $3;
|
||||
cmd_parse_free_commands($4.commands);
|
||||
cmd_parse_drop($4.commands);
|
||||
} else if ($4.flag) {
|
||||
$$.flag = 1;
|
||||
$$.commands = $4.commands;
|
||||
cmd_parse_free_commands($3);
|
||||
cmd_parse_drop($3);
|
||||
} else {
|
||||
$$.flag = 0;
|
||||
$$.commands = cmd_parse_new_commands();
|
||||
cmd_parse_free_commands($3);
|
||||
cmd_parse_free_commands($4.commands);
|
||||
$$.commands = cmd_parse_own_commands();
|
||||
cmd_parse_drop($3);
|
||||
cmd_parse_drop($4.commands);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,12 +424,13 @@ commands : command
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
|
||||
$$ = cmd_parse_new_commands();
|
||||
$$ = cmd_parse_own_commands();
|
||||
if (!TAILQ_EMPTY(&$1->arguments) &&
|
||||
(ps->scope == NULL || ps->scope->flag))
|
||||
(ps->scope == NULL || ps->scope->flag)) {
|
||||
cmd_parse_take($1);
|
||||
TAILQ_INSERT_TAIL($$, $1, entry);
|
||||
else
|
||||
cmd_parse_free_command($1);
|
||||
} else
|
||||
cmd_parse_drop($1);
|
||||
}
|
||||
| commands ';'
|
||||
{
|
||||
@@ -417,7 +440,7 @@ commands : command
|
||||
{
|
||||
$$ = $1;
|
||||
TAILQ_CONCAT($$, $3, entry);
|
||||
free($3);
|
||||
cmd_parse_drop($3);
|
||||
}
|
||||
| commands ';' command
|
||||
{
|
||||
@@ -426,9 +449,10 @@ commands : command
|
||||
$$ = $1;
|
||||
if (!TAILQ_EMPTY(&$3->arguments) &&
|
||||
(ps->scope == NULL || ps->scope->flag)) {
|
||||
cmd_parse_take($3);
|
||||
TAILQ_INSERT_TAIL($$, $3, entry);
|
||||
} else
|
||||
cmd_parse_free_command($3);
|
||||
cmd_parse_drop($3);
|
||||
}
|
||||
| condition1
|
||||
{
|
||||
@@ -442,6 +466,7 @@ command : assignment
|
||||
$$ = xcalloc(1, sizeof *$$);
|
||||
$$->line = ps->input->line;
|
||||
TAILQ_INIT(&$$->arguments);
|
||||
cmd_parse_own(CMD_PARSE_VALUE_COMMAND, $$);
|
||||
}
|
||||
| optional_assignment TOKEN
|
||||
{
|
||||
@@ -454,8 +479,9 @@ command : assignment
|
||||
|
||||
arg = xcalloc(1, sizeof *arg);
|
||||
arg->type = CMD_PARSE_STRING;
|
||||
arg->string = $2;
|
||||
arg->string = cmd_parse_take($2);
|
||||
TAILQ_INSERT_HEAD(&$$->arguments, arg, entry);
|
||||
cmd_parse_own(CMD_PARSE_VALUE_COMMAND, $$);
|
||||
}
|
||||
| optional_assignment TOKEN arguments
|
||||
{
|
||||
@@ -467,12 +493,13 @@ command : assignment
|
||||
TAILQ_INIT(&$$->arguments);
|
||||
|
||||
TAILQ_CONCAT(&$$->arguments, $3, entry);
|
||||
free($3);
|
||||
cmd_parse_drop($3);
|
||||
|
||||
arg = xcalloc(1, sizeof *arg);
|
||||
arg->type = CMD_PARSE_STRING;
|
||||
arg->string = $2;
|
||||
arg->string = cmd_parse_take($2);
|
||||
TAILQ_INSERT_HEAD(&$$->arguments, arg, entry);
|
||||
cmd_parse_own(CMD_PARSE_VALUE_COMMAND, $$);
|
||||
}
|
||||
|
||||
condition1 : if_open commands if_close
|
||||
@@ -480,48 +507,48 @@ condition1 : if_open commands if_close
|
||||
if ($1)
|
||||
$$ = $2;
|
||||
else {
|
||||
$$ = cmd_parse_new_commands();
|
||||
cmd_parse_free_commands($2);
|
||||
$$ = cmd_parse_own_commands();
|
||||
cmd_parse_drop($2);
|
||||
}
|
||||
}
|
||||
| if_open commands if_else commands if_close
|
||||
{
|
||||
if ($1) {
|
||||
$$ = $2;
|
||||
cmd_parse_free_commands($4);
|
||||
cmd_parse_drop($4);
|
||||
} else {
|
||||
$$ = $4;
|
||||
cmd_parse_free_commands($2);
|
||||
cmd_parse_drop($2);
|
||||
}
|
||||
}
|
||||
| if_open commands elif1 if_close
|
||||
{
|
||||
if ($1) {
|
||||
$$ = $2;
|
||||
cmd_parse_free_commands($3.commands);
|
||||
cmd_parse_drop($3.commands);
|
||||
} else if ($3.flag) {
|
||||
$$ = $3.commands;
|
||||
cmd_parse_free_commands($2);
|
||||
cmd_parse_drop($2);
|
||||
} else {
|
||||
$$ = cmd_parse_new_commands();
|
||||
cmd_parse_free_commands($2);
|
||||
cmd_parse_free_commands($3.commands);
|
||||
$$ = cmd_parse_own_commands();
|
||||
cmd_parse_drop($2);
|
||||
cmd_parse_drop($3.commands);
|
||||
}
|
||||
}
|
||||
| if_open commands elif1 if_else commands if_close
|
||||
{
|
||||
if ($1) {
|
||||
$$ = $2;
|
||||
cmd_parse_free_commands($3.commands);
|
||||
cmd_parse_free_commands($5);
|
||||
cmd_parse_drop($3.commands);
|
||||
cmd_parse_drop($5);
|
||||
} else if ($3.flag) {
|
||||
$$ = $3.commands;
|
||||
cmd_parse_free_commands($2);
|
||||
cmd_parse_free_commands($5);
|
||||
cmd_parse_drop($2);
|
||||
cmd_parse_drop($5);
|
||||
} else {
|
||||
$$ = $5;
|
||||
cmd_parse_free_commands($2);
|
||||
cmd_parse_free_commands($3.commands);
|
||||
cmd_parse_drop($2);
|
||||
cmd_parse_drop($3.commands);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -532,8 +559,8 @@ elif1 : if_elif commands
|
||||
$$.commands = $2;
|
||||
} else {
|
||||
$$.flag = 0;
|
||||
$$.commands = cmd_parse_new_commands();
|
||||
cmd_parse_free_commands($2);
|
||||
$$.commands = cmd_parse_own_commands();
|
||||
cmd_parse_drop($2);
|
||||
}
|
||||
}
|
||||
| if_elif commands elif1
|
||||
@@ -541,16 +568,16 @@ elif1 : if_elif commands
|
||||
if ($1) {
|
||||
$$.flag = 1;
|
||||
$$.commands = $2;
|
||||
cmd_parse_free_commands($3.commands);
|
||||
cmd_parse_drop($3.commands);
|
||||
} else if ($3.flag) {
|
||||
$$.flag = 1;
|
||||
$$.commands = $3.commands;
|
||||
cmd_parse_free_commands($2);
|
||||
cmd_parse_drop($2);
|
||||
} else {
|
||||
$$.flag = 0;
|
||||
$$.commands = cmd_parse_new_commands();
|
||||
cmd_parse_free_commands($2);
|
||||
cmd_parse_free_commands($3.commands);
|
||||
$$.commands = cmd_parse_own_commands();
|
||||
cmd_parse_drop($2);
|
||||
cmd_parse_drop($3.commands);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -559,10 +586,13 @@ arguments : argument
|
||||
$$ = xcalloc(1, sizeof *$$);
|
||||
TAILQ_INIT($$);
|
||||
|
||||
cmd_parse_take($1);
|
||||
TAILQ_INSERT_HEAD($$, $1, entry);
|
||||
cmd_parse_own(CMD_PARSE_VALUE_ARGUMENTS, $$);
|
||||
}
|
||||
| argument arguments
|
||||
{
|
||||
cmd_parse_take($1);
|
||||
TAILQ_INSERT_HEAD($2, $1, entry);
|
||||
$$ = $2;
|
||||
}
|
||||
@@ -571,19 +601,22 @@ argument : TOKEN
|
||||
{
|
||||
$$ = xcalloc(1, sizeof *$$);
|
||||
$$->type = CMD_PARSE_STRING;
|
||||
$$->string = $1;
|
||||
$$->string = cmd_parse_take($1);
|
||||
cmd_parse_own(CMD_PARSE_VALUE_ARGUMENT, $$);
|
||||
}
|
||||
| EQUALS
|
||||
{
|
||||
$$ = xcalloc(1, sizeof *$$);
|
||||
$$->type = CMD_PARSE_STRING;
|
||||
$$->string = $1;
|
||||
$$->string = cmd_parse_take($1);
|
||||
cmd_parse_own(CMD_PARSE_VALUE_ARGUMENT, $$);
|
||||
}
|
||||
| '{' argument_statements
|
||||
{
|
||||
$$ = xcalloc(1, sizeof *$$);
|
||||
$$->type = CMD_PARSE_COMMANDS;
|
||||
$$->commands = $2;
|
||||
$$->commands = cmd_parse_take($2);
|
||||
cmd_parse_own(CMD_PARSE_VALUE_ARGUMENT, $$);
|
||||
}
|
||||
|
||||
argument_statements : statement '}'
|
||||
@@ -594,7 +627,7 @@ argument_statements : statement '}'
|
||||
{
|
||||
$$ = $1;
|
||||
TAILQ_CONCAT($$, $2, entry);
|
||||
free($2);
|
||||
cmd_parse_drop($2);
|
||||
}
|
||||
|
||||
%%
|
||||
@@ -683,22 +716,116 @@ cmd_parse_free_commands(struct cmd_parse_commands *cmds)
|
||||
free(cmds);
|
||||
}
|
||||
|
||||
static void *
|
||||
cmd_parse_own(enum cmd_parse_value_type type, void *value)
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
struct cmd_parse_owned_value *v;
|
||||
|
||||
v = xmalloc(sizeof *v);
|
||||
v->type = type;
|
||||
v->value = value;
|
||||
TAILQ_INSERT_TAIL(&ps->values, v, entry);
|
||||
return (value);
|
||||
}
|
||||
|
||||
static struct cmd_parse_commands *
|
||||
cmd_parse_own_commands(void)
|
||||
{
|
||||
struct cmd_parse_commands *cmds;
|
||||
|
||||
cmds = cmd_parse_new_commands();
|
||||
return (cmd_parse_own(CMD_PARSE_VALUE_COMMANDS, cmds));
|
||||
}
|
||||
|
||||
static struct cmd_parse_owned_value *
|
||||
cmd_parse_find_value(void *value)
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
struct cmd_parse_owned_value *v;
|
||||
|
||||
TAILQ_FOREACH_REVERSE(v, &ps->values, cmd_parse_owned_values, entry) {
|
||||
if (v->value == value)
|
||||
return (v);
|
||||
}
|
||||
fatalx("parser value not owned");
|
||||
}
|
||||
|
||||
static void *
|
||||
cmd_parse_take(void *value)
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
struct cmd_parse_owned_value *v;
|
||||
|
||||
v = cmd_parse_find_value(value);
|
||||
TAILQ_REMOVE(&ps->values, v, entry);
|
||||
free(v);
|
||||
return (value);
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_parse_free_value(enum cmd_parse_value_type type, void *value)
|
||||
{
|
||||
switch (type) {
|
||||
case CMD_PARSE_VALUE_STRING:
|
||||
free(value);
|
||||
break;
|
||||
case CMD_PARSE_VALUE_ARGUMENT:
|
||||
cmd_parse_free_argument(value);
|
||||
break;
|
||||
case CMD_PARSE_VALUE_ARGUMENTS:
|
||||
cmd_parse_free_arguments(value);
|
||||
free(value);
|
||||
break;
|
||||
case CMD_PARSE_VALUE_COMMAND:
|
||||
cmd_parse_free_command(value);
|
||||
break;
|
||||
case CMD_PARSE_VALUE_COMMANDS:
|
||||
cmd_parse_free_commands(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_parse_drop(void *value)
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
struct cmd_parse_owned_value *v;
|
||||
|
||||
v = cmd_parse_find_value(value);
|
||||
TAILQ_REMOVE(&ps->values, v, entry);
|
||||
cmd_parse_free_value(v->type, v->value);
|
||||
free(v);
|
||||
}
|
||||
|
||||
static struct cmd_parse_commands *
|
||||
cmd_parse_run_parser(char **cause)
|
||||
{
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
struct cmd_parse_scope *scope, *scope1;
|
||||
int retval;
|
||||
struct cmd_parse_state *ps = &parse_state;
|
||||
struct cmd_parse_scope *scope, *scope1;
|
||||
struct cmd_parse_owned_value *v, *v1;
|
||||
int retval;
|
||||
|
||||
ps->commands = NULL;
|
||||
TAILQ_INIT(&ps->stack);
|
||||
TAILQ_INIT(&ps->values);
|
||||
|
||||
retval = yyparse();
|
||||
TAILQ_FOREACH_SAFE(scope, &ps->stack, entry, scope1) {
|
||||
TAILQ_REMOVE(&ps->stack, scope, entry);
|
||||
free(scope);
|
||||
}
|
||||
free(ps->scope);
|
||||
ps->scope = NULL;
|
||||
|
||||
TAILQ_FOREACH_SAFE(v, &ps->values, entry, v1) {
|
||||
TAILQ_REMOVE(&ps->values, v, entry);
|
||||
cmd_parse_free_value(v->type, v->value);
|
||||
free(v);
|
||||
}
|
||||
if (retval != 0) {
|
||||
if (ps->commands != NULL)
|
||||
cmd_parse_free_commands(ps->commands);
|
||||
*cause = ps->error;
|
||||
return (NULL);
|
||||
}
|
||||
@@ -1329,9 +1456,10 @@ yylex(void)
|
||||
*/
|
||||
next = yylex_getc();
|
||||
if (condition && next == '{') {
|
||||
yylval.token = yylex_format();
|
||||
if (yylval.token == NULL)
|
||||
token = yylval.token = yylex_format();
|
||||
if (token == NULL)
|
||||
return (ERROR);
|
||||
cmd_parse_own(CMD_PARSE_VALUE_STRING, token);
|
||||
return (FORMAT);
|
||||
}
|
||||
while (next != '\n' && next != EOF)
|
||||
@@ -1348,35 +1476,37 @@ yylex(void)
|
||||
* % is a condition unless it is all % or all numbers,
|
||||
* then it is a token.
|
||||
*/
|
||||
yylval.token = yylex_get_word('%');
|
||||
for (cp = yylval.token; *cp != '\0'; cp++) {
|
||||
token = yylval.token = yylex_get_word('%');
|
||||
for (cp = token; *cp != '\0'; cp++) {
|
||||
if (*cp != '%' && !isdigit((u_char)*cp))
|
||||
break;
|
||||
}
|
||||
if (*cp == '\0')
|
||||
if (*cp == '\0') {
|
||||
cmd_parse_own(CMD_PARSE_VALUE_STRING, token);
|
||||
return (TOKEN);
|
||||
}
|
||||
ps->condition = 1;
|
||||
if (strcmp(yylval.token, "%hidden") == 0) {
|
||||
free(yylval.token);
|
||||
if (strcmp(token, "%hidden") == 0) {
|
||||
free(token);
|
||||
return (HIDDEN);
|
||||
}
|
||||
if (strcmp(yylval.token, "%if") == 0) {
|
||||
free(yylval.token);
|
||||
if (strcmp(token, "%if") == 0) {
|
||||
free(token);
|
||||
return (IF);
|
||||
}
|
||||
if (strcmp(yylval.token, "%else") == 0) {
|
||||
free(yylval.token);
|
||||
if (strcmp(token, "%else") == 0) {
|
||||
free(token);
|
||||
return (ELSE);
|
||||
}
|
||||
if (strcmp(yylval.token, "%elif") == 0) {
|
||||
free(yylval.token);
|
||||
if (strcmp(token, "%elif") == 0) {
|
||||
free(token);
|
||||
return (ELIF);
|
||||
}
|
||||
if (strcmp(yylval.token, "%endif") == 0) {
|
||||
free(yylval.token);
|
||||
if (strcmp(token, "%endif") == 0) {
|
||||
free(token);
|
||||
return (ENDIF);
|
||||
}
|
||||
free(yylval.token);
|
||||
free(token);
|
||||
return (ERROR);
|
||||
}
|
||||
|
||||
@@ -1386,7 +1516,7 @@ yylex(void)
|
||||
token = yylex_token(ch);
|
||||
if (token == NULL)
|
||||
return (ERROR);
|
||||
yylval.token = token;
|
||||
yylval.token = cmd_parse_own(CMD_PARSE_VALUE_STRING, token);
|
||||
|
||||
if (strchr(token, '=') != NULL && yylex_is_var(*token, 1)) {
|
||||
for (cp = token + 1; *cp != '='; cp++) {
|
||||
|
||||
Reference in New Issue
Block a user