From 4daed31c3e0bfb314f83050fe77a310eec11eb5a Mon Sep 17 00:00:00 2001 From: Deiz Date: Sat, 28 Mar 2015 14:30:35 -0400 Subject: [PATCH] Move resolve_tilde and get_config_path into libi3 --- i3-config-wizard/main.c | 32 --------------- include/libi3.h | 18 ++++++++ include/util.h | 8 ---- libi3/get_config_path.c | 91 +++++++++++++++++++++++++++++++++++++++++ libi3/resolve_tilde.c | 45 ++++++++++++++++++++ src/config.c | 74 +++------------------------------ src/util.c | 32 --------------- 7 files changed, 160 insertions(+), 140 deletions(-) create mode 100644 libi3/get_config_path.c create mode 100644 libi3/resolve_tilde.c diff --git a/i3-config-wizard/main.c b/i3-config-wizard/main.c index 35770dc9..673259b9 100644 --- a/i3-config-wizard/main.c +++ b/i3-config-wizard/main.c @@ -461,38 +461,6 @@ void errorlog(char *fmt, ...) { void debuglog(char *fmt, ...) { } -/* - * This function resolves ~ in pathnames. - * It may resolve wildcards in the first part of the path, but if no match - * or multiple matches are found, it just returns a copy of path as given. - * - */ -static char *resolve_tilde(const char *path) { - static glob_t globbuf; - char *head, *tail, *result; - - tail = strchr(path, '/'); - head = strndup(path, tail ? (size_t)(tail - path) : strlen(path)); - - int res = glob(head, GLOB_TILDE, NULL, &globbuf); - free(head); - /* no match, or many wildcard matches are bad */ - if (res == GLOB_NOMATCH || globbuf.gl_pathc != 1) - result = strdup(path); - else if (res != 0) { - err(1, "glob() failed"); - } else { - head = globbuf.gl_pathv[0]; - result = calloc(1, strlen(head) + (tail ? strlen(tail) : 0) + 1); - strncpy(result, head, strlen(head)); - if (tail) - strncat(result, tail, strlen(tail)); - } - globfree(&globbuf); - - return result; -} - /* * Handles expose events, that is, draws the window contents. * diff --git a/include/libi3.h b/include/libi3.h index 3a125827..82c46fce 100644 --- a/include/libi3.h +++ b/include/libi3.h @@ -434,3 +434,21 @@ char *get_exe_path(const char *argv0); * */ int logical_px(const int logical); + +/** + * This function resolves ~ in pathnames. + * It may resolve wildcards in the first part of the path, but if no match + * or multiple matches are found, it just returns a copy of path as given. + * + */ +char *resolve_tilde(const char *path); + +/** + * Get the path of the first configuration file found. If override_configpath + * is specified, that path is returned and saved for further calls. Otherwise, + * checks the home directory first, then the system directory first, always + * taking into account the XDG Base Directory Specification ($XDG_CONFIG_HOME, + * $XDG_CONFIG_DIRS) + * + */ +char *get_config_path(const char *override_configpath, bool use_system_paths); diff --git a/include/util.h b/include/util.h index dec68116..270b2f22 100644 --- a/include/util.h +++ b/include/util.h @@ -106,14 +106,6 @@ void exec_i3_utility(char *name, char *argv[]); void check_error(xcb_connection_t *conn, xcb_void_cookie_t cookie, char *err_message); -/** - * This function resolves ~ in pathnames. - * It may resolve wildcards in the first part of the path, but if no match - * or multiple matches are found, it just returns a copy of path as given. - * - */ -char *resolve_tilde(const char *path); - /** * Checks if the given path exists by calling stat(). * diff --git a/libi3/get_config_path.c b/libi3/get_config_path.c new file mode 100644 index 00000000..8b6eeb7c --- /dev/null +++ b/libi3/get_config_path.c @@ -0,0 +1,91 @@ +/* + * vim:ts=4:sw=4:expandtab + * + * i3 - an improved dynamic tiling window manager + * © 2009-2015 Michael Stapelberg and contributors (see also: LICENSE) + * + */ +#include "libi3.h" +#include +#include +#include + +/* + * Checks if the given path exists by calling stat(). + * + */ +static bool path_exists(const char *path) { + struct stat buf; + return (stat(path, &buf) == 0); +} + +/* + * Get the path of the first configuration file found. If override_configpath + * is specified, that path is returned and saved for further calls. Otherwise, + * checks the home directory first, then the system directory first, always + * taking into account the XDG Base Directory Specification ($XDG_CONFIG_HOME, + * $XDG_CONFIG_DIRS) + * + */ +char *get_config_path(const char *override_configpath, bool use_system_paths) { + char *xdg_config_home, *xdg_config_dirs, *config_path; + + static const char *saved_configpath = NULL; + + if (override_configpath != NULL) { + saved_configpath = override_configpath; + return sstrdup(saved_configpath); + } + + if (saved_configpath != NULL) + return sstrdup(saved_configpath); + + /* 1: check the traditional path under the home directory */ + config_path = resolve_tilde("~/.i3/config"); + if (path_exists(config_path)) + return config_path; + free(config_path); + + /* 2: check for $XDG_CONFIG_HOME/i3/config */ + if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) + xdg_config_home = "~/.config"; + + xdg_config_home = resolve_tilde(xdg_config_home); + sasprintf(&config_path, "%s/i3/config", xdg_config_home); + free(xdg_config_home); + + if (path_exists(config_path)) + return config_path; + free(config_path); + + /* The below paths are considered system-level, and can be skipped if the + * caller only wants user-level configs. */ + if (!use_system_paths) + return NULL; + + /* 3: check the traditional path under /etc */ + config_path = SYSCONFDIR "/i3/config"; + if (path_exists(config_path)) + return sstrdup(config_path); + + /* 4: check for $XDG_CONFIG_DIRS/i3/config */ + if ((xdg_config_dirs = getenv("XDG_CONFIG_DIRS")) == NULL) + xdg_config_dirs = "/etc/xdg"; + + char *buf = sstrdup(xdg_config_dirs); + char *tok = strtok(buf, ":"); + while (tok != NULL) { + tok = resolve_tilde(tok); + sasprintf(&config_path, "%s/i3/config", tok); + free(tok); + if (path_exists(config_path)) { + free(buf); + return config_path; + } + free(config_path); + tok = strtok(NULL, ":"); + } + free(buf); + + return NULL; +} diff --git a/libi3/resolve_tilde.c b/libi3/resolve_tilde.c new file mode 100644 index 00000000..a4e82873 --- /dev/null +++ b/libi3/resolve_tilde.c @@ -0,0 +1,45 @@ +/* + * vim:ts=4:sw=4:expandtab + * + * i3 - an improved dynamic tiling window manager + * © 2009-2015 Michael Stapelberg and contributors (see also: LICENSE) + * + */ + +#include "libi3.h" +#include +#include +#include +#include + +/* + * This function resolves ~ in pathnames. + * It may resolve wildcards in the first part of the path, but if no match + * or multiple matches are found, it just returns a copy of path as given. + * + */ +char *resolve_tilde(const char *path) { + static glob_t globbuf; + char *head, *tail, *result; + + tail = strchr(path, '/'); + head = strndup(path, tail ? (size_t)(tail - path) : strlen(path)); + + int res = glob(head, GLOB_TILDE, NULL, &globbuf); + free(head); + /* no match, or many wildcard matches are bad */ + if (res == GLOB_NOMATCH || globbuf.gl_pathc != 1) + result = sstrdup(path); + else if (res != 0) { + err(EXIT_FAILURE, "glob() failed"); + } else { + head = globbuf.gl_pathv[0]; + result = scalloc(strlen(head) + (tail ? strlen(tail) : 0) + 1); + strncpy(result, head, strlen(head)); + if (tail) + strncat(result, tail, strlen(tail)); + } + globfree(&globbuf); + + return result; +} diff --git a/src/config.c b/src/config.c index 6f906b8c..36b7a163 100644 --- a/src/config.c +++ b/src/config.c @@ -39,73 +39,6 @@ void update_barconfig() { } } -/* - * Get the path of the first configuration file found. If override_configpath - * is specified, that path is returned and saved for further calls. Otherwise, - * checks the home directory first, then the system directory first, always - * taking into account the XDG Base Directory Specification ($XDG_CONFIG_HOME, - * $XDG_CONFIG_DIRS) - * - */ -static char *get_config_path(const char *override_configpath) { - char *xdg_config_home, *xdg_config_dirs, *config_path; - - static const char *saved_configpath = NULL; - - if (override_configpath != NULL) { - saved_configpath = override_configpath; - return sstrdup(saved_configpath); - } - - if (saved_configpath != NULL) - return sstrdup(saved_configpath); - - /* 1: check the traditional path under the home directory */ - config_path = resolve_tilde("~/.i3/config"); - if (path_exists(config_path)) - return config_path; - free(config_path); - - /* 2: check for $XDG_CONFIG_HOME/i3/config */ - if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) - xdg_config_home = "~/.config"; - - xdg_config_home = resolve_tilde(xdg_config_home); - sasprintf(&config_path, "%s/i3/config", xdg_config_home); - free(xdg_config_home); - - if (path_exists(config_path)) - return config_path; - free(config_path); - - /* 3: check the traditional path under /etc */ - config_path = SYSCONFDIR "/i3/config"; - if (path_exists(config_path)) - return sstrdup(config_path); - - /* 4: check for $XDG_CONFIG_DIRS/i3/config */ - if ((xdg_config_dirs = getenv("XDG_CONFIG_DIRS")) == NULL) - xdg_config_dirs = "/etc/xdg"; - - char *buf = sstrdup(xdg_config_dirs); - char *tok = strtok(buf, ":"); - while (tok != NULL) { - tok = resolve_tilde(tok); - sasprintf(&config_path, "%s/i3/config", tok); - free(tok); - if (path_exists(config_path)) { - free(buf); - return config_path; - } - free(config_path); - tok = strtok(NULL, ":"); - } - free(buf); - - die("Unable to find the configuration file (looked at " - "~/.i3/config, $XDG_CONFIG_HOME/i3/config, " SYSCONFDIR "/i3/config and $XDG_CONFIG_DIRS/i3/config)"); -} - /* * Finds the configuration file to use (either the one specified by * override_configpath), the user’s one or the system default) and calls @@ -113,7 +46,12 @@ static char *get_config_path(const char *override_configpath) { * */ bool parse_configuration(const char *override_configpath, bool use_nagbar) { - char *path = get_config_path(override_configpath); + char *path = get_config_path(override_configpath, true); + if (path == NULL) { + die("Unable to find the configuration file (looked at " + "~/.i3/config, $XDG_CONFIG_HOME/i3/config, " SYSCONFDIR "/i3/config and $XDG_CONFIG_DIRS/i3/config)"); + } + LOG("Parsing configfile %s\n", path); FREE(current_configpath); current_configpath = path; diff --git a/src/util.c b/src/util.c index 5760ae72..c891a6bc 100644 --- a/src/util.c +++ b/src/util.c @@ -159,38 +159,6 @@ void check_error(xcb_connection_t *conn, xcb_void_cookie_t cookie, char *err_mes } } -/* - * This function resolves ~ in pathnames. - * It may resolve wildcards in the first part of the path, but if no match - * or multiple matches are found, it just returns a copy of path as given. - * - */ -char *resolve_tilde(const char *path) { - static glob_t globbuf; - char *head, *tail, *result; - - tail = strchr(path, '/'); - head = strndup(path, tail ? (size_t)(tail - path) : strlen(path)); - - int res = glob(head, GLOB_TILDE, NULL, &globbuf); - free(head); - /* no match, or many wildcard matches are bad */ - if (res == GLOB_NOMATCH || globbuf.gl_pathc != 1) - result = sstrdup(path); - else if (res != 0) { - die("glob() failed"); - } else { - head = globbuf.gl_pathv[0]; - result = scalloc(strlen(head) + (tail ? strlen(tail) : 0) + 1); - strncpy(result, head, strlen(head)); - if (tail) - strncat(result, tail, strlen(tail)); - } - globfree(&globbuf); - - return result; -} - /* * Checks if the given path exists by calling stat(). * -- 2.39.2