diff options
-rw-r--r-- | include/commands.h | 2 | ||||
-rw-r--r-- | sway/commands.c | 59 | ||||
-rw-r--r-- | sway/config.c | 29 | ||||
-rw-r--r-- | sway/stringop.c | 46 |
4 files changed, 78 insertions, 58 deletions
diff --git a/include/commands.h b/include/commands.h index 8fb0c1d8..e521306c 100644 --- a/include/commands.h +++ b/include/commands.h | |||
@@ -15,6 +15,8 @@ struct cmd_handler { | |||
15 | 15 | ||
16 | struct cmd_handler *find_handler(char *line); | 16 | struct cmd_handler *find_handler(char *line); |
17 | bool handle_command(char *command); | 17 | bool handle_command(char *command); |
18 | // Handles commands during config | ||
19 | bool config_command(char *command); | ||
18 | 20 | ||
19 | void remove_view_from_scratchpad(); | 21 | void remove_view_from_scratchpad(); |
20 | 22 | ||
diff --git a/sway/commands.c b/sway/commands.c index 44407bfa..edc56466 100644 --- a/sway/commands.c +++ b/sway/commands.c | |||
@@ -835,7 +835,7 @@ static int compare_set(const void *_l, const void *_r) { | |||
835 | } | 835 | } |
836 | 836 | ||
837 | static bool cmd_set(int argc, char **argv) { | 837 | static bool cmd_set(int argc, char **argv) { |
838 | if (!checkarg(argc, "set", EXPECTED_EQUAL_TO, 2)) { | 838 | if (!checkarg(argc, "set", EXPECTED_AT_LEAST, 2)) { |
839 | return false; | 839 | return false; |
840 | } | 840 | } |
841 | struct sway_variable *var = NULL; | 841 | struct sway_variable *var = NULL; |
@@ -856,7 +856,7 @@ static bool cmd_set(int argc, char **argv) { | |||
856 | list_add(config->symbols, var); | 856 | list_add(config->symbols, var); |
857 | list_sort(config->symbols, compare_set); | 857 | list_sort(config->symbols, compare_set); |
858 | } | 858 | } |
859 | var->value = strdup(argv[1]); | 859 | var->value = join_args(argv + 1, argc - 1); |
860 | return true; | 860 | return true; |
861 | } | 861 | } |
862 | 862 | ||
@@ -1067,17 +1067,54 @@ bool handle_command(char *exec) { | |||
1067 | } | 1067 | } |
1068 | struct cmd_handler *handler = find_handler(argv[0]); | 1068 | struct cmd_handler *handler = find_handler(argv[0]); |
1069 | bool exec_success = false; | 1069 | bool exec_success = false; |
1070 | if (handler) { | 1070 | if (handler && !(handler->handle(argc - 1, argv + 1))) { |
1071 | int i; | ||
1072 | // Skip var replacement for first value of cmd_set | ||
1073 | for (i = (handler->handle == cmd_set ? 2 : 1); i < argc; ++i) { | ||
1074 | argv[i] = do_var_replacement(argv[i]); | ||
1075 | } | ||
1076 | exec_success = handler->handle(argc - 1, argv + 1); | ||
1077 | } | ||
1078 | if (exec_success == false) { | ||
1079 | sway_log(L_ERROR, "Command failed: %s", argv[0]); | 1071 | sway_log(L_ERROR, "Command failed: %s", argv[0]); |
1080 | } | 1072 | } |
1081 | free_argv(argc, argv); | 1073 | free_argv(argc, argv); |
1082 | return exec_success; | 1074 | return exec_success; |
1083 | } | 1075 | } |
1076 | |||
1077 | bool config_command(char *exec) { | ||
1078 | sway_log(L_INFO, "handling config command '%s'", exec); | ||
1079 | struct cmd_handler *handler; | ||
1080 | int argc; | ||
1081 | char **argv = split_args(exec, &argc); | ||
1082 | bool res = false; | ||
1083 | if (!argc) { | ||
1084 | return true; | ||
1085 | } | ||
1086 | //TODO make this better, it only handles modes right now, and very | ||
1087 | //simply at that | ||
1088 | if (strncmp(argv[0], "}", 1) == 0) { | ||
1089 | config->current_mode = config->modes->items[0]; | ||
1090 | res = true; | ||
1091 | goto cleanup; | ||
1092 | } | ||
1093 | if ((handler = find_handler(argv[0]))) { | ||
1094 | int i = 1, e = argc; | ||
1095 | // dont var replace first argument | ||
1096 | if (handler->handle == cmd_set) { | ||
1097 | i = 2; | ||
1098 | } | ||
1099 | for (; i < e; ++i) { | ||
1100 | argv[i] = do_var_replacement(argv[i]); | ||
1101 | } | ||
1102 | if (handler->config_type == CMD_KEYBIND) { | ||
1103 | sway_log(L_ERROR, "Invalid command during config `%s'", exec); | ||
1104 | } else if (handler->config_type == CMD_COMPOSITOR_READY && !config->active) { | ||
1105 | sway_log(L_DEBUG, "Defferring command `%s'", exec); | ||
1106 | char *cmd = join_args(argv, argc); | ||
1107 | list_add(config->cmd_queue, cmd); | ||
1108 | res = true; | ||
1109 | } else if (!handler->handle(argc-1, argv+1)) { | ||
1110 | sway_log(L_DEBUG, "Config load failed for line `%s'", exec); | ||
1111 | } else { | ||
1112 | res = true; | ||
1113 | } | ||
1114 | } else { | ||
1115 | sway_log(L_ERROR, "Unknown command `%s'", exec); | ||
1116 | } | ||
1117 | cleanup: | ||
1118 | free_argv(argc, argv); | ||
1119 | return res; | ||
1120 | } | ||
diff --git a/sway/config.c b/sway/config.c index 6d445ec6..7d3104c7 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -231,34 +231,9 @@ bool read_config(FILE *file, bool is_active) { | |||
231 | while (!feof(file)) { | 231 | while (!feof(file)) { |
232 | line = read_line(file); | 232 | line = read_line(file); |
233 | line = strip_comments(line); | 233 | line = strip_comments(line); |
234 | list_t *args = split_string(line, whitespace); | 234 | if (!config_command(line)) { |
235 | if (!args->length) { | 235 | success = false; |
236 | goto cleanup; | ||
237 | } | ||
238 | //TODO make this better, it only handles modes right now, and very | ||
239 | //simply at that | ||
240 | if (strncmp(args->items[0], "}", 1) == 0) { | ||
241 | config->current_mode = default_mode; | ||
242 | goto cleanup; | ||
243 | } | ||
244 | struct cmd_handler *handler; | ||
245 | if ((handler = find_handler(args->items[0]))) { | ||
246 | if (handler->config_type == CMD_KEYBIND) { | ||
247 | sway_log(L_ERROR, "Invalid command during config ``%s''", line); | ||
248 | } else if (handler->config_type == CMD_COMPOSITOR_READY && !is_active) { | ||
249 | sway_log(L_DEBUG, "Deferring command ``%s''", line); | ||
250 | char *cmd = strdup(line); | ||
251 | list_add(config->cmd_queue, cmd); | ||
252 | } else if (!handle_command(line)) { | ||
253 | sway_log(L_DEBUG, "Config load failed for line ``%s''", line); | ||
254 | success = false; | ||
255 | config->failed = true; | ||
256 | } | ||
257 | } else { | ||
258 | sway_log(L_ERROR, "Invalid command ``%s''", line); | ||
259 | } | 236 | } |
260 | cleanup: | ||
261 | free_flat_list(args); | ||
262 | free(line); | 237 | free(line); |
263 | } | 238 | } |
264 | 239 | ||
diff --git a/sway/stringop.c b/sway/stringop.c index 1ba54ec6..7de6eded 100644 --- a/sway/stringop.c +++ b/sway/stringop.c | |||
@@ -179,76 +179,82 @@ int unescape_string(char *string) { | |||
179 | int i; | 179 | int i; |
180 | for (i = 0; string[i]; ++i) { | 180 | for (i = 0; string[i]; ++i) { |
181 | if (string[i] == '\\') { | 181 | if (string[i] == '\\') { |
182 | --len; | ||
183 | int shift = 0; | ||
184 | switch (string[++i]) { | 182 | switch (string[++i]) { |
185 | case '0': | 183 | case '0': |
186 | string[i - 1] = '\0'; | 184 | string[i - 1] = '\0'; |
187 | shift = 1; | 185 | return i - 1; |
188 | break; | ||
189 | case 'a': | 186 | case 'a': |
190 | string[i - 1] = '\a'; | 187 | string[i - 1] = '\a'; |
191 | shift = 1; | 188 | string[i] = '\0'; |
192 | break; | 189 | break; |
193 | case 'b': | 190 | case 'b': |
194 | string[i - 1] = '\b'; | 191 | string[i - 1] = '\b'; |
195 | shift = 1; | 192 | string[i] = '\0'; |
196 | break; | 193 | break; |
197 | case 'f': | 194 | case 'f': |
198 | string[i - 1] = '\f'; | 195 | string[i - 1] = '\f'; |
199 | shift = 1; | 196 | string[i] = '\0'; |
200 | break; | 197 | break; |
201 | case 'n': | 198 | case 'n': |
202 | string[i - 1] = '\n'; | 199 | string[i - 1] = '\n'; |
203 | shift = 1; | 200 | string[i] = '\0'; |
204 | break; | 201 | break; |
205 | case 'r': | 202 | case 'r': |
206 | string[i - 1] = '\r'; | 203 | string[i - 1] = '\r'; |
207 | shift = 1; | 204 | string[i] = '\0'; |
208 | break; | 205 | break; |
209 | case 't': | 206 | case 't': |
210 | string[i - 1] = '\t'; | 207 | string[i - 1] = '\t'; |
211 | shift = 1; | 208 | string[i] = '\0'; |
212 | break; | 209 | break; |
213 | case 'v': | 210 | case 'v': |
214 | string[i - 1] = '\v'; | 211 | string[i - 1] = '\v'; |
215 | shift = 1; | 212 | string[i] = '\0'; |
216 | break; | 213 | break; |
217 | case '\\': | 214 | case '\\': |
218 | shift = 1; | 215 | string[i] = '\0'; |
219 | break; | 216 | break; |
220 | case '\'': | 217 | case '\'': |
221 | string[i - 1] = '\''; | 218 | string[i - 1] = '\''; |
222 | shift = 1; | 219 | string[i] = '\0'; |
223 | break; | 220 | break; |
224 | case '\"': | 221 | case '\"': |
225 | string[i - 1] = '\"'; | 222 | string[i - 1] = '\"'; |
226 | shift = 1; | 223 | string[i] = '\0'; |
227 | break; | 224 | break; |
228 | case '?': | 225 | case '?': |
229 | string[i - 1] = '?'; | 226 | string[i - 1] = '?'; |
230 | shift = 1; | 227 | string[i] = '\0'; |
231 | break; | 228 | break; |
232 | case 'x': | 229 | case 'x': |
233 | { | 230 | { |
234 | unsigned char c = 0; | 231 | unsigned char c = 0; |
235 | shift = 1; | ||
236 | if (string[i+1] >= '0' && string[i+1] <= '9') { | 232 | if (string[i+1] >= '0' && string[i+1] <= '9') { |
237 | shift = 2; | ||
238 | c = string[i+1] - '0'; | 233 | c = string[i+1] - '0'; |
239 | if (string[i+2] >= '0' && string[i+2] <= '9') { | 234 | if (string[i+2] >= '0' && string[i+2] <= '9') { |
240 | shift = 3; | ||
241 | c *= 0x10; | 235 | c *= 0x10; |
242 | c += string[i+2] - '0'; | 236 | c += string[i+2] - '0'; |
237 | string[i+2] = '\0'; | ||
243 | } | 238 | } |
239 | string[i+1] = '\0'; | ||
244 | } | 240 | } |
241 | string[i] = '\0'; | ||
245 | string[i - 1] = c; | 242 | string[i - 1] = c; |
246 | } | 243 | } |
247 | } | 244 | } |
248 | memmove(string + i, string + i + shift, len - i + 1); | ||
249 | } | 245 | } |
250 | } | 246 | } |
251 | return len; | 247 | // Shift characters over nullspaces |
248 | int shift = 0; | ||
249 | for (i = 0; i < len; ++i) { | ||
250 | if (string[i] == 0) { | ||
251 | shift++; | ||
252 | continue; | ||
253 | } | ||
254 | string[i-shift] = string[i]; | ||
255 | } | ||
256 | string[len - shift] = 0; | ||
257 | return len - shift; | ||
252 | } | 258 | } |
253 | 259 | ||
254 | char *join_args(char **argv, int argc) { | 260 | char *join_args(char **argv, int argc) { |