Parser changes shortly before a release. What could possibly go wrong.
%x BAR_COLORS
%x BAR_COLOR
+%x EXEC
+
%%
{
<COLOR_COND>#[0-9a-fA-F]+ { yy_pop_state(); yylval.string = sstrdup(yytext); return HEXCOLOR; }
<ASSIGN_TARGET_COND>[ \t]*→[ \t]* { BEGIN(WANT_STRING); }
<ASSIGN_TARGET_COND>[ \t]+ { BEGIN(WANT_STRING); }
+<EXEC>--no-startup-id { printf("no startup id\n"); yy_pop_state(); return TOK_NO_STARTUP_ID; }
+<EXEC>. { printf("anything else: *%s*\n", yytext); yyless(0); yy_pop_state(); yy_pop_state(); }
[0-9]+ { yylval.number = atoi(yytext); return NUMBER; }
bar { yy_push_state(BAR); return TOK_BAR; }
mode { return TOKMODE; }
stack-limit { return TOKSTACKLIMIT; }
cols { /* yylval.number = STACK_LIMIT_COLS; */return TOKSTACKLIMIT; }
rows { /* yylval.number = STACK_LIMIT_ROWS; */return TOKSTACKLIMIT; }
-exec { WS_STRING; return TOKEXEC; }
-exec_always { WS_STRING; return TOKEXEC_ALWAYS; }
+exec { WS_STRING; yy_push_state(EXEC); yy_push_state(EAT_WHITESPACE); return TOKEXEC; }
+exec_always { WS_STRING; yy_push_state(EXEC); yy_push_state(EAT_WHITESPACE); return TOKEXEC_ALWAYS; }
client.background { yy_push_state(COLOR_COND); yylval.single_color = &config.client.background; return TOKSINGLECOLOR; }
client.focused { yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yylval.color = &config.client.focused; return TOKCOLOR; }
client.focused_inactive { yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yy_push_state(COLOR_COND); yylval.color = &config.client.focused_inactive; return TOKCOLOR; }
%token TOK_BAR_COLOR_ACTIVE_WORKSPACE "active_workspace"
%token TOK_BAR_COLOR_INACTIVE_WORKSPACE "inactive_workspace"
%token TOK_BAR_COLOR_URGENT_WORKSPACE "urgent_workspace"
+%token TOK_NO_STARTUP_ID "--no-startup-id"
%token TOK_MARK "mark"
%token TOK_CLASS "class"
%type <number> popup_setting
%type <number> bar_position_position
%type <number> bar_mode_mode
+%type <number> optional_no_startup_id
%type <string> command
%type <string> word_or_number
%type <string> qstring_or_number
;
exec:
- TOKEXEC STR
+ TOKEXEC optional_no_startup_id STR
{
- char *command = $2;
- bool no_startup_id = false;
- if (strncasecmp($2, "--no-startup-id ", strlen("--no-startup-id ")) == 0) {
- no_startup_id = true;
- /* We need to make a copy here, otherwise we leak the
- * --no-startup-id bytes in the beginning of the string */
- command = sstrdup(command + strlen("--no-startup-id "));
- free($2);
- }
-
struct Autostart *new = smalloc(sizeof(struct Autostart));
- new->command = command;
- new->no_startup_id = no_startup_id;
+ new->command = $3;
+ new->no_startup_id = $2;
TAILQ_INSERT_TAIL(&autostarts, new, autostarts);
}
;
exec_always:
- TOKEXEC_ALWAYS STR
+ TOKEXEC_ALWAYS optional_no_startup_id STR
{
- char *command = $2;
- bool no_startup_id = false;
- if (strncasecmp($2, "--no-startup-id ", strlen("--no-startup-id ")) == 0) {
- no_startup_id = true;
- /* We need to make a copy here, otherwise we leak the
- * --no-startup-id bytes in the beginning of the string */
- command = sstrdup(command + strlen("--no-startup-id "));
- free($2);
- }
-
struct Autostart *new = smalloc(sizeof(struct Autostart));
- new->command = command;
- new->no_startup_id = no_startup_id;
+ new->command = $3;
+ new->no_startup_id = $2;
TAILQ_INSERT_TAIL(&autostarts_always, new, autostarts_always);
}
;
+optional_no_startup_id:
+ /* empty */ { $$ = false; }
+ | TOK_NO_STARTUP_ID { $$ = true; }
+ ;
+
terminal:
TOKTERMINAL STR
{
/* handle a quoted string or everything up to the next whitespace */
%s WANT_QSTRING
+%x EXEC
+
%x BUFFER_LINE
%%
<EAT_WHITESPACE>[ \t]* { yy_pop_state(); }
[ \t]* { /* ignore whitespace */ ; }
-exec { WS_STRING; return TOK_EXEC; }
+<EXEC>--no-startup-id { printf("no startup id\n"); yy_pop_state(); return TOK_NO_STARTUP_ID; }
+<EXEC>. { printf("anything else: *%s*\n", yytext); yyless(0); yy_pop_state(); yy_pop_state(); }
+exec { WS_STRING; yy_push_state(EXEC); yy_push_state(EAT_WHITESPACE); return TOK_EXEC; }
exit { return TOK_EXIT; }
reload { return TOK_RELOAD; }
restart { return TOK_RESTART; }
%token TOK_PPT "ppt"
%token TOK_NOP "nop"
%token TOK_BACK_AND_FORTH "back_and_forth"
+%token TOK_NO_STARTUP_ID "--no-startup-id"
%token TOK_CLASS "class"
%token TOK_INSTANCE "instance"
%type <number> resize_way
%type <number> resize_tiling
%type <number> optional_kill_mode
+%type <number> optional_no_startup_id
%%
;
exec:
- TOK_EXEC STR
+ TOK_EXEC optional_no_startup_id STR
{
- char *command = $2;
- bool no_startup_id = false;
- if (strncasecmp($2, "--no-startup-id ", strlen("--no-startup-id ")) == 0) {
- no_startup_id = true;
- command += strlen("--no-startup-id ");
- }
+ char *command = $3;
+ bool no_startup_id = $2;
printf("should execute %s, no_startup_id = %d\n", command, no_startup_id);
start_application(command, no_startup_id);
- free($2);
+ free($3);
}
;
+optional_no_startup_id:
+ /* empty */ { $$ = false; }
+ | TOK_NO_STARTUP_ID { $$ = true; }
+ ;
+
exit:
TOK_EXIT
{
is($startup_id, '', 'startup_id empty');
+######################################################################
+# 4) same thing, but with double quotes in exec
+######################################################################
+
+mkfifo($tmp, 0600) or die "Could not create FIFO in $tmp";
+
+cmd qq|exec --no-startup-id "echo \$DESKTOP_STARTUP_ID >$tmp"|;
+
+open($fh, '<', $tmp);
+chomp($startup_id = <$fh>);
+close($fh);
+
+unlink($tmp);
+
+is($startup_id, '', 'startup_id empty');
+
+
done_testing;