aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortaiyu <taiyu.len@gmail.com>2015-09-07 14:29:40 -0700
committertaiyu <taiyu.len@gmail.com>2015-09-07 14:29:40 -0700
commit71af5b7ddebe6b714f3be65bf8c810c952a7e0af (patch)
tree20eac4917bad5c08c89bffa1c33063ebda03a2f5
parentafe9cf0be0f12662f10ebb888a2a41aa613a9422 (diff)
config modes
-rw-r--r--include/commands.h4
-rw-r--r--include/config.h2
-rw-r--r--include/stringop.h12
-rw-r--r--sway/commands.c197
-rw-r--r--sway/config.c104
-rw-r--r--sway/handlers.c11
-rw-r--r--sway/ipc.c2
-rw-r--r--sway/stringop.c151
8 files changed, 256 insertions, 227 deletions
diff --git a/include/commands.h b/include/commands.h
index 808e64eb..8fb0c1d8 100644
--- a/include/commands.h
+++ b/include/commands.h
@@ -5,7 +5,7 @@
struct cmd_handler {
char *command;
- bool (*handle)(struct sway_config *config, int argc, char **argv);
+ bool (*handle)(int argc, char **argv);
enum {
CMD_COMPOSITOR_READY,
CMD_KEYBIND,
@@ -14,7 +14,7 @@ struct cmd_handler {
};
struct cmd_handler *find_handler(char *line);
-bool handle_command(struct sway_config *config, char *command);
+bool handle_command(char *command);
void remove_view_from_scratchpad();
diff --git a/include/config.h b/include/config.h
index 653e790f..4070c9ef 100644
--- a/include/config.h
+++ b/include/config.h
@@ -60,7 +60,7 @@ struct sway_config {
bool load_config(const char *file);
bool read_config(FILE *file, bool is_active);
-char *do_var_replacement(struct sway_config *config, char *str);
+char *do_var_replacement(char *str);
extern struct sway_config *config;
diff --git a/include/stringop.h b/include/stringop.h
index 7d17af95..dde50f13 100644
--- a/include/stringop.h
+++ b/include/stringop.h
@@ -2,17 +2,25 @@
#define _SWAY_STRINGOP_H
#include "list.h"
-char *strip_whitespace(char *str, int *trimmed_start);
+// array of whitespace characters to use for delims
+extern const char *whitespace;
+
+char *strip_whitespace(char *str);
char *strip_comments(char *str);
-// Must be freed with free_flat_list
+// Simply split a string with delims, free with `free_flat_list`
list_t *split_string(const char *str, const char *delims);
void free_flat_list(list_t *list);
+// Splits an argument string, keeping quotes intact
+char **split_args(const char *str, int *argc);
+void free_argv(int argc, char **argv);
+
char *code_strchr(const char *string, char delimiter);
char *code_strstr(const char *haystack, const char *needle);
int unescape_string(char *string);
char *join_args(char **argv, int argc);
char *join_list(list_t *list, char *separator);
+char *strdup(const char *);
#endif
diff --git a/sway/commands.c b/sway/commands.c
index 5c782e99..72d53ff0 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -96,7 +96,7 @@ static int bindsym_sort(const void *_lbind, const void *_rbind) {
return (rbind->keys->length + rmod) - (lbind->keys->length + lmod);
}
-static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) {
+static bool cmd_bindsym(int argc, char **argv) {
if (!checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1)) {
return false;
};
@@ -146,7 +146,7 @@ static bool cmd_bindsym(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_exec_always(struct sway_config *config, int argc, char **argv) {
+static bool cmd_exec_always(int argc, char **argv) {
if (!checkarg(argc, "exec_always", EXPECTED_MORE_THAN, 0)) {
return false;
}
@@ -171,14 +171,14 @@ static bool cmd_exec_always(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_exec(struct sway_config *config, int argc, char **argv) {
+static bool cmd_exec(int argc, char **argv) {
if (config->reloading) {
char *args = join_args(argv, argc);
sway_log(L_DEBUG, "Ignoring exec %s due to reload", args);
free(args);
return true;
}
- return cmd_exec_always(config, argc, argv);
+ return cmd_exec_always(argc, argv);
}
static void kill_views(swayc_t *container, void *data) {
@@ -187,7 +187,7 @@ static void kill_views(swayc_t *container, void *data) {
}
}
-static bool cmd_exit(struct sway_config *config, int argc, char **argv) {
+static bool cmd_exit(int argc, char **argv) {
if (!checkarg(argc, "exit", EXPECTED_EQUAL_TO, 0)) {
return false;
}
@@ -197,7 +197,7 @@ static bool cmd_exit(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_floating(struct sway_config *config, int argc, char **argv) {
+static bool cmd_floating(int argc, char **argv) {
if (!checkarg(argc, "floating", EXPECTED_EQUAL_TO, 1)) {
return false;
}
@@ -258,7 +258,7 @@ static bool cmd_floating(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_floating_mod(struct sway_config *config, int argc, char **argv) {
+static bool cmd_floating_mod(int argc, char **argv) {
if (!checkarg(argc, "floating_modifier", EXPECTED_EQUAL_TO, 1)) {
return false;
}
@@ -282,7 +282,7 @@ static bool cmd_floating_mod(struct sway_config *config, int argc, char **argv)
return true;
}
-static bool cmd_focus(struct sway_config *config, int argc, char **argv) {
+static bool cmd_focus(int argc, char **argv) {
static int floating_toggled_index = 0;
static int tiled_toggled_index = 0;
if (!checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1)) {
@@ -340,7 +340,7 @@ static bool cmd_focus(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_focus_follows_mouse(struct sway_config *config, int argc, char **argv) {
+static bool cmd_focus_follows_mouse(int argc, char **argv) {
if (!checkarg(argc, "focus_follows_mouse", EXPECTED_EQUAL_TO, 1)) {
return false;
}
@@ -365,7 +365,40 @@ static void hide_view_in_scratchpad(swayc_t *sp_view) {
set_focused_container(container_under_pointer());
}
-static bool cmd_move(struct sway_config *config, int argc, char **argv) {
+static bool cmd_mode(int argc, char **argv) {
+ if (!checkarg(argc, "move", EXPECTED_AT_LEAST, 1)) {
+ return false;
+ }
+ const char *mode_name = argv[0];
+ struct sway_mode *mode = NULL;
+ // Find mode
+ int i, len = config->modes->length;
+ for (i = 0; i < len; ++i) {
+ struct sway_mode *find = config->modes->items[i];
+ if (strcasecmp(find->name, mode_name)==0) {
+ mode = find;
+ break;
+ }
+ }
+ // Create mode if it doesnt exist
+ if (!mode && argc >= 2 && strncmp(argv[1],"{",1) == 0) {
+ mode = malloc(sizeof*mode);
+ mode->name = malloc(strlen(mode_name) + 1);
+ mode->bindings = create_list();
+ strcpy(mode->name, mode_name);
+ list_add(config->modes, mode);
+ }
+ if (!mode) {
+ sway_log(L_ERROR, "Invalide mode `%s'", mode_name);
+ return false;
+ }
+ sway_log(L_DEBUG, "Switching to mode `%s'",mode->name);
+ // Set current mode
+ config->current_mode = mode;
+ return true;
+}
+
+static bool cmd_move(int argc, char **argv) {
if (!checkarg(argc, "move", EXPECTED_AT_LEAST, 1)) {
return false;
}
@@ -435,7 +468,7 @@ static bool cmd_move(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_orientation(struct sway_config *config, int argc, char **argv) {
+static bool cmd_orientation(int argc, char **argv) {
if (strcasecmp(argv[0], "horizontal") == 0) {
config->default_orientation = L_HORIZ;
} else if (strcasecmp(argv[0], "vertical") == 0) {
@@ -448,7 +481,7 @@ static bool cmd_orientation(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_output(struct sway_config *config, int argc, char **argv) {
+static bool cmd_output(int argc, char **argv) {
if (!checkarg(argc, "output", EXPECTED_AT_LEAST, 1)) {
return false;
}
@@ -513,7 +546,7 @@ static bool cmd_output(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_gaps(struct sway_config *config, int argc, char **argv) {
+static bool cmd_gaps(int argc, char **argv) {
if (!checkarg(argc, "gaps", EXPECTED_AT_LEAST, 1)) {
return false;
}
@@ -655,13 +688,13 @@ static bool cmd_gaps(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_kill(struct sway_config *config, int argc, char **argv) {
+static bool cmd_kill(int argc, char **argv) {
swayc_t *view = get_focused_container(&root_container);
wlc_view_close(view->handle);
return true;
}
-static bool cmd_layout(struct sway_config *config, int argc, char **argv) {
+static bool cmd_layout(int argc, char **argv) {
if (!checkarg(argc, "layout", EXPECTED_MORE_THAN, 0)) {
return false;
}
@@ -686,7 +719,7 @@ static bool cmd_layout(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_reload(struct sway_config *config, int argc, char **argv) {
+static bool cmd_reload(int argc, char **argv) {
if (!checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0)) {
return false;
}
@@ -697,7 +730,7 @@ static bool cmd_reload(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_resize(struct sway_config *config, int argc, char **argv) {
+static bool cmd_resize(int argc, char **argv) {
if (!checkarg(argc, "resize", EXPECTED_AT_LEAST, 3)) {
return false;
}
@@ -769,7 +802,7 @@ void remove_view_from_scratchpad(swayc_t *view) {
}
}
-static bool cmd_scratchpad(struct sway_config *config, int argc, char **argv) {
+static bool cmd_scratchpad(int argc, char **argv) {
if (!checkarg(argc, "scratchpad", EXPECTED_EQUAL_TO, 1)) {
return false;
}
@@ -796,7 +829,7 @@ static bool cmd_scratchpad(struct sway_config *config, int argc, char **argv) {
}
}
-static bool cmd_set(struct sway_config *config, int argc, char **argv) {
+static bool cmd_set(int argc, char **argv) {
if (!checkarg(argc, "set", EXPECTED_EQUAL_TO, 2)) {
return false;
}
@@ -809,7 +842,7 @@ static bool cmd_set(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool _do_split(struct sway_config *config, int argc, char **argv, int layout) {
+static bool _do_split(int argc, char **argv, int layout) {
char *name = layout == L_VERT ? "splitv" :
layout == L_HORIZ ? "splith" : "split";
if (!checkarg(argc, name, EXPECTED_EQUAL_TO, 0)) {
@@ -840,15 +873,15 @@ static bool _do_split(struct sway_config *config, int argc, char **argv, int lay
return true;
}
-static bool cmd_split(struct sway_config *config, int argc, char **argv) {
+static bool cmd_split(int argc, char **argv) {
if (!checkarg(argc, "split", EXPECTED_EQUAL_TO, 1)) {
return false;
}
if (strcasecmp(argv[0], "v") == 0 || strcasecmp(argv[0], "vertical") == 0) {
- _do_split(config, argc - 1, argv + 1, L_VERT);
+ _do_split(argc - 1, argv + 1, L_VERT);
} else if (strcasecmp(argv[0], "h") == 0 || strcasecmp(argv[0], "horizontal") == 0) {
- _do_split(config, argc - 1, argv + 1, L_HORIZ);
+ _do_split(argc - 1, argv + 1, L_HORIZ);
} else {
sway_log(L_ERROR, "Invalid split command (expected either horiziontal or vertical).");
return false;
@@ -857,15 +890,15 @@ static bool cmd_split(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_splitv(struct sway_config *config, int argc, char **argv) {
- return _do_split(config, argc, argv, L_VERT);
+static bool cmd_splitv(int argc, char **argv) {
+ return _do_split(argc, argv, L_VERT);
}
-static bool cmd_splith(struct sway_config *config, int argc, char **argv) {
- return _do_split(config, argc, argv, L_HORIZ);
+static bool cmd_splith(int argc, char **argv) {
+ return _do_split(argc, argv, L_HORIZ);
}
-static bool cmd_log_colors(struct sway_config *config, int argc, char **argv) {
+static bool cmd_log_colors(int argc, char **argv) {
if (!checkarg(argc, "log_colors", EXPECTED_EQUAL_TO, 1)) {
return false;
}
@@ -878,7 +911,7 @@ static bool cmd_log_colors(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_fullscreen(struct sway_config *config, int argc, char **argv) {
+static bool cmd_fullscreen(int argc, char **argv) {
if (!checkarg(argc, "fullscreen", EXPECTED_AT_LEAST, 0)) {
return false;
}
@@ -897,7 +930,7 @@ static bool cmd_fullscreen(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_workspace(struct sway_config *config, int argc, char **argv) {
+static bool cmd_workspace(int argc, char **argv) {
if (!checkarg(argc, "workspace", EXPECTED_AT_LEAST, 1)) {
return false;
}
@@ -953,7 +986,7 @@ static bool cmd_workspace(struct sway_config *config, int argc, char **argv) {
return true;
}
-static bool cmd_ws_auto_back_and_forth(struct sway_config *config, int argc, char **argv) {
+static bool cmd_ws_auto_back_and_forth(int argc, char **argv) {
if (!checkarg(argc, "workspace_auto_back_and_forth", EXPECTED_EQUAL_TO, 1)) {
return false;
}
@@ -979,6 +1012,7 @@ static struct cmd_handler handlers[] = {
{ "kill", cmd_kill, CMD_KEYBIND },
{ "layout", cmd_layout, CMD_KEYBIND },
{ "log_colors", cmd_log_colors, CMD_ANYTIME },
+ { "mode", cmd_mode, CMD_ANYTIME },
{ "move", cmd_move, CMD_KEYBIND },
{ "output", cmd_output, CMD_ANYTIME },
{ "reload", cmd_reload, CMD_KEYBIND },
@@ -992,58 +1026,6 @@ static struct cmd_handler handlers[] = {
{ "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth, CMD_ANYTIME },
};
-static char **split_directive(char *line, int *argc) {
- const char *delimiters = " ";
- *argc = 0;
- while (isspace(*line) && *line) ++line;
-
- int capacity = 10;
- char **parts = malloc(sizeof(char *) * capacity);
-
- if (!*line) return parts;
-
- int in_string = 0, in_character = 0;
- int i, j, _;
- for (i = 0, j = 0; line[i]; ++i) {
- if (line[i] == '\\') {
- ++i;
- } else if (line[i] == '"' && !in_character) {
- in_string = !in_string;
- } else if (line[i] == '\'' && !in_string) {
- in_character = !in_character;
- } else if (!in_character && !in_string) {
- if (strchr(delimiters, line[i]) != NULL) {
- char *item = malloc(i - j + 1);
- strncpy(item, line + j, i - j);
- item[i - j] = '\0';
- item = strip_whitespace(item, &_);
- if (item[0] == '\0') {
- free(item);
- } else {
- if (*argc == capacity) {
- capacity *= 2;
- parts = realloc(parts, sizeof(char *) * capacity);
- }
- parts[*argc] = item;
- j = i + 1;
- ++*argc;
- }
- }
- }
- }
- char *item = malloc(i - j + 1);
- strncpy(item, line + j, i - j);
- item[i - j] = '\0';
- item = strip_whitespace(item, &_);
- if (*argc == capacity) {
- capacity++;
- parts = realloc(parts, sizeof(char *) * capacity);
- }
- parts[*argc] = item;
- ++*argc;
- return parts;
-}
-
static int handler_compare(const void *_a, const void *_b) {
const struct cmd_handler *a = _a;
const struct cmd_handler *b = _b;
@@ -1058,44 +1040,25 @@ struct cmd_handler *find_handler(char *line) {
return res;
}
-bool handle_command(struct sway_config *config, char *exec) {
+bool handle_command(char *exec) {
sway_log(L_INFO, "Handling command '%s'", exec);
- char *ptr, *cmd;
- bool exec_success;
-
- if ((ptr = strchr(exec, ' ')) == NULL) {
- cmd = exec;
- } else {
- int index = ptr - exec;
- cmd = malloc(index + 1);
- strncpy(cmd, exec, index);
- cmd[index] = '\0';
- }
- struct cmd_handler *handler = find_handler(cmd);
- if (handler == NULL) {
- sway_log(L_ERROR, "Unknown command '%s'", cmd);
- exec_success = false; // TODO: return error, probably
- } else {
- int argc;
- char **argv = split_directive(exec + strlen(handler->command), &argc);
+ int argc;
+ char **argv = split_args(exec, &argc);
+ if (argc == 0) {
+ return false;
+ }
+ struct cmd_handler *handler = find_handler(argv[0]);
+ bool exec_success = false;
+ if (handler) {
int i;
-
- // Perform var subs on all parts of the command
- for (i = 0; i < argc; ++i) {
- argv[i] = do_var_replacement(config, argv[i]);
- }
-
- exec_success = handler->handle(config, argc, argv);
- for (i = 0; i < argc; ++i) {
- free(argv[i]);
- }
- free(argv);
- if (!exec_success) {
- sway_log(L_ERROR, "Command failed: %s", cmd);
+ for (i = 1; i < argc; ++i) {
+ argv[i] = do_var_replacement(argv[i]);
}
+ exec_success = handler->handle(argc - 1, argv + 1);
}
- if (ptr) {
- free(cmd);
+ if (exec_success == false) {
+ sway_log(L_ERROR, "Command failed: %s", argv[0]);
}
+ free_argv(argc, argv);
return exec_success;
}
diff --git a/sway/config.c b/sway/config.c
index b64dd4b1..119730ca 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -13,6 +13,7 @@
struct sway_config *config = NULL;
+
static void free_variable(struct sway_variable *var) {
free(var->name);
free(var->value);
@@ -46,6 +47,33 @@ static void free_workspace_output(struct workspace_output *wo) {
free(wo);
}
+static void free_config(struct sway_config *config) {
+ int i;
+ for (i = 0; i < config->symbols->length; ++i) {
+ free_variable(config->symbols->items[i]);
+ }
+ list_free(config->symbols);
+
+ for (i = 0; i < config->modes->length; ++i) {
+ free_mode(config->modes->items[i]);
+ }
+ list_free(config->modes);
+
+ free_flat_list(config->cmd_queue);
+
+ for (i = 0; i < config->workspace_outputs->length; ++i) {
+ free_workspace_output(config->workspace_outputs->items[i]);
+ }
+ list_free(config->workspace_outputs);
+
+ for (i = 0; i < config->output_configs->length; ++i) {
+ free_outut_config(config->output_configs->items[i]);
+ }
+ list_free(config->output_configs);
+ free(config);
+}
+
+
static bool file_exists(const char *path) {
return access(path, R_OK) != -1;
}
@@ -59,7 +87,8 @@ static void config_defaults(struct sway_config *config) {
config->cmd_queue = create_list();
config->current_mode = malloc(sizeof(struct sway_mode));
- config->current_mode->name = NULL;
+ config->current_mode->name = malloc(sizeof("default"));
+ strcpy(config->current_mode->name, "default");
config->current_mode->bindings = create_list();
list_add(config->modes, config->current_mode);
@@ -78,32 +107,6 @@ static void config_defaults(struct sway_config *config) {
config->gaps_outer = 0;
}
-void free_config(struct sway_config *config) {
- int i;
- for (i = 0; i < config->symbols->length; ++i) {
- free_variable(config->symbols->items[i]);
- }
- list_free(config->symbols);
-
- for (i = 0; i < config->modes->length; ++i) {
- free_mode(config->modes->items[i]);
- }
- list_free(config->modes);
-
- free_flat_list(config->cmd_queue);
-
- for (i = 0; i < config->workspace_outputs->length; ++i) {
- free_workspace_output(config->workspace_outputs->items[i]);
- }
- list_free(config->workspace_outputs);
-
- for (i = 0; i < config->output_configs->length; ++i) {
- free_outut_config(config->output_configs->items[i]);
- }
- list_free(config->output_configs);
- free(config);
-}
-
static char *get_config_path(void) {
char *config_path = NULL;
char *paths[3] = {getenv("HOME"), getenv("XDG_CONFIG_HOME"), ""};
@@ -210,34 +213,35 @@ bool load_config(const char *file) {
}
bool read_config(FILE *file, bool is_active) {
- struct sway_config *temp_config = malloc(sizeof(struct sway_config));
- config_defaults(temp_config);
+ struct sway_config *old_config = config;
+ struct sway_mode *default_mode;
+ config = malloc(sizeof(struct sway_config));
+
+ config_defaults(config);
+ default_mode = config->current_mode;
+
if (is_active) {
sway_log(L_DEBUG, "Performing configuration file reload");
- temp_config->reloading = true;
- temp_config->active = true;
+ config->reloading = true;
+ config->active = true;
}
-
bool success = true;
- int temp_depth = 0; // Temporary: skip all config sections with depth
-
+ char *line;
while (!feof(file)) {
- int _;
- char *line = read_line(file);
- line = strip_whitespace(line, &_);
+ line = read_line(file);
line = strip_comments(line);
- if (!line[0]) {
+ if (line[0] == '\0') {
goto _continue;
}
- if (temp_depth && line[0] == '}') {
- temp_depth--;
+ if (line[0] == '}') {
+ config->current_mode = default_mode;
goto _continue;
}
// Any command which would require wlc to be initialized
// should be queued for later execution
- list_t *args = split_string(line, " ");
+ list_t *args = split_string(line, whitespace);
struct cmd_handler *handler;
if ((handler = find_handler(args->items[0]))) {
if (handler->config_type == CMD_KEYBIND) {
@@ -246,11 +250,11 @@ bool read_config(FILE *file, bool is_active) {
sway_log(L_DEBUG, "Deferring command ``%s''", line);
char *cmd = malloc(strlen(line) + 1);
strcpy(cmd, line);
- list_add(temp_config->cmd_queue, cmd);
- } else if (!temp_depth && !handle_command(temp_config, line)) {
+ list_add(config->cmd_queue, cmd);
+ } else if (!handle_command(line)) {
sway_log(L_DEBUG, "Config load failed for line ``%s''", line);
success = false;
- temp_config->failed = true;
+ config->failed = true;
}
} else {
sway_log(L_ERROR, "Invalid command ``%s''", line);
@@ -258,25 +262,21 @@ bool read_config(FILE *file, bool is_active) {
free_flat_list(args);
_continue:
- if (line && line[strlen(line) - 1] == '{') {
- temp_depth++;
- }
free(line);
}
if (is_active) {
- temp_config->reloading = false;
+ config->reloading = false;
arrange_windows(&root_container, -1, -1);
}
- if (config) {
- free_config(config);
+ if (old_config) {
+ free_config(old_config);
}
- config = temp_config;
return success;
}
-char *do_var_replacement(struct sway_config *config, char *str) {
+char *do_var_replacement(char *str) {
// TODO: Handle escaping $ and using $ in string literals
int i;
for (i = 0; str[i]; ++i) {
diff --git a/sway/handlers.c b/sway/handlers.c
index 482d52c6..c0472817 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -130,13 +130,6 @@ static void handle_output_resolution_change(wlc_handle output, const struct wlc_
if (!c) return;
c->width = to->w;
c->height = to->h;
- if (config->default_layout == L_NONE && config->default_orientation == L_NONE) {
- if (c->width >= c->height) {
- ((swayc_t*)c->children->items[0])->layout = L_HORIZ;
- } else {
- ((swayc_t*)c->children->items[0])->layout = L_VERT;
- }
- }
arrange_windows(&root_container, -1, -1);
}
@@ -348,7 +341,7 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier
}
if (match) {
if (state == WLC_KEY_STATE_PRESSED) {
- handle_command(config, binding->command);
+ handle_command(binding->command);
return EVENT_HANDLED;
} else if (state == WLC_KEY_STATE_RELEASED) {
// TODO: --released
@@ -486,7 +479,7 @@ static void handle_wlc_ready(void) {
sway_log(L_DEBUG, "Compositor is ready, executing cmds in queue");
// Execute commands until there are none left
while (config->cmd_queue->length) {
- handle_command(config, config->cmd_queue->items[0]);
+ handle_command(config->cmd_queue->items[0]);
free(config->cmd_queue->items[0]);
list_del(config->cmd_queue, 0);
}
diff --git a/sway/ipc.c b/sway/ipc.c
index f6217bfd..abf2ed0c 100644
--- a/sway/ipc.c
+++ b/sway/ipc.c
@@ -198,7 +198,7 @@ void ipc_client_handle_command(struct ipc_client *client) {
case IPC_COMMAND:
{
buf[client->payload_length] = '\0';
- bool success = handle_command(config, buf);
+ bool success = handle_command(buf);
char reply[64];
int length = snprintf(reply, sizeof(reply), "{\"success\":%s}", success ? "true" : "false");
ipc_send_reply(client, reply, (uint32_t) length);
diff --git a/sway/stringop.c b/sway/stringop.c
index c39e2c34..d2b74655 100644
--- a/sway/stringop.c
+++ b/sway/stringop.c
@@ -1,34 +1,26 @@
-#include "stringop.h"
#include <stdlib.h>
#include <stdio.h>
+#include <strings.h>
+#include <ctype.h>
+#include "stringop.h"
+#include "log.h"
#include "string.h"
#include "list.h"
-#include <strings.h>
-#include <log.h>
+
+const char *whitespace = " \f\n\r\t\v";
/* Note: This returns 8 characters for trimmed_start per tab character. */
-char *strip_whitespace(char *_str, int *trimmed_start) {
- *trimmed_start = 0;
- if (*_str == '\0')
- return _str;
- char *strold = _str;
- while (*_str == ' ' || *_str == '\t') {
- if (*_str == '\t') {
- *trimmed_start += 8;
- } else {
- *trimmed_start += 1;
- }
- _str++;
- }
- char *str = malloc(strlen(_str) + 1);
- strcpy(str, _str);
- free(strold);
- int i;
- for (i = 0; str[i] != '\0'; ++i);
+char *strip_whitespace(char *_str) {
+ int ws = strspn(_str, whitespace);
+ int len = strlen(_str) - ws + 1;
+ sway_log(L_DEBUG,"%d, %d..",ws,len);
+ char *str = malloc(len);
+ strcpy(str, _str+ws);
+ free(_str);
do {
- i--;
- } while (i >= 0 && (str[i] == ' ' || str[i] == '\t'));
- str[i + 1] = '\0';
+ len--;
+ } while (len >= 0 && (str[len] == ' ' || str[len] == '\t'));
+ str[len + 1] = '\0';
return str;
}
@@ -41,7 +33,7 @@ char *strip_comments(char *str) {
} else if (str[i] == '\'' && !in_string) {
in_character = !in_character;
} else if (!in_character && !in_string) {
- if (str[i] == '#' && i == 0) {
+ if (str[i] == '#') {
str[i] = '\0';
break;
}
@@ -51,26 +43,45 @@ char *strip_comments(char *str) {
return str;
}
+void strip_quotes(char *str) {
+ bool in_str = false;
+ bool in_chr = false;
+ bool escaped = false;
+ char *end = strchr(str,0);
+ while (*str) {
+ if (*str == '\'' && !in_str && !escaped) {
+ in_chr = !in_chr;
+ goto shift_over;
+ } else if (*str == '\"' && !in_chr && !escaped) {
+ in_str = !in_str;
+ goto shift_over;
+ } else if (*str == '\\') {
+ escaped = !escaped;
+ ++str;
+ continue;
+ }
+ escaped = false;
+ ++str;
+ continue;
+ shift_over:
+ memmove(str, str+1, end-- - str);
+ }
+ *end = '\0';
+}
+
list_t *split_string(const char *str, const char *delims) {
list_t *res = create_list();
- int i, j;
- int len = strlen(str);
- for (i = 0, j = 0; i < len + 1; ++i) {
- if (strchr(delims, str[i]) || i == len) {
- if (i - j == 0) {
- continue;
- }
- char *left = malloc(i - j + 1);
- memcpy(left, str + j, i - j);
- left[i - j] = 0;
- list_add(res, left);
- j = i + 1;
- while (j <= len && str[j] && strchr(delims, str[j])) {
- j++;
- i++;
- }
- }
+ char *copy = malloc(strlen(str) + 1);
+ char *token;
+ strcpy(copy, str);
+
+ token = strtok(copy, delims);
+ while(token) {
+ token = strdup(token);
+ list_add(res, token);
+ token = strtok(NULL, delims);
}
+ free(copy);
return res;
}
@@ -82,6 +93,60 @@ void free_flat_list(list_t *list) {
list_free(list);
}
+char **split_args(const char *start, int *argc) {
+ *argc = 0;
+ int alloc = 2;
+ char **parts = malloc(sizeof(char *) * alloc);
+ bool in_token = false;
+ bool in_string = false;
+ bool in_char = false;
+ bool escaped = false;
+ const char *end = start;
+ while (*start) {
+ if (!in_token) {
+ start = (end += strspn(end, whitespace));
+ in_token = true;
+ }
+ if (*end == '"' && !in_char && !escaped) {
+ in_string = !in_string;
+ } else if (*end == '\'' && !in_string && !escaped) {
+ in_char = !in_char;
+ } else if (*end == '\\') {
+ escaped = !escaped;
+ } else if (*end == '\0' || (!in_string && !in_char && !escaped
+ && strchr(whitespace, *end))) {
+ goto add_part;
+ }
+ if (*end != '\\') {
+ escaped = false;
+ }
+ ++end;
+ continue;
+ add_part:
+ if (end - start > 0) {
+ char *token = malloc(end - start + 1);
+ strncpy(token, start, end - start + 1);
+ token[end - start] = '\0';
+ strip_quotes(token);
+ unescape_string(token);
+ parts[*argc] = token;
+ if (++*argc == alloc) {
+ parts = realloc(parts, (alloc *= 2) * sizeof(char *));
+ }
+ }
+ in_token = false;
+ escaped = false;
+ }
+ return parts;
+}
+
+void free_argv(int argc, char **argv) {
+ while (--argc) {
+ free(argv[argc]);
+ }
+ free(argv);
+}
+
char *code_strstr(const char *haystack, const char *needle) {
/* TODO */
return strstr(haystack, needle);
@@ -177,7 +242,7 @@ int unescape_string(char *string) {
string[i - 1] = c;
}
}
- memmove(string + i, string + i + shift, len - i);
+ memmove(string + i, string + i + shift, len - i + 1);
}
}
return len;