Track allocations in yacc to avoid leaking when parsing commands, GitHub

issue 5632 from Jeong, Heon.
This commit is contained in:
nicm
2026-10-08 06:44:16 +00:00
committed by tmux update bot
parent 4dc67a5dd6
commit 9a92292029

View File

@@ -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> * 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); 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 { struct cmd_parse_state {
FILE *f; FILE *f;
@@ -87,10 +103,16 @@ struct cmd_parse_state {
struct cmd_parse_scope *scope; struct cmd_parse_scope *scope;
TAILQ_HEAD(, cmd_parse_scope) stack; TAILQ_HEAD(, cmd_parse_scope) stack;
struct cmd_parse_owned_values values;
}; };
static struct cmd_parse_state parse_state; 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_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 void cmd_parse_free_command(struct cmd_parse_command *);
static struct cmd_parse_commands *cmd_parse_new_commands(void); 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 *);
@@ -139,7 +161,7 @@ lines : /* empty */
{ {
struct cmd_parse_state *ps = &parse_state; struct cmd_parse_state *ps = &parse_state;
ps->commands = $1; ps->commands = cmd_parse_take($1);
} }
statements : statement '\n' statements : statement '\n'
@@ -150,18 +172,16 @@ statements : statement '\n'
{ {
$$ = $1; $$ = $1;
TAILQ_CONCAT($$, $2, entry); TAILQ_CONCAT($$, $2, entry);
free($2); cmd_parse_drop($2);
} }
statement : /* empty */ statement : /* empty */
{ {
$$ = xmalloc (sizeof *$$); $$ = cmd_parse_own_commands();
TAILQ_INIT($$);
} }
| hidden_assignment | hidden_assignment
{ {
$$ = xmalloc (sizeof *$$); $$ = cmd_parse_own_commands();
TAILQ_INIT($$);
} }
| condition | condition
{ {
@@ -170,8 +190,8 @@ statement : /* empty */
if (ps->scope == NULL || ps->scope->flag) if (ps->scope == NULL || ps->scope->flag)
$$ = $1; $$ = $1;
else { else {
$$ = cmd_parse_new_commands(); $$ = cmd_parse_own_commands();
cmd_parse_free_commands($1); cmd_parse_drop($1);
} }
} }
| commands | commands
@@ -181,8 +201,8 @@ statement : /* empty */
if (ps->scope == NULL || ps->scope->flag) if (ps->scope == NULL || ps->scope->flag)
$$ = $1; $$ = $1;
else { else {
$$ = cmd_parse_new_commands(); $$ = cmd_parse_own_commands();
cmd_parse_free_commands($1); cmd_parse_drop($1);
} }
} }
@@ -204,6 +224,7 @@ expanded : format
struct cmd_find_state *fsp; struct cmd_find_state *fsp;
struct cmd_find_state fs; struct cmd_find_state fs;
int flags = FORMAT_NOJOBS; int flags = FORMAT_NOJOBS;
char *expanded;
if (cmd_find_valid_state(&pi->fs)) if (cmd_find_valid_state(&pi->fs))
fsp = &pi->fs; fsp = &pi->fs;
@@ -214,9 +235,10 @@ expanded : format
ft = format_create(c, pi->item, FORMAT_NONE, flags); ft = format_create(c, pi->item, FORMAT_NONE, flags);
format_defaults(ft, c, fsp->s, fsp->wl, fsp->wp); 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); format_free(ft);
free($1); cmd_parse_drop($1);
} }
optional_assignment : /* empty */ optional_assignment : /* empty */
@@ -241,7 +263,7 @@ assignment : EQUALS
} }
if ((~flags & CMD_PARSE_PARSEONLY) && flag) if ((~flags & CMD_PARSE_PARSEONLY) && flag)
environ_put(global_environ, $1, 0); environ_put(global_environ, $1, 0);
free($1); cmd_parse_drop($1);
} }
hidden_assignment : HIDDEN EQUALS hidden_assignment : HIDDEN EQUALS
@@ -263,7 +285,7 @@ hidden_assignment : HIDDEN EQUALS
} }
if ((~flags & CMD_PARSE_PARSEONLY) && flag) if ((~flags & CMD_PARSE_PARSEONLY) && flag)
environ_put(global_environ, $2, ENVIRON_HIDDEN); environ_put(global_environ, $2, ENVIRON_HIDDEN);
free($2); cmd_parse_drop($2);
} }
if_open : IF expanded if_open : IF expanded
@@ -274,7 +296,7 @@ if_open : IF expanded
scope = xmalloc(sizeof *scope); scope = xmalloc(sizeof *scope);
$$ = scope->flag = format_true($2); $$ = scope->flag = format_true($2);
scope->taken = scope->flag; scope->taken = scope->flag;
free($2); cmd_parse_drop($2);
if (ps->scope != NULL) if (ps->scope != NULL)
TAILQ_INSERT_HEAD(&ps->stack, ps->scope, entry); 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->flag = !ps->scope->taken && format_true($2);
scope->taken = ps->scope->taken || scope->flag; scope->taken = ps->scope->taken || scope->flag;
$$ = scope->flag; $$ = scope->flag;
free($2); cmd_parse_drop($2);
free(ps->scope); free(ps->scope);
ps->scope = scope; ps->scope = scope;
@@ -324,48 +346,48 @@ condition : if_open '\n' statements if_close
if ($1) if ($1)
$$ = $3; $$ = $3;
else { else {
$$ = cmd_parse_new_commands(); $$ = cmd_parse_own_commands();
cmd_parse_free_commands($3); cmd_parse_drop($3);
} }
} }
| if_open '\n' statements if_else '\n' statements if_close | if_open '\n' statements if_else '\n' statements if_close
{ {
if ($1) { if ($1) {
$$ = $3; $$ = $3;
cmd_parse_free_commands($6); cmd_parse_drop($6);
} else { } else {
$$ = $6; $$ = $6;
cmd_parse_free_commands($3); cmd_parse_drop($3);
} }
} }
| if_open '\n' statements elif if_close | if_open '\n' statements elif if_close
{ {
if ($1) { if ($1) {
$$ = $3; $$ = $3;
cmd_parse_free_commands($4.commands); cmd_parse_drop($4.commands);
} else if ($4.flag) { } else if ($4.flag) {
$$ = $4.commands; $$ = $4.commands;
cmd_parse_free_commands($3); cmd_parse_drop($3);
} else { } else {
$$ = cmd_parse_new_commands(); $$ = cmd_parse_own_commands();
cmd_parse_free_commands($3); cmd_parse_drop($3);
cmd_parse_free_commands($4.commands); cmd_parse_drop($4.commands);
} }
} }
| if_open '\n' statements elif if_else '\n' statements if_close | if_open '\n' statements elif if_else '\n' statements if_close
{ {
if ($1) { if ($1) {
$$ = $3; $$ = $3;
cmd_parse_free_commands($4.commands); cmd_parse_drop($4.commands);
cmd_parse_free_commands($7); cmd_parse_drop($7);
} else if ($4.flag) { } else if ($4.flag) {
$$ = $4.commands; $$ = $4.commands;
cmd_parse_free_commands($3); cmd_parse_drop($3);
cmd_parse_free_commands($7); cmd_parse_drop($7);
} else { } else {
$$ = $7; $$ = $7;
cmd_parse_free_commands($3); cmd_parse_drop($3);
cmd_parse_free_commands($4.commands); cmd_parse_drop($4.commands);
} }
} }
@@ -376,8 +398,8 @@ elif : if_elif '\n' statements
$$.commands = $3; $$.commands = $3;
} else { } else {
$$.flag = 0; $$.flag = 0;
$$.commands = cmd_parse_new_commands(); $$.commands = cmd_parse_own_commands();
cmd_parse_free_commands($3); cmd_parse_drop($3);
} }
} }
| if_elif '\n' statements elif | if_elif '\n' statements elif
@@ -385,16 +407,16 @@ elif : if_elif '\n' statements
if ($1) { if ($1) {
$$.flag = 1; $$.flag = 1;
$$.commands = $3; $$.commands = $3;
cmd_parse_free_commands($4.commands); cmd_parse_drop($4.commands);
} else if ($4.flag) { } else if ($4.flag) {
$$.flag = 1; $$.flag = 1;
$$.commands = $4.commands; $$.commands = $4.commands;
cmd_parse_free_commands($3); cmd_parse_drop($3);
} else { } else {
$$.flag = 0; $$.flag = 0;
$$.commands = cmd_parse_new_commands(); $$.commands = cmd_parse_own_commands();
cmd_parse_free_commands($3); cmd_parse_drop($3);
cmd_parse_free_commands($4.commands); cmd_parse_drop($4.commands);
} }
} }
@@ -402,12 +424,13 @@ commands : command
{ {
struct cmd_parse_state *ps = &parse_state; struct cmd_parse_state *ps = &parse_state;
$$ = cmd_parse_new_commands(); $$ = cmd_parse_own_commands();
if (!TAILQ_EMPTY(&$1->arguments) && 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); TAILQ_INSERT_TAIL($$, $1, entry);
else } else
cmd_parse_free_command($1); cmd_parse_drop($1);
} }
| commands ';' | commands ';'
{ {
@@ -417,7 +440,7 @@ commands : command
{ {
$$ = $1; $$ = $1;
TAILQ_CONCAT($$, $3, entry); TAILQ_CONCAT($$, $3, entry);
free($3); cmd_parse_drop($3);
} }
| commands ';' command | commands ';' command
{ {
@@ -426,9 +449,10 @@ commands : command
$$ = $1; $$ = $1;
if (!TAILQ_EMPTY(&$3->arguments) && if (!TAILQ_EMPTY(&$3->arguments) &&
(ps->scope == NULL || ps->scope->flag)) { (ps->scope == NULL || ps->scope->flag)) {
cmd_parse_take($3);
TAILQ_INSERT_TAIL($$, $3, entry); TAILQ_INSERT_TAIL($$, $3, entry);
} else } else
cmd_parse_free_command($3); cmd_parse_drop($3);
} }
| condition1 | condition1
{ {
@@ -442,6 +466,7 @@ command : assignment
$$ = xcalloc(1, sizeof *$$); $$ = xcalloc(1, sizeof *$$);
$$->line = ps->input->line; $$->line = ps->input->line;
TAILQ_INIT(&$$->arguments); TAILQ_INIT(&$$->arguments);
cmd_parse_own(CMD_PARSE_VALUE_COMMAND, $$);
} }
| optional_assignment TOKEN | optional_assignment TOKEN
{ {
@@ -454,8 +479,9 @@ command : assignment
arg = xcalloc(1, sizeof *arg); arg = xcalloc(1, sizeof *arg);
arg->type = CMD_PARSE_STRING; arg->type = CMD_PARSE_STRING;
arg->string = $2; arg->string = cmd_parse_take($2);
TAILQ_INSERT_HEAD(&$$->arguments, arg, entry); TAILQ_INSERT_HEAD(&$$->arguments, arg, entry);
cmd_parse_own(CMD_PARSE_VALUE_COMMAND, $$);
} }
| optional_assignment TOKEN arguments | optional_assignment TOKEN arguments
{ {
@@ -467,12 +493,13 @@ command : assignment
TAILQ_INIT(&$$->arguments); TAILQ_INIT(&$$->arguments);
TAILQ_CONCAT(&$$->arguments, $3, entry); TAILQ_CONCAT(&$$->arguments, $3, entry);
free($3); cmd_parse_drop($3);
arg = xcalloc(1, sizeof *arg); arg = xcalloc(1, sizeof *arg);
arg->type = CMD_PARSE_STRING; arg->type = CMD_PARSE_STRING;
arg->string = $2; arg->string = cmd_parse_take($2);
TAILQ_INSERT_HEAD(&$$->arguments, arg, entry); TAILQ_INSERT_HEAD(&$$->arguments, arg, entry);
cmd_parse_own(CMD_PARSE_VALUE_COMMAND, $$);
} }
condition1 : if_open commands if_close condition1 : if_open commands if_close
@@ -480,48 +507,48 @@ condition1 : if_open commands if_close
if ($1) if ($1)
$$ = $2; $$ = $2;
else { else {
$$ = cmd_parse_new_commands(); $$ = cmd_parse_own_commands();
cmd_parse_free_commands($2); cmd_parse_drop($2);
} }
} }
| if_open commands if_else commands if_close | if_open commands if_else commands if_close
{ {
if ($1) { if ($1) {
$$ = $2; $$ = $2;
cmd_parse_free_commands($4); cmd_parse_drop($4);
} else { } else {
$$ = $4; $$ = $4;
cmd_parse_free_commands($2); cmd_parse_drop($2);
} }
} }
| if_open commands elif1 if_close | if_open commands elif1 if_close
{ {
if ($1) { if ($1) {
$$ = $2; $$ = $2;
cmd_parse_free_commands($3.commands); cmd_parse_drop($3.commands);
} else if ($3.flag) { } else if ($3.flag) {
$$ = $3.commands; $$ = $3.commands;
cmd_parse_free_commands($2); cmd_parse_drop($2);
} else { } else {
$$ = cmd_parse_new_commands(); $$ = cmd_parse_own_commands();
cmd_parse_free_commands($2); cmd_parse_drop($2);
cmd_parse_free_commands($3.commands); cmd_parse_drop($3.commands);
} }
} }
| if_open commands elif1 if_else commands if_close | if_open commands elif1 if_else commands if_close
{ {
if ($1) { if ($1) {
$$ = $2; $$ = $2;
cmd_parse_free_commands($3.commands); cmd_parse_drop($3.commands);
cmd_parse_free_commands($5); cmd_parse_drop($5);
} else if ($3.flag) { } else if ($3.flag) {
$$ = $3.commands; $$ = $3.commands;
cmd_parse_free_commands($2); cmd_parse_drop($2);
cmd_parse_free_commands($5); cmd_parse_drop($5);
} else { } else {
$$ = $5; $$ = $5;
cmd_parse_free_commands($2); cmd_parse_drop($2);
cmd_parse_free_commands($3.commands); cmd_parse_drop($3.commands);
} }
} }
@@ -532,8 +559,8 @@ elif1 : if_elif commands
$$.commands = $2; $$.commands = $2;
} else { } else {
$$.flag = 0; $$.flag = 0;
$$.commands = cmd_parse_new_commands(); $$.commands = cmd_parse_own_commands();
cmd_parse_free_commands($2); cmd_parse_drop($2);
} }
} }
| if_elif commands elif1 | if_elif commands elif1
@@ -541,16 +568,16 @@ elif1 : if_elif commands
if ($1) { if ($1) {
$$.flag = 1; $$.flag = 1;
$$.commands = $2; $$.commands = $2;
cmd_parse_free_commands($3.commands); cmd_parse_drop($3.commands);
} else if ($3.flag) { } else if ($3.flag) {
$$.flag = 1; $$.flag = 1;
$$.commands = $3.commands; $$.commands = $3.commands;
cmd_parse_free_commands($2); cmd_parse_drop($2);
} else { } else {
$$.flag = 0; $$.flag = 0;
$$.commands = cmd_parse_new_commands(); $$.commands = cmd_parse_own_commands();
cmd_parse_free_commands($2); cmd_parse_drop($2);
cmd_parse_free_commands($3.commands); cmd_parse_drop($3.commands);
} }
} }
@@ -559,10 +586,13 @@ arguments : argument
$$ = xcalloc(1, sizeof *$$); $$ = xcalloc(1, sizeof *$$);
TAILQ_INIT($$); TAILQ_INIT($$);
cmd_parse_take($1);
TAILQ_INSERT_HEAD($$, $1, entry); TAILQ_INSERT_HEAD($$, $1, entry);
cmd_parse_own(CMD_PARSE_VALUE_ARGUMENTS, $$);
} }
| argument arguments | argument arguments
{ {
cmd_parse_take($1);
TAILQ_INSERT_HEAD($2, $1, entry); TAILQ_INSERT_HEAD($2, $1, entry);
$$ = $2; $$ = $2;
} }
@@ -571,19 +601,22 @@ argument : TOKEN
{ {
$$ = xcalloc(1, sizeof *$$); $$ = xcalloc(1, sizeof *$$);
$$->type = CMD_PARSE_STRING; $$->type = CMD_PARSE_STRING;
$$->string = $1; $$->string = cmd_parse_take($1);
cmd_parse_own(CMD_PARSE_VALUE_ARGUMENT, $$);
} }
| EQUALS | EQUALS
{ {
$$ = xcalloc(1, sizeof *$$); $$ = xcalloc(1, sizeof *$$);
$$->type = CMD_PARSE_STRING; $$->type = CMD_PARSE_STRING;
$$->string = $1; $$->string = cmd_parse_take($1);
cmd_parse_own(CMD_PARSE_VALUE_ARGUMENT, $$);
} }
| '{' argument_statements | '{' argument_statements
{ {
$$ = xcalloc(1, sizeof *$$); $$ = xcalloc(1, sizeof *$$);
$$->type = CMD_PARSE_COMMANDS; $$->type = CMD_PARSE_COMMANDS;
$$->commands = $2; $$->commands = cmd_parse_take($2);
cmd_parse_own(CMD_PARSE_VALUE_ARGUMENT, $$);
} }
argument_statements : statement '}' argument_statements : statement '}'
@@ -594,7 +627,7 @@ argument_statements : statement '}'
{ {
$$ = $1; $$ = $1;
TAILQ_CONCAT($$, $2, entry); 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); 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 * 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_scope *scope, *scope1; struct cmd_parse_scope *scope, *scope1;
int retval; struct cmd_parse_owned_value *v, *v1;
int retval;
ps->commands = NULL; ps->commands = NULL;
TAILQ_INIT(&ps->stack); TAILQ_INIT(&ps->stack);
TAILQ_INIT(&ps->values);
retval = yyparse(); retval = yyparse();
TAILQ_FOREACH_SAFE(scope, &ps->stack, entry, scope1) { TAILQ_FOREACH_SAFE(scope, &ps->stack, entry, scope1) {
TAILQ_REMOVE(&ps->stack, scope, entry); TAILQ_REMOVE(&ps->stack, scope, entry);
free(scope); 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 (retval != 0) {
if (ps->commands != NULL)
cmd_parse_free_commands(ps->commands);
*cause = ps->error; *cause = ps->error;
return (NULL); return (NULL);
} }
@@ -1329,9 +1456,10 @@ yylex(void)
*/ */
next = yylex_getc(); next = yylex_getc();
if (condition && next == '{') { if (condition && next == '{') {
yylval.token = yylex_format(); token = yylval.token = yylex_format();
if (yylval.token == NULL) if (token == NULL)
return (ERROR); return (ERROR);
cmd_parse_own(CMD_PARSE_VALUE_STRING, token);
return (FORMAT); return (FORMAT);
} }
while (next != '\n' && next != EOF) while (next != '\n' && next != EOF)
@@ -1348,35 +1476,37 @@ yylex(void)
* % is a condition unless it is all % or all numbers, * % is a condition unless it is all % or all numbers,
* then it is a token. * then it is a token.
*/ */
yylval.token = yylex_get_word('%'); token = yylval.token = yylex_get_word('%');
for (cp = yylval.token; *cp != '\0'; cp++) { for (cp = token; *cp != '\0'; cp++) {
if (*cp != '%' && !isdigit((u_char)*cp)) if (*cp != '%' && !isdigit((u_char)*cp))
break; break;
} }
if (*cp == '\0') if (*cp == '\0') {
cmd_parse_own(CMD_PARSE_VALUE_STRING, token);
return (TOKEN); return (TOKEN);
}
ps->condition = 1; ps->condition = 1;
if (strcmp(yylval.token, "%hidden") == 0) { if (strcmp(token, "%hidden") == 0) {
free(yylval.token); free(token);
return (HIDDEN); return (HIDDEN);
} }
if (strcmp(yylval.token, "%if") == 0) { if (strcmp(token, "%if") == 0) {
free(yylval.token); free(token);
return (IF); return (IF);
} }
if (strcmp(yylval.token, "%else") == 0) { if (strcmp(token, "%else") == 0) {
free(yylval.token); free(token);
return (ELSE); return (ELSE);
} }
if (strcmp(yylval.token, "%elif") == 0) { if (strcmp(token, "%elif") == 0) {
free(yylval.token); free(token);
return (ELIF); return (ELIF);
} }
if (strcmp(yylval.token, "%endif") == 0) { if (strcmp(token, "%endif") == 0) {
free(yylval.token); free(token);
return (ENDIF); return (ENDIF);
} }
free(yylval.token); free(token);
return (ERROR); return (ERROR);
} }
@@ -1386,7 +1516,7 @@ yylex(void)
token = yylex_token(ch); token = yylex_token(ch);
if (token == NULL) if (token == NULL)
return (ERROR); return (ERROR);
yylval.token = token; yylval.token = cmd_parse_own(CMD_PARSE_VALUE_STRING, token);
if (strchr(token, '=') != NULL && yylex_is_var(*token, 1)) { if (strchr(token, '=') != NULL && yylex_is_var(*token, 1)) {
for (cp = token + 1; *cp != '='; cp++) { for (cp = token + 1; *cp != '='; cp++) {