From 07d5674d3984d008de1ecc768a296afbed731e4e Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sat, 28 Jul 2007 11:38:53 -0400 Subject: move the xdg path stuff into obt/paths.[ch], and make render and openbox use it --- obt/parse.c | 217 +++---------------------------------------------------- obt/parse.h | 18 ----- obt/paths.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ obt/paths.h | 43 +++++++++++ 4 files changed, 286 insertions(+), 226 deletions(-) create mode 100644 obt/paths.c create mode 100644 obt/paths.h (limited to 'obt') diff --git a/obt/parse.c b/obt/parse.c index f23ed194..d181b679 100644 --- a/obt/parse.c +++ b/obt/parse.c @@ -17,14 +17,12 @@ */ #include "obt/parse.h" +#include "obt/paths.h" #include -#ifdef HAVE_STRING_H -# include -#endif -#ifdef HAVE_ERRNO_H -# include +#ifdef HAVE_STDLIB_H +# include #endif #ifdef HAVE_SYS_STAT_H # include @@ -36,12 +34,6 @@ # include #endif -static gboolean xdg_start; -static gchar *xdg_config_home_path; -static gchar *xdg_data_home_path; -static GSList *xdg_config_dir_paths; -static GSList *xdg_data_dir_paths; - struct Callback { gchar *tag; ObtParseCallback func; @@ -50,6 +42,7 @@ struct Callback { struct _ObtParseInst { gint ref; + ObtPaths *xdg_paths; GHashTable *callbacks; xmlDocPtr doc; xmlNodePtr root; @@ -66,6 +59,7 @@ ObtParseInst* obt_parse_instance_new(void) { ObtParseInst *i = g_new(ObtParseInst, 1); i->ref = 1; + i->xdg_paths = obt_paths_new(); i->callbacks = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, (GDestroyNotify)destfunc); i->doc = NULL; @@ -82,6 +76,7 @@ void obt_parse_instance_ref(ObtParseInst *i) void obt_parse_instance_unref(ObtParseInst *i) { if (i && --i->ref == 0) { + obt_paths_unref(i->xdg_paths); g_hash_table_destroy(i->callbacks); g_free(i); } @@ -195,7 +190,7 @@ gboolean obt_parse_load_config_file(ObtParseInst *i, GSList *it, *paths = NULL; gboolean r; - for (it = xdg_config_dir_paths; it; it = g_slist_next(it)) + for (it = obt_paths_config_dirs(i->xdg_paths); it; it = g_slist_next(it)) paths = g_slist_append(paths, g_strdup(it->data)); r = load_file(i, domain, filename, root_node, paths); @@ -215,7 +210,7 @@ gboolean obt_parse_load_data_file(ObtParseInst *i, GSList *it, *paths = NULL; gboolean r; - for (it = xdg_data_dir_paths; it; it = g_slist_next(it)) + for (it = obt_paths_data_dirs(i->xdg_paths); it; it = g_slist_next(it)) paths = g_slist_append(paths, g_strdup(it->data)); r = load_file(i, domain, filename, root_node, paths); @@ -240,7 +235,7 @@ gboolean obt_parse_load_theme_file(ObtParseInst *i, paths = g_slist_append (paths, g_build_filename(g_get_home_dir(), ".themes", theme, NULL)); - for (it = xdg_data_dir_paths; it; it = g_slist_next(it)) + for (it = obt_paths_data_dirs(i->xdg_paths); it; it = g_slist_next(it)) paths = g_slist_append (paths, g_build_filename(it->data, "themes", theme, NULL)); @@ -416,197 +411,3 @@ gboolean obt_parse_attr_contains(xmlNodePtr node, const gchar *name, xmlFree(c); 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); - else - g_free(data); - - return list; -} - -static GSList* split_paths(const gchar *paths) -{ - GSList *list = NULL; - gchar **spl, **it; - - if (!paths) - return NULL; - spl = g_strsplit(paths, ":", -1); - for (it = spl; *it; ++it) - list = slist_path_add(list, *it, (GSListFunc) g_slist_append); - g_free(spl); - return list; -} - -void parse_paths_startup(void) -{ - const gchar *path; - - if (xdg_start) - return; - xdg_start = TRUE; - - 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 = 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 = 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 = slist_path_add(xdg_config_dir_paths, - g_strdup(CONFIGDIR), - (GSListFunc) g_slist_append); - xdg_config_dir_paths = slist_path_add(xdg_config_dir_paths, - g_build_filename - (G_DIR_SEPARATOR_S, - "etc", "xdg", NULL), - (GSListFunc) g_slist_append); - } - xdg_config_dir_paths = slist_path_add(xdg_config_dir_paths, - g_strdup(xdg_config_home_path), - (GSListFunc) g_slist_prepend); - - 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 = slist_path_add(xdg_data_dir_paths, - g_strdup(DATADIR), - (GSListFunc) g_slist_append); - xdg_data_dir_paths = slist_path_add(xdg_data_dir_paths, - g_build_filename - (G_DIR_SEPARATOR_S, - "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), - (GSListFunc) g_slist_append); - } - xdg_data_dir_paths = slist_path_add(xdg_data_dir_paths, - g_strdup(xdg_data_home_path), - (GSListFunc) g_slist_prepend); -} - -void parse_paths_shutdown(void) -{ - GSList *it; - - if (!xdg_start) - return; - xdg_start = FALSE; - - for (it = xdg_config_dir_paths; it; it = g_slist_next(it)) - g_free(it->data); - g_slist_free(xdg_config_dir_paths); - xdg_config_dir_paths = NULL; - for (it = xdg_data_dir_paths; it; it = g_slist_next(it)) - g_free(it->data); - g_slist_free(xdg_data_dir_paths); - xdg_data_dir_paths = NULL; - g_free(xdg_config_home_path); - xdg_config_home_path = NULL; - g_free(xdg_data_home_path); - xdg_data_home_path = NULL; -} - -gchar *parse_expand_tilde(const gchar *f) -{ - gchar **spl; - gchar *ret; - - if (!f) - return NULL; - spl = g_strsplit(f, "~", 0); - ret = g_strjoinv(g_get_home_dir(), spl); - g_strfreev(spl); - return ret; -} - -gboolean parse_mkdir(const gchar *path, gint mode) -{ - gboolean ret = TRUE; - - g_return_val_if_fail(path != NULL, FALSE); - g_return_val_if_fail(path[0] != '\0', FALSE); - - if (!g_file_test(path, G_FILE_TEST_IS_DIR)) - if (mkdir(path, mode) == -1) - ret = FALSE; - - 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); - } - - return ret; -} - -const gchar* parse_xdg_config_home_path(void) -{ - return xdg_config_home_path; -} - -const gchar* parse_xdg_data_home_path(void) -{ - return xdg_data_home_path; -} - -GSList* parse_xdg_config_dir_paths(void) -{ - return xdg_config_dir_paths; -} - -GSList* parse_xdg_data_dir_paths(void) -{ - return xdg_data_dir_paths; -} diff --git a/obt/parse.h b/obt/parse.h index 5836df0f..37f0439e 100644 --- a/obt/parse.h +++ b/obt/parse.h @@ -82,24 +82,6 @@ gboolean obt_parse_attr_int (xmlNodePtr node, const gchar *name, gboolean obt_parse_attr_bool (xmlNodePtr node, const gchar *name, gboolean *value); -/* paths */ - -void parse_paths_startup(); -void parse_paths_shutdown(); - -const gchar* parse_xdg_config_home_path(); -const gchar* parse_xdg_data_home_path(); -GSList* parse_xdg_config_dir_paths(); -GSList* parse_xdg_data_dir_paths(); - -/*! Expands the ~ character to the home directory throughout the given - string */ -gchar *parse_expand_tilde(const gchar *f); -/*! Makes a directory */ -gboolean parse_mkdir(const gchar *path, gint mode); -/*! Makes a directory and all its parents */ -gboolean parse_mkdir_path(const gchar *path, gint mode); - G_END_DECLS #endif diff --git a/obt/paths.c b/obt/paths.c new file mode 100644 index 00000000..6357b777 --- /dev/null +++ b/obt/paths.c @@ -0,0 +1,234 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + obt/paths.c for the Openbox window manager + Copyright (c) 2003-2007 Dana Jansens + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#include "obt/paths.h" +#include "obt/util.h" + +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif + +struct _ObtPaths +{ + gint ref; + gchar *config_home; + gchar *data_home; + GSList *config_dirs; + GSList *data_dirs; +}; + +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); + else + g_free(data); + + return list; +} + +static GSList* split_paths(const gchar *paths) +{ + GSList *list = NULL; + gchar **spl, **it; + + if (!paths) + return NULL; + spl = g_strsplit(paths, ":", -1); + for (it = spl; *it; ++it) + list = slist_path_add(list, *it, (GSListFunc) g_slist_append); + g_free(spl); + return list; +} + +ObtPaths* obt_paths_new(void) +{ + ObtPaths *p; + const gchar *path; + + p = g_new(ObtPaths, 1); + p->ref = 1; + + path = g_getenv("XDG_CONFIG_HOME"); + if (path && path[0] != '\0') /* not unset or empty */ + p->config_home = g_build_filename(path, NULL); + else + p->config_home = g_build_filename(g_get_home_dir(), ".config", NULL); + + path = g_getenv("XDG_DATA_HOME"); + if (path && path[0] != '\0') /* not unset or empty */ + p->data_home = g_build_filename(path, NULL); + else + p->data_home = g_build_filename(g_get_home_dir(), ".local", + "share", NULL); + + path = g_getenv("XDG_CONFIG_DIRS"); + if (path && path[0] != '\0') /* not unset or empty */ + p->config_dirs = split_paths(path); + else { + p->config_dirs = slist_path_add(p->config_dirs, + g_strdup(CONFIGDIR), + (GSListFunc) g_slist_append); + p->config_dirs = slist_path_add(p->config_dirs, + g_build_filename + (G_DIR_SEPARATOR_S, + "etc", "xdg", NULL), + (GSListFunc) g_slist_append); + } + p->config_dirs = slist_path_add(p->config_dirs, + g_strdup(p->config_home), + (GSListFunc) g_slist_prepend); + + path = g_getenv("XDG_DATA_DIRS"); + if (path && path[0] != '\0') /* not unset or empty */ + p->data_dirs = split_paths(path); + else { + p->data_dirs = slist_path_add(p->data_dirs, + g_strdup(DATADIR), + (GSListFunc) g_slist_append); + p->data_dirs = slist_path_add(p->data_dirs, + g_build_filename + (G_DIR_SEPARATOR_S, + "usr", "local", "share", NULL), + (GSListFunc) g_slist_append); + p->data_dirs = slist_path_add(p->data_dirs, + g_build_filename + (G_DIR_SEPARATOR_S, + "usr", "share", NULL), + (GSListFunc) g_slist_append); + } + p->data_dirs = slist_path_add(p->data_dirs, + g_strdup(p->data_home), + (GSListFunc) g_slist_prepend); + return p; +} + +void obt_paths_ref(ObtPaths *p) +{ + ++p->ref; +} + +void obt_paths_unref(ObtPaths *p) +{ + if (p && --p->ref == 0) { + GSList *it; + + for (it = p->config_dirs; it; it = g_slist_next(it)) + g_free(it->data); + g_slist_free(p->config_dirs); + for (it = p->data_dirs; it; it = g_slist_next(it)) + g_free(it->data); + g_slist_free(p->data_dirs); + g_free(p->config_home); + g_free(p->data_home); + + obt_free0(p, ObtPaths, 1); + } +} + +gchar *obt_paths_expand_tilde(const gchar *f) +{ + gchar **spl; + gchar *ret; + + if (!f) + return NULL; + spl = g_strsplit(f, "~", 0); + ret = g_strjoinv(g_get_home_dir(), spl); + g_strfreev(spl); + return ret; +} + +gboolean obt_paths_mkdir(const gchar *path, gint mode) +{ + gboolean ret = TRUE; + + g_return_val_if_fail(path != NULL, FALSE); + g_return_val_if_fail(path[0] != '\0', FALSE); + + if (!g_file_test(path, G_FILE_TEST_IS_DIR)) + if (mkdir(path, mode) == -1) + ret = FALSE; + + return ret; +} + +gboolean obt_paths_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 = obt_paths_mkdir(c, mode))) + goto parse_mkdir_path_end; + *e = '/'; + } + ret = obt_paths_mkdir(c, mode); + + parse_mkdir_path_end: + g_free(c); + } + + return ret; +} + +const gchar* obt_paths_config_home(ObtPaths *p) +{ + return p->config_home; +} + +const gchar* obt_paths_data_home(ObtPaths *p) +{ + return p->data_home; +} + +GSList* obt_paths_config_dirs(ObtPaths *p) +{ + return p->config_dirs; +} + +GSList* obt_paths_data_dirs(ObtPaths *p) +{ + return p->data_dirs; +} diff --git a/obt/paths.h b/obt/paths.h new file mode 100644 index 00000000..b9a09595 --- /dev/null +++ b/obt/paths.h @@ -0,0 +1,43 @@ +/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- + + obt/paths.h for the Openbox window manager + Copyright (c) 2003-2007 Dana Jansens + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + See the COPYING file for a copy of the GNU General Public License. +*/ + +#ifndef __obt_paths_h +#define __obt_paths_h + +#include + +G_BEGIN_DECLS + +typedef struct _ObtPaths ObtPaths; + +ObtPaths* obt_paths_new(); +void obt_paths_ref(ObtPaths *p); +void obt_paths_unref(ObtPaths *p); + +const gchar* obt_paths_config_home(ObtPaths *p); +const gchar* obt_paths_data_home(ObtPaths *p); +GSList* obt_paths_config_dirs(ObtPaths *p); +GSList* obt_paths_data_dirs(ObtPaths *p); + +gchar *obt_paths_expand_tilde(const gchar *f); +gboolean obt_paths_mkdir(const gchar *path, gint mode); +gboolean obt_paths_mkdir_path(const gchar *path, gint mode); + +G_END_DECLS + +#endif -- cgit v1.2.3