diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-11-12 11:13:59 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-12 11:13:59 -0500 |
commit | 2e43f02427282fa045aa774f79d0e67e39e62adb (patch) | |
tree | 717eca06cbc2c4cd05fa04469bde1b9d5afceec2 | |
parent | Merge pull request #3113 from RedSoxFan/fix-ws-auto-back-and-forth (diff) | |
parent | Alter config variable replacement process (diff) | |
download | sway-2e43f02427282fa045aa774f79d0e67e39e62adb.tar.gz sway-2e43f02427282fa045aa774f79d0e67e39e62adb.tar.zst sway-2e43f02427282fa045aa774f79d0e67e39e62adb.zip |
Merge pull request #2979 from RedSoxFan/config-var-repl
Alter config variable replacement process
-rw-r--r-- | sway/commands.c | 61 |
1 files changed, 46 insertions, 15 deletions
diff --git a/sway/commands.c b/sway/commands.c index 37c7169a..4b86c2fa 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -353,12 +353,14 @@ struct cmd_results *config_command(char *exec) { | |||
353 | struct cmd_results *results = NULL; | 353 | struct cmd_results *results = NULL; |
354 | int argc; | 354 | int argc; |
355 | char **argv = split_args(exec, &argc); | 355 | char **argv = split_args(exec, &argc); |
356 | |||
357 | // Check for empty lines | ||
356 | if (!argc) { | 358 | if (!argc) { |
357 | results = cmd_results_new(CMD_SUCCESS, NULL, NULL); | 359 | results = cmd_results_new(CMD_SUCCESS, NULL, NULL); |
358 | goto cleanup; | 360 | goto cleanup; |
359 | } | 361 | } |
360 | 362 | ||
361 | // Start block | 363 | // Check for the start of a block |
362 | if (argc > 1 && strcmp(argv[argc - 1], "{") == 0) { | 364 | if (argc > 1 && strcmp(argv[argc - 1], "{") == 0) { |
363 | char *block = join_args(argv, argc - 1); | 365 | char *block = join_args(argv, argc - 1); |
364 | results = cmd_results_new(CMD_BLOCK, block, NULL); | 366 | results = cmd_results_new(CMD_BLOCK, block, NULL); |
@@ -366,22 +368,54 @@ struct cmd_results *config_command(char *exec) { | |||
366 | goto cleanup; | 368 | goto cleanup; |
367 | } | 369 | } |
368 | 370 | ||
369 | // Endblock | 371 | // Check for the end of a block |
370 | if (strcmp(argv[argc - 1], "}") == 0) { | 372 | if (strcmp(argv[argc - 1], "}") == 0) { |
371 | results = cmd_results_new(CMD_BLOCK_END, NULL, NULL); | 373 | results = cmd_results_new(CMD_BLOCK_END, NULL, NULL); |
372 | goto cleanup; | 374 | goto cleanup; |
373 | } | 375 | } |
374 | wlr_log(WLR_INFO, "handling config command '%s'", exec); | 376 | |
377 | // Make sure the command is not stored in a variable | ||
378 | if (*argv[0] == '$') { | ||
379 | argv[0] = do_var_replacement(argv[0]); | ||
380 | char *temp = join_args(argv, argc); | ||
381 | free_argv(argc, argv); | ||
382 | argv = split_args(temp, &argc); | ||
383 | free(temp); | ||
384 | if (!argc) { | ||
385 | results = cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
386 | goto cleanup; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | // Determine the command handler | ||
391 | wlr_log(WLR_INFO, "Config command: %s", exec); | ||
375 | struct cmd_handler *handler = find_handler(argv[0], NULL, 0); | 392 | struct cmd_handler *handler = find_handler(argv[0], NULL, 0); |
376 | if (!handler) { | 393 | if (!handler || !handler->handle) { |
377 | char *input = argv[0] ? argv[0] : "(empty)"; | 394 | char *input = argv[0] ? argv[0] : "(empty)"; |
378 | results = cmd_results_new(CMD_INVALID, input, "Unknown/invalid command"); | 395 | char *error = handler |
396 | ? "This command is shimmed, but unimplemented" | ||
397 | : "Unknown/invalid command"; | ||
398 | results = cmd_results_new(CMD_INVALID, input, error); | ||
379 | goto cleanup; | 399 | goto cleanup; |
380 | } | 400 | } |
381 | int i; | 401 | |
382 | // Var replacement, for all but first argument of set | 402 | // Do variable replacement |
383 | // TODO commands | 403 | if (handler->handle == cmd_set && argc > 1 && *argv[1] == '$') { |
384 | for (i = handler->handle == cmd_set ? 2 : 1; i < argc; ++i) { | 404 | // Escape the variable name so it does not get replaced by one shorter |
405 | char *temp = calloc(1, strlen(argv[1]) + 2); | ||
406 | temp[0] = '$'; | ||
407 | strcpy(&temp[1], argv[1]); | ||
408 | free(argv[1]); | ||
409 | argv[1] = temp; | ||
410 | } | ||
411 | char *command = do_var_replacement(join_args(argv, argc)); | ||
412 | wlr_log(WLR_INFO, "After replacement: %s", command); | ||
413 | free_argv(argc, argv); | ||
414 | argv = split_args(command, &argc); | ||
415 | free(command); | ||
416 | |||
417 | // Strip quotes and unescape the string | ||
418 | for (int i = handler->handle == cmd_set ? 2 : 1; i < argc; ++i) { | ||
385 | if (handler->handle != cmd_exec && handler->handle != cmd_exec_always | 419 | if (handler->handle != cmd_exec && handler->handle != cmd_exec_always |
386 | && handler->handle != cmd_bindsym | 420 | && handler->handle != cmd_bindsym |
387 | && handler->handle != cmd_bindcode | 421 | && handler->handle != cmd_bindcode |
@@ -389,14 +423,11 @@ struct cmd_results *config_command(char *exec) { | |||
389 | && (*argv[i] == '\"' || *argv[i] == '\'')) { | 423 | && (*argv[i] == '\"' || *argv[i] == '\'')) { |
390 | strip_quotes(argv[i]); | 424 | strip_quotes(argv[i]); |
391 | } | 425 | } |
392 | argv[i] = do_var_replacement(argv[i]); | ||
393 | unescape_string(argv[i]); | 426 | unescape_string(argv[i]); |
394 | } | 427 | } |
395 | if (handler->handle) { | 428 | |
396 | results = handler->handle(argc-1, argv+1); | 429 | // Run command |
397 | } else { | 430 | results = handler->handle(argc - 1, argv + 1); |
398 | results = cmd_results_new(CMD_INVALID, argv[0], "This command is shimmed, but unimplemented"); | ||
399 | } | ||
400 | 431 | ||
401 | cleanup: | 432 | cleanup: |
402 | free_argv(argc, argv); | 433 | free_argv(argc, argv); |