aboutsummaryrefslogtreecommitdiff
path: root/cmd-parse.y
diff options
context:
space:
mode:
Diffstat (limited to 'cmd-parse.y')
-rw-r--r--cmd-parse.y96
1 files changed, 92 insertions, 4 deletions
diff --git a/cmd-parse.y b/cmd-parse.y
index 2375370b..891f2289 100644
--- a/cmd-parse.y
+++ b/cmd-parse.y
@@ -99,6 +99,7 @@ static void cmd_parse_print_commands(struct cmd_parse_input *, u_int,
}
%token ERROR
+%token HIDDEN
%token IF
%token ELSE
%token ELIF
@@ -138,6 +139,11 @@ statement : /* empty */
$$ = xmalloc (sizeof *$$);
TAILQ_INIT($$);
}
+ | hidden_assignment
+ {
+ $$ = xmalloc (sizeof *$$);
+ TAILQ_INIT($$);
+ }
| condition
{
struct cmd_parse_state *ps = &parse_state;
@@ -204,10 +210,21 @@ assignment : EQUALS
if ((~flags & CMD_PARSE_PARSEONLY) &&
(ps->scope == NULL || ps->scope->flag))
- environ_put(global_environ, $1);
+ environ_put(global_environ, $1, 0);
free($1);
}
+hidden_assignment : HIDDEN EQUALS
+ {
+ struct cmd_parse_state *ps = &parse_state;
+ int flags = ps->input->flags;
+
+ if ((~flags & CMD_PARSE_PARSEONLY) &&
+ (ps->scope == NULL || ps->scope->flag))
+ environ_put(global_environ, $2, ENVIRON_HIDDEN);
+ free($2);
+ }
+
if_open : IF expanded
{
struct cmd_parse_state *ps = &parse_state;
@@ -683,15 +700,17 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds,
/*
* Parse each command into a command list. Create a new command list
- * for each line so they get a new group (so the queue knows which ones
- * to remove if a command fails when executed).
+ * for each line (unless the flag is set) so they get a new group (so
+ * the queue knows which ones to remove if a command fails when
+ * executed).
*/
result = cmd_list_new();
TAILQ_FOREACH(cmd, cmds, entry) {
log_debug("%s: %u %s", __func__, cmd->line, cmd->name);
cmd_log_argv(cmd->argc, cmd->argv, __func__);
- if (cmdlist == NULL || cmd->line != line) {
+ if (cmdlist == NULL ||
+ ((~pi->flags & CMD_PARSE_ONEGROUP) && cmd->line != line)) {
if (cmdlist != NULL) {
cmd_parse_print_commands(pi, line, cmdlist);
cmd_list_move(result, cmdlist);
@@ -758,9 +777,74 @@ cmd_parse_from_file(FILE *f, struct cmd_parse_input *pi)
struct cmd_parse_result *
cmd_parse_from_string(const char *s, struct cmd_parse_input *pi)
{
+ struct cmd_parse_input input;
+
+ if (pi == NULL) {
+ memset(&input, 0, sizeof input);
+ pi = &input;
+ }
+
+ /*
+ * When parsing a string, put commands in one group even if there are
+ * multiple lines. This means { a \n b } is identical to "a ; b" when
+ * given as an argument to another command.
+ */
+ pi->flags |= CMD_PARSE_ONEGROUP;
return (cmd_parse_from_buffer(s, strlen(s), pi));
}
+enum cmd_parse_status
+cmd_parse_and_insert(const char *s, struct cmd_parse_input *pi,
+ struct cmdq_item *after, struct cmdq_state *state, char **error)
+{
+ struct cmd_parse_result *pr;
+ struct cmdq_item *item;
+
+ pr = cmd_parse_from_string(s, pi);
+ switch (pr->status) {
+ case CMD_PARSE_EMPTY:
+ break;
+ case CMD_PARSE_ERROR:
+ if (error != NULL)
+ *error = pr->error;
+ else
+ free(pr->error);
+ break;
+ case CMD_PARSE_SUCCESS:
+ item = cmdq_get_command(pr->cmdlist, state);
+ cmdq_insert_after(after, item);
+ cmd_list_free(pr->cmdlist);
+ break;
+ }
+ return (pr->status);
+}
+
+enum cmd_parse_status
+cmd_parse_and_append(const char *s, struct cmd_parse_input *pi,
+ struct client *c, struct cmdq_state *state, char **error)
+{
+ struct cmd_parse_result *pr;
+ struct cmdq_item *item;
+
+ pr = cmd_parse_from_string(s, pi);
+ switch (pr->status) {
+ case CMD_PARSE_EMPTY:
+ break;
+ case CMD_PARSE_ERROR:
+ if (error != NULL)
+ *error = pr->error;
+ else
+ free(pr->error);
+ break;
+ case CMD_PARSE_SUCCESS:
+ item = cmdq_get_command(pr->cmdlist, state);
+ cmdq_append(c, item);
+ cmd_list_free(pr->cmdlist);
+ break;
+ }
+ return (pr->status);
+}
+
struct cmd_parse_result *
cmd_parse_from_buffer(const void *buf, size_t len, struct cmd_parse_input *pi)
{
@@ -1079,6 +1163,10 @@ yylex(void)
if (*cp == '\0')
return (TOKEN);
ps->condition = 1;
+ if (strcmp(yylval.token, "%hidden") == 0) {
+ free(yylval.token);
+ return (HIDDEN);
+ }
if (strcmp(yylval.token, "%if") == 0) {
free(yylval.token);
return (IF);