From e07c77fbb78b1d57a19904f2f5a7309ddfc40955 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 5 Aug 2015 17:30:40 -0400 Subject: [PATCH] Build out command subsystem Everyone loves code stolen from your own projects --- sway/commands.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++ sway/commands.h | 13 +++++++ sway/config.c | 15 +++++++- sway/main.c | 1 - 4 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 sway/commands.c create mode 100644 sway/commands.h diff --git a/sway/commands.c b/sway/commands.c new file mode 100644 index 000000000..14192c441 --- /dev/null +++ b/sway/commands.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include "stringop.h" +#include "commands.h" + +int cmd_set(struct sway_config *config, int argc, char **argv) { + return 0; +} + +/* Keep alphabetized */ +struct cmd_handler handlers[] = { + { "set", cmd_set } +}; + +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; +} + +int handler_compare(const void *_a, const void *_b) { + const struct cmd_handler *a = _a; + const struct cmd_handler *b = _b; + return strcasecmp(a->command, b->command); +} + +struct cmd_handler *find_handler(struct cmd_handler handlers[], int l, char *line) { + struct cmd_handler d = { .command=line }; + struct cmd_handler *res = bsearch(&d, handlers, l, sizeof(struct cmd_handler), handler_compare); + return res; +} + +int handle_command(struct sway_config *config, char *exec) { + char *ptr, *cmd; + if ((ptr = strchr(exec, ' ')) == NULL) { + cmd = malloc(strlen(exec) + 1); + strcpy(exec, cmd); + } else { + int index = ptr - exec; + cmd = malloc(index + 1); + strncpy(cmd, exec, index); + cmd[index] = '\0'; + } + struct cmd_handler *handler = find_handler(handlers, sizeof(handlers) / sizeof(struct cmd_handler), cmd); + if (handler == NULL) { + return 1; + } + int argc; + char **argv = split_directive(exec + strlen(handler->command), &argc); + return handler->handle(config, argc, argv); +} diff --git a/sway/commands.h b/sway/commands.h new file mode 100644 index 000000000..f99a5201c --- /dev/null +++ b/sway/commands.h @@ -0,0 +1,13 @@ +#ifndef _SWAY_COMMANDS_H +#define _SWAY_COMMANDS_H +#include +#include "config.h" + +struct cmd_handler { + char *command; + int (*handle)(struct sway_config *config, int argc, char **argv); +}; + +int handle_command(struct sway_config *config, char *command); + +#endif diff --git a/sway/config.c b/sway/config.c index 3ad1bcf97..bb6533c28 100644 --- a/sway/config.c +++ b/sway/config.c @@ -1,8 +1,10 @@ #include +#include #include #include "readline.h" #include "stringop.h" #include "list.h" +#include "commands.h" #include "config.h" struct sway_config *read_config(FILE *file) { @@ -10,6 +12,8 @@ struct sway_config *read_config(FILE *file) { config->symbols = create_list(); config->modes = create_list(); + int temp_braces = 0; // Temporary: skip all config sections with braces + while (!feof(file)) { int _; char *line = read_line(file); @@ -18,8 +22,17 @@ struct sway_config *read_config(FILE *file) { if (!line[0]) { goto _continue; } - printf("Parsing config line %s\n", line); + if (temp_braces && line[0] == '}') { + temp_braces--; + goto _continue; + } + + handle_command(config, line); + _continue: + if (line && line[strlen(line) - 1] == '{') { + temp_braces++; + } free(line); } diff --git a/sway/main.c b/sway/main.c index ab687b17f..1058c613b 100644 --- a/sway/main.c +++ b/sway/main.c @@ -30,7 +30,6 @@ int main(int argc, char **argv) { return 0; } return 0; - // TODO: static struct wlc_interface interface = { }; if (!wlc_init(&interface, argc, argv)) {