From a4424fbebf929f4ad742200365fc330a26a65d7f Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 29 May 2019 10:08:36 +0000 Subject: Support \ooo escapes, from Avi Halachmi. --- cmd-parse.y | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'cmd-parse.y') diff --git a/cmd-parse.y b/cmd-parse.y index f347280b..739ca56c 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -1083,12 +1083,34 @@ error: static int yylex_token_escape(char **buf, size_t *len) { - int ch, type; + int ch, type, o2, o3; u_int size, i, tmp; char s[9]; struct utf8_data ud; - switch (ch = yylex_getc()) { + ch = yylex_getc(); + + if (ch >= '4' && ch <= '7') { + yyerror("invalid octal escape"); + return (0); + } + if (ch >= '0' && ch <= '3') { + o2 = yylex_getc(); + if (o2 >= '0' && o2 <= '7') { + o3 = yylex_getc(); + if (o3 >= '0' && o3 <= '7') { + ch = 64 * (ch - '0') + + 8 * (o2 - '0') + + (o3 - '0'); + yylex_append1(buf, len, ch); + return (1); + } + } + yyerror("invalid octal escape"); + return (0); + } + + switch (ch) { case EOF: return (0); case 'e': -- cgit From c17edd594e8088d2355102a8ca58f4b256c59397 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 29 May 2019 19:34:42 +0000 Subject: The line number needs to be updated only after the \n is processed by the parser, so store a flag and update it next time around. Also each new line needs its own shared data. --- cmd-parse.y | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'cmd-parse.y') diff --git a/cmd-parse.y b/cmd-parse.y index 739ca56c..a235fde1 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -58,6 +58,7 @@ struct cmd_parse_state { size_t len; size_t off; + int eol; int eof; struct cmd_parse_input *input; u_int escapes; @@ -933,6 +934,10 @@ yylex(void) char *token, *cp; int ch, next; + if (ps->eol) + ps->input->line++; + ps->eol = 0; + for (;;) { ch = yylex_getc(); @@ -959,7 +964,7 @@ yylex(void) /* * End of line. Update the line number. */ - ps->input->line++; + ps->eol = 1; return ('\n'); } -- cgit From 7dced376737ef685e09fd5a49161ca2bf423e91b Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 29 May 2019 20:05:14 +0000 Subject: Use VIS_CSTYLE for the arguments and add the missing escapes it can generate to the parser. --- cmd-parse.y | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'cmd-parse.y') diff --git a/cmd-parse.y b/cmd-parse.y index a235fde1..a623caa5 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -1118,9 +1118,24 @@ yylex_token_escape(char **buf, size_t *len) switch (ch) { case EOF: return (0); + case 'a': + ch = '\a'; + break; + case 'b': + ch = '\b'; + break; case 'e': ch = '\033'; break; + case 'f': + ch = '\f'; + break; + case 's': + ch = ' '; + break; + case 'v': + ch = '\v'; + break; case 'r': ch = '\r'; break; -- cgit From 8fb796b5b3fbd7ff430d1b6ad2a49f97feea8f3c Mon Sep 17 00:00:00 2001 From: nicm Date: Thu, 30 May 2019 10:04:33 +0000 Subject: No longer need to reduce line number by one. --- cmd-parse.y | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cmd-parse.y') diff --git a/cmd-parse.y b/cmd-parse.y index a623caa5..d5d12d95 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -361,7 +361,7 @@ command : assignment TOKEN $$ = xcalloc(1, sizeof *$$); $$->name = $2; - $$->line = ps->input->line - 1; + $$->line = ps->input->line; } | assignment TOKEN arguments @@ -370,7 +370,7 @@ command : assignment TOKEN $$ = xcalloc(1, sizeof *$$); $$->name = $2; - $$->line = ps->input->line - 1; + $$->line = ps->input->line; $$->argc = $3.argc; $$->argv = $3.argv; -- cgit From 82e47403c6a8d6fff90f77e9262840050b8e6b2e Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 31 May 2019 11:34:09 +0000 Subject: Allow % strings that are all numbers or %s, and fix a double free. Both reported by George Nachman, GitHub issues 1765 and 1766. --- cmd-parse.y | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'cmd-parse.y') diff --git a/cmd-parse.y b/cmd-parse.y index d5d12d95..0a627268 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -998,11 +998,15 @@ yylex(void) if (ch == '%') { /* - * % is a condition unless it is alone, then it is a - * token. + * % is a condition unless it is all % or all numbers, + * then it is a token. */ yylval.token = yylex_get_word('%'); - if (strcmp(yylval.token, "%") == 0) + for (cp = yylval.token; *cp != '\0'; cp++) { + if (*cp != '%' && !isdigit((u_char)*cp)) + break; + } + if (*cp == '\0') return (TOKEN); if (strcmp(yylval.token, "%if") == 0) { free(yylval.token); -- cgit From 39ea8a2787a29265970d0ef47a879527bc30d1f8 Mon Sep 17 00:00:00 2001 From: nicm Date: Sat, 1 Jun 2019 06:20:22 +0000 Subject: Need stdlib.h, from Ben Boeckel. --- cmd-parse.y | 1 + 1 file changed, 1 insertion(+) (limited to 'cmd-parse.y') diff --git a/cmd-parse.y b/cmd-parse.y index 0a627268..402ec806 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -23,6 +23,7 @@ #include #include #include +#include #include #include -- cgit From 900238a30657a477f3c62ba344fcc73fc0948ac7 Mon Sep 17 00:00:00 2001 From: nicm Date: Sun, 2 Jun 2019 07:10:15 +0000 Subject: 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@. --- cmd-parse.y | 263 ++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 140 insertions(+), 123 deletions(-) (limited to 'cmd-parse.y') 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)); } -- cgit From 8f40796f05f2db0ff8b2c9231054b62b511a7ba0 Mon Sep 17 00:00:00 2001 From: nicm Date: Wed, 5 Jun 2019 20:00:53 +0000 Subject: Add a -v flag to source-file to show the commands and line numbers. --- cmd-parse.y | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'cmd-parse.y') diff --git a/cmd-parse.y b/cmd-parse.y index e27cdcd8..a7c12f62 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -76,6 +76,8 @@ 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 *); +static void cmd_parse_print_commands(struct cmd_parse_input *, u_int, + struct cmd_list *); %} @@ -497,6 +499,19 @@ cmd_parse_get_error(const char *file, u_int line, const char *error) return (s); } +static void +cmd_parse_print_commands(struct cmd_parse_input *pi, u_int line, + struct cmd_list *cmdlist) +{ + char *s; + + if (pi->item != NULL && (pi->flags & CMD_PARSE_VERBOSE)) { + s = cmd_list_print(cmdlist, 0); + cmdq_print(pi->item, "%u: %s", line, s); + free(s); + } +} + static void cmd_parse_free_command(struct cmd_parse_command *cmd) { @@ -653,6 +668,7 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds, if (cmdlist == NULL || cmd->line != line) { if (cmdlist != NULL) { + cmd_parse_print_commands(pi, line, cmdlist); cmd_list_move(result, cmdlist); cmd_list_free(cmdlist); } @@ -672,6 +688,7 @@ cmd_parse_build_commands(struct cmd_parse_commands *cmds, cmd_list_append(cmdlist, add); } if (cmdlist != NULL) { + cmd_parse_print_commands(pi, line, cmdlist); cmd_list_move(result, cmdlist); cmd_list_free(cmdlist); } -- cgit From 45203582ff8708042c5f4f7134ad7d4ec71d2050 Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 14 Jun 2019 12:04:11 +0000 Subject: A couple of minor parser changes around conditions: 1) only treat #{ specially after a condition, otherwise as a comment (which is more as most people expect) 2) allow formats to be quoted after a condition. --- cmd-parse.y | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'cmd-parse.y') diff --git a/cmd-parse.y b/cmd-parse.y index a7c12f62..1a6af3e7 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -59,6 +59,7 @@ struct cmd_parse_state { size_t len; size_t off; + int condition; int eol; int eof; struct cmd_parse_input *input; @@ -104,7 +105,7 @@ static void cmd_parse_print_commands(struct cmd_parse_input *, u_int, %token ENDIF %token FORMAT TOKEN EQUALS -%type argument expanded +%type argument expanded format %type arguments %type if_open if_elif %type elif elif1 @@ -160,7 +161,16 @@ statement : condition } } -expanded : FORMAT +format : FORMAT + { + $$ = $1; + } + | TOKEN + { + $$ = $1; + } + +expanded : format { struct cmd_parse_state *ps = &parse_state; struct cmd_parse_input *pi = ps->input; @@ -967,12 +977,15 @@ yylex(void) { struct cmd_parse_state *ps = &parse_state; char *token, *cp; - int ch, next; + int ch, next, condition; if (ps->eol) ps->input->line++; ps->eol = 0; + condition = ps->condition; + ps->condition = 0; + for (;;) { ch = yylex_getc(); @@ -1012,11 +1025,11 @@ yylex(void) if (ch == '#') { /* - * #{ opens a format; anything else is a comment, - * ignore up to the end of the line. + * #{ after a condition opens a format; anything else + * is a comment, ignore up to the end of the line. */ next = yylex_getc(); - if (next == '{') { + if (condition && next == '{') { yylval.token = yylex_format(); if (yylval.token == NULL) return (ERROR); @@ -1043,6 +1056,7 @@ yylex(void) } if (*cp == '\0') return (TOKEN); + ps->condition = 1; if (strcmp(yylval.token, "%if") == 0) { free(yylval.token); return (IF); -- cgit From d1d3bbb458b50ec455d65774d5c6669546b3b4ca Mon Sep 17 00:00:00 2001 From: nicm Date: Fri, 14 Jun 2019 13:34:45 +0000 Subject: Show filename with -v for source-file. --- cmd-parse.y | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'cmd-parse.y') diff --git a/cmd-parse.y b/cmd-parse.y index 1a6af3e7..1dbc27a7 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -517,7 +517,10 @@ cmd_parse_print_commands(struct cmd_parse_input *pi, u_int line, if (pi->item != NULL && (pi->flags & CMD_PARSE_VERBOSE)) { s = cmd_list_print(cmdlist, 0); - cmdq_print(pi->item, "%u: %s", line, s); + if (pi->file != NULL) + cmdq_print(pi->item, "%s:%u: %s", pi->file, line, s); + else + cmdq_print(pi->item, "%u: %s", line, s); free(s); } } -- cgit From 250fdd08bea74f47fc9a8962d5688db353896921 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 18 Jun 2019 11:17:40 +0000 Subject: Handle comments more correctly inside {}, from Avi Halachmi. --- cmd-parse.y | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'cmd-parse.y') diff --git a/cmd-parse.y b/cmd-parse.y index 1dbc27a7..6d2b970c 100644 --- a/cmd-parse.y +++ b/cmd-parse.y @@ -1338,8 +1338,8 @@ static int yylex_token_brace(char **buf, size_t *len) { struct cmd_parse_state *ps = &parse_state; - int ch, nesting = 1, escape = 0, quote = '\0'; - int lines = 0; + int ch, lines = 0, nesting = 1, escape = 0; + int quote = '\0', token = 0; /* * Extract a string up to the matching unquoted '}', including newlines @@ -1349,6 +1349,10 @@ yylex_token_brace(char **buf, size_t *len) * depth, we scan the input as if it was a tmux config file, and ignore * braces which would be considered quoted, escaped, or in a comment. * + * We update the token state after every character because '#' begins a + * comment only when it begins a token. For simplicity, we treat an + * unquoted directive format as comment. + * * The result is verbatim copy of the input excluding the final brace. */ @@ -1368,6 +1372,8 @@ yylex_token_brace(char **buf, size_t *len) ch == '\n' || ch == '\\')) { escape = 0; + if (ch != '\n') + token = 1; continue; } @@ -1383,7 +1389,7 @@ yylex_token_brace(char **buf, size_t *len) /* A newline always resets to unquoted. */ if (ch == '\n') { - quote = 0; + quote = token = 0; continue; } @@ -1394,33 +1400,47 @@ yylex_token_brace(char **buf, size_t *len) */ if (ch == quote && quote != '#') quote = 0; - } else { + token = 1; /* token continues regardless */ + } else { /* Not inside quotes or comment. */ switch (ch) { case '"': case '\'': case '#': - /* Beginning of quote or comment. */ - quote = ch; + /* Beginning of quote or maybe comment. */ + if (ch != '#' || !token) + quote = ch; + token = 1; + break; + case ' ': + case '\t': + case ';': + /* Delimiter - token resets. */ + token = 0; break; case '{': nesting++; + token = 0; /* new commands set - token resets */ break; case '}': nesting--; + token = 1; /* same as after quotes */ if (nesting == 0) { (*len)--; /* remove closing } */ ps->input->line += lines; return (1); } break; + default: + token = 1; + break; } } } /* - * Update line count after error as reporting the opening line - * is more useful than EOF. + * Update line count after error as reporting the opening line is more + * useful than EOF. */ yyerror("unterminated brace string"); ps->input->line += lines; -- cgit