X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=parser%2Fparse.c;h=fb53f1c5515cc14f4529debab0ae32c42e9097dd;hb=eb2a0feb0154e86a1c6c117fd0f6d1a18959b694;hp=69343a8e4c7c216ede2069b52ddbe0dc5ca1b3e5;hpb=138d98fc3f743f29bdf78efcdc25b515357d6817;p=chaz%2Fopenbox diff --git a/parser/parse.c b/parser/parse.c index 69343a8e..fb53f1c5 100644 --- a/parser/parse.c +++ b/parser/parse.c @@ -1,7 +1,7 @@ /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- parse.c for the Openbox window manager - Copyright (c) 2003 Ben Jansens + 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 @@ -19,8 +19,10 @@ #include "parse.h" #include #include +#include #include #include +#include static gboolean xdg_start; static gchar *xdg_config_home_path; @@ -31,7 +33,7 @@ static GSList *xdg_data_dir_paths; struct Callback { gchar *tag; ParseCallback func; - void *data; + gpointer data; }; struct _ObParseInst { @@ -61,12 +63,12 @@ void parse_shutdown(ObParseInst *i) } void parse_register(ObParseInst *i, const gchar *tag, - ParseCallback func, void *data) + ParseCallback func, gpointer data) { struct Callback *c; if ((c = g_hash_table_lookup(i->callbacks, tag))) { - g_warning("tag '%s' already registered", tag); + g_warning("Tag '%s' already registered", tag); return; } @@ -89,7 +91,35 @@ gboolean parse_load_rc(xmlDocPtr *doc, xmlNodePtr *root) g_free(path); } if (!r) - g_warning("unable to find a valid config file, using defaults"); + g_warning("Unable to find a valid config file, using defaults"); + return r; +} + +gboolean parse_load_theme(const gchar *name, xmlDocPtr *doc, xmlNodePtr *root, + gchar **retpath) +{ + GSList *it; + gchar *path; + gboolean r = FALSE; + + /* backward compatibility.. */ + path = g_build_filename(g_get_home_dir(), ".themes", name, + "openbox-3", "themerc.xml", NULL); + if ((r = parse_load(path, "openbox_theme", doc, root))) + *retpath = g_path_get_dirname(path); + g_free(path); + + if (!r) { + for (it = xdg_data_dir_paths; !r && it; it = g_slist_next(it)) { + path = g_build_filename(it->data, "themes", name, "openbox-3", + "themerc.xml", NULL); + if ((r = parse_load(path, "openbox_theme", doc, root))) + *retpath = g_path_get_dirname(path); + g_free(path); + } + } + if (!r) + g_warning("Unable to load the theme %s", name); return r; } @@ -109,14 +139,21 @@ gboolean parse_load_menu(const gchar *file, xmlDocPtr *doc, xmlNodePtr *root) } } if (!r) - g_warning("unable to find a valid menu file '%s'", file); + g_warning("Unable to find a valid menu file '%s'", file); return r; } gboolean parse_load(const gchar *path, const gchar *rootname, xmlDocPtr *doc, xmlNodePtr *root) { - if ((*doc = xmlParseFile(path))) { + struct stat s; + if (stat(path, &s) < 0) + return FALSE; + + /* XML_PARSE_BLANKS is needed apparently. When it loads a theme file, + without this option, the tree is weird and has extra nodes in it. */ + if ((*doc = xmlReadFile(path, NULL, + XML_PARSE_NOBLANKS | XML_PARSE_RECOVER))) { *root = xmlDocGetRootElement(*doc); if (!*root) { xmlFreeDoc(*doc); @@ -126,7 +163,7 @@ gboolean parse_load(const gchar *path, const gchar *rootname, if (xmlStrcasecmp((*root)->name, (const xmlChar*)rootname)) { xmlFreeDoc(*doc); *doc = NULL; - g_warning("document %s is of wrong type. root node is " + g_warning("Document %s is of wrong type. root node is " "not '%s'", path, rootname); } } @@ -149,7 +186,7 @@ gboolean parse_load_mem(gpointer data, guint len, const gchar *rootname, if (xmlStrcasecmp((*root)->name, (const xmlChar*)rootname)) { xmlFreeDoc(*doc); *doc = NULL; - g_warning("document in given memory is of wrong type. root " + g_warning("Document in given memory is of wrong type. root " "node is not '%s'", rootname); } } @@ -225,6 +262,28 @@ xmlNodePtr parse_find_node(const gchar *tag, xmlNodePtr node) return NULL; } +gboolean parse_attr_bool(const gchar *name, xmlNodePtr node, gboolean *value) +{ + xmlChar *c = xmlGetProp(node, (const xmlChar*) name); + gboolean r = FALSE; + if (c) { + if (!xmlStrcasecmp(c, (const xmlChar*) "true")) + *value = TRUE, r = TRUE; + else if (!xmlStrcasecmp(c, (const xmlChar*) "yes")) + *value = TRUE, r = TRUE; + else if (!xmlStrcasecmp(c, (const xmlChar*) "on")) + *value = TRUE, r = TRUE; + else if (!xmlStrcasecmp(c, (const xmlChar*) "false")) + *value = FALSE, r = TRUE; + else if (!xmlStrcasecmp(c, (const xmlChar*) "no")) + *value = FALSE, r = TRUE; + else if (!xmlStrcasecmp(c, (const xmlChar*) "off")) + *value = FALSE, r = TRUE; + } + xmlFree(c); + return r; +} + gboolean parse_attr_int(const gchar *name, xmlNodePtr node, gint *value) { xmlChar *c = xmlGetProp(node, (const xmlChar*) name); @@ -253,8 +312,9 @@ gboolean parse_attr_contains(const gchar *val, xmlNodePtr node, const gchar *name) { xmlChar *c = xmlGetProp(node, (const xmlChar*) name); - gboolean r; - r = !xmlStrcasecmp(c, (const xmlChar*) val); + gboolean r = FALSE; + if (c) + r = !xmlStrcasecmp(c, (const xmlChar*) val); xmlFree(c); return r; } @@ -275,6 +335,8 @@ static GSList* slist_path_add(GSList *list, gpointer data, GSListFunc func) if (!g_slist_find_custom(list, data, (GCompareFunc) slist_path_cmp)) list = func(list, data); + else + g_free(data); return list; } @@ -295,27 +357,27 @@ static GSList* split_paths(const gchar *paths) 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 { @@ -329,10 +391,10 @@ void parse_paths_startup() (GSListFunc) g_slist_append); } xdg_config_dir_paths = slist_path_add(xdg_config_dir_paths, - xdg_config_home_path, + g_strdup(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 { @@ -351,7 +413,7 @@ void parse_paths_startup() (GSListFunc) g_slist_append); } xdg_data_dir_paths = slist_path_add(xdg_data_dir_paths, - xdg_data_home_path, + g_strdup(xdg_data_home_path), (GSListFunc) g_slist_prepend); } @@ -371,6 +433,10 @@ void parse_paths_shutdown() 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) @@ -386,21 +452,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) +{ + 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) { - gchar *c, *e; + gboolean ret = TRUE; + + g_return_val_if_fail(path != NULL, FALSE); + g_return_val_if_fail(path[0] == '/', FALSE); - g_assert(path[0] == '/'); + 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'; - mkdir(c, mode); - *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()