X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=parser%2Fparse.c;h=e79eec6e6be3679b041e1d7a5ae06588feb82cd9;hb=c1b2fc5324522f74a14a5cfa210c95e1509a6e7f;hp=75bc3a3da3a6595cf8ff11c26576f539d8d044fd;hpb=cf40ff879161d33f3879c855d0c787d3a335b342;p=chaz%2Fopenbox diff --git a/parser/parse.c b/parser/parse.c index 75bc3a3d..e79eec6e 100644 --- a/parser/parse.c +++ b/parser/parse.c @@ -1,5 +1,14 @@ #include "parse.h" #include +#include +#include +#include + +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 { char *tag; @@ -52,25 +61,40 @@ void parse_register(ObParseInst *i, const char *tag, gboolean parse_load_rc(xmlDocPtr *doc, xmlNodePtr *root) { - char *path; + GSList *it; + gchar *path; gboolean r = FALSE; - path = g_build_filename(g_get_home_dir(), ".openbox", "rc.xml", NULL); - if (parse_load(path, "openbox_config", doc, root)) { - r = TRUE; - } else { + for (it = xdg_config_dir_paths; !r && it; it = g_slist_next(it)) { + path = g_build_filename(it->data, "openbox", "rc.xml", NULL); + r = parse_load(path, "openbox_config", doc, root); g_free(path); - path = g_build_filename(RCDIR, "rc.xml", NULL); - if (parse_load(path, "openbox_config", doc, root)) { - r = TRUE; - } } - g_free(path); if (!r) g_warning("unable to find a valid config file, using defaults"); return r; } +gboolean parse_load_menu(const gchar *file, xmlDocPtr *doc, xmlNodePtr *root) +{ + GSList *it; + gchar *path; + gboolean r = FALSE; + + if (file[0] == '/') { + r = parse_load(file, "openbox_menu", doc, root); + } else { + for (it = xdg_config_dir_paths; !r && it; it = g_slist_next(it)) { + path = g_build_filename(it->data, "openbox", file, NULL); + r = parse_load(path, "openbox_menu", doc, root); + g_free(path); + } + } + if (!r) + g_warning("unable to find a valid menu file '%s'", file); + return r; +} + gboolean parse_load(const char *path, const char *rootname, xmlDocPtr *doc, xmlNodePtr *root) { @@ -136,7 +160,7 @@ void parse_tree(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node) char *parse_string(xmlDocPtr doc, xmlNodePtr node) { - xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE); + xmlChar *c = xmlNodeListGetString(doc, node->children, TRUE); char *s = g_strdup(c ? (char*)c : ""); xmlFree(c); return s; @@ -144,7 +168,7 @@ char *parse_string(xmlDocPtr doc, xmlNodePtr node) int parse_int(xmlDocPtr doc, xmlNodePtr node) { - xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE); + xmlChar *c = xmlNodeListGetString(doc, node->children, TRUE); int i = atoi((char*)c); xmlFree(c); return i; @@ -152,7 +176,7 @@ int parse_int(xmlDocPtr doc, xmlNodePtr node) gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node) { - xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE); + xmlChar *c = xmlNodeListGetString(doc, node->children, TRUE); gboolean b = FALSE; if (!xmlStrcasecmp(c, (const xmlChar*) "true")) b = TRUE; @@ -166,7 +190,7 @@ gboolean parse_bool(xmlDocPtr doc, xmlNodePtr node) gboolean parse_contains(const char *val, xmlDocPtr doc, xmlNodePtr node) { - xmlChar *c = xmlNodeListGetString(doc, node->xmlChildrenNode, TRUE); + xmlChar *c = xmlNodeListGetString(doc, node->children, TRUE); gboolean r; r = !xmlStrcasecmp(c, (const xmlChar*) val); xmlFree(c); @@ -216,3 +240,144 @@ gboolean parse_attr_contains(const char *val, xmlNodePtr node, xmlFree(c); return r; } + +static GSList* split_paths(const gchar *paths) +{ + GSList *list = NULL; + gchar *c, *e, *s; + + c = g_strdup(paths); + s = c; + e = c - 1; + g_message("paths %s", paths); + while ((e = strchr(e + 1, ':'))) { + *e = '\0'; + g_message("s %s", s); + if (s[0] != '\0') + list = g_slist_append(list, g_strdup(s)); + s = e + 1; + } + if (s[0] != '\0') + list = g_slist_append(list, g_strdup(s)); + g_free(c); + return list; +} + +void parse_paths_startup() +{ + gchar *path; + + if (xdg_start) + return; + xdg_start = TRUE; + + path = 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"); + 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"); + 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, + g_build_filename + (G_DIR_SEPARATOR_S, + "etc", "xdg", NULL)); + xdg_config_dir_paths = g_slist_append(xdg_config_dir_paths, + g_strdup(CONFIGDIR)); + } + xdg_config_dir_paths = g_slist_prepend(xdg_config_dir_paths, + xdg_config_home_path); + + path = 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, + g_build_filename + (G_DIR_SEPARATOR_S, + "usr", "local", "share", NULL)); + xdg_data_dir_paths = g_slist_append(xdg_data_dir_paths, + g_build_filename + (G_DIR_SEPARATOR_S, + "usr", "share", NULL)); + xdg_config_dir_paths = g_slist_append(xdg_config_dir_paths, + g_strdup(DATADIR)); + } + xdg_data_dir_paths = g_slist_prepend(xdg_data_dir_paths, + xdg_data_home_path); +} + +void parse_paths_shutdown() +{ + 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; +} + +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; +} + +void parse_mkdir_path(const gchar *path, gint mode) +{ + gchar *c, *e; + + g_assert(path[0] == '/'); + + c = g_strdup(path); + e = c; + while ((e = strchr(e + 1, '/'))) { + *e = '\0'; + mkdir(c, mode); + *e = '/'; + } + mkdir(c, mode); + g_free(c); +} + +const gchar* parse_xdg_config_home_path() +{ + return xdg_config_home_path; +} + +const gchar* parse_xdg_data_home_path() +{ + return xdg_data_home_path; +} + +GSList* parse_xdg_config_dir_paths() +{ + return xdg_config_dir_paths; +} + +GSList* parse_xdg_data_dir_paths() +{ + return xdg_data_dir_paths; +}