summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar emersion <contact@emersion.fr>2018-11-28 09:26:47 +0100
committerLibravatar GitHub <noreply@github.com>2018-11-28 09:26:47 +0100
commit048b96a56d3d3a817c7c63bce2f8226fffc88aa4 (patch)
tree13d0886bd0887aeaaa8d10b8c67ac63685544a8d
parentMerge pull request #3209 from RedSoxFan/fix-3146 (diff)
parentChange execute_command to return a list of results (diff)
downloadsway-048b96a56d3d3a817c7c63bce2f8226fffc88aa4.tar.gz
sway-048b96a56d3d3a817c7c63bce2f8226fffc88aa4.tar.zst
sway-048b96a56d3d3a817c7c63bce2f8226fffc88aa4.zip
Merge pull request #3204 from RedSoxFan/cmd-res-list
Change execute_command to return a list of results
-rw-r--r--include/sway/commands.h6
-rw-r--r--sway/commands.c67
-rw-r--r--sway/commands/bind.c21
-rw-r--r--sway/ipc-server.c11
-rw-r--r--sway/main.c13
-rw-r--r--sway/tree/view.c9
6 files changed, 69 insertions, 58 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h
index eb446eae..c3913c79 100644
--- a/include/sway/commands.h
+++ b/include/sway/commands.h
@@ -56,7 +56,7 @@ struct cmd_handler *find_handler(char *line, struct cmd_handler *cmd_handlers,
56 * all matching containers. Otherwise, it'll run on the `con` container. If 56 * all matching containers. Otherwise, it'll run on the `con` container. If
57 * `con` is NULL then it'll run on the currently focused container. 57 * `con` is NULL then it'll run on the currently focused container.
58 */ 58 */
59struct cmd_results *execute_command(char *command, struct sway_seat *seat, 59list_t *execute_command(char *command, struct sway_seat *seat,
60 struct sway_container *con); 60 struct sway_container *con);
61/** 61/**
62 * Parse and handles a command during config file loading. 62 * Parse and handles a command during config file loading.
@@ -82,11 +82,11 @@ struct cmd_results *cmd_results_new(enum cmd_status status, const char* input, c
82 */ 82 */
83void free_cmd_results(struct cmd_results *results); 83void free_cmd_results(struct cmd_results *results);
84/** 84/**
85 * Serializes cmd_results to a JSON string. 85 * Serializes a list of cmd_results to a JSON string.
86 * 86 *
87 * Free the JSON string later on. 87 * Free the JSON string later on.
88 */ 88 */
89char *cmd_results_to_json(struct cmd_results *results); 89char *cmd_results_to_json(list_t *res_list);
90 90
91struct cmd_results *add_color(const char *name, 91struct cmd_results *add_color(const char *name,
92 char *buffer, const char *color); 92 char *buffer, const char *color);
diff --git a/sway/commands.c b/sway/commands.c
index bdf9fe83..1203f63a 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -215,12 +215,9 @@ static void set_config_node(struct sway_node *node) {
215 } 215 }
216} 216}
217 217
218struct cmd_results *execute_command(char *_exec, struct sway_seat *seat, 218list_t *execute_command(char *_exec, struct sway_seat *seat,
219 struct sway_container *con) { 219 struct sway_container *con) {
220 // Even though this function will process multiple commands we will only 220 list_t *res_list = create_list();
221 // return the last error, if any (for now). (Since we have access to an
222 // error string we could e.g. concatenate all errors there.)
223 struct cmd_results *results = NULL;
224 char *exec = strdup(_exec); 221 char *exec = strdup(_exec);
225 char *head = exec; 222 char *head = exec;
226 char *cmdlist; 223 char *cmdlist;
@@ -254,8 +251,8 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat,
254 char *error = NULL; 251 char *error = NULL;
255 struct criteria *criteria = criteria_parse(head, &error); 252 struct criteria *criteria = criteria_parse(head, &error);
256 if (!criteria) { 253 if (!criteria) {
257 results = cmd_results_new(CMD_INVALID, head, 254 list_add(res_list, cmd_results_new(CMD_INVALID, head,
258 "%s", error); 255 "%s", error));
259 free(error); 256 free(error);
260 goto cleanup; 257 goto cleanup;
261 } 258 }
@@ -291,10 +288,8 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat,
291 } 288 }
292 struct cmd_handler *handler = find_handler(argv[0], NULL, 0); 289 struct cmd_handler *handler = find_handler(argv[0], NULL, 0);
293 if (!handler) { 290 if (!handler) {
294 if (results) { 291 list_add(res_list, cmd_results_new(CMD_INVALID, cmd,
295 free_cmd_results(results); 292 "Unknown/invalid command"));
296 }
297 results = cmd_results_new(CMD_INVALID, cmd, "Unknown/invalid command");
298 free_argv(argc, argv); 293 free_argv(argc, argv);
299 goto cleanup; 294 goto cleanup;
300 } 295 }
@@ -308,29 +303,21 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat,
308 if (!config->handler_context.using_criteria) { 303 if (!config->handler_context.using_criteria) {
309 set_config_node(node); 304 set_config_node(node);
310 struct cmd_results *res = handler->handle(argc-1, argv+1); 305 struct cmd_results *res = handler->handle(argc-1, argv+1);
311 if (res->status != CMD_SUCCESS) { 306 list_add(res_list, res);
307 if (res->status == CMD_INVALID) {
312 free_argv(argc, argv); 308 free_argv(argc, argv);
313 if (results) {
314 free_cmd_results(results);
315 }
316 results = res;
317 goto cleanup; 309 goto cleanup;
318 } 310 }
319 free_cmd_results(res);
320 } else { 311 } else {
321 for (int i = 0; i < views->length; ++i) { 312 for (int i = 0; i < views->length; ++i) {
322 struct sway_view *view = views->items[i]; 313 struct sway_view *view = views->items[i];
323 set_config_node(&view->container->node); 314 set_config_node(&view->container->node);
324 struct cmd_results *res = handler->handle(argc-1, argv+1); 315 struct cmd_results *res = handler->handle(argc-1, argv+1);
325 if (res->status != CMD_SUCCESS) { 316 list_add(res_list, res);
317 if (res->status == CMD_INVALID) {
326 free_argv(argc, argv); 318 free_argv(argc, argv);
327 if (results) {
328 free_cmd_results(results);
329 }
330 results = res;
331 goto cleanup; 319 goto cleanup;
332 } 320 }
333 free_cmd_results(res);
334 } 321 }
335 } 322 }
336 free_argv(argc, argv); 323 free_argv(argc, argv);
@@ -339,10 +326,7 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat,
339cleanup: 326cleanup:
340 free(exec); 327 free(exec);
341 list_free(views); 328 list_free(views);
342 if (!results) { 329 return res_list;
343 results = cmd_results_new(CMD_SUCCESS, NULL, NULL);
344 }
345 return results;
346} 330}
347 331
348// this is like execute_command above, except: 332// this is like execute_command above, except:
@@ -575,20 +559,25 @@ void free_cmd_results(struct cmd_results *results) {
575 free(results); 559 free(results);
576} 560}
577 561
578char *cmd_results_to_json(struct cmd_results *results) { 562char *cmd_results_to_json(list_t *res_list) {
579 json_object *result_array = json_object_new_array(); 563 json_object *result_array = json_object_new_array();
580 json_object *root = json_object_new_object(); 564 for (int i = 0; i < res_list->length; ++i) {
581 json_object_object_add(root, "success", 565 struct cmd_results *results = res_list->items[i];
582 json_object_new_boolean(results->status == CMD_SUCCESS)); 566 json_object *root = json_object_new_object();
583 if (results->input) { 567 json_object_object_add(root, "success",
584 json_object_object_add( 568 json_object_new_boolean(results->status == CMD_SUCCESS));
585 root, "input", json_object_new_string(results->input)); 569 if (results->error) {
586 } 570 json_object_object_add(root, "parse_error",
587 if (results->error) { 571 json_object_new_boolean(results->status == CMD_INVALID));
588 json_object_object_add( 572 json_object_object_add(
589 root, "error", json_object_new_string(results->error)); 573 root, "error", json_object_new_string(results->error));
574 }
575 if (results->input) {
576 json_object_object_add(
577 root, "input", json_object_new_string(results->input));
578 }
579 json_object_array_add(result_array, root);
590 } 580 }
591 json_object_array_add(result_array, root);
592 const char *json = json_object_to_json_string(result_array); 581 const char *json = json_object_to_json_string(result_array);
593 char *res = strdup(json); 582 char *res = strdup(json);
594 json_object_put(result_array); 583 json_object_put(result_array);
diff --git a/sway/commands/bind.c b/sway/commands/bind.c
index 08acbe7a..34881b0f 100644
--- a/sway/commands/bind.c
+++ b/sway/commands/bind.c
@@ -289,13 +289,20 @@ void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding)
289 wlr_log(WLR_DEBUG, "running command for binding: %s", binding->command); 289 wlr_log(WLR_DEBUG, "running command for binding: %s", binding->command);
290 290
291 config->handler_context.seat = seat; 291 config->handler_context.seat = seat;
292 struct cmd_results *results = execute_command(binding->command, NULL, NULL); 292 list_t *res_list = execute_command(binding->command, NULL, NULL);
293 if (results->status == CMD_SUCCESS) { 293 bool success = true;
294 while (res_list->length) {
295 struct cmd_results *results = res_list->items[0];
296 if (results->status != CMD_SUCCESS) {
297 wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)",
298 binding->command, results->error);
299 success = false;
300 }
301 free_cmd_results(results);
302 list_del(res_list, 0);
303 }
304 list_free(res_list);
305 if (success) {
294 ipc_event_binding(binding); 306 ipc_event_binding(binding);
295 } else {
296 wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)",
297 binding->command, results->error);
298 } 307 }
299
300 free_cmd_results(results);
301} 308}
diff --git a/sway/ipc-server.c b/sway/ipc-server.c
index aa0f0fad..95433d97 100644
--- a/sway/ipc-server.c
+++ b/sway/ipc-server.c
@@ -597,13 +597,18 @@ void ipc_client_handle_command(struct ipc_client *client) {
597 switch (client->current_command) { 597 switch (client->current_command) {
598 case IPC_COMMAND: 598 case IPC_COMMAND:
599 { 599 {
600 struct cmd_results *results = execute_command(buf, NULL, NULL); 600 list_t *res_list = execute_command(buf, NULL, NULL);
601 transaction_commit_dirty(); 601 transaction_commit_dirty();
602 char *json = cmd_results_to_json(results); 602 char *json = cmd_results_to_json(res_list);
603 int length = strlen(json); 603 int length = strlen(json);
604 client_valid = ipc_send_reply(client, json, (uint32_t)length); 604 client_valid = ipc_send_reply(client, json, (uint32_t)length);
605 free(json); 605 free(json);
606 free_cmd_results(results); 606 while (res_list->length) {
607 struct cmd_results *results = res_list->items[0];
608 free_cmd_results(results);
609 list_del(res_list, 0);
610 }
611 list_free(res_list);
607 goto exit_cleanup; 612 goto exit_cleanup;
608 } 613 }
609 614
diff --git a/sway/main.c b/sway/main.c
index a21970e2..a74183fe 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -392,11 +392,16 @@ int main(int argc, char **argv) {
392 wlr_log(WLR_DEBUG, "Running deferred commands"); 392 wlr_log(WLR_DEBUG, "Running deferred commands");
393 while (config->cmd_queue->length) { 393 while (config->cmd_queue->length) {
394 char *line = config->cmd_queue->items[0]; 394 char *line = config->cmd_queue->items[0];
395 struct cmd_results *res = execute_command(line, NULL, NULL); 395 list_t *res_list = execute_command(line, NULL, NULL);
396 if (res->status != CMD_SUCCESS) { 396 while (res_list->length) {
397 wlr_log(WLR_ERROR, "Error on line '%s': %s", line, res->error); 397 struct cmd_results *res = res_list->items[0];
398 if (res->status != CMD_SUCCESS) {
399 wlr_log(WLR_ERROR, "Error on line '%s': %s", line, res->error);
400 }
401 free_cmd_results(res);
402 list_del(res_list, 0);
398 } 403 }
399 free_cmd_results(res); 404 list_free(res_list);
400 free(line); 405 free(line);
401 list_del(config->cmd_queue, 0); 406 list_del(config->cmd_queue, 0);
402 } 407 }
diff --git a/sway/tree/view.c b/sway/tree/view.c
index febba3b9..511c2ecc 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -437,9 +437,14 @@ void view_execute_criteria(struct sway_view *view) {
437 wlr_log(WLR_DEBUG, "for_window '%s' matches view %p, cmd: '%s'", 437 wlr_log(WLR_DEBUG, "for_window '%s' matches view %p, cmd: '%s'",
438 criteria->raw, view, criteria->cmdlist); 438 criteria->raw, view, criteria->cmdlist);
439 list_add(view->executed_criteria, criteria); 439 list_add(view->executed_criteria, criteria);
440 struct cmd_results *res = execute_command( 440 list_t *res_list = execute_command(
441 criteria->cmdlist, NULL, view->container); 441 criteria->cmdlist, NULL, view->container);
442 free_cmd_results(res); 442 while (res_list->length) {
443 struct cmd_results *res = res_list->items[0];
444 free_cmd_results(res);
445 list_del(res_list, 0);
446 }
447 list_free(res_list);
443 } 448 }
444 list_free(criterias); 449 list_free(criterias);
445} 450}