X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=parser%2Fparse.c;h=f8aed0b5b0228258eef79b2abf28cf2a48dea939;hb=a908e04818e2d9eab3e3d8049c573e8d9ddcd0b8;hp=2076bad1fb6c3d4a022ca0eebe422f756550d625;hpb=740c5b2a20d5110435d0874f8cc6a4c9dfd14777;p=chaz%2Fopenbox diff --git a/parser/parse.c b/parser/parse.c index 2076bad1..f8aed0b5 100644 --- a/parser/parse.c +++ b/parser/parse.c @@ -19,6 +19,7 @@ #include "parse.h" #include #include +#include #include #include @@ -31,7 +32,7 @@ static GSList *xdg_data_dir_paths; struct Callback { gchar *tag; ParseCallback func; - void *data; + gpointer data; }; struct _ObParseInst { @@ -61,7 +62,7 @@ void parse_shutdown(ObParseInst *i) } void parse_register(ObParseInst *i, const gchar *tag, - ParseCallback func, void *data) + ParseCallback func, gpointer data) { struct Callback *c; @@ -259,6 +260,26 @@ gboolean parse_attr_contains(const gchar *val, xmlNodePtr node, return r; } +static gint slist_path_cmp(const gchar *a, const gchar *b) +{ + return strcmp(a, b); +} + +typedef GSList* (*GSListFunc) (gpointer list, gconstpointer data); + +static GSList* slist_path_add(GSList *list, gpointer data, GSListFunc func) +{ + g_assert(func); + + if (!data) + return list; + + if (!g_slist_find_custom(list, data, (GCompareFunc) slist_path_cmp)) + list = func(list, data); + + return list; +} + static GSList* split_paths(const gchar *paths) { GSList *list = NULL; @@ -268,64 +289,71 @@ static GSList* split_paths(const gchar *paths) return NULL; spl = g_strsplit(paths, ":", -1); for (it = spl; *it; ++it) - list = g_slist_append(list, *it); + list = slist_path_add(list, *it, (GSListFunc) g_slist_append); g_free(spl); return list; } void parse_paths_startup() { - gchar *path; + const gchar *path; if (xdg_start) return; xdg_start = TRUE; - path = getenv("XDG_CONFIG_HOME"); + path = g_getenv("XDG_CONFIG_HOME"); if (path && path[0] != '\0') /* not unset or empty */ xdg_config_home_path = g_build_filename(path, NULL); else xdg_config_home_path = g_build_filename(g_get_home_dir(), ".config", NULL); - path = getenv("XDG_DATA_HOME"); + path = g_getenv("XDG_DATA_HOME"); if (path && path[0] != '\0') /* not unset or empty */ xdg_data_home_path = g_build_filename(path, NULL); else xdg_data_home_path = g_build_filename(g_get_home_dir(), ".local", "share", NULL); - path = getenv("XDG_CONFIG_DIRS"); + path = g_getenv("XDG_CONFIG_DIRS"); if (path && path[0] != '\0') /* not unset or empty */ xdg_config_dir_paths = split_paths(path); else { - xdg_config_dir_paths = g_slist_append(xdg_config_dir_paths, + xdg_config_dir_paths = slist_path_add(xdg_config_dir_paths, g_build_filename (G_DIR_SEPARATOR_S, - "etc", "xdg", NULL)); - xdg_config_dir_paths = g_slist_append(xdg_config_dir_paths, - g_strdup(CONFIGDIR)); + "etc", "xdg", NULL), + (GSListFunc) g_slist_append); + xdg_config_dir_paths = slist_path_add(xdg_config_dir_paths, + g_strdup(CONFIGDIR), + (GSListFunc) g_slist_append); } - xdg_config_dir_paths = g_slist_prepend(xdg_config_dir_paths, - xdg_config_home_path); + xdg_config_dir_paths = slist_path_add(xdg_config_dir_paths, + xdg_config_home_path, + (GSListFunc) g_slist_prepend); - path = getenv("XDG_DATA_DIRS"); + path = g_getenv("XDG_DATA_DIRS"); if (path && path[0] != '\0') /* not unset or empty */ xdg_data_dir_paths = split_paths(path); else { - xdg_data_dir_paths = g_slist_append(xdg_data_dir_paths, + xdg_data_dir_paths = slist_path_add(xdg_data_dir_paths, g_build_filename (G_DIR_SEPARATOR_S, - "usr", "local", "share", NULL)); - xdg_data_dir_paths = g_slist_append(xdg_data_dir_paths, + "usr", "local", "share", NULL), + (GSListFunc) g_slist_append); + xdg_data_dir_paths = slist_path_add(xdg_data_dir_paths, g_build_filename (G_DIR_SEPARATOR_S, - "usr", "share", NULL)); - xdg_data_dir_paths = g_slist_append(xdg_data_dir_paths, - g_strdup(DATADIR)); + "usr", "share", NULL), + (GSListFunc) g_slist_append); + xdg_data_dir_paths = slist_path_add(xdg_data_dir_paths, + g_strdup(DATADIR), + (GSListFunc) g_slist_append); } - xdg_data_dir_paths = g_slist_prepend(xdg_data_dir_paths, - xdg_data_home_path); + xdg_data_dir_paths = slist_path_add(xdg_data_dir_paths, + xdg_data_home_path, + (GSListFunc) g_slist_prepend); } void parse_paths_shutdown() @@ -359,21 +387,45 @@ gchar *parse_expand_tilde(const gchar *f) return ret; } -void parse_mkdir_path(const gchar *path, gint mode) +gboolean parse_mkdir(const gchar *path, gint mode) { - gchar *c, *e; + gboolean ret = TRUE; + + g_return_val_if_fail(path != NULL, FALSE); + g_return_val_if_fail(path[0] != '\0', FALSE); - g_assert(path[0] == '/'); + if (!g_file_test(path, G_FILE_TEST_IS_DIR)) + if (mkdir(path, mode) == -1) + ret = FALSE; - c = g_strdup(path); - e = c; - while ((e = strchr(e + 1, '/'))) { - *e = '\0'; - mkdir(c, mode); - *e = '/'; + return ret; +} + +gboolean parse_mkdir_path(const gchar *path, gint mode) +{ + gboolean ret = TRUE; + + g_return_val_if_fail(path != NULL, FALSE); + g_return_val_if_fail(path[0] == '/', FALSE); + + if (!g_file_test(path, G_FILE_TEST_IS_DIR)) { + gchar *c, *e; + + c = g_strdup(path); + e = c; + while ((e = strchr(e + 1, '/'))) { + *e = '\0'; + if (!(ret = parse_mkdir(c, mode))) + goto parse_mkdir_path_end; + *e = '/'; + } + ret = parse_mkdir(c, mode); + + parse_mkdir_path_end: + g_free(c); } - mkdir(c, mode); - g_free(c); + + return ret; } const gchar* parse_xdg_config_home_path()