aboutsummaryrefslogtreecommitdiff
path: root/sway/config.c
diff options
context:
space:
mode:
authorTony Crisci <tony@dubstepdish.com>2017-12-10 10:25:56 -0500
committerTony Crisci <tony@dubstepdish.com>2017-12-10 10:25:56 -0500
commit0fdecb4d3a36d4c73a906bcc0465620293b6e6d2 (patch)
tree08a071ae7c4725a633209b47daa339ef33046a0f /sway/config.c
parent5f644d78fc77f48c7f7d839f7c2e318b51c2c6d7 (diff)
parentab36a5a4d73ddb026c9b1d416c1e7388d63958ea (diff)
Merge branch 'wlroots' into feature/input
Diffstat (limited to 'sway/config.c')
-rw-r--r--sway/config.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/sway/config.c b/sway/config.c
index 475e8b04..61131845 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -311,6 +311,95 @@ bool load_main_config(const char *file, bool is_active) {
return success;
}
+static bool load_include_config(const char *path, const char *parent_dir, struct sway_config *config) {
+ // save parent config
+ const char *parent_config = config->current_config;
+
+ char *full_path = strdup(path);
+ int len = strlen(path);
+ if (len >= 1 && path[0] != '/') {
+ len = len + strlen(parent_dir) + 2;
+ full_path = malloc(len * sizeof(char));
+ if (!full_path) {
+ sway_log(L_ERROR, "Unable to allocate full path to included config");
+ return false;
+ }
+ snprintf(full_path, len, "%s/%s", parent_dir, path);
+ }
+
+ char *real_path = realpath(full_path, NULL);
+ free(full_path);
+
+ if (real_path == NULL) {
+ sway_log(L_DEBUG, "%s not found.", path);
+ return false;
+ }
+
+ // check if config has already been included
+ int j;
+ for (j = 0; j < config->config_chain->length; ++j) {
+ char *old_path = config->config_chain->items[j];
+ if (strcmp(real_path, old_path) == 0) {
+ sway_log(L_DEBUG, "%s already included once, won't be included again.", real_path);
+ free(real_path);
+ return false;
+ }
+ }
+
+ config->current_config = real_path;
+ list_add(config->config_chain, real_path);
+ int index = config->config_chain->length - 1;
+
+ if (!load_config(real_path, config)) {
+ free(real_path);
+ config->current_config = parent_config;
+ list_del(config->config_chain, index);
+ return false;
+ }
+
+ // restore current_config
+ config->current_config = parent_config;
+ return true;
+}
+
+bool load_include_configs(const char *path, struct sway_config *config) {
+ char *wd = getcwd(NULL, 0);
+ char *parent_path = strdup(config->current_config);
+ const char *parent_dir = dirname(parent_path);
+
+ if (chdir(parent_dir) < 0) {
+ free(parent_path);
+ free(wd);
+ return false;
+ }
+
+ wordexp_t p;
+
+ if (wordexp(path, &p, 0) < 0) {
+ free(parent_path);
+ free(wd);
+ return false;
+ }
+
+ char **w = p.we_wordv;
+ size_t i;
+ for (i = 0; i < p.we_wordc; ++i) {
+ load_include_config(w[i], parent_dir, config);
+ }
+ free(parent_path);
+ wordfree(&p);
+
+ // restore wd
+ if (chdir(wd) < 0) {
+ free(wd);
+ sway_log(L_ERROR, "failed to restore working directory");
+ return false;
+ }
+
+ free(wd);
+ return true;
+}
+
bool read_config(FILE *file, struct sway_config *config) {
bool success = true;
enum cmd_status block = CMD_BLOCK_END;