aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/commands.c')
-rw-r--r--sway/commands.c75
1 files changed, 30 insertions, 45 deletions
diff --git a/sway/commands.c b/sway/commands.c
index 1d190e0b..6f786035 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -36,7 +36,7 @@ struct cmd_results *checkarg(int argc, const char *name, enum expected_args type
36 } 36 }
37 } 37 }
38 return error_name ? 38 return error_name ?
39 cmd_results_new(CMD_INVALID, name, "Invalid %s command " 39 cmd_results_new(CMD_INVALID, "Invalid %s command "
40 "(expected %s%d argument%s, got %d)", 40 "(expected %s%d argument%s, got %d)",
41 name, error_name, val, val != 1 ? "s" : "", argc) 41 name, error_name, val, val != 1 ? "s" : "", argc)
42 : NULL; 42 : NULL;
@@ -228,8 +228,7 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
228 char *error = NULL; 228 char *error = NULL;
229 struct criteria *criteria = criteria_parse(head, &error); 229 struct criteria *criteria = criteria_parse(head, &error);
230 if (!criteria) { 230 if (!criteria) {
231 list_add(res_list, cmd_results_new(CMD_INVALID, head, 231 list_add(res_list, cmd_results_new(CMD_INVALID, "%s", error));
232 "%s", error));
233 free(error); 232 free(error);
234 goto cleanup; 233 goto cleanup;
235 } 234 }
@@ -265,8 +264,8 @@ list_t *execute_command(char *_exec, struct sway_seat *seat,
265 } 264 }
266 struct cmd_handler *handler = find_handler(argv[0], NULL, 0); 265 struct cmd_handler *handler = find_handler(argv[0], NULL, 0);
267 if (!handler) { 266 if (!handler) {
268 list_add(res_list, cmd_results_new(CMD_INVALID, cmd, 267 list_add(res_list, cmd_results_new(CMD_INVALID,
269 "Unknown/invalid command")); 268 "Unknown/invalid command '%s'", argv[0]));
270 free_argv(argc, argv); 269 free_argv(argc, argv);
271 goto cleanup; 270 goto cleanup;
272 } 271 }
@@ -316,28 +315,27 @@ cleanup:
316// be chained together) 315// be chained together)
317// 4) execute_command handles all state internally while config_command has 316// 4) execute_command handles all state internally while config_command has
318// some state handled outside (notably the block mode, in read_config) 317// some state handled outside (notably the block mode, in read_config)
319struct cmd_results *config_command(char *exec) { 318struct cmd_results *config_command(char *exec, char **new_block) {
320 struct cmd_results *results = NULL; 319 struct cmd_results *results = NULL;
321 int argc; 320 int argc;
322 char **argv = split_args(exec, &argc); 321 char **argv = split_args(exec, &argc);
323 322
324 // Check for empty lines 323 // Check for empty lines
325 if (!argc) { 324 if (!argc) {
326 results = cmd_results_new(CMD_SUCCESS, NULL, NULL); 325 results = cmd_results_new(CMD_SUCCESS, NULL);
327 goto cleanup; 326 goto cleanup;
328 } 327 }
329 328
330 // Check for the start of a block 329 // Check for the start of a block
331 if (argc > 1 && strcmp(argv[argc - 1], "{") == 0) { 330 if (argc > 1 && strcmp(argv[argc - 1], "{") == 0) {
332 char *block = join_args(argv, argc - 1); 331 *new_block = join_args(argv, argc - 1);
333 results = cmd_results_new(CMD_BLOCK, block, NULL); 332 results = cmd_results_new(CMD_BLOCK, NULL);
334 free(block);
335 goto cleanup; 333 goto cleanup;
336 } 334 }
337 335
338 // Check for the end of a block 336 // Check for the end of a block
339 if (strcmp(argv[argc - 1], "}") == 0) { 337 if (strcmp(argv[argc - 1], "}") == 0) {
340 results = cmd_results_new(CMD_BLOCK_END, NULL, NULL); 338 results = cmd_results_new(CMD_BLOCK_END, NULL);
341 goto cleanup; 339 goto cleanup;
342 } 340 }
343 341
@@ -349,7 +347,7 @@ struct cmd_results *config_command(char *exec) {
349 argv = split_args(temp, &argc); 347 argv = split_args(temp, &argc);
350 free(temp); 348 free(temp);
351 if (!argc) { 349 if (!argc) {
352 results = cmd_results_new(CMD_SUCCESS, NULL, NULL); 350 results = cmd_results_new(CMD_SUCCESS, NULL);
353 goto cleanup; 351 goto cleanup;
354 } 352 }
355 } 353 }
@@ -358,11 +356,10 @@ struct cmd_results *config_command(char *exec) {
358 wlr_log(WLR_INFO, "Config command: %s", exec); 356 wlr_log(WLR_INFO, "Config command: %s", exec);
359 struct cmd_handler *handler = find_handler(argv[0], NULL, 0); 357 struct cmd_handler *handler = find_handler(argv[0], NULL, 0);
360 if (!handler || !handler->handle) { 358 if (!handler || !handler->handle) {
361 char *input = argv[0] ? argv[0] : "(empty)"; 359 const char *error = handler
362 char *error = handler 360 ? "Command '%s' is shimmed, but unimplemented"
363 ? "This command is shimmed, but unimplemented" 361 : "Unknown/invalid command '%s'";
364 : "Unknown/invalid command"; 362 results = cmd_results_new(CMD_INVALID, error, argv[0]);
365 results = cmd_results_new(CMD_INVALID, input, error);
366 goto cleanup; 363 goto cleanup;
367 } 364 }
368 365
@@ -411,14 +408,14 @@ struct cmd_results *config_subcommand(char **argv, int argc,
411 struct cmd_handler *handler = find_handler(argv[0], handlers, 408 struct cmd_handler *handler = find_handler(argv[0], handlers,
412 handlers_size); 409 handlers_size);
413 if (!handler) { 410 if (!handler) {
414 char *input = argv[0] ? argv[0] : "(empty)"; 411 return cmd_results_new(CMD_INVALID,
415 return cmd_results_new(CMD_INVALID, input, "Unknown/invalid command"); 412 "Unknown/invalid command '%s'", argv[0]);
416 } 413 }
417 if (handler->handle) { 414 if (handler->handle) {
418 return handler->handle(argc - 1, argv + 1); 415 return handler->handle(argc - 1, argv + 1);
419 } 416 }
420 return cmd_results_new(CMD_INVALID, argv[0], 417 return cmd_results_new(CMD_INVALID,
421 "This command is shimmed, but unimplemented"); 418 "The command '%s' is shimmed, but unimplemented", argv[0]);
422} 419}
423 420
424struct cmd_results *config_commands_command(char *exec) { 421struct cmd_results *config_commands_command(char *exec) {
@@ -426,7 +423,7 @@ struct cmd_results *config_commands_command(char *exec) {
426 int argc; 423 int argc;
427 char **argv = split_args(exec, &argc); 424 char **argv = split_args(exec, &argc);
428 if (!argc) { 425 if (!argc) {
429 results = cmd_results_new(CMD_SUCCESS, NULL, NULL); 426 results = cmd_results_new(CMD_SUCCESS, NULL);
430 goto cleanup; 427 goto cleanup;
431 } 428 }
432 429
@@ -434,13 +431,14 @@ struct cmd_results *config_commands_command(char *exec) {
434 char *cmd = argv[0]; 431 char *cmd = argv[0];
435 432
436 if (strcmp(cmd, "}") == 0) { 433 if (strcmp(cmd, "}") == 0) {
437 results = cmd_results_new(CMD_BLOCK_END, NULL, NULL); 434 results = cmd_results_new(CMD_BLOCK_END, NULL);
438 goto cleanup; 435 goto cleanup;
439 } 436 }
440 437
441 struct cmd_handler *handler = find_handler(cmd, NULL, 0); 438 struct cmd_handler *handler = find_handler(cmd, NULL, 0);
442 if (!handler && strcmp(cmd, "*") != 0) { 439 if (!handler && strcmp(cmd, "*") != 0) {
443 results = cmd_results_new(CMD_INVALID, cmd, "Unknown/invalid command"); 440 results = cmd_results_new(CMD_INVALID,
441 "Unknown/invalid command '%s'", cmd);
444 goto cleanup; 442 goto cleanup;
445 } 443 }
446 444
@@ -465,7 +463,7 @@ struct cmd_results *config_commands_command(char *exec) {
465 } 463 }
466 } 464 }
467 if (j == sizeof(context_names) / sizeof(context_names[0])) { 465 if (j == sizeof(context_names) / sizeof(context_names[0])) {
468 results = cmd_results_new(CMD_INVALID, cmd, 466 results = cmd_results_new(CMD_INVALID,
469 "Invalid command context %s", argv[i]); 467 "Invalid command context %s", argv[i]);
470 goto cleanup; 468 goto cleanup;
471 } 469 }
@@ -483,7 +481,7 @@ struct cmd_results *config_commands_command(char *exec) {
483 if (!policy) { 481 if (!policy) {
484 policy = alloc_command_policy(cmd); 482 policy = alloc_command_policy(cmd);
485 if (!sway_assert(policy, "Unable to allocate security policy")) { 483 if (!sway_assert(policy, "Unable to allocate security policy")) {
486 results = cmd_results_new(CMD_INVALID, cmd, 484 results = cmd_results_new(CMD_INVALID,
487 "Unable to allocate memory"); 485 "Unable to allocate memory");
488 goto cleanup; 486 goto cleanup;
489 } 487 }
@@ -494,7 +492,7 @@ struct cmd_results *config_commands_command(char *exec) {
494 wlr_log(WLR_INFO, "Set command policy for %s to %d", 492 wlr_log(WLR_INFO, "Set command policy for %s to %d",
495 policy->command, policy->context); 493 policy->command, policy->context);
496 494
497 results = cmd_results_new(CMD_SUCCESS, NULL, NULL); 495 results = cmd_results_new(CMD_SUCCESS, NULL);
498 496
499cleanup: 497cleanup:
500 free_argv(argc, argv); 498 free_argv(argc, argv);
@@ -502,18 +500,13 @@ cleanup:
502} 500}
503 501
504struct cmd_results *cmd_results_new(enum cmd_status status, 502struct cmd_results *cmd_results_new(enum cmd_status status,
505 const char *input, const char *format, ...) { 503 const char *format, ...) {
506 struct cmd_results *results = malloc(sizeof(struct cmd_results)); 504 struct cmd_results *results = malloc(sizeof(struct cmd_results));
507 if (!results) { 505 if (!results) {
508 wlr_log(WLR_ERROR, "Unable to allocate command results"); 506 wlr_log(WLR_ERROR, "Unable to allocate command results");
509 return NULL; 507 return NULL;
510 } 508 }
511 results->status = status; 509 results->status = status;
512 if (input) {
513 results->input = strdup(input); // input is the command name
514 } else {
515 results->input = NULL;
516 }
517 if (format) { 510 if (format) {
518 char *error = malloc(256); 511 char *error = malloc(256);
519 va_list args; 512 va_list args;
@@ -530,9 +523,6 @@ struct cmd_results *cmd_results_new(enum cmd_status status,
530} 523}
531 524
532void free_cmd_results(struct cmd_results *results) { 525void free_cmd_results(struct cmd_results *results) {
533 if (results->input) {
534 free(results->input);
535 }
536 if (results->error) { 526 if (results->error) {
537 free(results->error); 527 free(results->error);
538 } 528 }
@@ -552,10 +542,6 @@ char *cmd_results_to_json(list_t *res_list) {
552 json_object_object_add( 542 json_object_object_add(
553 root, "error", json_object_new_string(results->error)); 543 root, "error", json_object_new_string(results->error));
554 } 544 }
555 if (results->input) {
556 json_object_object_add(
557 root, "input", json_object_new_string(results->input));
558 }
559 json_object_array_add(result_array, root); 545 json_object_array_add(result_array, root);
560 } 546 }
561 const char *json = json_object_to_json_string(result_array); 547 const char *json = json_object_to_json_string(result_array);
@@ -569,20 +555,19 @@ char *cmd_results_to_json(list_t *res_list) {
569 * 555 *
570 * return error object, or NULL if color is valid. 556 * return error object, or NULL if color is valid.
571 */ 557 */
572struct cmd_results *add_color(const char *name, 558struct cmd_results *add_color(char *buffer, const char *color) {
573 char *buffer, const char *color) {
574 int len = strlen(color); 559 int len = strlen(color);
575 if (len != 7 && len != 9) { 560 if (len != 7 && len != 9) {
576 return cmd_results_new(CMD_INVALID, name, 561 return cmd_results_new(CMD_INVALID,
577 "Invalid color definition %s", color); 562 "Invalid color definition %s", color);
578 } 563 }
579 if (color[0] != '#') { 564 if (color[0] != '#') {
580 return cmd_results_new(CMD_INVALID, name, 565 return cmd_results_new(CMD_INVALID,
581 "Invalid color definition %s", color); 566 "Invalid color definition %s", color);
582 } 567 }
583 for (int i = 1; i < len; ++i) { 568 for (int i = 1; i < len; ++i) {
584 if (!isxdigit(color[i])) { 569 if (!isxdigit(color[i])) {
585 return cmd_results_new(CMD_INVALID, name, 570 return cmd_results_new(CMD_INVALID,
586 "Invalid color definition %s", color); 571 "Invalid color definition %s", color);
587 } 572 }
588 } 573 }