diff --git a/CMakeLists.txt b/CMakeLists.txt index 66879422..3ce94d9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ set(CMAKE_BUILD_TYPE Debug) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMake) find_package(XKBCommon REQUIRED) +find_package(WLC REQUIRED) if (UNIX) find_library(DL_LIBRARY dl) diff --git a/sway/config.c b/sway/config.c new file mode 100644 index 00000000..3ad1bcf9 --- /dev/null +++ b/sway/config.c @@ -0,0 +1,27 @@ +#include +#include +#include "readline.h" +#include "stringop.h" +#include "list.h" +#include "config.h" + +struct sway_config *read_config(FILE *file) { + struct sway_config *config = malloc(sizeof(struct sway_config)); + config->symbols = create_list(); + config->modes = create_list(); + + while (!feof(file)) { + int _; + char *line = read_line(file); + line = strip_whitespace(line, &_); + line = strip_comments(line); + if (!line[0]) { + goto _continue; + } + printf("Parsing config line %s\n", line); +_continue: + free(line); + } + + return config; +} diff --git a/sway/config.h b/sway/config.h new file mode 100644 index 00000000..2fe566f0 --- /dev/null +++ b/sway/config.h @@ -0,0 +1,26 @@ +#ifndef _SWAY_CONFIG_H +#define _SWAY_CONFIG_H + +#include +#include +#include "list.h" + +struct sway_binding { + list_t *keys; + struct wlc_modifiers modifiers; + char *command; +}; + +struct sway_mode { + char *name; + list_t *bindings; +}; + +struct sway_config { + list_t *symbols; + list_t *modes; +}; + +struct sway_config *read_config(FILE *file); + +#endif diff --git a/sway/list.c b/sway/list.c new file mode 100644 index 00000000..120cfbcd --- /dev/null +++ b/sway/list.c @@ -0,0 +1,37 @@ +#include "list.h" +#include +#include +#include + +list_t *create_list() { + list_t *list = malloc(sizeof(list_t)); + list->capacity = 10; + list->length = 0; + list->items = malloc(sizeof(void*) * list->capacity); + return list; +} + +void list_free(list_t *list) { + free(list->items); + free(list); +} + +void list_add(list_t *list, void *item) { + if (list->length == list->capacity) { + list->capacity += 10; + list->items = realloc(list->items, sizeof(void*) * list->capacity); + } + list->items[list->length++] = item; +} + +void list_del(list_t *list, int index) { + list->length--; + memmove(&list->items[index], &list->items[index + 1], sizeof(void*) * (list->capacity - index - 1)); +} + +void list_cat(list_t *list, list_t *source) { + int i; + for (i = 0; i < source->length; ++i) { + list_add(list, source->items[i]); + } +} diff --git a/sway/list.h b/sway/list.h new file mode 100644 index 00000000..2f60b0df --- /dev/null +++ b/sway/list.h @@ -0,0 +1,16 @@ +#ifndef _SWAY_LIST_H +#define _SWAY_LIST_H + +typedef struct { + int capacity; + int length; + void **items; +} list_t; + +list_t *create_list(); +void list_free(list_t *list); +void list_add(list_t *list, void *item); +void list_del(list_t *list, int index); +void list_cat(list_t *list, list_t *source); + +#endif diff --git a/sway/main.c b/sway/main.c index e6a5b851..ab687b17 100644 --- a/sway/main.c +++ b/sway/main.c @@ -1,6 +1,41 @@ #include +#include +#include +#include +#include "config.h" -int main() { - printf("Hello world\n"); +struct sway_config *config; + +bool load_config() { + // TODO: Allow use of more config file locations + const char *name = "/.i3/config"; + const char *home = getenv("HOME"); + char *temp = malloc(strlen(home) + strlen(name) + 1); + strcpy(temp, home); + strcat(temp, name); + FILE *f = fopen(temp, "r"); + if (!f) { + fprintf(stderr, "Unable to open %s for reading", temp); + free(temp); + exit(1); + } + free(temp); + config = read_config(f); + fclose(f); + return true; +} + +int main(int argc, char **argv) { + if (!load_config()) { + return 0; + } + return 0; + // TODO: + + static struct wlc_interface interface = { }; + if (!wlc_init(&interface, argc, argv)) { + return 1; + } + wlc_run(); return 0; } diff --git a/sway/readline.c b/sway/readline.c new file mode 100644 index 00000000..be8c35cc --- /dev/null +++ b/sway/readline.c @@ -0,0 +1,36 @@ +#include "readline.h" +#include +#include + +char *read_line(FILE *file) { + int i = 0, length = 0, size = 128; + char *string = malloc(size); + if (!string) { + return NULL; + } + while (1) { + int c = getc(file); + if (c == EOF || c == '\n' || c == '\0') { + break; + } + if (c == '\r') { + continue; + } + if (i == size) { + string = realloc(string, length *= 2); + if (!string) { + return NULL; + } + } + string[i++] = (char)c; + length++; + } + if (i + 1 != size) { + string = realloc(string, length + 1); + if (!string) { + return NULL; + } + } + string[i] = '\0'; + return string; +} diff --git a/sway/readline.h b/sway/readline.h new file mode 100644 index 00000000..dbe937c1 --- /dev/null +++ b/sway/readline.h @@ -0,0 +1,8 @@ +#ifndef _SWAY_READLINE_H +#define _SWAY_READLINE_H + +#include + +char *read_line(FILE *file); + +#endif diff --git a/sway/stringop.c b/sway/stringop.c new file mode 100644 index 00000000..0e7ad6a9 --- /dev/null +++ b/sway/stringop.c @@ -0,0 +1,150 @@ +#include "stringop.h" +#include +#include +#include "string.h" +#include "list.h" +#include + +/* 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); + do { + i--; + } while (i >= 0 && (str[i] == ' ' || str[i] == '\t')); + str[i + 1] = '\0'; + return str; +} + +char *strip_comments(char *str) { + int in_string = 0, in_character = 0; + int i = 0; + while (str[i] != '\0') { + if (str[i] == '"' && !in_character) { + in_string = !in_string; + } else if (str[i] == '\'' && !in_string) { + in_character = !in_character; + } else if (!in_character && !in_string) { + if (str[i] == '#') { + str[i] = '\0'; + break; + } + } + ++i; + } + return str; +} + +list_t *split_string(const char *str, const char *delims) { + list_t *res = create_list(); + int i, j; + for (i = 0, j = 0; i < strlen(str) + 1; ++i) { + if (strchr(delims, str[i]) || i == strlen(str)) { + 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 <= strlen(str) && str[j] && strchr(delims, str[j])) { + j++; + i++; + } + } + } + return res; +} + +void free_flat_list(list_t *list) { + int i; + for (i = 0; i < list->length; ++i) { + free(list->items[i]); + } + list_free(list); +} + +char *code_strstr(const char *haystack, const char *needle) { + /* TODO */ + return strstr(haystack, needle); +} + +char *code_strchr(const char *str, char delimiter) { + int in_string = 0, in_character = 0; + int i = 0; + while (str[i] != '\0') { + if (str[i] == '"' && !in_character) { + in_string = !in_string; + } else if (str[i] == '\'' && !in_string) { + in_character = !in_character; + } else if (!in_character && !in_string) { + if (str[i] == delimiter) { + return (char *)str + i; + } + } + ++i; + } + return NULL; +} + +int unescape_string(char *string) { + /* TODO: More C string escapes */ + int len = strlen(string); + int i; + for (i = 0; string[i]; ++i) { + if (string[i] == '\\') { + --len; + switch (string[++i]) { + case '0': + string[i - 1] = '\0'; + memmove(string + i, string + i + 1, len - i); + break; + case 'a': + string[i - 1] = '\a'; + memmove(string + i, string + i + 1, len - i); + break; + case 'b': + string[i - 1] = '\b'; + memmove(string + i, string + i + 1, len - i); + break; + case 't': + string[i - 1] = '\t'; + memmove(string + i, string + i + 1, len - i); + break; + case 'n': + string[i - 1] = '\n'; + memmove(string + i, string + i + 1, len - i); + break; + case 'v': + string[i - 1] = '\v'; + memmove(string + i, string + i + 1, len - i); + break; + case 'f': + string[i - 1] = '\f'; + memmove(string + i, string + i + 1, len - i); + break; + case 'r': + string[i - 1] = '\r'; + memmove(string + i, string + i + 1, len - i); + break; + } + } + } + return len; +} diff --git a/sway/stringop.h b/sway/stringop.h new file mode 100644 index 00000000..74f34ebf --- /dev/null +++ b/sway/stringop.h @@ -0,0 +1,13 @@ +#ifndef _SWAY_STRINGOP_H +#define _SWAY_STRINGOP_H +#include "list.h" + +char *strip_whitespace(char *str, int *trimmed_start); +char *strip_comments(char *str); +list_t *split_string(const char *str, const char *delims); +void free_flat_list(list_t *list); +char *code_strchr(const char *string, char delimiter); +char *code_strstr(const char *haystack, const char *needle); +int unescape_string(char *string); + +#endif